View Issue Details

IDProjectCategoryView StatusLast Update
0032549FPCCompilerpublic2019-01-25 19:55
ReporterKeith BowesAssigned To 
PrioritynormalSeverityminorReproducibilityN/A
Status newResolutionopen 
Product Version3.1.1Product Build 
Target VersionFixed in Version 
Summary0032549: ISO 10206 support
DescriptionI'm planning on trying to get Extended Pascal fully supported in FPC, so I'll use this bug to submit incremental patches as I gradually implement it.

Also, semi-on-topic, the Wiki page about Extended Pascal has a couple of errors, so someone with edit permissions should look into it. Namely:
* The mode is called extendedpascal, not extpas (though I wouldn't mind it changing).
* The type access keyword is restricted, not restrictive.
Additional InformationIn this first patch, I've implemented the easy things (the 1s on the scale of 1 to 10 like on the Future Plans page). Namely, complex numbers, date/time, and strings.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files
  • 0001-Complex-numbers-date-time-and-string-routines.patch (12,965 bytes)
    From 54880d4c665c297e76a3978665149fa8c9b64760 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Thu, 12 Oct 2017 15:12:04 -0400
    Subject: [PATCH 1/3] Complex numbers, date/time, and string routines
    
    ---
     rtl/inc/extpas.pp | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
     1 file changed, 301 insertions(+), 2 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 0cbf660954..fbe1a60f15 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -14,10 +14,83 @@
     
      **********************************************************************}
     
    -unit extpas;
    +unit extpas; { TODO: Make a module }
    +
    +{ TODO: Implement these things to make macros unnecessary }
    +{ These macros don't cover all use cases for these keywords anyway }
    +{$MACRO ON}
    +{$DEFINE protected := const}
    +{$DEFINE value := =}
    +
    +{
    +export
    +  iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
    +    Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
    +    BindingType, Extend, { files },
    +    TimeStamp, GetTimeStamp, Date, Time, { date/time }
    +    String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
    +}
     
       interface
     
    +uses
    +  uComplex; { Do I need to also import the definitions from iso7185 ? }
    +
    +{
    +import
    +  SysUtils;
    +  uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
    +}
    +
    +{ Implement as much of ISO 10206 as is possible }
    +
    +type
    +  real = double;
    +
    +{ Required constants }
    +const
    +  maxchar = Chr(255); { Should this depend on the codepage? }
    +
    +  maxreal = 1.7E308;
    +  minreal = 5.0E-324;
    +  epsreal = 1 + 5.0E-15 - 1.0;
    +
    +type
    +{ Complex numbers}
    +  Complex = uComplex.complex; { TODO: Implement as an opaque type }
    +
    +function Cmplx(re, im: real): Complex;
    +function Im(x: Complex): real;
    +function Re(x: Complex): real;
    +
    +{ The real and integer versions should be handled by System }
    +function abs(x: Complex): real; overload;
    +function arctan(x: Complex): Complex; overload;
    +function cos(x: Complex): Complex; overload;
    +function exp(x: Complex): Complex; overload;
    +function ln(x: Complex): Complex; overload;
    +function sin(x: Complex): Complex; overload;
    +function sqr(x: Complex): Complex; overload;
    +function sqrt(x: Complex): Complex; overload;
    +
    +{ AFAIK, not provided in System }
    +function arg(x: Complex): real;
    +function polar(r, t: real): Complex;
    +
    +{ TODO: Operators?  Are these importable from uComplex, or must I rewrite them? E.g. uComplex.+ doesn't work. }
    +{ TODO: Implement the required operator pow (non-real powers) }
    +
    +{ File routines }
    +type
    +  BindingType = packed record
    +    Name: String;
    +    Bound: Boolean;
    +  end;
    +
    +procedure Extend(var f: text);
    +{ TODO: Implement other file functions: Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty, and the bindable keyword }
    +
    +{ date/time }
         type
           TimeStamp = packed record
             DateValid : Boolean;
    @@ -33,11 +106,159 @@ unit extpas;
           end;
     
         procedure GetTimeStamp(var ts : TimeStamp);
    +function Date(t: TimeStamp): String;
    +function Time(t: TimeStamp): String;
    +
    +{ Strings }
    +{
    +type
    +  String(capacity: integer) = packed array[0..capacity-1] of char;
    +} { TODO: Implement ISO 10206 string type; just settling for Short/Ansi strings for now }
    +
    +function Index(s1, s2: String): integer;
    +function Substr(s: String; i: integer): String;
    +function Substr(s: String; i, j: integer): String;
    +function Trim(protected s: String): String; { It's not marked as protected in the spec; it's just to show the syntax }
    +
    +function EQ(s1, s2: String): Boolean;
    +function LT(s1, s2: String): Boolean;
    +function GT(s1, s2: String): Boolean;
    +function NE(s1, s2: String): Boolean;
    +function LE(s1, s2: String): Boolean;
    +function GE(s1, s2: String): Boolean;
     
       implementation
     
         uses
    -      dos;
    +{$IFDEF UNIX}
    +  clocale,
    +{$ENDIF}
    +      dos, SysUtils;
    +{
    +import
    +{$IFDEF UNIX}
    +  clocale; { So that dates will print out in a localized format }  
    +{$ENDIF}
    +  dos;
    +}
    +
    +function Cmplx(re, im: real): Complex;
    +begin
    +  Cmplx := cinit(re, im);
    +end;
    +
    +function Im(x: Complex): real;
    +begin
    +  Im := x.im;
    +end;
    +
    +function Re(x: Complex): real;
    +begin
    +  Re := x.re;
    +end;
    +
    +function abs(x: Complex): real;
    +begin
    +  { Thanks, Wikipedia! }
    +  abs := abs(sqrt(sqr(x.re) + sqr(x.im)));
    +end;
    +
    +function arctan(x: Complex): Complex;
    +begin
    +  arctan := carc_tg(x);
    +end;
    +
    +function cos(x: Complex): Complex;
    +begin
    +  cos := ccos(x);
    +end;
    +
    +function exp(x: Complex): Complex;
    +begin
    +  exp := cexp(x);
    +end;
    +
    +function ln(x: Complex): Complex;
    +begin
    +  ln := cln(x);
    +end;
    +
    +function sin(x: Complex): Complex;
    +begin
    +  sin := csin(x);
    +end;
    +
    +function sqr(x: Complex): Complex;
    +begin
    +  sqr := csqr(x);
    +end;
    +
    +function sqrt(x: Complex): Complex;
    +begin
    +  sqrt := csqrt(x);
    +end;
    +
    +function arg(x: Complex): real;
    +begin
    +  arg := carg(x);
    +end;
    +
    +function polar(r, t: real){ = c}: Complex;
    +var
    +  c: Complex;
    +begin
    +  { Thanks, Wikipedia!  Math gives me a headache, but I somehow figured out how
    +  to convert the equations to Pascal code on my first try }
    +  c.re := r * cos(t);
    +  c.im := r * sin(t);
    +  polar := c;{}
    +end;
    +
    +procedure Extend(var f: text);
    +begin
    +  Append(f);
    +end;
    +
    +{ Keith Bowes's implementation, yielded to Florian Klämpfl's }
    +{
    +procedure GetTimeStamp(var t: TimeStamp);
    +var
    +  day, month, year: word;
    +  hour, minute, second: word;
    +  Millisecond: word;
    +begin
    +  DecodeDate(SysUtils.Date, year, day, month);
    +  DecodeTime(SysUtils.Time, hour, minute, second, Millisecond);
    +
    +  t.DateValid := (day > 0) and (month > 0) and (year >= 1900);
    +  if t.DateValid then
    +  begin
    +    t.day := day;
    +    t.month := month;
    +    t.year := year;
    +  end
    +  else
    +  begin
    +    t.day := 1;
    +    t.month := 1;
    +    t.year := 1;
    +  end;
    +
    +  t.TimeValid := (hour > 0) and (minute > 0) and (second > 0);
    +  if t.TimeValid then
    +  begin
    +    t.hour := hour;
    +    t.minute := minute;
    +    t.second := second;
    +  end
    +  else
    +  begin
    +    t.hour := 0;
    +    t.minute := 0;
    +    t.second := 0;
    +  end;
    +end;
    +}
     
         procedure GetTimeStamp(var ts : TimeStamp);
           var
    @@ -62,5 +283,83 @@ unit extpas;
             ts.second100:=sec100;
           end;
     
    +function Date(t: TimeStamp): String;
    +var
    +  d: TDateTime;
    +begin
    +  d := EncodeDate(t.year, t.month, t.day);
    +  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d); 
    +end;
    +
    +function Time(t: TimeStamp): String;
    +var
    +  d: TDateTime;
    +  MSec: word value 0;
    +begin
    +  d := EncodeTime(t.Hour, t.Minute, t.Second, Msec);
    +  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d); 
    +end;
    +
    +function Index(s1, s2: String): integer;
    +begin
    +  Index := Pos(s2, s1);
    +end;
    +
    +function Substr(s: String; i: integer): String;
    +begin
    +  Substr := Substr(s, i, Length(s) - i + 1);
    +end;
    +
    +function Substr(s: String; i, j: integer): String;
    +begin
    +  Substr := s[i..i+j-1];
    +end;
    +
    +function Trim(protected s: String): String;
    +begin
    +  Trim := SysUtils.Trim(s);
    +end;
    +
    +function EQ(s1, s2: String): Boolean;
    +begin
    +  EQ := ((s1 = s2) and (Length(s1) = Length(s2)));
    +end;
    +
    +function LT(s1, s2: String): Boolean;
    +var
    +  n1, n2: integer;
    +begin
    +  n1 := Length(s1);
    +  n2 := Length(s2);
    +
    +  if n1 < n2 then
    +  begin
    +    LT := (s1 <= Substr(s2, 1, n1));
    +  end
    +  else
    +  begin
    +    LT := (Substr(s1, 1, n2) < s2);
    +  end;
    +end;
    +
    +function GT(s1, s2: String): Boolean;
    +begin
    +  GT := (not LT(s1, s2) and not EQ(s1, s2));
    +end;
    +
    +function NE(s1, s2: String): Boolean;
    +begin
    +  NE := not EQ(s1, s2);
    +end;
    +
    +function LE(s1, s2: String): Boolean;
    +begin
    +  LE := (LT(s1, s2) or EQ(s1, s2));
    +end;
    +
    +function GE(s1, s2: String): Boolean;
    +begin
    +  GE := (not LT(s1, s2));
    +end;
     
     end.
    -- 
    2.13.5
    
    
    From 722c2ba9276cdb746cfd927dd85546dab94003ab Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Thu, 12 Oct 2017 16:59:29 -0400
    Subject: [PATCH 2/3] Made FPC compilable with it
    
    ---
     rtl/Makefile      |  6 ++++--
     rtl/Makefile.fpc  |  6 ++++++
     rtl/inc/extpas.pp | 17 ++++++++++-------
     3 files changed, 20 insertions(+), 9 deletions(-)
    
    diff --git a/rtl/Makefile b/rtl/Makefile
    index 259b7374c5..8e6952095c 100644
    --- a/rtl/Makefile
    +++ b/rtl/Makefile
    @@ -3625,7 +3625,6 @@ win16:
     	$(MAKE) -C win16 all
     .PHONY: win16_all win16_debug win16_smart win16_release win16_units win16_examples win16_shared win16_install win16_sourceinstall win16_exampleinstall win16_distinstall win16_zipinstall win16_zipsourceinstall win16_zipexampleinstall win16_zipdistinstall win16_clean win16_distclean win16_cleanall win16_info win16_makefiles win16
     endif
    -all: $(addsuffix _all,$(TARGET_DIRS))
     debug: $(addsuffix _debug,$(TARGET_DIRS))
     smart: $(addsuffix _smart,$(TARGET_DIRS))
     release: $(addsuffix _release,$(TARGET_DIRS))
    @@ -3645,8 +3644,11 @@ distclean: fpc_distclean $(addsuffix _distclean,$(TARGET_DIRS))
     cleanall: fpc_cleanall $(addsuffix _cleanall,$(TARGET_DIRS))
     info: fpc_info
     makefiles: fpc_makefiles
    -.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
    +.PHONY: debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
     ifneq ($(wildcard fpcmake.loc),)
     include fpcmake.loc
     endif
     .NOTPARALLEL:
    +.PHONY: all
    +all: $(addsuffix _all,$(TARGET_DIRS))
    +	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
    diff --git a/rtl/Makefile.fpc b/rtl/Makefile.fpc
    index bd8267252d..7d6f28f4d9 100644
    --- a/rtl/Makefile.fpc
    +++ b/rtl/Makefile.fpc
    @@ -57,3 +57,9 @@ fpcdir=..
     
     [rules]
     .NOTPARALLEL:
    +.PHONY: all
    +
    +# uComplex has to be built for extpas, but the compiled version becomes unusable on the next pass
    +# So, we need to delete it after the build
    +all: $(addsuffix _all,$(TARGET_DIRS))
    +	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index fbe1a60f15..c1fe57a840 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -14,6 +14,12 @@
     
      **********************************************************************}
     
    +{$H+}
    +
    +{ Make sure uComplex can be found }
    +{ Should we perhaps move the complex-number code here and then let the uComplex unit import these? }
    +{$UNITPATH ../../packages/rtl-extra/src/inc}
    +
     unit extpas; { TODO: Make a module }
     
     { TODO: Implement these things to make macros unnecessary }
    @@ -38,6 +44,9 @@ uses
     
     {
     import
    +{$IFDEF UNIX}
    +  clocale; { So that dates will print out in a localized format }  
    +{$ENDIF}
       SysUtils;
       uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
     }
    @@ -113,7 +122,7 @@ function Time(t: TimeStamp): String;
     {
     type
       String(capacity: integer) = packed array[0..capacity-1] of char;
    -} { TODO: Implement ISO 10206 string type; just settling for Short/Ansi strings for now }
    +} { TODO: Implement ISO 10206 string type; just settling for Ansistrings for now }
     
     function Index(s1, s2: String): integer;
     function Substr(s: String; i: integer): String;
    @@ -130,15 +139,9 @@ function GE(s1, s2: String): Boolean;
       implementation
     
         uses
    -{$IFDEF UNIX}
    -  clocale,
    -{$ENDIF}
           dos, SysUtils;
     {
     import
    -{$IFDEF UNIX}
    -  clocale; { So that dates will print out in a localized format }  
    -{$ENDIF}
       dos;
     }
     
    -- 
    2.13.5
    
    
    From e58cc70610a1b3100bb36b85d374743a91025565 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Thu, 12 Oct 2017 17:03:04 -0400
    Subject: [PATCH 3/3] Removed the extra whitespaces that seem to bother Git so
     much
    
    ---
     rtl/inc/extpas.pp | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index c1fe57a840..98c20a94fb 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -45,7 +45,7 @@ uses
     {
     import
     {$IFDEF UNIX}
    -  clocale; { So that dates will print out in a localized format }  
    +  clocale; { So that dates will print out in a localized format }
     {$ENDIF}
       SysUtils;
       uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
    @@ -291,7 +291,7 @@ var
       d: TDateTime;
     begin
       d := EncodeDate(t.year, t.month, t.day);
    -  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d); 
    +  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d);
     end;
     
     function Time(t: TimeStamp): String;
    @@ -300,7 +300,7 @@ var
       MSec: word value 0;
     begin
       d := EncodeTime(t.Hour, t.Minute, t.Second, Msec);
    -  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d); 
    +  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d);
     end;
     
     function Index(s1, s2: String): integer;
    -- 
    2.13.5
    
    
  • bind-and-co.patch (122,436 bytes)
    From 54880d4c665c297e76a3978665149fa8c9b64760 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Thu, 12 Oct 2017 15:12:04 -0400
    Subject: [PATCH 01/20] Complex numbers, date/time, and string routines
    
    ---
     rtl/inc/extpas.pp | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
     1 file changed, 301 insertions(+), 2 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 0cbf660954..fbe1a60f15 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -14,10 +14,83 @@
     
      **********************************************************************}
     
    -unit extpas;
    +unit extpas; { TODO: Make a module }
    +
    +{ TODO: Implement these things to make macros unnecessary }
    +{ These macros don't cover all use cases for these keywords anyway }
    +{$MACRO ON}
    +{$DEFINE protected := const}
    +{$DEFINE value := =}
    +
    +{
    +export
    +  iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
    +    Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
    +    BindingType, Extend, { files },
    +    TimeStamp, GetTimeStamp, Date, Time, { date/time }
    +    String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
    +}
     
       interface
     
    +uses
    +  uComplex; { Do I need to also import the definitions from iso7185 ? }
    +
    +{
    +import
    +  SysUtils;
    +  uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
    +}
    +
    +{ Implement as much of ISO 10206 as is possible }
    +
    +type
    +  real = double;
    +
    +{ Required constants }
    +const
    +  maxchar = Chr(255); { Should this depend on the codepage? }
    +
    +  maxreal = 1.7E308;
    +  minreal = 5.0E-324;
    +  epsreal = 1 + 5.0E-15 - 1.0;
    +
    +type
    +{ Complex numbers}
    +  Complex = uComplex.complex; { TODO: Implement as an opaque type }
    +
    +function Cmplx(re, im: real): Complex;
    +function Im(x: Complex): real;
    +function Re(x: Complex): real;
    +
    +{ The real and integer versions should be handled by System }
    +function abs(x: Complex): real; overload;
    +function arctan(x: Complex): Complex; overload;
    +function cos(x: Complex): Complex; overload;
    +function exp(x: Complex): Complex; overload;
    +function ln(x: Complex): Complex; overload;
    +function sin(x: Complex): Complex; overload;
    +function sqr(x: Complex): Complex; overload;
    +function sqrt(x: Complex): Complex; overload;
    +
    +{ AFAIK, not provided in System }
    +function arg(x: Complex): real;
    +function polar(r, t: real): Complex;
    +
    +{ TODO: Operators?  Are these importable from uComplex, or must I rewrite them? E.g. uComplex.+ doesn't work. }
    +{ TODO: Implement the required operator pow (non-real powers) }
    +
    +{ File routines }
    +type
    +  BindingType = packed record
    +    Name: String;
    +    Bound: Boolean;
    +  end;
    +
    +procedure Extend(var f: text);
    +{ TODO: Implement other file functions: Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty, and the bindable keyword }
    +
    +{ date/time }
         type
           TimeStamp = packed record
             DateValid : Boolean;
    @@ -33,11 +106,159 @@ unit extpas;
           end;
     
         procedure GetTimeStamp(var ts : TimeStamp);
    +function Date(t: TimeStamp): String;
    +function Time(t: TimeStamp): String;
    +
    +{ Strings }
    +{
    +type
    +  String(capacity: integer) = packed array[0..capacity-1] of char;
    +} { TODO: Implement ISO 10206 string type; just settling for Short/Ansi strings for now }
    +
    +function Index(s1, s2: String): integer;
    +function Substr(s: String; i: integer): String;
    +function Substr(s: String; i, j: integer): String;
    +function Trim(protected s: String): String; { It's not marked as protected in the spec; it's just to show the syntax }
    +
    +function EQ(s1, s2: String): Boolean;
    +function LT(s1, s2: String): Boolean;
    +function GT(s1, s2: String): Boolean;
    +function NE(s1, s2: String): Boolean;
    +function LE(s1, s2: String): Boolean;
    +function GE(s1, s2: String): Boolean;
     
       implementation
     
         uses
    -      dos;
    +{$IFDEF UNIX}
    +  clocale,
    +{$ENDIF}
    +      dos, SysUtils;
    +{
    +import
    +{$IFDEF UNIX}
    +  clocale; { So that dates will print out in a localized format }  
    +{$ENDIF}
    +  dos;
    +}
    +
    +function Cmplx(re, im: real): Complex;
    +begin
    +  Cmplx := cinit(re, im);
    +end;
    +
    +function Im(x: Complex): real;
    +begin
    +  Im := x.im;
    +end;
    +
    +function Re(x: Complex): real;
    +begin
    +  Re := x.re;
    +end;
    +
    +function abs(x: Complex): real;
    +begin
    +  { Thanks, Wikipedia! }
    +  abs := abs(sqrt(sqr(x.re) + sqr(x.im)));
    +end;
    +
    +function arctan(x: Complex): Complex;
    +begin
    +  arctan := carc_tg(x);
    +end;
    +
    +function cos(x: Complex): Complex;
    +begin
    +  cos := ccos(x);
    +end;
    +
    +function exp(x: Complex): Complex;
    +begin
    +  exp := cexp(x);
    +end;
    +
    +function ln(x: Complex): Complex;
    +begin
    +  ln := cln(x);
    +end;
    +
    +function sin(x: Complex): Complex;
    +begin
    +  sin := csin(x);
    +end;
    +
    +function sqr(x: Complex): Complex;
    +begin
    +  sqr := csqr(x);
    +end;
    +
    +function sqrt(x: Complex): Complex;
    +begin
    +  sqrt := csqrt(x);
    +end;
    +
    +function arg(x: Complex): real;
    +begin
    +  arg := carg(x);
    +end;
    +
    +function polar(r, t: real){ = c}: Complex;
    +var
    +  c: Complex;
    +begin
    +  { Thanks, Wikipedia!  Math gives me a headache, but I somehow figured out how
    +  to convert the equations to Pascal code on my first try }
    +  c.re := r * cos(t);
    +  c.im := r * sin(t);
    +  polar := c;{}
    +end;
    +
    +procedure Extend(var f: text);
    +begin
    +  Append(f);
    +end;
    +
    +{ Keith Bowes's implementation, yielded to Florian Klämpfl's }
    +{
    +procedure GetTimeStamp(var t: TimeStamp);
    +var
    +  day, month, year: word;
    +  hour, minute, second: word;
    +  Millisecond: word;
    +begin
    +  DecodeDate(SysUtils.Date, year, day, month);
    +  DecodeTime(SysUtils.Time, hour, minute, second, Millisecond);
    +
    +  t.DateValid := (day > 0) and (month > 0) and (year >= 1900);
    +  if t.DateValid then
    +  begin
    +    t.day := day;
    +    t.month := month;
    +    t.year := year;
    +  end
    +  else
    +  begin
    +    t.day := 1;
    +    t.month := 1;
    +    t.year := 1;
    +  end;
    +
    +  t.TimeValid := (hour > 0) and (minute > 0) and (second > 0);
    +  if t.TimeValid then
    +  begin
    +    t.hour := hour;
    +    t.minute := minute;
    +    t.second := second;
    +  end
    +  else
    +  begin
    +    t.hour := 0;
    +    t.minute := 0;
    +    t.second := 0;
    +  end;
    +end;
    +}
     
         procedure GetTimeStamp(var ts : TimeStamp);
           var
    @@ -62,5 +283,83 @@ unit extpas;
             ts.second100:=sec100;
           end;
     
    +function Date(t: TimeStamp): String;
    +var
    +  d: TDateTime;
    +begin
    +  d := EncodeDate(t.year, t.month, t.day);
    +  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d); 
    +end;
    +
    +function Time(t: TimeStamp): String;
    +var
    +  d: TDateTime;
    +  MSec: word value 0;
    +begin
    +  d := EncodeTime(t.Hour, t.Minute, t.Second, Msec);
    +  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d); 
    +end;
    +
    +function Index(s1, s2: String): integer;
    +begin
    +  Index := Pos(s2, s1);
    +end;
    +
    +function Substr(s: String; i: integer): String;
    +begin
    +  Substr := Substr(s, i, Length(s) - i + 1);
    +end;
    +
    +function Substr(s: String; i, j: integer): String;
    +begin
    +  Substr := s[i..i+j-1];
    +end;
    +
    +function Trim(protected s: String): String;
    +begin
    +  Trim := SysUtils.Trim(s);
    +end;
    +
    +function EQ(s1, s2: String): Boolean;
    +begin
    +  EQ := ((s1 = s2) and (Length(s1) = Length(s2)));
    +end;
    +
    +function LT(s1, s2: String): Boolean;
    +var
    +  n1, n2: integer;
    +begin
    +  n1 := Length(s1);
    +  n2 := Length(s2);
    +
    +  if n1 < n2 then
    +  begin
    +    LT := (s1 <= Substr(s2, 1, n1));
    +  end
    +  else
    +  begin
    +    LT := (Substr(s1, 1, n2) < s2);
    +  end;
    +end;
    +
    +function GT(s1, s2: String): Boolean;
    +begin
    +  GT := (not LT(s1, s2) and not EQ(s1, s2));
    +end;
    +
    +function NE(s1, s2: String): Boolean;
    +begin
    +  NE := not EQ(s1, s2);
    +end;
    +
    +function LE(s1, s2: String): Boolean;
    +begin
    +  LE := (LT(s1, s2) or EQ(s1, s2));
    +end;
    +
    +function GE(s1, s2: String): Boolean;
    +begin
    +  GE := (not LT(s1, s2));
    +end;
     
     end.
    -- 
    2.13.5
    
    
    From 722c2ba9276cdb746cfd927dd85546dab94003ab Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Thu, 12 Oct 2017 16:59:29 -0400
    Subject: [PATCH 02/20] Made FPC compilable with it
    
    ---
     rtl/Makefile      |  6 ++++--
     rtl/Makefile.fpc  |  6 ++++++
     rtl/inc/extpas.pp | 17 ++++++++++-------
     3 files changed, 20 insertions(+), 9 deletions(-)
    
    diff --git a/rtl/Makefile b/rtl/Makefile
    index 259b7374c5..8e6952095c 100644
    --- a/rtl/Makefile
    +++ b/rtl/Makefile
    @@ -3625,7 +3625,6 @@ win16:
     	$(MAKE) -C win16 all
     .PHONY: win16_all win16_debug win16_smart win16_release win16_units win16_examples win16_shared win16_install win16_sourceinstall win16_exampleinstall win16_distinstall win16_zipinstall win16_zipsourceinstall win16_zipexampleinstall win16_zipdistinstall win16_clean win16_distclean win16_cleanall win16_info win16_makefiles win16
     endif
    -all: $(addsuffix _all,$(TARGET_DIRS))
     debug: $(addsuffix _debug,$(TARGET_DIRS))
     smart: $(addsuffix _smart,$(TARGET_DIRS))
     release: $(addsuffix _release,$(TARGET_DIRS))
    @@ -3645,8 +3644,11 @@ distclean: fpc_distclean $(addsuffix _distclean,$(TARGET_DIRS))
     cleanall: fpc_cleanall $(addsuffix _cleanall,$(TARGET_DIRS))
     info: fpc_info
     makefiles: fpc_makefiles
    -.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
    +.PHONY: debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
     ifneq ($(wildcard fpcmake.loc),)
     include fpcmake.loc
     endif
     .NOTPARALLEL:
    +.PHONY: all
    +all: $(addsuffix _all,$(TARGET_DIRS))
    +	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
    diff --git a/rtl/Makefile.fpc b/rtl/Makefile.fpc
    index bd8267252d..7d6f28f4d9 100644
    --- a/rtl/Makefile.fpc
    +++ b/rtl/Makefile.fpc
    @@ -57,3 +57,9 @@ fpcdir=..
     
     [rules]
     .NOTPARALLEL:
    +.PHONY: all
    +
    +# uComplex has to be built for extpas, but the compiled version becomes unusable on the next pass
    +# So, we need to delete it after the build
    +all: $(addsuffix _all,$(TARGET_DIRS))
    +	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index fbe1a60f15..c1fe57a840 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -14,6 +14,12 @@
     
      **********************************************************************}
     
    +{$H+}
    +
    +{ Make sure uComplex can be found }
    +{ Should we perhaps move the complex-number code here and then let the uComplex unit import these? }
    +{$UNITPATH ../../packages/rtl-extra/src/inc}
    +
     unit extpas; { TODO: Make a module }
     
     { TODO: Implement these things to make macros unnecessary }
    @@ -38,6 +44,9 @@ uses
     
     {
     import
    +{$IFDEF UNIX}
    +  clocale; { So that dates will print out in a localized format }  
    +{$ENDIF}
       SysUtils;
       uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
     }
    @@ -113,7 +122,7 @@ function Time(t: TimeStamp): String;
     {
     type
       String(capacity: integer) = packed array[0..capacity-1] of char;
    -} { TODO: Implement ISO 10206 string type; just settling for Short/Ansi strings for now }
    +} { TODO: Implement ISO 10206 string type; just settling for Ansistrings for now }
     
     function Index(s1, s2: String): integer;
     function Substr(s: String; i: integer): String;
    @@ -130,15 +139,9 @@ function GE(s1, s2: String): Boolean;
       implementation
     
         uses
    -{$IFDEF UNIX}
    -  clocale,
    -{$ENDIF}
           dos, SysUtils;
     {
     import
    -{$IFDEF UNIX}
    -  clocale; { So that dates will print out in a localized format }  
    -{$ENDIF}
       dos;
     }
     
    -- 
    2.13.5
    
    
    From e58cc70610a1b3100bb36b85d374743a91025565 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Thu, 12 Oct 2017 17:03:04 -0400
    Subject: [PATCH 03/20] Removed the extra whitespaces that seem to bother Git
     so much
    
    ---
     rtl/inc/extpas.pp | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index c1fe57a840..98c20a94fb 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -45,7 +45,7 @@ uses
     {
     import
     {$IFDEF UNIX}
    -  clocale; { So that dates will print out in a localized format }  
    +  clocale; { So that dates will print out in a localized format }
     {$ENDIF}
       SysUtils;
       uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
    @@ -291,7 +291,7 @@ var
       d: TDateTime;
     begin
       d := EncodeDate(t.year, t.month, t.day);
    -  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d); 
    +  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d);
     end;
     
     function Time(t: TimeStamp): String;
    @@ -300,7 +300,7 @@ var
       MSec: word value 0;
     begin
       d := EncodeTime(t.Hour, t.Minute, t.Second, Msec);
    -  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d); 
    +  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d);
     end;
     
     function Index(s1, s2: String): integer;
    -- 
    2.13.5
    
    
    From f9ddb617439c1a81943850d5ea1d55beb631cfc9 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sat, 14 Oct 2017 01:04:30 -0400
    Subject: [PATCH 04/20] Otherwise is defined in ISO 10206
    
    ---
     compiler/tokens.pas | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/compiler/tokens.pas b/compiler/tokens.pas
    index 3edfe6e794..6d44f4470e 100644
    --- a/compiler/tokens.pas
    +++ b/compiler/tokens.pas
    @@ -605,7 +605,7 @@ const
           (str:'LOGICALOR'     ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
           (str:'NODEFAULT'     ;special:false;keyword:[m_none];op:NOTOKEN),
           (str:'OBJCCLASS'     ;special:false;keyword:[m_objectivec1];op:NOTOKEN),
    -      (str:'OTHERWISE'     ;special:false;keyword:alllanguagemodes-[m_iso,m_extpas];op:NOTOKEN),
    +      (str:'OTHERWISE'     ;special:false;keyword:alllanguagemodes-[m_iso];op:NOTOKEN),
           (str:'PROCEDURE'     ;special:false;keyword:alllanguagemodes;op:NOTOKEN),
           (str:'PROTECTED'     ;special:false;keyword:[m_none];op:NOTOKEN),
           (str:'PUBLISHED'     ;special:false;keyword:[m_none];op:NOTOKEN),
    -- 
    2.13.5
    
    
    From ecfb0f7189776619f44d5a807a6b3a9e223d8dd7 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sat, 14 Oct 2017 03:08:55 -0400
    Subject: [PATCH 05/20] Moved the complex code to shared include files
    
    ---
     packages/Makefile                      | 436 ++++++++++++++--------------
     packages/Makefile.fpc                  |   3 +
     packages/rtl-extra/src/inc/ucomplex.pp | 515 +--------------------------------
     rtl/Makefile                           |   6 +-
     rtl/Makefile.fpc                       |   6 -
     rtl/inc/complex.inc                    | 367 +++++++++++++++++++++++
     rtl/inc/complexh.inc                   |  89 ++++++
     rtl/inc/extpas.pp                      |  34 ++-
     8 files changed, 709 insertions(+), 747 deletions(-)
     create mode 100644 rtl/inc/complex.inc
     create mode 100644 rtl/inc/complexh.inc
    
    diff --git a/packages/Makefile b/packages/Makefile
    index 2443b4ce93..bf9e7db547 100644
    --- a/packages/Makefile
    +++ b/packages/Makefile
    @@ -1,11 +1,11 @@
     #
    -# Don't edit, this file is generated by FPCMake Version 2.0.0 [2017-08-22 rev 37024]
    +# Don't edit, this file is generated by FPCMake Version 2.0.0 [2014/10/17]
     #
     default: all
    -MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-aros x86_64-dragonfly arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-darwin wasm-wasm sparc64-linux
    -BSDs = freebsd netbsd openbsd darwin dragonfly
    -UNIXs = linux $(BSDs) solaris qnx haiku aix
    -LIMIT83fs = go32v2 os2 emx watcom msdos win16
    +MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
    +BSDs = freebsd netbsd openbsd darwin
    +UNIXs = linux $(BSDs) solaris qnx haiku
    +LIMIT83fs = go32v2 os2 emx watcom
     OSNeedsComspecToRunBatch = go32v2 watcom
     FORCE:
     .PHONY: FORCE
    @@ -178,24 +178,6 @@ else
     ARCH=$(CPU_TARGET)
     endif
     endif
    -ifeq ($(FULL_TARGET),arm-embedded)
    -ifeq ($(SUBARCH),)
    -$(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t or SUBARCH=armv7m) must be defined)
    -endif
    -override FPCOPT+=-Cp$(SUBARCH)
    -endif
    -ifeq ($(FULL_TARGET),avr-embedded)
    -ifeq ($(SUBARCH),)
    -$(error When compiling for avr-embedded, a sub-architecture (e.g. SUBARCH=avr25 or SUBARCH=avr35) must be defined)
    -endif
    -override FPCOPT+=-Cp$(SUBARCH)
    -endif
    -ifeq ($(FULL_TARGET),mipsel-embedded)
    -ifeq ($(SUBARCH),)
    -$(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
    -endif
    -override FPCOPT+=-Cp$(SUBARCH)
    -endif
     ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
     TARGETSUFFIX=$(OS_TARGET)
     SOURCESUFFIX=$(OS_SOURCE)
    @@ -221,18 +203,10 @@ endif
     ifeq ($(OS_TARGET),linux)
     linuxHier=1
     endif
    -ifndef CROSSCOMPILE
    -BUILDFULLNATIVE=1
    -export BUILDFULLNATIVE
    -endif
    -ifdef BUILDFULLNATIVE
    -BUILDNATIVE=1
    -export BUILDNATIVE
    -endif
     export OS_TARGET OS_SOURCE ARCH CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
     ifdef FPCDIR
     override FPCDIR:=$(subst \,/,$(FPCDIR))
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
     override FPCDIR=wrong
     endif
     else
    @@ -241,7 +215,7 @@ endif
     ifdef DEFAULT_FPCDIR
     ifeq ($(FPCDIR),wrong)
     override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
     override FPCDIR=wrong
     endif
     endif
    @@ -255,11 +229,11 @@ endif
     else
     override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
     override FPCDIR:=$(FPCDIR)/..
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
     override FPCDIR:=$(FPCDIR)/..
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
     override FPCDIR:=$(BASEDIR)
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
     override FPCDIR=c:/pp
     endif
     endif
    @@ -277,27 +251,8 @@ endif
     ifndef BINUTILSPREFIX
     ifndef CROSSBINDIR
     ifdef CROSSCOMPILE
    -ifneq ($(OS_TARGET),msdos)
     ifndef DARWIN2DARWIN
    -ifneq ($(CPU_TARGET),jvm)
     BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
    -ifeq ($(OS_TARGET),android)
    -ifeq ($(CPU_TARGET),arm)
    -BINUTILSPREFIX=arm-linux-androideabi-
    -else
    -ifeq ($(CPU_TARGET),i386)
    -BINUTILSPREFIX=i686-linux-android-
    -else
    -ifeq ($(CPU_TARGET),mipsel)
    -BINUTILSPREFIX=mipsel-linux-android-
    -endif
    -endif
    -endif
    -endif
    -endif
    -endif
    -else
    -BINUTILSPREFIX=$(OS_TARGET)-
     endif
     endif
     endif
    @@ -306,7 +261,7 @@ UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
     ifeq ($(UNITSDIR),)
     UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
     endif
    -PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages)
    +PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
     ifndef FPCFPMAKE
     ifdef CROSSCOMPILE
     ifeq ($(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR)))),)
    @@ -363,6 +318,201 @@ endif
     SUB_FPMAKE_SRCS=$(wildcard */fpmake.pp)
     override INSTALL_FPCPACKAGE=y
     override INSTALL_FPCSUBDIR=packages
    +ifeq ($(FULL_TARGET),i386-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-go32v2)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-win32)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-os2)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-freebsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-beos)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-haiku)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-netbsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-solaris)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-qnx)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-netware)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-openbsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-wdosx)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-darwin)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-emx)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-watcom)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-netwlibc)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-wince)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-symbian)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-nativent)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-iphonesim)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),m68k-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),m68k-freebsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),m68k-netbsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),m68k-amiga)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),m68k-atari)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),m68k-openbsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),m68k-palmos)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),m68k-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc-netbsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc-amiga)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc-macos)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc-darwin)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc-morphos)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc-wii)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),sparc-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),sparc-netbsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),sparc-solaris)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),sparc-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-freebsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-netbsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-solaris)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-openbsd)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-darwin)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-win64)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),arm-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),arm-palmos)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),arm-darwin)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),arm-wince)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),arm-gba)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),arm-nds)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),arm-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),arm-symbian)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc64-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc64-darwin)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),powerpc64-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),avr-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),armeb-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),armeb-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),mipsel-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
     ifdef REQUIRE_UNITSDIR
     override UNITSDIR+=$(REQUIRE_UNITSDIR)
     endif
    @@ -591,26 +741,12 @@ SHAREDLIBEXT=.dll
     SHORTSUFFIX=wat
     IMPORTLIBPREFIX=
     endif
    -ifneq ($(CPU_TARGET),jvm)
    -ifeq ($(OS_TARGET),android)
    -BATCHEXT=.sh
    -EXEEXT=
    -HASSHAREDLIB=1
    -SHORTSUFFIX=lnx
    -endif
    -endif
     ifeq ($(OS_TARGET),linux)
     BATCHEXT=.sh
     EXEEXT=
     HASSHAREDLIB=1
     SHORTSUFFIX=lnx
     endif
    -ifeq ($(OS_TARGET),dragonfly)
    -BATCHEXT=.sh
    -EXEEXT=
    -HASSHAREDLIB=1
    -SHORTSUFFIX=df
    -endif
     ifeq ($(OS_TARGET),freebsd)
     BATCHEXT=.sh
     EXEEXT=
    @@ -656,11 +792,6 @@ EXEEXT=
     SHAREDLIBEXT=.library
     SHORTSUFFIX=amg
     endif
    -ifeq ($(OS_TARGET),aros)
    -EXEEXT=
    -SHAREDLIBEXT=.library
    -SHORTSUFFIX=aros
    -endif
     ifeq ($(OS_TARGET),morphos)
     EXEEXT=
     SHAREDLIBEXT=.library
    @@ -734,45 +865,6 @@ EXEEXT=.dol
     SHAREDLIBEXT=.so
     SHORTSUFFIX=wii
     endif
    -ifeq ($(OS_TARGET),aix)
    -BATCHEXT=.sh
    -EXEEXT=
    -SHORTSUFFIX=aix
    -endif
    -ifeq ($(OS_TARGET),java)
    -OEXT=.class
    -ASMEXT=.j
    -SHAREDLIBEXT=.jar
    -SHORTSUFFIX=java
    -endif
    -ifeq ($(CPU_TARGET),jvm)
    -ifeq ($(OS_TARGET),android)
    -OEXT=.class
    -ASMEXT=.j
    -SHAREDLIBEXT=.jar
    -SHORTSUFFIX=android
    -endif
    -endif
    -ifeq ($(OS_TARGET),msdos)
    -STATICLIBPREFIX=
    -STATICLIBEXT=.a
    -SHORTSUFFIX=d16
    -endif
    -ifeq ($(OS_TARGET),embedded)
    -ifeq ($(CPU_TARGET),i8086)
    -STATICLIBPREFIX=
    -STATICLIBEXT=.a
    -else
    -EXEEXT=.bin
    -endif
    -SHORTSUFFIX=emb
    -endif
    -ifeq ($(OS_TARGET),win16)
    -STATICLIBPREFIX=
    -STATICLIBEXT=.a
    -SHAREDLIBEXT=.dll
    -SHORTSUFFIX=w16
    -endif
     ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
     FPCMADE=fpcmade.$(SHORTSUFFIX)
     ZIPSUFFIX=$(SHORTSUFFIX)
    @@ -962,7 +1054,6 @@ ASNAME=$(BINUTILSPREFIX)as
     LDNAME=$(BINUTILSPREFIX)ld
     ARNAME=$(BINUTILSPREFIX)ar
     RCNAME=$(BINUTILSPREFIX)rc
    -NASMNAME=$(BINUTILSPREFIX)nasm
     ifndef ASPROG
     ifdef CROSSBINDIR
     ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
    @@ -991,23 +1082,11 @@ else
     ARPROG=$(ARNAME)
     endif
     endif
    -ifndef NASMPROG
    -ifdef CROSSBINDIR
    -NASMPROG=$(CROSSBINDIR)/$(NASMNAME)$(SRCEXEEXT)
    -else
    -NASMPROG=$(NASMNAME)
    -endif
    -endif
     AS=$(ASPROG)
     LD=$(LDPROG)
     RC=$(RCPROG)
     AR=$(ARPROG)
    -NASM=$(NASMPROG)
    -ifdef inUnix
    -PPAS=./ppas$(SRCBATCHEXT)
    -else
     PPAS=ppas$(SRCBATCHEXT)
    -endif
     ifdef inUnix
     LDCONFIG=ldconfig
     else
    @@ -1055,6 +1134,9 @@ endif
     ifeq ($(FULL_TARGET),i386-solaris)
     REQUIRE_PACKAGES_RTL=1
     endif
    +ifeq ($(FULL_TARGET),i386-qnx)
    +REQUIRE_PACKAGES_RTL=1
    +endif
     ifeq ($(FULL_TARGET),i386-netware)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1091,13 +1173,10 @@ endif
     ifeq ($(FULL_TARGET),i386-iphonesim)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),i386-android)
    +ifeq ($(FULL_TARGET),m68k-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),i386-aros)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),m68k-linux)
    +ifeq ($(FULL_TARGET),m68k-freebsd)
     REQUIRE_PACKAGES_RTL=1
     endif
     ifeq ($(FULL_TARGET),m68k-netbsd)
    @@ -1109,10 +1188,10 @@ endif
     ifeq ($(FULL_TARGET),m68k-atari)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),m68k-palmos)
    +ifeq ($(FULL_TARGET),m68k-openbsd)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),m68k-macos)
    +ifeq ($(FULL_TARGET),m68k-palmos)
     REQUIRE_PACKAGES_RTL=1
     endif
     ifeq ($(FULL_TARGET),m68k-embedded)
    @@ -1142,9 +1221,6 @@ endif
     ifeq ($(FULL_TARGET),powerpc-wii)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),powerpc-aix)
    -REQUIRE_PACKAGES_RTL=1
    -endif
     ifeq ($(FULL_TARGET),sparc-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1181,15 +1257,6 @@ endif
     ifeq ($(FULL_TARGET),x86_64-embedded)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),x86_64-iphonesim)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),x86_64-aros)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),x86_64-dragonfly)
    -REQUIRE_PACKAGES_RTL=1
    -endif
     ifeq ($(FULL_TARGET),arm-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1214,12 +1281,6 @@ endif
     ifeq ($(FULL_TARGET),arm-symbian)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),arm-android)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),arm-aros)
    -REQUIRE_PACKAGES_RTL=1
    -endif
     ifeq ($(FULL_TARGET),powerpc64-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1229,9 +1290,6 @@ endif
     ifeq ($(FULL_TARGET),powerpc64-embedded)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),powerpc64-aix)
    -REQUIRE_PACKAGES_RTL=1
    -endif
     ifeq ($(FULL_TARGET),avr-embedded)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1241,45 +1299,9 @@ endif
     ifeq ($(FULL_TARGET),armeb-embedded)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),mips-linux)
    -REQUIRE_PACKAGES_RTL=1
    -endif
     ifeq ($(FULL_TARGET),mipsel-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),mipsel-embedded)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),mipsel-android)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),jvm-java)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),jvm-android)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),i8086-embedded)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),i8086-msdos)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),i8086-win16)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),aarch64-linux)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),aarch64-darwin)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),wasm-wasm)
    -REQUIRE_PACKAGES_RTL=1
    -endif
    -ifeq ($(FULL_TARGET),sparc64-linux)
    -REQUIRE_PACKAGES_RTL=1
    -endif
     ifdef REQUIRE_PACKAGES_RTL
     PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
     ifneq ($(PACKAGEDIR_RTL),)
    @@ -1330,7 +1352,6 @@ endif
     ifeq ($(OS_SOURCE),openbsd)
     override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
     override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
    -override FPMAKE_BUILD_OPT+=-FD$(NEW_BINUTILS_PATH)
     endif
     ifndef CROSSBOOTSTRAP
     ifneq ($(BINUTILSPREFIX),)
    @@ -1343,7 +1364,6 @@ endif
     ifndef CROSSCOMPILE
     ifneq ($(BINUTILSPREFIX),)
     override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
    -override FPMAKE_BUILD_OPT+=-XP$(BINUTILSPREFIX)
     endif
     endif
     ifdef UNITDIR
    @@ -1432,20 +1452,22 @@ endif
     endif
     ifdef CREATESHARED
     override FPCOPT+=-Cg
    +ifeq ($(CPU_TARGET),i386)
    +override FPCOPT+=-Aas
    +endif
     endif
    -ifneq ($(findstring $(OS_TARGET),dragonfly freebsd openbsd netbsd linux solaris),)
    -ifneq ($(findstring $(CPU_TARGET),x86_64 mips mipsel),)
    +ifeq ($(findstring 2.0.,$(FPC_VERSION)),)
    +ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris),)
    +ifeq ($(CPU_TARGET),x86_64)
     override FPCOPT+=-Cg
     endif
     endif
    +endif
     ifdef LINKSHARED
     endif
     ifdef OPT
     override FPCOPT+=$(OPT)
     endif
    -ifdef FPMAKEBUILDOPT
    -override FPMAKE_BUILD_OPT+=$(FPMAKEBUILDOPT)
    -endif
     ifdef FPCOPTDEF
     override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
     endif
    @@ -1465,24 +1487,18 @@ endif
     ifdef ACROSSCOMPILE
     override FPCOPT+=$(CROSSOPT)
     endif
    -override COMPILER:=$(strip $(FPC) $(FPCOPT))
    -ifneq (,$(findstring -sh ,$(COMPILER)))
    -UseEXECPPAS=1
    -endif
    -ifneq (,$(findstring -s ,$(COMPILER)))
    -ifeq ($(FULL_SOURCE),$(FULL_TARGET))
    -UseEXECPPAS=1
    -endif
    -endif
    -ifneq ($(UseEXECPPAS),1)
    +override COMPILER:=$(FPC) $(FPCOPT)
    +ifeq (,$(findstring -s ,$(COMPILER)))
     EXECPPAS=
     else
    +ifeq ($(FULL_SOURCE),$(FULL_TARGET))
     ifdef RUNBATCH
     EXECPPAS:=@$(RUNBATCH) $(PPAS)
     else
     EXECPPAS:=@$(PPAS)
     endif
     endif
    +endif
     ifdef TARGET_RSTS
     override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
     override CLEANRSTFILES+=$(RSTFILES)
    @@ -1563,10 +1579,6 @@ endif
     ifdef DEBUGSYMEXT
     	-$(DEL) *$(DEBUGSYMEXT)
     endif
    -ifdef LOCALFPMAKEBIN
    -	-$(DEL) $(LOCALFPMAKEBIN)
    -	-$(DEL) $(FPMAKEBINOBJ)
    -endif
     fpc_distclean: cleanall
     .PHONY: fpc_baseinfo
     override INFORULES+=fpc_baseinfo
    diff --git a/packages/Makefile.fpc b/packages/Makefile.fpc
    index 1a856db5cb..e886a37c1f 100644
    --- a/packages/Makefile.fpc
    +++ b/packages/Makefile.fpc
    @@ -12,6 +12,9 @@ fpcsubdir=packages
     [default]
     fpcdir=..
     
    +[compiler]
    +includedir=../rtl/inc
    +
     [prerules]
     # Translate INSTALL_UNITDIR to fpmake's --unitinstalldir parameter
     ifdef INSTALL_UNITDIR
    diff --git a/packages/rtl-extra/src/inc/ucomplex.pp b/packages/rtl-extra/src/inc/ucomplex.pp
    index 87127218a9..fc70785c8c 100644
    --- a/packages/rtl-extra/src/inc/ucomplex.pp
    +++ b/packages/rtl-extra/src/inc/ucomplex.pp
    @@ -12,8 +12,6 @@
     
      **********************************************************************}
     Unit UComplex;
    -{$INLINE ON}
    -{$define TEST_INLINE}
     
     { created for FPC by Pierre Muller }
     { inpired from the complex unit from  JD GAYRARD mai 95 }
    @@ -25,135 +23,14 @@ Unit UComplex;
     {$ifndef FPUNONE}
         uses math;
     
    -    type complex = record
    -                     re : real;
    -                     im : real;
    -                   end;
    +  {$I complexh.inc}
     
    +  type
         pcomplex = ^complex;
     
    -    const i : complex = (re : 0.0; im : 1.0);
    -          _0 : complex = (re : 0.0; im : 0.0);
    -
    -
    -    { assignment overloading is also used in type conversions
    -      (beware also in implicit type conversions)
    -      after this operator any real can be passed to a function
    -      as a complex arg !! }
    -
    -    operator := (r : real) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
     
         { operator := (i : longint) z : complex;
           not needed because longint can be converted to real }
    -
    -
    -    { four operator : +, -, * , /  and comparison = }
    -    operator + (z1, z2 : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    { these ones are created because the code
    -      is simpler and thus faster }
    -    operator + (z1 : complex; r : real) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator + (r : real; z1 : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -
    -    operator - (z1, z2 : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator - (z1 : complex;r : real) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator - (r : real; z1 : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -
    -    operator * (z1, z2 : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator * (z1 : complex; r : real) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator * (r : real; z1 : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -
    -    operator / (znum, zden : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator / (znum : complex; r : real) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator / (r : real; zden : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    { ** is the exponentiation operator }
    -    operator ** (z1, z2 : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator ** (z1 : complex; r : real) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator ** (r : real; z1 : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -
    -    operator = (z1, z2 : complex) b : boolean;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator = (z1 : complex;r : real) b : boolean;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator = (r : real; z1 : complex) b : boolean;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    operator - (z1 : complex) z : complex;
    -    {$ifdef TEST_INLINE}
    -    inline;
    -    {$endif TEST_INLINE}
    -
    -    function cinit(_re,_im : real) : complex;inline;
         function csamevalue(z1, z2 : complex) : boolean;
     
         { complex functions }
    @@ -162,36 +39,11 @@ Unit UComplex;
         { inverse function 1/z }
         function cinv (z : complex) : complex;
     
    -    { complex functions with real return values }
    -    function cmod (z : complex) : real;           { module }
    -    function carg (z : complex) : real;           { argument : a / z = p.e^ia }
    -
    -    { fonctions elementaires }
    -    function cexp (z : complex) : complex;       { exponential }
    -    function cln (z : complex) : complex;        { natural logarithm }
    -    function csqr (z: complex) : complex;        { square }
    -    function csqrt (z : complex) : complex;      { square root }
    -
    -    { complex trigonometric functions  }
    -    function ccos (z : complex) : complex;       { cosinus }
    -    function csin (z : complex) : complex;       { sinus }
    -    function ctg  (z : complex) : complex;       { tangent }
    -
    -    { inverse complex trigonometric functions }
    -    function carc_cos (z : complex) : complex;   { arc cosinus }
    -    function carc_sin (z : complex) : complex;   { arc sinus }
    -    function carc_tg  (z : complex) : complex;   { arc tangent }
    -
         { hyperbolic complex functions }
         function cch (z : complex) : complex;        { hyperbolic cosinus }
         function csh (z : complex) : complex;        { hyperbolic sinus }
         function cth (z : complex) : complex;        { hyperbolic tangent }
     
    -    { inverse hyperbolic complex functions }
    -    function carg_ch (z : complex) : complex;    { hyperbolic arc cosinus }
    -    function carg_sh (z : complex) : complex;    { hyperbolic arc sinus }
    -    function carg_th (z : complex) : complex;    { hyperbolic arc tangente }
    -
         { functions to write out a complex value }
         function cstr(z : complex) : string;
         function cstr(z:complex;len : integer) : string;
    @@ -199,204 +51,13 @@ Unit UComplex;
     
       implementation
     
    -    function cinit(_re,_im : real) : complex;inline;
    -    begin
    -      cinit.re:=_re;
    -      cinit.im:=_im;
    -    end;
    +  {$I complex.inc}
     
         function csamevalue(z1, z2: complex): boolean;
         begin
           csamevalue:=SameValue(z1.re, z2.re) and SameValue(z1.im, z2.im);
         end;
     
    -  operator := (r : real) z : complex;
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -
    -    begin
    -       z.re:=r;
    -       z.im:=0.0;
    -    end;
    -
    -  { four base operations  +, -, * , / }
    -
    -  operator + (z1, z2 : complex) z : complex;
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -    { addition : z := z1 + z2 }
    -    begin
    -       z.re := z1.re + z2.re;
    -       z.im := z1.im + z2.im;
    -    end;
    -
    -  operator + (z1 : complex; r : real) z : complex;
    -  { addition : z := z1 + r }
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -    begin
    -       z.re := z1.re + r;
    -       z.im := z1.im;
    -    end;
    -
    -  operator + (r : real; z1 : complex) z : complex;
    -  { addition : z := r + z1 }
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -
    -    begin
    -       z.re := z1.re + r;
    -       z.im := z1.im;
    -    end;
    -
    -  operator - (z1, z2 : complex) z : complex;
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -    { substraction : z := z1 - z2 }
    -    begin
    -       z.re := z1.re - z2.re;
    -       z.im := z1.im - z2.im;
    -    end;
    -
    -  operator - (z1 : complex; r : real) z : complex;
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -    { substraction : z := z1 - r }
    -    begin
    -       z.re := z1.re - r;
    -       z.im := z1.im;
    -    end;
    -
    -  operator - (z1 : complex) z : complex;
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -    { substraction : z := - z1 }
    -    begin
    -       z.re := -z1.re;
    -       z.im := -z1.im;
    -    end;
    -
    -  operator - (r : real; z1 : complex) z : complex;
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -    { substraction : z := r - z1 }
    -    begin
    -       z.re := r - z1.re;
    -       z.im := - z1.im;
    -    end;
    -
    -  operator * (z1, z2 : complex) z : complex;
    -  { multiplication : z := z1 * z2 }
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -    begin
    -       z.re := (z1.re * z2.re) - (z1.im * z2.im);
    -       z.im := (z1.re * z2.im) + (z1.im * z2.re);
    -    end;
    -
    -  operator * (z1 : complex; r : real) z : complex;
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -    { multiplication : z := z1 * r }
    -    begin
    -       z.re := z1.re * r;
    -       z.im := z1.im * r;
    -    end;
    -
    -  operator * (r : real; z1 : complex) z : complex;
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -  { multiplication : z := r * z1 }
    -    begin
    -       z.re := z1.re * r;
    -       z.im := z1.im * r;
    -    end;
    -
    -  operator / (znum, zden : complex) z : complex;
    -  {$ifdef TEST_INLINE}
    -  inline;
    -  {$endif TEST_INLINE}
    -    { division : z := znum / zden }
    -    { The following algorithm is used to properly handle
    -      denominator overflow:
    -
    -                 |  a + b(d/c)   c - a(d/c)
    -                 |  ---------- + ---------- I     if |d| < |c|
    -      a + b I    |  c + d(d/c)   a + d(d/c)
    -      -------  = |
    -      c + d I    |  b + a(c/d)   -a+ b(c/d)
    -                 |  ---------- + ---------- I     if |d| >= |c|
    -                 |  d + c(c/d)   d + c(c/d)
    -    }
    -     var
    -       tmp, denom : real;
    -     begin
    -       if ( abs(zden.re) > abs(zden.im) ) then
    -       begin
    -          tmp := zden.im / zden.re;
    -          denom := zden.re + zden.im * tmp;
    -          z.re := (znum.re + znum.im * tmp) / denom;
    -          z.im := (znum.im - znum.re * tmp) / denom;
    -       end
    -       else
    -       begin
    -          tmp := zden.re / zden.im;
    -          denom := zden.im + zden.re * tmp;
    -          z.re := (znum.im + znum.re * tmp) / denom;
    -          z.im := (-znum.re + znum.im * tmp) / denom;
    -       end;
    -     end;
    -
    -    operator / (znum : complex; r : real) z : complex;
    -      { division : z := znum / r }
    -      begin
    -         z.re := znum.re / r;
    -         z.im := znum.im / r;
    -      end;
    -
    -  operator / (r : real; zden : complex) z : complex;
    -    { division : z := r / zden }
    -    var denom : real;
    -    begin
    -       with zden do denom := (re * re) + (im * im);
    -       { generates a fpu exception if denom=0 as for reals }
    -       z.re := (r * zden.re) / denom;
    -       z.im := - (r * zden.im) / denom;
    -    end;
    -
    -  function cmod (z : complex): real;
    -    { module : r = |z| }
    -    begin
    -       with z do
    -         cmod := sqrt((re * re) + (im * im));
    -    end;
    -
    -  function carg (z : complex): real;
    -    { argument : 0 / z = p ei0 }
    -    begin
    -       carg := arctan2(z.im, z.re);
    -    end;
    -
    -  function cong (z : complex) : complex;
    -    { complex conjugee :
    -       if z := x + i.y
    -       then cong is x - i.y }
    -    begin
    -       cong.re := z.re;
    -       cong.im := - z.im;
    -    end;
    -
       function cinv (z : complex) : complex;
         { inverse : r := 1 / z }
         var
    @@ -408,151 +69,6 @@ Unit UComplex;
            cinv.im:=-z.im/denom;
         end;
     
    -  operator = (z1, z2 : complex) b : boolean;
    -    { returns TRUE if z1 = z2 }
    -    begin
    -       b := (z1.re = z2.re) and (z1.im = z2.im);
    -    end;
    -
    -  operator = (z1 : complex; r :real) b : boolean;
    -    { returns TRUE if z1 = r }
    -    begin
    -       b := (z1.re = r) and (z1.im = 0.0)
    -    end;
    -
    -  operator = (r : real; z1 : complex) b : boolean;
    -    { returns TRUE if z1 = r }
    -    begin
    -       b := (z1.re = r) and (z1.im = 0.0)
    -    end;
    -
    -
    -  { fonctions elementaires }
    -
    -  function cexp (z : complex) : complex;
    -    { exponantial : r := exp(z) }
    -    { exp(x + iy) = exp(x).exp(iy) = exp(x).[cos(y) + i sin(y)] }
    -    var expz : real;
    -    begin
    -       expz := exp(z.re);
    -       cexp.re := expz * cos(z.im);
    -       cexp.im := expz * sin(z.im);
    -    end;
    -
    -  function cln (z : complex) : complex;
    -    { natural logarithm : r := ln(z) }
    -    { ln( p exp(i0)) = ln(p) + i0 + 2kpi }
    -    begin
    -       cln.re := ln(cmod(z));
    -       cln.im := arctan2(z.im, z.re);
    -    end;
    -
    -  function csqr(z: complex): complex;
    -    { square : r := z*z }
    -    begin
    -      csqr.re := z.re * z.re - z.im * z.im;
    -      csqr.im := 2 * z.re * z.im;
    -    end;
    -
    -  function csqrt (z : complex) : complex;
    -    { square root : r := sqrt(z) }
    -    var
    -       root, q : real;
    -    begin
    -      if (z.re<>0.0) or (z.im<>0.0) then
    -        begin
    -           root := sqrt(0.5 * (abs(z.re) + cmod(z)));
    -           q := z.im / (2.0 * root);
    -           if z.re >= 0.0 then
    -             begin
    -                csqrt.re := root;
    -                csqrt.im := q;
    -             end
    -           else if z.im < 0.0 then
    -             begin
    -                csqrt.re := - q;
    -                csqrt.im := - root
    -             end
    -           else
    -             begin
    -                csqrt.re :=  q;
    -                csqrt.im :=  root
    -             end
    -        end
    -       else csqrt := z;
    -    end;
    -
    -
    -  operator ** (z1, z2 : complex) z : complex;
    -    { exp : z := z1 ** z2 }
    -    begin
    -       z := cexp(z2*cln(z1));
    -    end;
    -
    -  operator ** (z1 : complex; r : real) z : complex;
    -    { multiplication : z := z1 * r }
    -    begin
    -       z := cexp( r *cln(z1));
    -    end;
    -
    -  operator ** (r : real; z1 : complex) z : complex;
    -    { multiplication : z := r + z1 }
    -    begin
    -       z := cexp(z1*ln(r));
    -    end;
    -
    -  { direct trigonometric functions }
    -
    -  function ccos (z : complex) : complex;
    -    { complex cosinus }
    -    { cos(x+iy) = cos(x).cos(iy) - sin(x).sin(iy) }
    -    { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
    -    begin
    -       ccos.re := cos(z.re) * cosh(z.im);
    -       ccos.im := - sin(z.re) * sinh(z.im);
    -    end;
    -
    -  function csin (z : complex) : complex;
    -    { sinus complex }
    -    { sin(x+iy) = sin(x).cos(iy) + cos(x).sin(iy) }
    -    { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
    -    begin
    -       csin.re := sin(z.re) * cosh(z.im);
    -       csin.im := cos(z.re) * sinh(z.im);
    -    end;
    -
    -  function ctg (z : complex) : complex;
    -    { tangente }
    -    var ccosz, temp : complex;
    -    begin
    -       ccosz := ccos(z);
    -       temp := csin(z);
    -       ctg := temp / ccosz;
    -    end;
    -
    -  { fonctions trigonometriques inverses }
    -
    -  function carc_cos (z : complex) : complex;
    -    { arc cosinus complex }
    -    { arccos(z) = -i.argch(z) }
    -    begin
    -       carc_cos := -i*carg_ch(z);
    -    end;
    -
    -  function carc_sin (z : complex) : complex;
    -    { arc sinus complex }
    -    { arcsin(z) = -i.argsh(i.z) }
    -    begin
    -       carc_sin := -i*carg_sh(i*z);
    -    end;
    -
    -  function carc_tg (z : complex) : complex;
    -    { arc tangente complex }
    -    { arctg(z) = -i.argth(i.z) }
    -    begin
    -       carc_tg := -i*carg_th(i*z);
    -    end;
    -
       { hyberbolic complex functions }
     
       function cch (z : complex) : complex;
    @@ -584,31 +100,6 @@ Unit UComplex;
            cth := z / temp;
         end;
     
    -  { inverse complex hyperbolic functions }
    -
    -  function carg_ch (z : complex) : complex;
    -    {   hyberbolic arg cosinus }
    -    {                          _________  }
    -    { argch(z) = -/+ ln(z + i.V 1 - z.z)  }
    -    begin
    -       carg_ch:=-cln(z+i*csqrt(1.0-z*z));
    -    end;
    -
    -  function carg_sh (z : complex) : complex;
    -    {   hyperbolic arc sinus       }
    -    {                    ________  }
    -    { argsh(z) = ln(z + V 1 + z.z) }
    -    begin
    -       carg_sh:=cln(z+csqrt(z*z+1.0));
    -    end;
    -
    -  function carg_th (z : complex) : complex;
    -    { hyperbolic arc tangent }
    -    { argth(z) = 1/2 ln((z + 1) / (1 - z)) }
    -    begin
    -       carg_th:=cln((z+1.0)/(1.0-z))/2.0;
    -    end;
    -
       { functions to write out a complex value }
       function cstr(z : complex) : string;
         var
    diff --git a/rtl/Makefile b/rtl/Makefile
    index 8e6952095c..259b7374c5 100644
    --- a/rtl/Makefile
    +++ b/rtl/Makefile
    @@ -3625,6 +3625,7 @@ win16:
     	$(MAKE) -C win16 all
     .PHONY: win16_all win16_debug win16_smart win16_release win16_units win16_examples win16_shared win16_install win16_sourceinstall win16_exampleinstall win16_distinstall win16_zipinstall win16_zipsourceinstall win16_zipexampleinstall win16_zipdistinstall win16_clean win16_distclean win16_cleanall win16_info win16_makefiles win16
     endif
    +all: $(addsuffix _all,$(TARGET_DIRS))
     debug: $(addsuffix _debug,$(TARGET_DIRS))
     smart: $(addsuffix _smart,$(TARGET_DIRS))
     release: $(addsuffix _release,$(TARGET_DIRS))
    @@ -3644,11 +3645,8 @@ distclean: fpc_distclean $(addsuffix _distclean,$(TARGET_DIRS))
     cleanall: fpc_cleanall $(addsuffix _cleanall,$(TARGET_DIRS))
     info: fpc_info
     makefiles: fpc_makefiles
    -.PHONY: debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
    +.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
     ifneq ($(wildcard fpcmake.loc),)
     include fpcmake.loc
     endif
     .NOTPARALLEL:
    -.PHONY: all
    -all: $(addsuffix _all,$(TARGET_DIRS))
    -	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
    diff --git a/rtl/Makefile.fpc b/rtl/Makefile.fpc
    index 7d6f28f4d9..bd8267252d 100644
    --- a/rtl/Makefile.fpc
    +++ b/rtl/Makefile.fpc
    @@ -57,9 +57,3 @@ fpcdir=..
     
     [rules]
     .NOTPARALLEL:
    -.PHONY: all
    -
    -# uComplex has to be built for extpas, but the compiled version becomes unusable on the next pass
    -# So, we need to delete it after the build
    -all: $(addsuffix _all,$(TARGET_DIRS))
    -	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
    diff --git a/rtl/inc/complex.inc b/rtl/inc/complex.inc
    new file mode 100644
    index 0000000000..7dd3dff5cb
    --- /dev/null
    +++ b/rtl/inc/complex.inc
    @@ -0,0 +1,367 @@
    +{ ISO 10206 complex numbers implementation }
    +const
    +  Zero = {$IFNDEF FPUNONE}0.0{$ELSE}0{$ENDIF};
    +  One = {$IFNDEF FPUNONE}1.0{$ELSE}1{$ENDIF};
    +  Two = {$IFNDEF FPUNONE}2.0{$ELSE}2{$ENDIF};
    +
    +    function cinit(_re,_im : real) : complex;inline;
    +    begin
    +      cinit.re:=_re;
    +      cinit.im:=_im;
    +    end;
    +
    +  operator := (r : real) z : complex; inline;
    +    begin
    +       z.re:=r;
    +       z.im:=Zero;
    +    end;
    +
    +  { four base operations  +, -, * , / }
    +
    +  operator + (z1, z2 : complex) z : complex; inline;
    +    { addition : z := z1 + z2 }
    +    begin
    +       z.re := z1.re + z2.re;
    +       z.im := z1.im + z2.im;
    +    end;
    +
    +  operator + (z1 : complex; r : real) z : complex; inline;
    +  { addition : z := z1 + r }
    +    begin
    +       z.re := z1.re + r;
    +       z.im := z1.im;
    +    end;
    +
    +  operator + (r : real; z1 : complex) z : complex; inline;
    +  { addition : z := r + z1 }
    +    begin
    +       z.re := z1.re + r;
    +       z.im := z1.im;
    +    end;
    +
    +  operator - (z1, z2 : complex) z : complex; inline;
    +    { substraction : z := z1 - z2 }
    +    begin
    +       z.re := z1.re - z2.re;
    +       z.im := z1.im - z2.im;
    +    end;
    +
    +  operator - (z1 : complex; r : real) z : complex; inline;
    +    { substraction : z := z1 - r }
    +    begin
    +       z.re := z1.re - r;
    +       z.im := z1.im;
    +    end;
    +
    +  operator - (z1 : complex) z : complex; inline;
    +    { substraction : z := - z1 }
    +    begin
    +       z.re := -z1.re;
    +       z.im := -z1.im;
    +    end;
    +
    +  operator - (r : real; z1 : complex) z : complex; inline;
    +    { substraction : z := r - z1 }
    +    begin
    +       z.re := r - z1.re;
    +       z.im := - z1.im;
    +    end;
    +
    +  operator * (z1, z2 : complex) z : complex; inline;
    +  { multiplication : z := z1 * z2 }
    +    begin
    +       z.re := (z1.re * z2.re) - (z1.im * z2.im);
    +       z.im := (z1.re * z2.im) + (z1.im * z2.re);
    +    end;
    +
    +  operator * (z1 : complex; r : real) z : complex; inline;
    +    { multiplication : z := z1 * r }
    +    begin
    +       z.re := z1.re * r;
    +       z.im := z1.im * r;
    +    end;
    +
    +  operator * (r : real; z1 : complex) z : complex; inline;
    +  { multiplication : z := r * z1 }
    +    begin
    +       z.re := z1.re * r;
    +       z.im := z1.im * r;
    +    end;
    +
    +  operator / (znum, zden : complex) z : complex; inline;
    +    { division : z := znum / zden }
    +    { The following algorithm is used to properly handle
    +      denominator overflow:
    +
    +                 |  a + b(d/c)   c - a(d/c)
    +                 |  ---------- + ---------- I     if |d| < |c|
    +      a + b I    |  c + d(d/c)   a + d(d/c)
    +      -------  = |
    +      c + d I    |  b + a(c/d)   -a+ b(c/d)
    +                 |  ---------- + ---------- I     if |d| >= |c|
    +                 |  d + c(c/d)   d + c(c/d)
    +    }
    +     var
    +       tmp, denom : real;
    +     begin
    +       if ( abs(zden.re) > abs(zden.im) ) then
    +       begin
    +          tmp := zden.im / zden.re;
    +          denom := zden.re + zden.im * tmp;
    +          z.re := (znum.re + znum.im * tmp) / denom;
    +          z.im := (znum.im - znum.re * tmp) / denom;
    +       end
    +       else
    +       begin
    +          tmp := zden.re / zden.im;
    +          denom := zden.im + zden.re * tmp;
    +          z.re := (znum.im + znum.re * tmp) / denom;
    +          z.im := (-znum.re + znum.im * tmp) / denom;
    +       end;
    +     end;
    +
    +    operator / (znum : complex; r : real) z : complex;
    +      { division : z := znum / r }
    +      begin
    +         z.re := znum.re / r;
    +         z.im := znum.im / r;
    +      end;
    +
    +  operator / (r : real; zden : complex) z : complex;
    +    { division : z := r / zden }
    +    var denom : real;
    +    begin
    +       with zden do denom := (re * re) + (im * im);
    +       { generates a fpu exception if denom=0 as for reals }
    +       z.re := (r * zden.re) / denom;
    +       z.im := - (r * zden.im) / denom;
    +    end;
    +
    +  function cmod (z : complex): real;
    +    { module : r = |z| }
    +    begin
    +       with z do
    +         cmod := sqrt((re * re) + (im * im));
    +    end;
    +
    +  function carg (z : complex): real;
    +    { argument : 0 / z = p ei0 }
    +    begin
    +      {$IFNDEF FPUNONE}
    +       carg := arctan2(z.im, z.re);
    +       {$ELSE}
    +       carg := Zero;
    +       {$ENDIF}
    +    end;
    +
    +  function cong (z : complex) : complex;
    +    { complex conjugee :
    +       if z := x + i.y
    +       then cong is x - i.y }
    +    begin
    +       cong.re := z.re;
    +       cong.im := - z.im;
    +    end;
    +
    +  operator = (z1, z2 : complex) b : boolean;
    +    { returns TRUE if z1 = z2 }
    +    begin
    +       b := (z1.re = z2.re) and (z1.im = z2.im);
    +    end;
    +
    +  operator = (z1 : complex; r :real) b : boolean;
    +    { returns TRUE if z1 = r }
    +    begin
    +       b := (z1.re = r) and (z1.im = Zero)
    +    end;
    +
    +  operator = (r : real; z1 : complex) b : boolean;
    +    { returns TRUE if z1 = r }
    +    begin
    +       b := (z1.re = r) and (z1.im = Zero)
    +    end;
    +
    +
    +  { fonctions elementaires }
    +
    +  function cexp (z : complex) : complex;
    +    { exponantial : r := exp(z) }
    +    { exp(x + iy) = exp(x).exp(iy) = exp(x).[cos(y) + i sin(y)] }
    +    var expz : real;
    +    begin
    +       expz := exp(z.re);
    +       cexp.re := expz * cos(z.im);
    +       cexp.im := expz * sin(z.im);
    +    end;
    +
    +  function cln (z : complex) : complex;
    +    { natural logarithm : r := ln(z) }
    +    { ln( p exp(i0)) = ln(p) + i0 + 2kpi }
    +    begin
    +       cln.re := ln(cmod(z));
    +       {$IFNDEF FPUNONE}
    +       cln.im := arctan2(z.im, z.re);
    +       {$ELSE}
    +       cln.im := Zero;
    +       {$ENDIF}
    +    end;
    +
    +  function csqr(z: complex): complex;
    +    { square : r := z*z }
    +    begin
    +      csqr.re := z.re * z.re - z.im * z.im;
    +      csqr.im := 2 * z.re * z.im;
    +    end;
    +
    +  function csqrt (z : complex) : complex;
    +    { square root : r := sqrt(z) }
    +    var
    +       root, q : real;
    +    begin
    +      if (z.re<>Zero) or (z.im<>Zero) then
    +        begin
    +          {$IFNDEF FPUNONE}
    +           root := sqrt(0.5 * (abs(z.re) + cmod(z)));
    +           q := z.im / (Two * root);
    +           {$ELSE}
    +           root := 1;
    +           q := z.im div (2 * root);
    +           {$ENDIF}
    +           if z.re >= Zero then
    +             begin
    +                csqrt.re := root;
    +                csqrt.im := q;
    +             end
    +           else if z.im < Zero then
    +             begin
    +                csqrt.re := - q;
    +                csqrt.im := - root
    +             end
    +           else
    +             begin
    +                csqrt.re :=  q;
    +                csqrt.im :=  root
    +             end
    +        end
    +       else csqrt := z;
    +    end;
    +
    +
    +  operator ** (z1, z2 : complex) z : complex;
    +    { exp : z := z1 ** z2 }
    +    begin
    +       z := cexp(z2*cln(z1));
    +    end;
    +
    +  operator ** (z1 : complex; r : real) z : complex;
    +    { multiplication : z := z1 * r }
    +    begin
    +       z := cexp( r *cln(z1));
    +    end;
    +
    +  operator ** (r : real; z1 : complex) z : complex;
    +    { multiplication : z := r + z1 }
    +    begin
    +       z := cexp(z1*ln(r));
    +    end;
    +
    +  { direct trigonometric functions }
    +
    +  function ccos (z : complex) : complex;
    +    { complex cosinus }
    +    { cos(x+iy) = cos(x).cos(iy) - sin(x).sin(iy) }
    +    { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
    +    begin
    +      {$IFNDEF FPUNONE}
    +       ccos.re := cos(z.re) * cosh(z.im);
    +       ccos.im := - sin(z.re) * sinh(z.im);
    +       {$ELSE}
    +       ccos := _0;
    +       {$ENDIF}
    +    end;
    +
    +  function csin (z : complex) : complex;
    +    { sinus complex }
    +    { sin(x+iy) = sin(x).cos(iy) + cos(x).sin(iy) }
    +    { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
    +    begin
    +      {$IFNDEF FPUNONE}
    +       csin.re := sin(z.re) * cosh(z.im);
    +       csin.im := cos(z.re) * sinh(z.im);
    +       {$ELSE}
    +       csin := _0;
    +       {$ENDIF}
    +    end;
    +
    +  function ctg (z : complex) : complex;
    +    { tangente }
    +    var ccosz, temp : complex;
    +    begin
    +       ccosz := ccos(z);
    +       temp := csin(z);
    +       ctg := temp / ccosz;
    +    end;
    +
    +  { fonctions trigonometriques inverses }
    +
    +  function carc_cos (z : complex) : complex;
    +    { arc cosinus complex }
    +    { arccos(z) = -i.argch(z) }
    +    begin
    +      {$IFNDEF FPUNONE}
    +       carc_cos := -i*carg_ch(z);
    +       {$ELSE}
    +       carc_cos := _0;
    +       {$ENDIF}
    +    end;
    +
    +  function carc_sin (z : complex) : complex;
    +    { arc sinus complex }
    +    { arcsin(z) = -i.argsh(i.z) }
    +    begin
    +      {$IFNDEF FPUNONE}
    +       carc_sin := -i*carg_sh(i*z);
    +       {$ELSE}
    +       carc_sin := _0;
    +       {$ENDIF}
    +    end;
    +
    +  function carc_tg (z : complex) : complex;
    +    { arc tangente complex }
    +    { arctg(z) = -i.argth(i.z) }
    +    begin
    +      {$IFNDEF FPUNONE}
    +       carc_tg := -i*carg_th(i*z);
    +       {$ELSE}
    +       carc_tg := _0;
    +       {$ENDIF}
    +    end;
    +
    +  { inverse complex hyperbolic functions }
    +
    +  function carg_ch (z : complex) : complex;
    +    {   hyberbolic arg cosinus }
    +    {                          _________  }
    +    { argch(z) = -/+ ln(z + i.V 1 - z.z)  }
    +    begin
    +      {$IFNDEF CPUNONE}
    +       carg_ch:=-cln(z+i*csqrt(One-z*z));
    +      {$ELSE}
    +       carg_ch := _0;
    +       {$ENDIF}
    +    end;
    +
    +  function carg_sh (z : complex) : complex;
    +    {   hyperbolic arc sinus       }
    +    {                    ________  }
    +    { argsh(z) = ln(z + V 1 + z.z) }
    +    begin
    +       carg_sh:=cln(z+csqrt(z*z+One));
    +    end;
    +
    +  function carg_th (z : complex) : complex;
    +    { hyperbolic arc tangent }
    +    { argth(z) = 1/2 ln((z + 1) / (1 - z)) }
    +    begin
    +       carg_th:=cln((z+One)/(One-z))/Two;
    +    end;
    diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
    new file mode 100644
    index 0000000000..29ce0b0f3a
    --- /dev/null
    +++ b/rtl/inc/complexh.inc
    @@ -0,0 +1,89 @@
    +{ ISO 10206 complex numbers definitions }
    +{$INLINE ON}
    +    type complex = record
    +                     re : real;
    +                     im : real;
    +                   end;
    +
    +    const i : complex = (re : 0.0; im : 1.0);
    +          _0 : complex = (re : 0.0; im : 0.0);
    +
    +    { assignment overloading is also used in type conversions
    +      (beware also in implicit type conversions)
    +      after this operator any real can be passed to a function
    +      as a complex arg !! }
    +
    +    operator := (r : real) z : complex; inline;
    +
    +    { four operator : +, -, * , /  and comparison = }
    +    operator + (z1, z2 : complex) z : complex; inline;
    +
    +    { these ones are created because the code
    +      is simpler and thus faster }
    +    operator + (z1 : complex; r : real) z : complex; inline;
    +
    +    operator + (r : real; z1 : complex) z : complex; inline;
    +
    +
    +    operator - (z1, z2 : complex) z : complex; inline;
    +
    +    operator - (z1 : complex;r : real) z : complex; inline;
    +
    +    operator - (r : real; z1 : complex) z : complex; inline;
    +
    +
    +    operator * (z1, z2 : complex) z : complex; inline;
    +
    +    operator * (z1 : complex; r : real) z : complex; inline;
    +
    +    operator * (r : real; z1 : complex) z : complex; inline;
    +
    +
    +    operator / (znum, zden : complex) z : complex; inline;
    +
    +    operator / (znum : complex; r : real) z : complex; inline;
    +
    +    operator / (r : real; zden : complex) z : complex; inline;
    +
    +    { ** is the exponentiation operator }
    +    operator ** (z1, z2 : complex) z : complex; inline;
    +
    +    operator ** (z1 : complex; r : real) z : complex; inline;
    +
    +    operator ** (r : real; z1 : complex) z : complex; inline;
    +
    +
    +    operator = (z1, z2 : complex) b : boolean; inline;
    +
    +    operator = (z1 : complex;r : real) b : boolean; inline;
    +
    +    operator = (r : real; z1 : complex) b : boolean; inline;
    +
    +    operator - (z1 : complex) z : complex; inline;
    +
    +    function cinit(_re,_im : real) : complex;inline;
    +
    +    { complex functions with real return values }
    +    function cmod (z : complex) : real;           { module }
    +    function carg (z : complex) : real;           { argument : a / z = p.e^ia }
    +
    +    { fonctions elementaires }
    +    function cexp (z : complex) : complex;       { exponential }
    +    function cln (z : complex) : complex;        { natural logarithm }
    +    function csqr (z: complex) : complex;        { square }
    +    function csqrt (z : complex) : complex;      { square root }
    +
    +    { complex trigonometric functions  }
    +    function ccos (z : complex) : complex;       { cosinus }
    +    function csin (z : complex) : complex;       { sinus }
    +    function ctg  (z : complex) : complex;       { tangent }
    +
    +    { inverse complex trigonometric functions }
    +    function carc_cos (z : complex) : complex;   { arc cosinus }
    +    function carc_sin (z : complex) : complex;   { arc sinus }
    +    function carc_tg  (z : complex) : complex;   { arc tangent }
    +
    +    { inverse hyperbolic complex functions }
    +    function carg_ch (z : complex) : complex;    { hyperbolic arc cosinus }
    +    function carg_sh (z : complex) : complex;    { hyperbolic arc sinus }
    +    function carg_th (z : complex) : complex;    { hyperbolic arc tangente }
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 98c20a94fb..6e6cc01022 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -16,10 +16,6 @@
     
     {$H+}
     
    -{ Make sure uComplex can be found }
    -{ Should we perhaps move the complex-number code here and then let the uComplex unit import these? }
    -{$UNITPATH ../../packages/rtl-extra/src/inc}
    -
     unit extpas; { TODO: Make a module }
     
     { TODO: Implement these things to make macros unnecessary }
    @@ -39,35 +35,40 @@ export
     
       interface
     
    -uses
    -  uComplex; { Do I need to also import the definitions from iso7185 ? }
    -
     {
     import
     {$IFDEF UNIX}
       clocale; { So that dates will print out in a localized format }
     {$ENDIF}
       SysUtils;
    -  uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
     }
     
     { Implement as much of ISO 10206 as is possible }
     
     type
    +{$IFNDEF FPUNONE}
       real = double;
    +{$ELSE}
    +  real = integer;
    +{$ENDIF}
    +
    +{$I complexh.inc}
     
     { Required constants }
     const
       maxchar = Chr(255); { Should this depend on the codepage? }
     
    +{$IFNDEF FPUNONE}
       maxreal = 1.7E308;
       minreal = 5.0E-324;
       epsreal = 1 + 5.0E-15 - 1.0;
    +{$ELSE}
    +  maxreal = maxint;
    +  minreal = 0 - maxint - 1;
    +  epsreal = 0;
    +{$ENDIF}
     
    -type
     { Complex numbers}
    -  Complex = uComplex.complex; { TODO: Implement as an opaque type }
    -
     function Cmplx(re, im: real): Complex;
     function Im(x: Complex): real;
     function Re(x: Complex): real;
    @@ -86,7 +87,6 @@ function sqrt(x: Complex): Complex; overload;
     function arg(x: Complex): real;
     function polar(r, t: real): Complex;
     
    -{ TODO: Operators?  Are these importable from uComplex, or must I rewrite them? E.g. uComplex.+ doesn't work. }
     { TODO: Implement the required operator pow (non-real powers) }
     
     { File routines }
    @@ -139,12 +139,20 @@ function GE(s1, s2: String): Boolean;
       implementation
     
         uses
    -      dos, SysUtils;
    +      dos, SysUtils
    +      {$IFNDEF FPUNONE}
    +      , Math
    +      {$ENDIF};
     {
     import
       dos;
    +  {$IFNDEF FPUNONE}
    +  Math;
    +  {$ENDIF}
     }
     
    +{$I complex.inc}
    +
     function Cmplx(re, im: real): Complex;
     begin
       Cmplx := cinit(re, im);
    -- 
    2.13.5
    
    
    From 0c84189e4052cf1b74ac794335150dc338c8f69f Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sat, 14 Oct 2017 03:32:42 -0400
    Subject: [PATCH 06/20] Implemented the ** operator
    
    ---
     rtl/inc/extpas.pp | 19 +++++++++++++++++++
     1 file changed, 19 insertions(+)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 6e6cc01022..42279ddd5b 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -68,6 +68,8 @@ const
       epsreal = 0;
     {$ENDIF}
     
    +operator ** (r1, r2: real) z: real;
    +
     { Complex numbers}
     function Cmplx(re, im: real): Complex;
     function Im(x: Complex): real;
    @@ -151,6 +153,23 @@ import
       {$ENDIF}
     }
     
    +operator ** (r1, r2: real) z: real;
    +{$IFDEF FPUNONE}
    +var
    +  i: real;
    +{$ENDIF}
    +begin
    +  {$IFNDEF FPUNONE}
    +  z := Power(r1, r2);
    +  {$ELSE}
    +  z := 1;
    +  for i := 1 to r2 do
    +  begin
    +    z := z * r1;
    +  end;
    +  {$ENDIF}
    +end;
    +
     {$I complex.inc}
     
     function Cmplx(re, im: real): Complex;
    -- 
    2.13.5
    
    
    From 0a6d05dda593eb5d3a2a1efdc71dc2ac94d3fbff Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sat, 14 Oct 2017 05:39:53 -0400
    Subject: [PATCH 07/20] Removed my version of GetTimeStamp
    
    ---
     rtl/inc/extpas.pp | 41 -----------------------------------------
     1 file changed, 41 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 42279ddd5b..17a763390a 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -249,47 +249,6 @@ begin
       Append(f);
     end;
     
    -{ Keith Bowes's implementation, yielded to Florian Klämpfl's }
    -{
    -procedure GetTimeStamp(var t: TimeStamp);
    -var
    -  day, month, year: word;
    -  hour, minute, second: word;
    -  Millisecond: word;
    -begin
    -  DecodeDate(SysUtils.Date, year, day, month);
    -  DecodeTime(SysUtils.Time, hour, minute, second, Millisecond);
    -
    -  t.DateValid := (day > 0) and (month > 0) and (year >= 1900);
    -  if t.DateValid then
    -  begin
    -    t.day := day;
    -    t.month := month;
    -    t.year := year;
    -  end
    -  else
    -  begin
    -    t.day := 1;
    -    t.month := 1;
    -    t.year := 1;
    -  end;
    -
    -  t.TimeValid := (hour > 0) and (minute > 0) and (second > 0);
    -  if t.TimeValid then
    -  begin
    -    t.hour := hour;
    -    t.minute := minute;
    -    t.second := second;
    -  end
    -  else
    -  begin
    -    t.hour := 0;
    -    t.minute := 0;
    -    t.second := 0;
    -  end;
    -end;
    -}
    -
         procedure GetTimeStamp(var ts : TimeStamp);
           var
             year1,month1,mday1,wday1,
    -- 
    2.13.5
    
    
    From 1d442221126710062c3970fba139a3ec75fc7d61 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sun, 15 Oct 2017 16:16:06 -0400
    Subject: [PATCH 08/20] Implemented ISO 10206 file routines
    
    ---
     rtl/inc/extpas.pp | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
     1 file changed, 160 insertions(+), 3 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 17a763390a..42e7c9d5e2 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -28,7 +28,7 @@ unit extpas; { TODO: Make a module }
     export
       iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
         Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
    -    BindingType, Extend, { files },
    +    BindingType, Extend, Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty { files },
         TimeStamp, GetTimeStamp, Date, Time, { date/time }
         String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
     }
    @@ -94,12 +94,27 @@ function polar(r, t: real): Complex;
     { File routines }
     type
       BindingType = packed record
    -    Name: String;
    +    Name: String{(TextRecNameLength)};
         Bound: Boolean;
       end;
     
    +procedure Bind(var f: text; b: BindingType);
    +procedure Bind(var f: TypedFile; b: BindingType);
    +procedure Unbind(var f: text);
    +procedure Unbind(var f: TypedFile);
    +
    +function Binding(var f: text): BindingType;
    +function Binding(var f: TypedFile): BindingType;
    +
     procedure Extend(var f: text);
    -{ TODO: Implement other file functions: Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty, and the bindable keyword }
    +
    +procedure Update(var f: TypedFile);
    +procedure SeekRead(var f: TypedFile; pos: integer);
    +procedure SeekWrite(var f: TypedFile; pos: integer);
    +procedure SeekUpdate(var f: TypedFile; pos: integer);
    +function Position(var f: TypedFile): integer;
    +function LastPosition(var f: TypedFile): integer;
    +function Empty(var f: TypedFile): Boolean;
     
     { date/time }
         type
    @@ -244,11 +259,153 @@ begin
       polar := c;{}
     end;
     
    +procedure Bind(var f: text; b: BindingType);
    +begin
    +  Assign(f, b.Name);
    +end;
    +
    +procedure Bind(var f: TypedFile; b: BindingType);
    +begin
    +  Assign(f, b.Name);
    +end;
    +
    +procedure Unbind(var f: text);
    +begin
    +  if TextRec(f).Mode <> fmClosed then
    +  begin
    +    Close(f);
    +  end;
    +end;
    +
    +procedure Unbind(var f: TypedFile);
    +begin
    +  if FileRec(f).Mode <> fmClosed then
    +  begin
    +    Close(f);
    +  end;
    +end;
    +
    +function Binding(var f: text): BindingType;
    +var
    +  fe: Boolean;
    +  Mode: longint;
    +begin
    +  Binding.Name := TextRec(f).Name;
    +
    +  Mode := TextRec(f).Mode;
    +  case Mode of
    +    fmClosed:
    +    begin
    +      fe := FileExists(Binding.Name);
    +      { If we can't extend the file, it's obviously not bound}
    +      {$I-}
    +      Append(f); { Has to be Append rather than Extend to catch the IO Error, if any }
    +      Binding.Bound := IOResult = 0;
    +      {$I+}
    +
    +      { If the file didn't already exist, erase it }
    +      if Binding.Bound and not fe then
    +      begin
    +        Erase(f);
    +      end;
    +      
    +      { Unbind the file again }
    +      if Binding.Bound then
    +      begin
    +        Unbind(f);
    +      end;
    +    end;
    +    otherwise
    +    begin
    +      { If the file isn't closed, we can assume it's bound }
    +      Binding.Bound := true;
    +    end;
    +  end;
    +end;
    +
    +function Binding(var f: TypedFile): BindingType;
    +var
    +  Mode: longint;
    +begin
    +  Binding.Name := FileRec(f).Name;
    +
    +  Mode := FileRec(f).Mode;
    +  case Mode of
    +    fmClosed:
    +    begin
    +      {$I-}
    +      { If the file exists, try renaming it }
    +      if FileExists(Binding.Name) then
    +      begin
    +        Rename(f, Binding.Name + '.binding');
    +        Rename(f, Binding.Name);
    +        Binding.Bound := IOResult = 0;
    +      end
    +      { If not, let's try writing to it }
    +      else
    +      begin
    +        Rewrite(f);
    +        Binding.Bound := IOResult = 0;
    +
    +        { Restore to previous state }
    +        if Binding.Bound then
    +        begin
    +          Erase(f);
    +          Unbind(f);
    +        end;
    +      end;
    +      {$I+}
    +    end;
    +    otherwise
    +    begin
    +      { If the file isn't closed, we can assume it's bound }
    +      Binding.Bound := true;
    +    end;
    +  end;
    +end;
    +
     procedure Extend(var f: text);
     begin
       Append(f);
     end;
     
    +procedure Update(var f: TypedFile);
    +begin
    +  SeekWrite(f, 0);
    +end;
    +
    +procedure SeekRead(var f: TypedFile; pos: integer);
    +begin
    +  Reset(f);
    +  Seek(f, pos);
    +end;
    +
    +procedure SeekWrite(var f: TypedFile; pos: integer);
    +begin
    +  Seek(f, pos);
    +  Truncate(f);
    +end;
    +
    +procedure SeekUpdate(var f: TypedFile; pos: integer);
    +begin
    +  Seek(f, pos);
    +end;
    +
    +function Position(var f: TypedFile): integer;
    +begin
    +  Position := FilePos(f);
    +end;
    +
    +function LastPosition(var f: TypedFile): integer;
    +begin
    +  LastPosition := 0; { Proper implementation depends on features that haven't been implemented yet }
    +end;
    +
    +function Empty(var f: TypedFile): Boolean;
    +begin
    +  Empty := Eof(f);
    +end;
    +
         procedure GetTimeStamp(var ts : TimeStamp);
           var
             year1,month1,mday1,wday1,
    -- 
    2.13.5
    
    
    From 105d54d8b1c1ddb106d49da5cf2df77b7275ec3d Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sun, 15 Oct 2017 16:49:52 -0400
    Subject: [PATCH 09/20] At least attempt to use an FPU
    
    ---
     rtl/inc/complexh.inc | 6 ++++++
     rtl/inc/extpas.pp    | 1 +
     2 files changed, 7 insertions(+)
    
    diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
    index 29ce0b0f3a..d7a9642eeb 100644
    --- a/rtl/inc/complexh.inc
    +++ b/rtl/inc/complexh.inc
    @@ -1,5 +1,11 @@
     { ISO 10206 complex numbers definitions }
     {$INLINE ON}
    +
    +{ Try to use at least some FPU, even an emulated one, if possible }
    +{$IFDEF FPUNONE}
    +{$FPUTYPE SOFT}
    +{$ENDIF}
    +
         type complex = record
                          re : real;
                          im : real;
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 42e7c9d5e2..f78411bea5 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -52,6 +52,7 @@ type
       real = integer;
     {$ENDIF}
     
    +{ This has to be included after the real redefinition, or you get errors about unresolved forward references }
     {$I complexh.inc}
     
     { Required constants }
    -- 
    2.13.5
    
    
    From 8dfd34e85f24c035b479e9ccebd4a5ef4405d140 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sun, 15 Oct 2017 17:15:35 -0400
    Subject: [PATCH 10/20] Alternative to defaulting to longstrings, so that
     Write/WriteLn will work in extpas programs (of course, a true ISO 10206
     string type is planned)
    
    ---
     rtl/inc/extpas.pp | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index f78411bea5..d8d65bb6fb 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -14,8 +14,6 @@
     
      **********************************************************************}
     
    -{$H+}
    -
     unit extpas; { TODO: Make a module }
     
     { TODO: Implement these things to make macros unnecessary }
    @@ -459,7 +457,9 @@ end;
     
     function Substr(s: String; i, j: integer): String;
     begin
    -  Substr := s[i..i+j-1];
    +  { The type casting is not part of the standard, but it's necessary for this to be compilable.
    +    Hopefully, the future implementation of the ISO 10206 string type will alleviate this problem. }
    +  Substr := String(AnsiString(s[i..i+j-1]));
     end;
     
     function Trim(protected s: String): String;
    -- 
    2.13.5
    
    
    From 760bd5d3cfafdaa0f918cc40c3236ffbf1e1fd50 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sun, 15 Oct 2017 19:36:08 -0400
    Subject: [PATCH 11/20] Hm, {$FPUTYPE SOFT} generates a fatal error instead of
     a warning. Disabling until it's implemented.
    
    ---
     rtl/inc/complexh.inc | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
    index d7a9642eeb..f514216f05 100644
    --- a/rtl/inc/complexh.inc
    +++ b/rtl/inc/complexh.inc
    @@ -3,7 +3,8 @@
     
     { Try to use at least some FPU, even an emulated one, if possible }
     {$IFDEF FPUNONE}
    -{$FPUTYPE SOFT}
    +{ $FPUTYPE SOFT}
    +{$WARNING No FPU is being used.  Please set one or complex numbers won't work correctly.}
     {$ENDIF}
     
         type complex = record
    -- 
    2.13.5
    
    
    From 7a6914267b215af0d62d7e7c6a69dae7ee191d5a Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sun, 15 Oct 2017 19:40:20 -0400
    Subject: [PATCH 12/20] Exporting in the right order
    
    ---
     rtl/inc/extpas.pp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index d8d65bb6fb..a837659c7d 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -26,7 +26,7 @@ unit extpas; { TODO: Make a module }
     export
       iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
         Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
    -    BindingType, Extend, Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty { files },
    +    BindingType, Bind, Unbind, Binding, Extend, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty { files },
         TimeStamp, GetTimeStamp, Date, Time, { date/time }
         String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
     }
    -- 
    2.13.5
    
    
    From c55451b0307918ee0a441e6f6205ae9bd4825489 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sun, 15 Oct 2017 19:55:58 -0400
    Subject: [PATCH 13/20] Makefile regenerated with latest fpcmake, as to not
     disable some targets
    
    ---
     packages/Makefile | 312 +++++++++++++++++++++++++++++++++++++++++++++++-------
     1 file changed, 276 insertions(+), 36 deletions(-)
    
    diff --git a/packages/Makefile b/packages/Makefile
    index bf9e7db547..e419ea8365 100644
    --- a/packages/Makefile
    +++ b/packages/Makefile
    @@ -1,11 +1,11 @@
     #
    -# Don't edit, this file is generated by FPCMake Version 2.0.0 [2014/10/17]
    +# Don't edit, this file is generated by FPCMake Version 2.0.0 [2017-09-21 rev 37286]
     #
     default: all
    -MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
    -BSDs = freebsd netbsd openbsd darwin
    -UNIXs = linux $(BSDs) solaris qnx haiku
    -LIMIT83fs = go32v2 os2 emx watcom
    +MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-aros x86_64-dragonfly arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-darwin wasm-wasm sparc64-linux
    +BSDs = freebsd netbsd openbsd darwin dragonfly
    +UNIXs = linux $(BSDs) solaris qnx haiku aix
    +LIMIT83fs = go32v2 os2 emx watcom msdos win16
     OSNeedsComspecToRunBatch = go32v2 watcom
     FORCE:
     .PHONY: FORCE
    @@ -178,6 +178,24 @@ else
     ARCH=$(CPU_TARGET)
     endif
     endif
    +ifeq ($(FULL_TARGET),arm-embedded)
    +ifeq ($(SUBARCH),)
    +$(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t or SUBARCH=armv7m) must be defined)
    +endif
    +override FPCOPT+=-Cp$(SUBARCH)
    +endif
    +ifeq ($(FULL_TARGET),avr-embedded)
    +ifeq ($(SUBARCH),)
    +$(error When compiling for avr-embedded, a sub-architecture (e.g. SUBARCH=avr25 or SUBARCH=avr35) must be defined)
    +endif
    +override FPCOPT+=-Cp$(SUBARCH)
    +endif
    +ifeq ($(FULL_TARGET),mipsel-embedded)
    +ifeq ($(SUBARCH),)
    +$(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
    +endif
    +override FPCOPT+=-Cp$(SUBARCH)
    +endif
     ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
     TARGETSUFFIX=$(OS_TARGET)
     SOURCESUFFIX=$(OS_SOURCE)
    @@ -203,10 +221,18 @@ endif
     ifeq ($(OS_TARGET),linux)
     linuxHier=1
     endif
    +ifndef CROSSCOMPILE
    +BUILDFULLNATIVE=1
    +export BUILDFULLNATIVE
    +endif
    +ifdef BUILDFULLNATIVE
    +BUILDNATIVE=1
    +export BUILDNATIVE
    +endif
     export OS_TARGET OS_SOURCE ARCH CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
     ifdef FPCDIR
     override FPCDIR:=$(subst \,/,$(FPCDIR))
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
     override FPCDIR=wrong
     endif
     else
    @@ -215,7 +241,7 @@ endif
     ifdef DEFAULT_FPCDIR
     ifeq ($(FPCDIR),wrong)
     override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
     override FPCDIR=wrong
     endif
     endif
    @@ -229,11 +255,11 @@ endif
     else
     override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
     override FPCDIR:=$(FPCDIR)/..
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
     override FPCDIR:=$(FPCDIR)/..
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
     override FPCDIR:=$(BASEDIR)
    -ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
    +ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
     override FPCDIR=c:/pp
     endif
     endif
    @@ -251,8 +277,27 @@ endif
     ifndef BINUTILSPREFIX
     ifndef CROSSBINDIR
     ifdef CROSSCOMPILE
    +ifneq ($(OS_TARGET),msdos)
     ifndef DARWIN2DARWIN
    +ifneq ($(CPU_TARGET),jvm)
     BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
    +ifeq ($(OS_TARGET),android)
    +ifeq ($(CPU_TARGET),arm)
    +BINUTILSPREFIX=arm-linux-androideabi-
    +else
    +ifeq ($(CPU_TARGET),i386)
    +BINUTILSPREFIX=i686-linux-android-
    +else
    +ifeq ($(CPU_TARGET),mipsel)
    +BINUTILSPREFIX=mipsel-linux-android-
    +endif
    +endif
    +endif
    +endif
    +endif
    +endif
    +else
    +BINUTILSPREFIX=$(OS_TARGET)-
     endif
     endif
     endif
    @@ -261,7 +306,7 @@ UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
     ifeq ($(UNITSDIR),)
     UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
     endif
    -PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
    +PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages)
     ifndef FPCFPMAKE
     ifdef CROSSCOMPILE
     ifeq ($(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR)))),)
    @@ -345,9 +390,6 @@ endif
     ifeq ($(FULL_TARGET),i386-solaris)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    -ifeq ($(FULL_TARGET),i386-qnx)
    -override COMPILER_INCLUDEDIR+=../rtl/inc
    -endif
     ifeq ($(FULL_TARGET),i386-netware)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    @@ -384,10 +426,13 @@ endif
     ifeq ($(FULL_TARGET),i386-iphonesim)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    -ifeq ($(FULL_TARGET),m68k-linux)
    +ifeq ($(FULL_TARGET),i386-android)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i386-aros)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    -ifeq ($(FULL_TARGET),m68k-freebsd)
    +ifeq ($(FULL_TARGET),m68k-linux)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
     ifeq ($(FULL_TARGET),m68k-netbsd)
    @@ -399,10 +444,10 @@ endif
     ifeq ($(FULL_TARGET),m68k-atari)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    -ifeq ($(FULL_TARGET),m68k-openbsd)
    +ifeq ($(FULL_TARGET),m68k-palmos)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    -ifeq ($(FULL_TARGET),m68k-palmos)
    +ifeq ($(FULL_TARGET),m68k-macos)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
     ifeq ($(FULL_TARGET),m68k-embedded)
    @@ -432,6 +477,9 @@ endif
     ifeq ($(FULL_TARGET),powerpc-wii)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    +ifeq ($(FULL_TARGET),powerpc-aix)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
     ifeq ($(FULL_TARGET),sparc-linux)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    @@ -468,6 +516,15 @@ endif
     ifeq ($(FULL_TARGET),x86_64-embedded)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    +ifeq ($(FULL_TARGET),x86_64-iphonesim)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-aros)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),x86_64-dragonfly)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
     ifeq ($(FULL_TARGET),arm-linux)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    @@ -492,6 +549,12 @@ endif
     ifeq ($(FULL_TARGET),arm-symbian)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    +ifeq ($(FULL_TARGET),arm-android)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),arm-aros)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
     ifeq ($(FULL_TARGET),powerpc64-linux)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    @@ -501,6 +564,9 @@ endif
     ifeq ($(FULL_TARGET),powerpc64-embedded)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    +ifeq ($(FULL_TARGET),powerpc64-aix)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
     ifeq ($(FULL_TARGET),avr-embedded)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    @@ -510,9 +576,45 @@ endif
     ifeq ($(FULL_TARGET),armeb-embedded)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    +ifeq ($(FULL_TARGET),mips-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
     ifeq ($(FULL_TARGET),mipsel-linux)
     override COMPILER_INCLUDEDIR+=../rtl/inc
     endif
    +ifeq ($(FULL_TARGET),mipsel-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),mipsel-android)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),jvm-java)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),jvm-android)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i8086-embedded)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i8086-msdos)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),i8086-win16)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),aarch64-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),aarch64-darwin)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),wasm-wasm)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
    +ifeq ($(FULL_TARGET),sparc64-linux)
    +override COMPILER_INCLUDEDIR+=../rtl/inc
    +endif
     ifdef REQUIRE_UNITSDIR
     override UNITSDIR+=$(REQUIRE_UNITSDIR)
     endif
    @@ -741,12 +843,26 @@ SHAREDLIBEXT=.dll
     SHORTSUFFIX=wat
     IMPORTLIBPREFIX=
     endif
    +ifneq ($(CPU_TARGET),jvm)
    +ifeq ($(OS_TARGET),android)
    +BATCHEXT=.sh
    +EXEEXT=
    +HASSHAREDLIB=1
    +SHORTSUFFIX=lnx
    +endif
    +endif
     ifeq ($(OS_TARGET),linux)
     BATCHEXT=.sh
     EXEEXT=
     HASSHAREDLIB=1
     SHORTSUFFIX=lnx
     endif
    +ifeq ($(OS_TARGET),dragonfly)
    +BATCHEXT=.sh
    +EXEEXT=
    +HASSHAREDLIB=1
    +SHORTSUFFIX=df
    +endif
     ifeq ($(OS_TARGET),freebsd)
     BATCHEXT=.sh
     EXEEXT=
    @@ -792,6 +908,11 @@ EXEEXT=
     SHAREDLIBEXT=.library
     SHORTSUFFIX=amg
     endif
    +ifeq ($(OS_TARGET),aros)
    +EXEEXT=
    +SHAREDLIBEXT=.library
    +SHORTSUFFIX=aros
    +endif
     ifeq ($(OS_TARGET),morphos)
     EXEEXT=
     SHAREDLIBEXT=.library
    @@ -865,6 +986,45 @@ EXEEXT=.dol
     SHAREDLIBEXT=.so
     SHORTSUFFIX=wii
     endif
    +ifeq ($(OS_TARGET),aix)
    +BATCHEXT=.sh
    +EXEEXT=
    +SHORTSUFFIX=aix
    +endif
    +ifeq ($(OS_TARGET),java)
    +OEXT=.class
    +ASMEXT=.j
    +SHAREDLIBEXT=.jar
    +SHORTSUFFIX=java
    +endif
    +ifeq ($(CPU_TARGET),jvm)
    +ifeq ($(OS_TARGET),android)
    +OEXT=.class
    +ASMEXT=.j
    +SHAREDLIBEXT=.jar
    +SHORTSUFFIX=android
    +endif
    +endif
    +ifeq ($(OS_TARGET),msdos)
    +STATICLIBPREFIX=
    +STATICLIBEXT=.a
    +SHORTSUFFIX=d16
    +endif
    +ifeq ($(OS_TARGET),embedded)
    +ifeq ($(CPU_TARGET),i8086)
    +STATICLIBPREFIX=
    +STATICLIBEXT=.a
    +else
    +EXEEXT=.bin
    +endif
    +SHORTSUFFIX=emb
    +endif
    +ifeq ($(OS_TARGET),win16)
    +STATICLIBPREFIX=
    +STATICLIBEXT=.a
    +SHAREDLIBEXT=.dll
    +SHORTSUFFIX=w16
    +endif
     ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
     FPCMADE=fpcmade.$(SHORTSUFFIX)
     ZIPSUFFIX=$(SHORTSUFFIX)
    @@ -1054,6 +1214,7 @@ ASNAME=$(BINUTILSPREFIX)as
     LDNAME=$(BINUTILSPREFIX)ld
     ARNAME=$(BINUTILSPREFIX)ar
     RCNAME=$(BINUTILSPREFIX)rc
    +NASMNAME=$(BINUTILSPREFIX)nasm
     ifndef ASPROG
     ifdef CROSSBINDIR
     ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
    @@ -1082,11 +1243,23 @@ else
     ARPROG=$(ARNAME)
     endif
     endif
    +ifndef NASMPROG
    +ifdef CROSSBINDIR
    +NASMPROG=$(CROSSBINDIR)/$(NASMNAME)$(SRCEXEEXT)
    +else
    +NASMPROG=$(NASMNAME)
    +endif
    +endif
     AS=$(ASPROG)
     LD=$(LDPROG)
     RC=$(RCPROG)
     AR=$(ARPROG)
    +NASM=$(NASMPROG)
    +ifdef inUnix
    +PPAS=./ppas$(SRCBATCHEXT)
    +else
     PPAS=ppas$(SRCBATCHEXT)
    +endif
     ifdef inUnix
     LDCONFIG=ldconfig
     else
    @@ -1134,9 +1307,6 @@ endif
     ifeq ($(FULL_TARGET),i386-solaris)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),i386-qnx)
    -REQUIRE_PACKAGES_RTL=1
    -endif
     ifeq ($(FULL_TARGET),i386-netware)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1173,10 +1343,13 @@ endif
     ifeq ($(FULL_TARGET),i386-iphonesim)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),m68k-linux)
    +ifeq ($(FULL_TARGET),i386-android)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),m68k-freebsd)
    +ifeq ($(FULL_TARGET),i386-aros)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),m68k-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
     ifeq ($(FULL_TARGET),m68k-netbsd)
    @@ -1188,10 +1361,10 @@ endif
     ifeq ($(FULL_TARGET),m68k-atari)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),m68k-openbsd)
    +ifeq ($(FULL_TARGET),m68k-palmos)
     REQUIRE_PACKAGES_RTL=1
     endif
    -ifeq ($(FULL_TARGET),m68k-palmos)
    +ifeq ($(FULL_TARGET),m68k-macos)
     REQUIRE_PACKAGES_RTL=1
     endif
     ifeq ($(FULL_TARGET),m68k-embedded)
    @@ -1221,6 +1394,9 @@ endif
     ifeq ($(FULL_TARGET),powerpc-wii)
     REQUIRE_PACKAGES_RTL=1
     endif
    +ifeq ($(FULL_TARGET),powerpc-aix)
    +REQUIRE_PACKAGES_RTL=1
    +endif
     ifeq ($(FULL_TARGET),sparc-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1257,6 +1433,15 @@ endif
     ifeq ($(FULL_TARGET),x86_64-embedded)
     REQUIRE_PACKAGES_RTL=1
     endif
    +ifeq ($(FULL_TARGET),x86_64-iphonesim)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),x86_64-aros)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),x86_64-dragonfly)
    +REQUIRE_PACKAGES_RTL=1
    +endif
     ifeq ($(FULL_TARGET),arm-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1281,6 +1466,12 @@ endif
     ifeq ($(FULL_TARGET),arm-symbian)
     REQUIRE_PACKAGES_RTL=1
     endif
    +ifeq ($(FULL_TARGET),arm-android)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),arm-aros)
    +REQUIRE_PACKAGES_RTL=1
    +endif
     ifeq ($(FULL_TARGET),powerpc64-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1290,6 +1481,9 @@ endif
     ifeq ($(FULL_TARGET),powerpc64-embedded)
     REQUIRE_PACKAGES_RTL=1
     endif
    +ifeq ($(FULL_TARGET),powerpc64-aix)
    +REQUIRE_PACKAGES_RTL=1
    +endif
     ifeq ($(FULL_TARGET),avr-embedded)
     REQUIRE_PACKAGES_RTL=1
     endif
    @@ -1299,9 +1493,45 @@ endif
     ifeq ($(FULL_TARGET),armeb-embedded)
     REQUIRE_PACKAGES_RTL=1
     endif
    +ifeq ($(FULL_TARGET),mips-linux)
    +REQUIRE_PACKAGES_RTL=1
    +endif
     ifeq ($(FULL_TARGET),mipsel-linux)
     REQUIRE_PACKAGES_RTL=1
     endif
    +ifeq ($(FULL_TARGET),mipsel-embedded)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),mipsel-android)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),jvm-java)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),jvm-android)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),i8086-embedded)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),i8086-msdos)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),i8086-win16)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),aarch64-linux)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),aarch64-darwin)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),wasm-wasm)
    +REQUIRE_PACKAGES_RTL=1
    +endif
    +ifeq ($(FULL_TARGET),sparc64-linux)
    +REQUIRE_PACKAGES_RTL=1
    +endif
     ifdef REQUIRE_PACKAGES_RTL
     PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
     ifneq ($(PACKAGEDIR_RTL),)
    @@ -1352,6 +1582,7 @@ endif
     ifeq ($(OS_SOURCE),openbsd)
     override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
     override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
    +override FPMAKE_BUILD_OPT+=-FD$(NEW_BINUTILS_PATH)
     endif
     ifndef CROSSBOOTSTRAP
     ifneq ($(BINUTILSPREFIX),)
    @@ -1364,6 +1595,7 @@ endif
     ifndef CROSSCOMPILE
     ifneq ($(BINUTILSPREFIX),)
     override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
    +override FPMAKE_BUILD_OPT+=-XP$(BINUTILSPREFIX)
     endif
     endif
     ifdef UNITDIR
    @@ -1452,22 +1684,20 @@ endif
     endif
     ifdef CREATESHARED
     override FPCOPT+=-Cg
    -ifeq ($(CPU_TARGET),i386)
    -override FPCOPT+=-Aas
     endif
    -endif
    -ifeq ($(findstring 2.0.,$(FPC_VERSION)),)
    -ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris),)
    -ifeq ($(CPU_TARGET),x86_64)
    +ifneq ($(findstring $(OS_TARGET),dragonfly freebsd openbsd netbsd linux solaris),)
    +ifneq ($(findstring $(CPU_TARGET),x86_64 mips mipsel),)
     override FPCOPT+=-Cg
     endif
     endif
    -endif
     ifdef LINKSHARED
     endif
     ifdef OPT
     override FPCOPT+=$(OPT)
     endif
    +ifdef FPMAKEBUILDOPT
    +override FPMAKE_BUILD_OPT+=$(FPMAKEBUILDOPT)
    +endif
     ifdef FPCOPTDEF
     override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
     endif
    @@ -1487,18 +1717,24 @@ endif
     ifdef ACROSSCOMPILE
     override FPCOPT+=$(CROSSOPT)
     endif
    -override COMPILER:=$(FPC) $(FPCOPT)
    -ifeq (,$(findstring -s ,$(COMPILER)))
    +override COMPILER:=$(strip $(FPC) $(FPCOPT))
    +ifneq (,$(findstring -sh ,$(COMPILER)))
    +UseEXECPPAS=1
    +endif
    +ifneq (,$(findstring -s ,$(COMPILER)))
    +ifeq ($(FULL_SOURCE),$(FULL_TARGET))
    +UseEXECPPAS=1
    +endif
    +endif
    +ifneq ($(UseEXECPPAS),1)
     EXECPPAS=
     else
    -ifeq ($(FULL_SOURCE),$(FULL_TARGET))
     ifdef RUNBATCH
     EXECPPAS:=@$(RUNBATCH) $(PPAS)
     else
     EXECPPAS:=@$(PPAS)
     endif
     endif
    -endif
     ifdef TARGET_RSTS
     override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
     override CLEANRSTFILES+=$(RSTFILES)
    @@ -1579,6 +1815,10 @@ endif
     ifdef DEBUGSYMEXT
     	-$(DEL) *$(DEBUGSYMEXT)
     endif
    +ifdef LOCALFPMAKEBIN
    +	-$(DEL) $(LOCALFPMAKEBIN)
    +	-$(DEL) $(FPMAKEBINOBJ)
    +endif
     fpc_distclean: cleanall
     .PHONY: fpc_baseinfo
     override INFORULES+=fpc_baseinfo
    -- 
    2.13.5
    
    
    From a3625f6d154526f630c5f1b957555d8c4fed7b70 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Sun, 15 Oct 2017 20:53:06 -0400
    Subject: [PATCH 14/20] Less iffy empty function
    
    ---
     rtl/inc/extpas.pp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index a837659c7d..9bb848616b 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -402,7 +402,7 @@ end;
     
     function Empty(var f: TypedFile): Boolean;
     begin
    -  Empty := Eof(f);
    +  Empty := FileSize(f) = 0;
     end;
     
         procedure GetTimeStamp(var ts : TimeStamp);
    -- 
    2.13.5
    
    
    From cd5077d6381ea9b204a3632bf6bd3068cbcd122e Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Mon, 16 Oct 2017 22:47:33 -0400
    Subject: [PATCH 15/20] Further changes for FPU-less systems
    
    ---
     rtl/inc/complex.inc  | 5 -----
     rtl/inc/complexh.inc | 9 +++++++--
     2 files changed, 7 insertions(+), 7 deletions(-)
    
    diff --git a/rtl/inc/complex.inc b/rtl/inc/complex.inc
    index 7dd3dff5cb..3e67c63b3a 100644
    --- a/rtl/inc/complex.inc
    +++ b/rtl/inc/complex.inc
    @@ -1,9 +1,4 @@
     { ISO 10206 complex numbers implementation }
    -const
    -  Zero = {$IFNDEF FPUNONE}0.0{$ELSE}0{$ENDIF};
    -  One = {$IFNDEF FPUNONE}1.0{$ELSE}1{$ENDIF};
    -  Two = {$IFNDEF FPUNONE}2.0{$ELSE}2{$ENDIF};
    -
         function cinit(_re,_im : real) : complex;inline;
         begin
           cinit.re:=_re;
    diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
    index f514216f05..86859fc068 100644
    --- a/rtl/inc/complexh.inc
    +++ b/rtl/inc/complexh.inc
    @@ -6,14 +6,19 @@
     { $FPUTYPE SOFT}
     {$WARNING No FPU is being used.  Please set one or complex numbers won't work correctly.}
     {$ENDIF}
    +const
    +  Zero = {$IFNDEF FPUNONE}0.0{$ELSE}0{$ENDIF};
    +  One = {$IFNDEF FPUNONE}1.0{$ELSE}1{$ENDIF};
    +  Two = {$IFNDEF FPUNONE}2.0{$ELSE}2{$ENDIF};
    +
     
         type complex = record
                          re : real;
                          im : real;
                        end;
     
    -    const i : complex = (re : 0.0; im : 1.0);
    -          _0 : complex = (re : 0.0; im : 0.0);
    +    const i : complex = (re : Zero; im : One);
    +          _0 : complex = (re : Zero; im : Zero);
     
         { assignment overloading is also used in type conversions
           (beware also in implicit type conversions)
    -- 
    2.13.5
    
    
    From 1212c930cfca20f4cc125eb863f07a9bec6f4717 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Mon, 16 Oct 2017 22:48:26 -0400
    Subject: [PATCH 16/20] Fixed Binding.Bound returning false for nonexistent
     text files and a crash with SeekRead
    
    ---
     rtl/inc/extpas.pp | 15 ++++++++++++---
     1 file changed, 12 insertions(+), 3 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 9bb848616b..fa8d1f3bb4 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -298,7 +298,15 @@ begin
           fe := FileExists(Binding.Name);
           { If we can't extend the file, it's obviously not bound}
           {$I-}
    -      Append(f); { Has to be Append rather than Extend to catch the IO Error, if any }
    +      if fe then
    +      begin
    +        Append(f); { Has to be Append rather than Extend to catch the IO Error, if any }
    +      end
    +      else
    +      begin
    +        Rewrite(f);
    +      end;
    +
           Binding.Bound := IOResult = 0;
           {$I+}
     
    @@ -375,8 +383,9 @@ end;
     
     procedure SeekRead(var f: TypedFile; pos: integer);
     begin
    -  Reset(f);
    -  Seek(f, pos);
    +  { f has to be cast to file or calling this function causes a crash }
    +  Reset(file(f));
    +  Seek(file(f), pos);
     end;
     
     procedure SeekWrite(var f: TypedFile; pos: integer);
    -- 
    2.13.5
    
    
    From fb47b910866194442be192f979a49cdcbbbf32cf Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Tue, 17 Oct 2017 00:01:13 -0400
    Subject: [PATCH 17/20] Switched to exceptions as to not propagate the I/O
     errors
    
    ---
     rtl/inc/extpas.pp | 107 +++++++++++++++++++++++++++++-------------------------
     1 file changed, 58 insertions(+), 49 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index fa8d1f3bb4..758ba4bc01 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -14,6 +14,8 @@
     
      **********************************************************************}
     
    +{$modeswitch exceptions}
    +
     unit extpas; { TODO: Make a module }
     
     { TODO: Implement these things to make macros unnecessary }
    @@ -290,43 +292,46 @@ var
       Mode: longint;
     begin
       Binding.Name := TextRec(f).Name;
    +  Binding.Bound := true;
     
       Mode := TextRec(f).Mode;
       case Mode of
         fmClosed:
         begin
           fe := FileExists(Binding.Name);
    -      { If we can't extend the file, it's obviously not bound}
    -      {$I-}
    -      if fe then
    -      begin
    -        Append(f); { Has to be Append rather than Extend to catch the IO Error, if any }
    -      end
    -      else
    -      begin
    -        Rewrite(f);
    -      end;
    -
    -      Binding.Bound := IOResult = 0;
    -      {$I+}
    +      try
    +        try
    +          { If we can't extend the file, it's obviously not bound}
    +          if fe then
    +          begin
    +            Extend(f);
    +          end
    +          else
    +          begin
    +            Rewrite(f);
    +          end;
    +        except
    +          Binding.Bound := false;
    +        end;
    +      finally
    +        { If the file didn't already exist, erase it }
    +        try
    +          if not fe then
    +          begin
    +            Unbind(f);
    +            Erase(f);
    +          end;
    +        except
    +          { If this fails, it can be silently ignored }
    +        end;
     
    -      { If the file didn't already exist, erase it }
    -      if Binding.Bound and not fe then
    -      begin
    -        Erase(f);
    -      end;
    -      
    -      { Unbind the file again }
    -      if Binding.Bound then
    -      begin
    -        Unbind(f);
    +        { Unbind the file again }
    +        if Binding.Bound then
    +        begin
    +          Unbind(f);
    +        end;
           end;
         end;
    -    otherwise
    -    begin
    -      { If the file isn't closed, we can assume it's bound }
    -      Binding.Bound := true;
    -    end;
       end;
     end;
     
    @@ -335,38 +340,42 @@ var
       Mode: longint;
     begin
       Binding.Name := FileRec(f).Name;
    +  Binding.Bound := true;
     
       Mode := FileRec(f).Mode;
       case Mode of
         fmClosed:
         begin
    -      {$I-}
    -      { If the file exists, try renaming it }
    -      if FileExists(Binding.Name) then
    -      begin
    -        Rename(f, Binding.Name + '.binding');
    -        Rename(f, Binding.Name);
    -        Binding.Bound := IOResult = 0;
    -      end
    -      { If not, let's try writing to it }
    -      else
    -      begin
    -        Rewrite(f);
    -        Binding.Bound := IOResult = 0;
    -
    +      try
    +        try
    +          { If the file exists, try renaming it }
    +          if FileExists(Binding.Name) then
    +          begin
    +            Rename(f, Binding.Name + '.binding');
    +            Rename(f, Binding.Name);
    +          end
    +          { If not, let's try writing to it }
    +          else
    +          begin
    +            Rewrite(file(f)); { Must be cast in order to work }
    +
    +            try
    +              Unbind(f);
    +              Erase(f);
    +            except
    +              { We can silently ignore if the file can't be erased }
    +            end;
    +          end;
    +        except
    +          Binding.Bound := false;
    +        end;
    +      finally
             { Restore to previous state }
             if Binding.Bound then
             begin
    -          Erase(f);
               Unbind(f);
             end;
           end;
    -      {$I+}
    -    end;
    -    otherwise
    -    begin
    -      { If the file isn't closed, we can assume it's bound }
    -      Binding.Bound := true;
         end;
       end;
     end;
    -- 
    2.13.5
    
    
    From e964461e7c0e6605e402f3ad5a535f6a00ca17de Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Tue, 17 Oct 2017 01:39:34 -0400
    Subject: [PATCH 18/20] Implemented Trim according to the standard
    
    ---
     rtl/inc/extpas.pp | 27 ++++++++++++++++++++++++---
     1 file changed, 24 insertions(+), 3 deletions(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 758ba4bc01..028f4c5541 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -145,7 +145,7 @@ type
     function Index(s1, s2: String): integer;
     function Substr(s: String; i: integer): String;
     function Substr(s: String; i, j: integer): String;
    -function Trim(protected s: String): String; { It's not marked as protected in the spec; it's just to show the syntax }
    +function Trim(s: String): String;
     
     function EQ(s1, s2: String): Boolean;
     function LT(s1, s2: String): Boolean;
    @@ -480,9 +480,30 @@ begin
       Substr := String(AnsiString(s[i..i+j-1]));
     end;
     
    -function Trim(protected s: String): String;
    +function Trim(s: String): String;
    +var
    +  n, p: integer;
     begin
    -  Trim := SysUtils.Trim(s);
    +  n := Length(s);
    +
    +  if n = 0 then
    +  begin
    +    Trim := '';
    +  end
    +  else if s[n] <> ' ' then
    +  begin
    +    Trim := s;
    +  end
    +  else
    +  begin
    +    p := n;
    +    while s[p - 1] = ' ' do
    +    begin
    +      p := Pred(p);
    +    end;
    +
    +    Trim := Substr(s, 1, p - 1);
    +  end;
     end;
     
     function EQ(s1, s2: String): Boolean;
    -- 
    2.13.5
    
    
    From 6cefc9793f0ea5231860e1442f920aba00f2b524 Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Tue, 17 Oct 2017 02:31:01 -0400
    Subject: [PATCH 19/20] Implemented Index according to the standard
    
    ---
     rtl/inc/extpas.pp | 29 ++++++++++++++++++++++++++++-
     1 file changed, 28 insertions(+), 1 deletion(-)
    
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 028f4c5541..2d4822c0df 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -464,8 +464,35 @@ begin
     end;
     
     function Index(s1, s2: String): integer;
    +var
    +  i: integer;
    +  iexists: Boolean;
     begin
    -  Index := Pos(s2, s1);
    +  if s2 = '' then
    +  begin
    +    Index := 1;
    +  end
    +  else if s1 = '' then
    +  begin
    +    Index := 0;
    +  end
    +  else
    +  begin
    +    i := 0;
    +    repeat
    +      i := Succ(i);
    +      iexists := Substr(s1, i, Length(s2)) = s2;
    +    until iexists or (i = Length(s1));
    +
    +    if iexists then
    +    begin
    +      Index := i;
    +    end
    +    else
    +    begin
    +      Index := 0;
    +    end;
    +  end;
     end;
     
     function Substr(s: String; i: integer): String;
    -- 
    2.13.5
    
    
    From 3cf9914f6d6f46e4181fa76820cd6fbbb2b3c59c Mon Sep 17 00:00:00 2001
    From: Keith Bowes <keithbowes@users.noreply.github.com>
    Date: Wed, 18 Oct 2017 22:17:20 -0400
    Subject: [PATCH 20/20] Finishing touches for difficulty level 2
    
    ---
     packages/rtl-extra/src/inc/ucomplex.pp |   5 +-
     rtl/inc/complex.inc                    |  66 ++++----------
     rtl/inc/complexh.inc                   |  27 +++---
     rtl/inc/extpas.pp                      | 152 ++++++++++++++-------------------
     4 files changed, 95 insertions(+), 155 deletions(-)
    
    diff --git a/packages/rtl-extra/src/inc/ucomplex.pp b/packages/rtl-extra/src/inc/ucomplex.pp
    index fc70785c8c..9cff0bbc7b 100644
    --- a/packages/rtl-extra/src/inc/ucomplex.pp
    +++ b/packages/rtl-extra/src/inc/ucomplex.pp
    @@ -28,14 +28,13 @@ Unit UComplex;
       type
         pcomplex = ^complex;
     
    +  const
    +    _0 : complex = (re : 0.0; im : 0.0);
     
         { operator := (i : longint) z : complex;
           not needed because longint can be converted to real }
         function csamevalue(z1, z2 : complex) : boolean;
     
    -    { complex functions }
    -    function cong (z : complex) : complex;      { conjuge }
    -
         { inverse function 1/z }
         function cinv (z : complex) : complex;
     
    diff --git a/rtl/inc/complex.inc b/rtl/inc/complex.inc
    index 3e67c63b3a..e2923a5d00 100644
    --- a/rtl/inc/complex.inc
    +++ b/rtl/inc/complex.inc
    @@ -1,4 +1,5 @@
    -{ ISO 10206 complex numbers implementation }
    +{ Complex numbers implementation }
    +{$IFNDEF FPUNONE}
         function cinit(_re,_im : real) : complex;inline;
         begin
           cinit.re:=_re;
    @@ -8,7 +9,7 @@
       operator := (r : real) z : complex; inline;
         begin
            z.re:=r;
    -       z.im:=Zero;
    +       z.im:=0.0;
         end;
     
       { four base operations  +, -, * , / }
    @@ -142,11 +143,7 @@
       function carg (z : complex): real;
         { argument : 0 / z = p ei0 }
         begin
    -      {$IFNDEF FPUNONE}
            carg := arctan2(z.im, z.re);
    -       {$ELSE}
    -       carg := Zero;
    -       {$ENDIF}
         end;
     
       function cong (z : complex) : complex;
    @@ -167,13 +164,13 @@
       operator = (z1 : complex; r :real) b : boolean;
         { returns TRUE if z1 = r }
         begin
    -       b := (z1.re = r) and (z1.im = Zero)
    +       b := (z1.re = r) and (z1.im = 0.0)
         end;
     
       operator = (r : real; z1 : complex) b : boolean;
         { returns TRUE if z1 = r }
         begin
    -       b := (z1.re = r) and (z1.im = Zero)
    +       b := (z1.re = r) and (z1.im = 0.0)
         end;
     
     
    @@ -194,11 +191,7 @@
         { ln( p exp(i0)) = ln(p) + i0 + 2kpi }
         begin
            cln.re := ln(cmod(z));
    -       {$IFNDEF FPUNONE}
            cln.im := arctan2(z.im, z.re);
    -       {$ELSE}
    -       cln.im := Zero;
    -       {$ENDIF}
         end;
     
       function csqr(z: complex): complex;
    @@ -213,21 +206,15 @@
         var
            root, q : real;
         begin
    -      if (z.re<>Zero) or (z.im<>Zero) then
    +      if (z.re<>0.0) or (z.im<>0.0) then
             begin
    -          {$IFNDEF FPUNONE}
                root := sqrt(0.5 * (abs(z.re) + cmod(z)));
    -           q := z.im / (Two * root);
    -           {$ELSE}
    -           root := 1;
    -           q := z.im div (2 * root);
    -           {$ENDIF}
    -           if z.re >= Zero then
    +           if z.re >= 0.0 then
                  begin
                     csqrt.re := root;
                     csqrt.im := q;
                  end
    -           else if z.im < Zero then
    +           else if z.im < 0.0 then
                  begin
                     csqrt.re := - q;
                     csqrt.im := - root
    @@ -267,12 +254,8 @@
         { cos(x+iy) = cos(x).cos(iy) - sin(x).sin(iy) }
         { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
         begin
    -      {$IFNDEF FPUNONE}
            ccos.re := cos(z.re) * cosh(z.im);
            ccos.im := - sin(z.re) * sinh(z.im);
    -       {$ELSE}
    -       ccos := _0;
    -       {$ENDIF}
         end;
     
       function csin (z : complex) : complex;
    @@ -280,12 +263,8 @@
         { sin(x+iy) = sin(x).cos(iy) + cos(x).sin(iy) }
         { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
         begin
    -      {$IFNDEF FPUNONE}
            csin.re := sin(z.re) * cosh(z.im);
            csin.im := cos(z.re) * sinh(z.im);
    -       {$ELSE}
    -       csin := _0;
    -       {$ENDIF}
         end;
     
       function ctg (z : complex) : complex;
    @@ -303,33 +282,21 @@
         { arc cosinus complex }
         { arccos(z) = -i.argch(z) }
         begin
    -      {$IFNDEF FPUNONE}
            carc_cos := -i*carg_ch(z);
    -       {$ELSE}
    -       carc_cos := _0;
    -       {$ENDIF}
         end;
     
       function carc_sin (z : complex) : complex;
         { arc sinus complex }
         { arcsin(z) = -i.argsh(i.z) }
         begin
    -      {$IFNDEF FPUNONE}
            carc_sin := -i*carg_sh(i*z);
    -       {$ELSE}
    -       carc_sin := _0;
    -       {$ENDIF}
         end;
     
       function carc_tg (z : complex) : complex;
         { arc tangente complex }
         { arctg(z) = -i.argth(i.z) }
         begin
    -      {$IFNDEF FPUNONE}
            carc_tg := -i*carg_th(i*z);
    -       {$ELSE}
    -       carc_tg := _0;
    -       {$ENDIF}
         end;
     
       { inverse complex hyperbolic functions }
    @@ -339,11 +306,7 @@
         {                          _________  }
         { argch(z) = -/+ ln(z + i.V 1 - z.z)  }
         begin
    -      {$IFNDEF CPUNONE}
    -       carg_ch:=-cln(z+i*csqrt(One-z*z));
    -      {$ELSE}
    -       carg_ch := _0;
    -       {$ENDIF}
    +       carg_ch:=-cln(z+i*csqrt(1.0-z*z));
         end;
     
       function carg_sh (z : complex) : complex;
    @@ -351,12 +314,19 @@
         {                    ________  }
         { argsh(z) = ln(z + V 1 + z.z) }
         begin
    -       carg_sh:=cln(z+csqrt(z*z+One));
    +       carg_sh:=cln(z+csqrt(z*z+1.0));
         end;
     
       function carg_th (z : complex) : complex;
         { hyperbolic arc tangent }
         { argth(z) = 1/2 ln((z + 1) / (1 - z)) }
         begin
    -       carg_th:=cln((z+One)/(One-z))/Two;
    +       carg_th:=cln((z+1.0)/(1.0-z))/2.0;
         end;
    +
    +  function cpolar(r, t: real): complex;
    +  begin
    +    cpolar.re := r * cos(t);
    +    cpolar.im := r * sin(t);
    +  end;
    +{$ENDIF}
    diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
    index 86859fc068..a51ca07c9a 100644
    --- a/rtl/inc/complexh.inc
    +++ b/rtl/inc/complexh.inc
    @@ -1,24 +1,14 @@
    -{ ISO 10206 complex numbers definitions }
    +{ Complex numbers definitions }
     {$INLINE ON}
    -
    -{ Try to use at least some FPU, even an emulated one, if possible }
    -{$IFDEF FPUNONE}
    -{ $FPUTYPE SOFT}
    -{$WARNING No FPU is being used.  Please set one or complex numbers won't work correctly.}
    -{$ENDIF}
    -const
    -  Zero = {$IFNDEF FPUNONE}0.0{$ELSE}0{$ENDIF};
    -  One = {$IFNDEF FPUNONE}1.0{$ELSE}1{$ENDIF};
    -  Two = {$IFNDEF FPUNONE}2.0{$ELSE}2{$ENDIF};
    -
    -
    +{$IFNDEF FPUNONE}
         type complex = record
                          re : real;
                          im : real;
                        end;
     
    -    const i : complex = (re : Zero; im : One);
    -          _0 : complex = (re : Zero; im : Zero);
    +    const i : complex = (re : 0.0; im : 1.0);
    +          Zero : complex = (re : 0.0; im : 0.0);
    +          One : complex = (re : 1.0; im : 0.0);
     
         { assignment overloading is also used in type conversions
           (beware also in implicit type conversions)
    @@ -79,6 +69,9 @@ const
         function cmod (z : complex) : real;           { module }
         function carg (z : complex) : real;           { argument : a / z = p.e^ia }
     
    +    { complex functions }
    +    function cong (z : complex) : complex;      { conjuge }
    +
         { fonctions elementaires }
         function cexp (z : complex) : complex;       { exponential }
         function cln (z : complex) : complex;        { natural logarithm }
    @@ -99,3 +92,7 @@ const
         function carg_ch (z : complex) : complex;    { hyperbolic arc cosinus }
         function carg_sh (z : complex) : complex;    { hyperbolic arc sinus }
         function carg_th (z : complex) : complex;    { hyperbolic arc tangente }
    +
    +    { polar }
    +    function cpolar (r, t : real) : complex;
    +{$ENDIF}
    diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
    index 2d4822c0df..0d065ac5cc 100644
    --- a/rtl/inc/extpas.pp
    +++ b/rtl/inc/extpas.pp
    @@ -27,7 +27,9 @@ unit extpas; { TODO: Make a module }
     {
     export
       iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
    -    Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
    +{$IFNDEF FPUNONE}
    +    Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, carg => arg, cpolar => polar, { complex numbers },
    +{$ENDIF}
         BindingType, Bind, Unbind, Binding, Extend, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty { files },
         TimeStamp, GetTimeStamp, Date, Time, { date/time }
         String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
    @@ -37,20 +39,14 @@ export
     
     {
     import
    -{$IFDEF UNIX}
    -  clocale; { So that dates will print out in a localized format }
    -{$ENDIF}
       SysUtils;
     }
     
     { Implement as much of ISO 10206 as is possible }
     
    -type
     {$IFNDEF FPUNONE}
    +type
       real = double;
    -{$ELSE}
    -  real = integer;
    -{$ENDIF}
     
     { This has to be included after the real redefinition, or you get errors about unresolved forward references }
     {$I complexh.inc}
    @@ -59,36 +55,32 @@ type
     const
       maxchar = Chr(255); { Should this depend on the codepage? }
     
    -{$IFNDEF FPUNONE}
       maxreal = 1.7E308;
       minreal = 5.0E-324;
       epsreal = 1 + 5.0E-15 - 1.0;
    -{$ELSE}
    -  maxreal = maxint;
    -  minreal = 0 - maxint - 1;
    -  epsreal = 0;
    -{$ENDIF}
     
    -operator ** (r1, r2: real) z: real;
    +operator ** (r1, r2: real) z: real; inline;
     
     { Complex numbers}
    -function Cmplx(re, im: real): Complex;
    -function Im(x: Complex): real;
    -function Re(x: Complex): real;
    +function Cmplx(re, im: real): Complex; inline;
    +function Im(x: Complex): real; inline;
    +function Re(x: Complex): real; inline;
     
     { The real and integer versions should be handled by System }
    -function abs(x: Complex): real; overload;
    -function arctan(x: Complex): Complex; overload;
    -function cos(x: Complex): Complex; overload;
    -function exp(x: Complex): Complex; overload;
    -function ln(x: Complex): Complex; overload;
    -function sin(x: Complex): Complex; overload;
    -function sqr(x: Complex): Complex; overload;
    -function sqrt(x: Complex): Complex; overload;
    +{ The overload directive has to be used so that the integer/real variants can also be used }
    +function abs(x: Complex): real; overload; inline;
    +function arctan(x: Complex): Complex; overload; inline;
    +function cos(x: Complex): Complex; overload; inline;
    +function exp(x: Complex): Complex; overload; inline;
    +function ln(x: Complex): Complex; overload; inline;
    +function sin(x: Complex): Complex; overload; inline;
    +function sqr(x: Complex): Complex; overload; inline;
    +function sqrt(x: Complex): Complex; overload; inline;
     
     { AFAIK, not provided in System }
    -function arg(x: Complex): real;
    -function polar(r, t: real): Complex;
    +function arg(x: Complex): real; inline;
    +function polar(r, t: real): Complex; inline;
    +{$ENDIF}
     
     { TODO: Implement the required operator pow (non-real powers) }
     
    @@ -99,23 +91,23 @@ type
         Bound: Boolean;
       end;
     
    -procedure Bind(var f: text; b: BindingType);
    -procedure Bind(var f: TypedFile; b: BindingType);
    -procedure Unbind(var f: text);
    -procedure Unbind(var f: TypedFile);
    +procedure Bind(var f: text; b: BindingType); inline;
    +procedure Bind(var f: file; b: BindingType); inline;
    +procedure Unbind(var f: text); inline;
    +procedure Unbind(var f: file); inline;
     
     function Binding(var f: text): BindingType;
    -function Binding(var f: TypedFile): BindingType;
    +function Binding(var f: file): BindingType;
     
    -procedure Extend(var f: text);
    +procedure Extend(var f: text); inline;
     
    -procedure Update(var f: TypedFile);
    -procedure SeekRead(var f: TypedFile; pos: integer);
    -procedure SeekWrite(var f: TypedFile; pos: integer);
    -procedure SeekUpdate(var f: TypedFile; pos: integer);
    -function Position(var f: TypedFile): integer;
    -function LastPosition(var f: TypedFile): integer;
    -function Empty(var f: TypedFile): Boolean;
    +procedure Update(var f: file); inline;
    +procedure SeekRead(var f: file; pos: integer); inline;
    +procedure SeekWrite(var f: file; pos: integer); inline;
    +procedure SeekUpdate(var f: file; pos: integer); inline;
    +function Position(var f: file): integer; inline;
    +function LastPosition(var f: file): integer; inline;
    +function Empty(var f: file): Boolean; inline;
     
     { date/time }
         type
    @@ -140,19 +132,19 @@ function Time(t: TimeStamp): String;
     {
     type
       String(capacity: integer) = packed array[0..capacity-1] of char;
    -} { TODO: Implement ISO 10206 string type; just settling for Ansistrings for now }
    +} { TODO: Implement ISO 10206 string type; just settling for ShortStrings for now }
     
     function Index(s1, s2: String): integer;
    -function Substr(s: String; i: integer): String;
    -function Substr(s: String; i, j: integer): String;
    +function Substr(s: String; i: integer): String; inline;
    +function Substr(s: String; i, j: integer): String; inline;
     function Trim(s: String): String;
     
    -function EQ(s1, s2: String): Boolean;
    +function EQ(s1, s2: String): Boolean; inline;
     function LT(s1, s2: String): Boolean;
    -function GT(s1, s2: String): Boolean;
    -function NE(s1, s2: String): Boolean;
    -function LE(s1, s2: String): Boolean;
    -function GE(s1, s2: String): Boolean;
    +function GT(s1, s2: String): Boolean; inline;
    +function NE(s1, s2: String): Boolean; inline;
    +function LE(s1, s2: String): Boolean; inline;
    +function GE(s1, s2: String): Boolean; inline;
     
       implementation
     
    @@ -169,21 +161,10 @@ import
       {$ENDIF}
     }
     
    +{$IFNDEF FPUNONE}
     operator ** (r1, r2: real) z: real;
    -{$IFDEF FPUNONE}
    -var
    -  i: real;
    -{$ENDIF}
     begin
    -  {$IFNDEF FPUNONE}
       z := Power(r1, r2);
    -  {$ELSE}
    -  z := 1;
    -  for i := 1 to r2 do
    -  begin
    -    z := z * r1;
    -  end;
    -  {$ENDIF}
     end;
     
     {$I complex.inc}
    @@ -205,8 +186,7 @@ end;
     
     function abs(x: Complex): real;
     begin
    -  { Thanks, Wikipedia! }
    -  abs := abs(sqrt(sqr(x.re) + sqr(x.im)));
    +  abs := abs(cmod(x));
     end;
     
     function arctan(x: Complex): Complex;
    @@ -249,23 +229,18 @@ begin
       arg := carg(x);
     end;
     
    -function polar(r, t: real){ = c}: Complex;
    -var
    -  c: Complex;
    +function polar(r, t: real): Complex;
     begin
    -  { Thanks, Wikipedia!  Math gives me a headache, but I somehow figured out how
    -  to convert the equations to Pascal code on my first try }
    -  c.re := r * cos(t);
    -  c.im := r * sin(t);
    -  polar := c;{}
    +  polar := cpolar(r, t);
     end;
    +{$ENDIF}
     
     procedure Bind(var f: text; b: BindingType);
     begin
       Assign(f, b.Name);
     end;
     
    -procedure Bind(var f: TypedFile; b: BindingType);
    +procedure Bind(var f: file; b: BindingType);
     begin
       Assign(f, b.Name);
     end;
    @@ -278,7 +253,7 @@ begin
       end;
     end;
     
    -procedure Unbind(var f: TypedFile);
    +procedure Unbind(var f: file);
     begin
       if FileRec(f).Mode <> fmClosed then
       begin
    @@ -335,7 +310,7 @@ begin
       end;
     end;
     
    -function Binding(var f: TypedFile): BindingType;
    +function Binding(var f: file): BindingType;
     var
       Mode: longint;
     begin
    @@ -357,7 +332,7 @@ begin
               { If not, let's try writing to it }
               else
               begin
    -            Rewrite(file(f)); { Must be cast in order to work }
    +            Rewrite(f);
     
                 try
                   Unbind(f);
    @@ -385,40 +360,39 @@ begin
       Append(f);
     end;
     
    -procedure Update(var f: TypedFile);
    +procedure Update(var f: file);
     begin
       SeekWrite(f, 0);
     end;
     
    -procedure SeekRead(var f: TypedFile; pos: integer);
    +procedure SeekRead(var f: file; pos: integer);
     begin
    -  { f has to be cast to file or calling this function causes a crash }
    -  Reset(file(f));
    -  Seek(file(f), pos);
    +  Reset(f);
    +  Seek(f, pos);
     end;
     
    -procedure SeekWrite(var f: TypedFile; pos: integer);
    +procedure SeekWrite(var f: file; pos: integer);
     begin
    -  Seek(f, pos);
    +  SeekUpdate(f, pos);
       Truncate(f);
     end;
     
    -procedure SeekUpdate(var f: TypedFile; pos: integer);
    +procedure SeekUpdate(var f: file; pos: integer);
     begin
       Seek(f, pos);
     end;
     
    -function Position(var f: TypedFile): integer;
    +function Position(var f: file): integer;
     begin
       Position := FilePos(f);
     end;
     
    -function LastPosition(var f: TypedFile): integer;
    +function LastPosition(var f: file): integer;
     begin
       LastPosition := 0; { Proper implementation depends on features that haven't been implemented yet }
     end;
     
    -function Empty(var f: TypedFile): Boolean;
    +function Empty(var f: file): Boolean;
     begin
       Empty := FileSize(f) = 0;
     end;
    @@ -504,7 +478,7 @@ function Substr(s: String; i, j: integer): String;
     begin
       { The type casting is not part of the standard, but it's necessary for this to be compilable.
         Hopefully, the future implementation of the ISO 10206 string type will alleviate this problem. }
    -  Substr := String(AnsiString(s[i..i+j-1]));
    +  Substr := String(AnsiString(s[i..(i)+(j)-1]));
     end;
     
     function Trim(s: String): String;
    @@ -526,7 +500,7 @@ begin
         p := n;
         while s[p - 1] = ' ' do
         begin
    -      p := Pred(p);
    +      p := p - 1;
         end;
     
         Trim := Substr(s, 1, p - 1);
    @@ -562,7 +536,7 @@ end;
     
     function NE(s1, s2: String): Boolean;
     begin
    -  NE := not EQ(s1, s2);
    +  NE := (not EQ(s1, s2));
     end;
     
     function LE(s1, s2: String): Boolean;
    -- 
    2.13.5
    
    
    bind-and-co.patch (122,436 bytes)

Activities

Keith Bowes

2017-10-14 11:33

reporter  

0001-Complex-numbers-date-time-and-string-routines.patch (12,965 bytes)
From 54880d4c665c297e76a3978665149fa8c9b64760 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Thu, 12 Oct 2017 15:12:04 -0400
Subject: [PATCH 1/3] Complex numbers, date/time, and string routines

---
 rtl/inc/extpas.pp | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 301 insertions(+), 2 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 0cbf660954..fbe1a60f15 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -14,10 +14,83 @@
 
  **********************************************************************}
 
-unit extpas;
+unit extpas; { TODO: Make a module }
+
+{ TODO: Implement these things to make macros unnecessary }
+{ These macros don't cover all use cases for these keywords anyway }
+{$MACRO ON}
+{$DEFINE protected := const}
+{$DEFINE value := =}
+
+{
+export
+  iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
+    Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
+    BindingType, Extend, { files },
+    TimeStamp, GetTimeStamp, Date, Time, { date/time }
+    String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
+}
 
   interface
 
+uses
+  uComplex; { Do I need to also import the definitions from iso7185 ? }
+
+{
+import
+  SysUtils;
+  uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
+}
+
+{ Implement as much of ISO 10206 as is possible }
+
+type
+  real = double;
+
+{ Required constants }
+const
+  maxchar = Chr(255); { Should this depend on the codepage? }
+
+  maxreal = 1.7E308;
+  minreal = 5.0E-324;
+  epsreal = 1 + 5.0E-15 - 1.0;
+
+type
+{ Complex numbers}
+  Complex = uComplex.complex; { TODO: Implement as an opaque type }
+
+function Cmplx(re, im: real): Complex;
+function Im(x: Complex): real;
+function Re(x: Complex): real;
+
+{ The real and integer versions should be handled by System }
+function abs(x: Complex): real; overload;
+function arctan(x: Complex): Complex; overload;
+function cos(x: Complex): Complex; overload;
+function exp(x: Complex): Complex; overload;
+function ln(x: Complex): Complex; overload;
+function sin(x: Complex): Complex; overload;
+function sqr(x: Complex): Complex; overload;
+function sqrt(x: Complex): Complex; overload;
+
+{ AFAIK, not provided in System }
+function arg(x: Complex): real;
+function polar(r, t: real): Complex;
+
+{ TODO: Operators?  Are these importable from uComplex, or must I rewrite them? E.g. uComplex.+ doesn't work. }
+{ TODO: Implement the required operator pow (non-real powers) }
+
+{ File routines }
+type
+  BindingType = packed record
+    Name: String;
+    Bound: Boolean;
+  end;
+
+procedure Extend(var f: text);
+{ TODO: Implement other file functions: Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty, and the bindable keyword }
+
+{ date/time }
     type
       TimeStamp = packed record
         DateValid : Boolean;
@@ -33,11 +106,159 @@ unit extpas;
       end;
 
     procedure GetTimeStamp(var ts : TimeStamp);
+function Date(t: TimeStamp): String;
+function Time(t: TimeStamp): String;
+
+{ Strings }
+{
+type
+  String(capacity: integer) = packed array[0..capacity-1] of char;
+} { TODO: Implement ISO 10206 string type; just settling for Short/Ansi strings for now }
+
+function Index(s1, s2: String): integer;
+function Substr(s: String; i: integer): String;
+function Substr(s: String; i, j: integer): String;
+function Trim(protected s: String): String; { It's not marked as protected in the spec; it's just to show the syntax }
+
+function EQ(s1, s2: String): Boolean;
+function LT(s1, s2: String): Boolean;
+function GT(s1, s2: String): Boolean;
+function NE(s1, s2: String): Boolean;
+function LE(s1, s2: String): Boolean;
+function GE(s1, s2: String): Boolean;
 
   implementation
 
     uses
-      dos;
+{$IFDEF UNIX}
+  clocale,
+{$ENDIF}
+      dos, SysUtils;
+{
+import
+{$IFDEF UNIX}
+  clocale; { So that dates will print out in a localized format }  
+{$ENDIF}
+  dos;
+}
+
+function Cmplx(re, im: real): Complex;
+begin
+  Cmplx := cinit(re, im);
+end;
+
+function Im(x: Complex): real;
+begin
+  Im := x.im;
+end;
+
+function Re(x: Complex): real;
+begin
+  Re := x.re;
+end;
+
+function abs(x: Complex): real;
+begin
+  { Thanks, Wikipedia! }
+  abs := abs(sqrt(sqr(x.re) + sqr(x.im)));
+end;
+
+function arctan(x: Complex): Complex;
+begin
+  arctan := carc_tg(x);
+end;
+
+function cos(x: Complex): Complex;
+begin
+  cos := ccos(x);
+end;
+
+function exp(x: Complex): Complex;
+begin
+  exp := cexp(x);
+end;
+
+function ln(x: Complex): Complex;
+begin
+  ln := cln(x);
+end;
+
+function sin(x: Complex): Complex;
+begin
+  sin := csin(x);
+end;
+
+function sqr(x: Complex): Complex;
+begin
+  sqr := csqr(x);
+end;
+
+function sqrt(x: Complex): Complex;
+begin
+  sqrt := csqrt(x);
+end;
+
+function arg(x: Complex): real;
+begin
+  arg := carg(x);
+end;
+
+function polar(r, t: real){ = c}: Complex;
+var
+  c: Complex;
+begin
+  { Thanks, Wikipedia!  Math gives me a headache, but I somehow figured out how
+  to convert the equations to Pascal code on my first try }
+  c.re := r * cos(t);
+  c.im := r * sin(t);
+  polar := c;{}
+end;
+
+procedure Extend(var f: text);
+begin
+  Append(f);
+end;
+
+{ Keith Bowes's implementation, yielded to Florian Klämpfl's }
+{
+procedure GetTimeStamp(var t: TimeStamp);
+var
+  day, month, year: word;
+  hour, minute, second: word;
+  Millisecond: word;
+begin
+  DecodeDate(SysUtils.Date, year, day, month);
+  DecodeTime(SysUtils.Time, hour, minute, second, Millisecond);
+
+  t.DateValid := (day > 0) and (month > 0) and (year >= 1900);
+  if t.DateValid then
+  begin
+    t.day := day;
+    t.month := month;
+    t.year := year;
+  end
+  else
+  begin
+    t.day := 1;
+    t.month := 1;
+    t.year := 1;
+  end;
+
+  t.TimeValid := (hour > 0) and (minute > 0) and (second > 0);
+  if t.TimeValid then
+  begin
+    t.hour := hour;
+    t.minute := minute;
+    t.second := second;
+  end
+  else
+  begin
+    t.hour := 0;
+    t.minute := 0;
+    t.second := 0;
+  end;
+end;
+}
 
     procedure GetTimeStamp(var ts : TimeStamp);
       var
@@ -62,5 +283,83 @@ unit extpas;
         ts.second100:=sec100;
       end;
 
+function Date(t: TimeStamp): String;
+var
+  d: TDateTime;
+begin
+  d := EncodeDate(t.year, t.month, t.day);
+  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d); 
+end;
+
+function Time(t: TimeStamp): String;
+var
+  d: TDateTime;
+  MSec: word value 0;
+begin
+  d := EncodeTime(t.Hour, t.Minute, t.Second, Msec);
+  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d); 
+end;
+
+function Index(s1, s2: String): integer;
+begin
+  Index := Pos(s2, s1);
+end;
+
+function Substr(s: String; i: integer): String;
+begin
+  Substr := Substr(s, i, Length(s) - i + 1);
+end;
+
+function Substr(s: String; i, j: integer): String;
+begin
+  Substr := s[i..i+j-1];
+end;
+
+function Trim(protected s: String): String;
+begin
+  Trim := SysUtils.Trim(s);
+end;
+
+function EQ(s1, s2: String): Boolean;
+begin
+  EQ := ((s1 = s2) and (Length(s1) = Length(s2)));
+end;
+
+function LT(s1, s2: String): Boolean;
+var
+  n1, n2: integer;
+begin
+  n1 := Length(s1);
+  n2 := Length(s2);
+
+  if n1 < n2 then
+  begin
+    LT := (s1 <= Substr(s2, 1, n1));
+  end
+  else
+  begin
+    LT := (Substr(s1, 1, n2) < s2);
+  end;
+end;
+
+function GT(s1, s2: String): Boolean;
+begin
+  GT := (not LT(s1, s2) and not EQ(s1, s2));
+end;
+
+function NE(s1, s2: String): Boolean;
+begin
+  NE := not EQ(s1, s2);
+end;
+
+function LE(s1, s2: String): Boolean;
+begin
+  LE := (LT(s1, s2) or EQ(s1, s2));
+end;
+
+function GE(s1, s2: String): Boolean;
+begin
+  GE := (not LT(s1, s2));
+end;
 
 end.
-- 
2.13.5


From 722c2ba9276cdb746cfd927dd85546dab94003ab Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Thu, 12 Oct 2017 16:59:29 -0400
Subject: [PATCH 2/3] Made FPC compilable with it

---
 rtl/Makefile      |  6 ++++--
 rtl/Makefile.fpc  |  6 ++++++
 rtl/inc/extpas.pp | 17 ++++++++++-------
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/rtl/Makefile b/rtl/Makefile
index 259b7374c5..8e6952095c 100644
--- a/rtl/Makefile
+++ b/rtl/Makefile
@@ -3625,7 +3625,6 @@ win16:
 	$(MAKE) -C win16 all
 .PHONY: win16_all win16_debug win16_smart win16_release win16_units win16_examples win16_shared win16_install win16_sourceinstall win16_exampleinstall win16_distinstall win16_zipinstall win16_zipsourceinstall win16_zipexampleinstall win16_zipdistinstall win16_clean win16_distclean win16_cleanall win16_info win16_makefiles win16
 endif
-all: $(addsuffix _all,$(TARGET_DIRS))
 debug: $(addsuffix _debug,$(TARGET_DIRS))
 smart: $(addsuffix _smart,$(TARGET_DIRS))
 release: $(addsuffix _release,$(TARGET_DIRS))
@@ -3645,8 +3644,11 @@ distclean: fpc_distclean $(addsuffix _distclean,$(TARGET_DIRS))
 cleanall: fpc_cleanall $(addsuffix _cleanall,$(TARGET_DIRS))
 info: fpc_info
 makefiles: fpc_makefiles
-.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+.PHONY: debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
 ifneq ($(wildcard fpcmake.loc),)
 include fpcmake.loc
 endif
 .NOTPARALLEL:
+.PHONY: all
+all: $(addsuffix _all,$(TARGET_DIRS))
+	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
diff --git a/rtl/Makefile.fpc b/rtl/Makefile.fpc
index bd8267252d..7d6f28f4d9 100644
--- a/rtl/Makefile.fpc
+++ b/rtl/Makefile.fpc
@@ -57,3 +57,9 @@ fpcdir=..
 
 [rules]
 .NOTPARALLEL:
+.PHONY: all
+
+# uComplex has to be built for extpas, but the compiled version becomes unusable on the next pass
+# So, we need to delete it after the build
+all: $(addsuffix _all,$(TARGET_DIRS))
+	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index fbe1a60f15..c1fe57a840 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -14,6 +14,12 @@
 
  **********************************************************************}
 
+{$H+}
+
+{ Make sure uComplex can be found }
+{ Should we perhaps move the complex-number code here and then let the uComplex unit import these? }
+{$UNITPATH ../../packages/rtl-extra/src/inc}
+
 unit extpas; { TODO: Make a module }
 
 { TODO: Implement these things to make macros unnecessary }
@@ -38,6 +44,9 @@ uses
 
 {
 import
+{$IFDEF UNIX}
+  clocale; { So that dates will print out in a localized format }  
+{$ENDIF}
   SysUtils;
   uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
 }
@@ -113,7 +122,7 @@ function Time(t: TimeStamp): String;
 {
 type
   String(capacity: integer) = packed array[0..capacity-1] of char;
-} { TODO: Implement ISO 10206 string type; just settling for Short/Ansi strings for now }
+} { TODO: Implement ISO 10206 string type; just settling for Ansistrings for now }
 
 function Index(s1, s2: String): integer;
 function Substr(s: String; i: integer): String;
@@ -130,15 +139,9 @@ function GE(s1, s2: String): Boolean;
   implementation
 
     uses
-{$IFDEF UNIX}
-  clocale,
-{$ENDIF}
       dos, SysUtils;
 {
 import
-{$IFDEF UNIX}
-  clocale; { So that dates will print out in a localized format }  
-{$ENDIF}
   dos;
 }
 
-- 
2.13.5


From e58cc70610a1b3100bb36b85d374743a91025565 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Thu, 12 Oct 2017 17:03:04 -0400
Subject: [PATCH 3/3] Removed the extra whitespaces that seem to bother Git so
 much

---
 rtl/inc/extpas.pp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index c1fe57a840..98c20a94fb 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -45,7 +45,7 @@ uses
 {
 import
 {$IFDEF UNIX}
-  clocale; { So that dates will print out in a localized format }  
+  clocale; { So that dates will print out in a localized format }
 {$ENDIF}
   SysUtils;
   uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
@@ -291,7 +291,7 @@ var
   d: TDateTime;
 begin
   d := EncodeDate(t.year, t.month, t.day);
-  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d); 
+  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d);
 end;
 
 function Time(t: TimeStamp): String;
@@ -300,7 +300,7 @@ var
   MSec: word value 0;
 begin
   d := EncodeTime(t.Hour, t.Minute, t.Second, Msec);
-  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d); 
+  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d);
 end;
 
 function Index(s1, s2: String): integer;
-- 
2.13.5

Florian

2017-10-15 22:18

administrator   ~0103453

Glad to hear that someone takes care of extended pascal mode.

Remarks:
- Can't you modify the wiki by yourself?
- Is it really mandatory for extended pascal to use clocale? The idea is to prevent always linking againt libc. If needed, people can still add clocale in their programs.
- Please write and provide test programs, this is probably one of the key elements needed for extended pascal support: to have test programs.
- I would recommend to add inline directive to the one liner routines doing only a single call
- The makefile modification is not correct, extpas should just depend on ucomplex and then everything should work, but this can be fixed later on.

Keith Bowes

2017-10-19 04:46

reporter   ~0103582

Yeah, I've been interested in EP since I read the standard a couple decades ago and was disappointed that FPC supported so little of. I always got a little joy out of when FPC added support for some aspect of it.

- I'll try to edit the Wiki. I assumed you had to be one of the project heads to do that.
- The clocale is only for localized dates. It's been removed.
- I have written some tests over on https://github.com/keithbowes/iso10206-tests/
- OK, I added inline.
- I've moved the shared complex number code to the include files rtl/inc/complex.inc and rtl/inc/complexh.inc. If you don't like that, I can move it all back and change the Makefile to make ucomplex a dependency of extpas.

One question:
How much of the EP features that require changes to the compiler should I make available to other modes? I know some EP features (like ReadStr/WriteStr) are already available to other modes, but I'm wondering what the best policy about this is.

Keith Bowes

2017-10-19 04:47

reporter  

bind-and-co.patch (122,436 bytes)
From 54880d4c665c297e76a3978665149fa8c9b64760 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Thu, 12 Oct 2017 15:12:04 -0400
Subject: [PATCH 01/20] Complex numbers, date/time, and string routines

---
 rtl/inc/extpas.pp | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 301 insertions(+), 2 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 0cbf660954..fbe1a60f15 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -14,10 +14,83 @@
 
  **********************************************************************}
 
-unit extpas;
+unit extpas; { TODO: Make a module }
+
+{ TODO: Implement these things to make macros unnecessary }
+{ These macros don't cover all use cases for these keywords anyway }
+{$MACRO ON}
+{$DEFINE protected := const}
+{$DEFINE value := =}
+
+{
+export
+  iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
+    Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
+    BindingType, Extend, { files },
+    TimeStamp, GetTimeStamp, Date, Time, { date/time }
+    String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
+}
 
   interface
 
+uses
+  uComplex; { Do I need to also import the definitions from iso7185 ? }
+
+{
+import
+  SysUtils;
+  uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
+}
+
+{ Implement as much of ISO 10206 as is possible }
+
+type
+  real = double;
+
+{ Required constants }
+const
+  maxchar = Chr(255); { Should this depend on the codepage? }
+
+  maxreal = 1.7E308;
+  minreal = 5.0E-324;
+  epsreal = 1 + 5.0E-15 - 1.0;
+
+type
+{ Complex numbers}
+  Complex = uComplex.complex; { TODO: Implement as an opaque type }
+
+function Cmplx(re, im: real): Complex;
+function Im(x: Complex): real;
+function Re(x: Complex): real;
+
+{ The real and integer versions should be handled by System }
+function abs(x: Complex): real; overload;
+function arctan(x: Complex): Complex; overload;
+function cos(x: Complex): Complex; overload;
+function exp(x: Complex): Complex; overload;
+function ln(x: Complex): Complex; overload;
+function sin(x: Complex): Complex; overload;
+function sqr(x: Complex): Complex; overload;
+function sqrt(x: Complex): Complex; overload;
+
+{ AFAIK, not provided in System }
+function arg(x: Complex): real;
+function polar(r, t: real): Complex;
+
+{ TODO: Operators?  Are these importable from uComplex, or must I rewrite them? E.g. uComplex.+ doesn't work. }
+{ TODO: Implement the required operator pow (non-real powers) }
+
+{ File routines }
+type
+  BindingType = packed record
+    Name: String;
+    Bound: Boolean;
+  end;
+
+procedure Extend(var f: text);
+{ TODO: Implement other file functions: Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty, and the bindable keyword }
+
+{ date/time }
     type
       TimeStamp = packed record
         DateValid : Boolean;
@@ -33,11 +106,159 @@ unit extpas;
       end;
 
     procedure GetTimeStamp(var ts : TimeStamp);
+function Date(t: TimeStamp): String;
+function Time(t: TimeStamp): String;
+
+{ Strings }
+{
+type
+  String(capacity: integer) = packed array[0..capacity-1] of char;
+} { TODO: Implement ISO 10206 string type; just settling for Short/Ansi strings for now }
+
+function Index(s1, s2: String): integer;
+function Substr(s: String; i: integer): String;
+function Substr(s: String; i, j: integer): String;
+function Trim(protected s: String): String; { It's not marked as protected in the spec; it's just to show the syntax }
+
+function EQ(s1, s2: String): Boolean;
+function LT(s1, s2: String): Boolean;
+function GT(s1, s2: String): Boolean;
+function NE(s1, s2: String): Boolean;
+function LE(s1, s2: String): Boolean;
+function GE(s1, s2: String): Boolean;
 
   implementation
 
     uses
-      dos;
+{$IFDEF UNIX}
+  clocale,
+{$ENDIF}
+      dos, SysUtils;
+{
+import
+{$IFDEF UNIX}
+  clocale; { So that dates will print out in a localized format }  
+{$ENDIF}
+  dos;
+}
+
+function Cmplx(re, im: real): Complex;
+begin
+  Cmplx := cinit(re, im);
+end;
+
+function Im(x: Complex): real;
+begin
+  Im := x.im;
+end;
+
+function Re(x: Complex): real;
+begin
+  Re := x.re;
+end;
+
+function abs(x: Complex): real;
+begin
+  { Thanks, Wikipedia! }
+  abs := abs(sqrt(sqr(x.re) + sqr(x.im)));
+end;
+
+function arctan(x: Complex): Complex;
+begin
+  arctan := carc_tg(x);
+end;
+
+function cos(x: Complex): Complex;
+begin
+  cos := ccos(x);
+end;
+
+function exp(x: Complex): Complex;
+begin
+  exp := cexp(x);
+end;
+
+function ln(x: Complex): Complex;
+begin
+  ln := cln(x);
+end;
+
+function sin(x: Complex): Complex;
+begin
+  sin := csin(x);
+end;
+
+function sqr(x: Complex): Complex;
+begin
+  sqr := csqr(x);
+end;
+
+function sqrt(x: Complex): Complex;
+begin
+  sqrt := csqrt(x);
+end;
+
+function arg(x: Complex): real;
+begin
+  arg := carg(x);
+end;
+
+function polar(r, t: real){ = c}: Complex;
+var
+  c: Complex;
+begin
+  { Thanks, Wikipedia!  Math gives me a headache, but I somehow figured out how
+  to convert the equations to Pascal code on my first try }
+  c.re := r * cos(t);
+  c.im := r * sin(t);
+  polar := c;{}
+end;
+
+procedure Extend(var f: text);
+begin
+  Append(f);
+end;
+
+{ Keith Bowes's implementation, yielded to Florian Klämpfl's }
+{
+procedure GetTimeStamp(var t: TimeStamp);
+var
+  day, month, year: word;
+  hour, minute, second: word;
+  Millisecond: word;
+begin
+  DecodeDate(SysUtils.Date, year, day, month);
+  DecodeTime(SysUtils.Time, hour, minute, second, Millisecond);
+
+  t.DateValid := (day > 0) and (month > 0) and (year >= 1900);
+  if t.DateValid then
+  begin
+    t.day := day;
+    t.month := month;
+    t.year := year;
+  end
+  else
+  begin
+    t.day := 1;
+    t.month := 1;
+    t.year := 1;
+  end;
+
+  t.TimeValid := (hour > 0) and (minute > 0) and (second > 0);
+  if t.TimeValid then
+  begin
+    t.hour := hour;
+    t.minute := minute;
+    t.second := second;
+  end
+  else
+  begin
+    t.hour := 0;
+    t.minute := 0;
+    t.second := 0;
+  end;
+end;
+}
 
     procedure GetTimeStamp(var ts : TimeStamp);
       var
@@ -62,5 +283,83 @@ unit extpas;
         ts.second100:=sec100;
       end;
 
+function Date(t: TimeStamp): String;
+var
+  d: TDateTime;
+begin
+  d := EncodeDate(t.year, t.month, t.day);
+  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d); 
+end;
+
+function Time(t: TimeStamp): String;
+var
+  d: TDateTime;
+  MSec: word value 0;
+begin
+  d := EncodeTime(t.Hour, t.Minute, t.Second, Msec);
+  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d); 
+end;
+
+function Index(s1, s2: String): integer;
+begin
+  Index := Pos(s2, s1);
+end;
+
+function Substr(s: String; i: integer): String;
+begin
+  Substr := Substr(s, i, Length(s) - i + 1);
+end;
+
+function Substr(s: String; i, j: integer): String;
+begin
+  Substr := s[i..i+j-1];
+end;
+
+function Trim(protected s: String): String;
+begin
+  Trim := SysUtils.Trim(s);
+end;
+
+function EQ(s1, s2: String): Boolean;
+begin
+  EQ := ((s1 = s2) and (Length(s1) = Length(s2)));
+end;
+
+function LT(s1, s2: String): Boolean;
+var
+  n1, n2: integer;
+begin
+  n1 := Length(s1);
+  n2 := Length(s2);
+
+  if n1 < n2 then
+  begin
+    LT := (s1 <= Substr(s2, 1, n1));
+  end
+  else
+  begin
+    LT := (Substr(s1, 1, n2) < s2);
+  end;
+end;
+
+function GT(s1, s2: String): Boolean;
+begin
+  GT := (not LT(s1, s2) and not EQ(s1, s2));
+end;
+
+function NE(s1, s2: String): Boolean;
+begin
+  NE := not EQ(s1, s2);
+end;
+
+function LE(s1, s2: String): Boolean;
+begin
+  LE := (LT(s1, s2) or EQ(s1, s2));
+end;
+
+function GE(s1, s2: String): Boolean;
+begin
+  GE := (not LT(s1, s2));
+end;
 
 end.
-- 
2.13.5


From 722c2ba9276cdb746cfd927dd85546dab94003ab Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Thu, 12 Oct 2017 16:59:29 -0400
Subject: [PATCH 02/20] Made FPC compilable with it

---
 rtl/Makefile      |  6 ++++--
 rtl/Makefile.fpc  |  6 ++++++
 rtl/inc/extpas.pp | 17 ++++++++++-------
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/rtl/Makefile b/rtl/Makefile
index 259b7374c5..8e6952095c 100644
--- a/rtl/Makefile
+++ b/rtl/Makefile
@@ -3625,7 +3625,6 @@ win16:
 	$(MAKE) -C win16 all
 .PHONY: win16_all win16_debug win16_smart win16_release win16_units win16_examples win16_shared win16_install win16_sourceinstall win16_exampleinstall win16_distinstall win16_zipinstall win16_zipsourceinstall win16_zipexampleinstall win16_zipdistinstall win16_clean win16_distclean win16_cleanall win16_info win16_makefiles win16
 endif
-all: $(addsuffix _all,$(TARGET_DIRS))
 debug: $(addsuffix _debug,$(TARGET_DIRS))
 smart: $(addsuffix _smart,$(TARGET_DIRS))
 release: $(addsuffix _release,$(TARGET_DIRS))
@@ -3645,8 +3644,11 @@ distclean: fpc_distclean $(addsuffix _distclean,$(TARGET_DIRS))
 cleanall: fpc_cleanall $(addsuffix _cleanall,$(TARGET_DIRS))
 info: fpc_info
 makefiles: fpc_makefiles
-.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+.PHONY: debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
 ifneq ($(wildcard fpcmake.loc),)
 include fpcmake.loc
 endif
 .NOTPARALLEL:
+.PHONY: all
+all: $(addsuffix _all,$(TARGET_DIRS))
+	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
diff --git a/rtl/Makefile.fpc b/rtl/Makefile.fpc
index bd8267252d..7d6f28f4d9 100644
--- a/rtl/Makefile.fpc
+++ b/rtl/Makefile.fpc
@@ -57,3 +57,9 @@ fpcdir=..
 
 [rules]
 .NOTPARALLEL:
+.PHONY: all
+
+# uComplex has to be built for extpas, but the compiled version becomes unusable on the next pass
+# So, we need to delete it after the build
+all: $(addsuffix _all,$(TARGET_DIRS))
+	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index fbe1a60f15..c1fe57a840 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -14,6 +14,12 @@
 
  **********************************************************************}
 
+{$H+}
+
+{ Make sure uComplex can be found }
+{ Should we perhaps move the complex-number code here and then let the uComplex unit import these? }
+{$UNITPATH ../../packages/rtl-extra/src/inc}
+
 unit extpas; { TODO: Make a module }
 
 { TODO: Implement these things to make macros unnecessary }
@@ -38,6 +44,9 @@ uses
 
 {
 import
+{$IFDEF UNIX}
+  clocale; { So that dates will print out in a localized format }  
+{$ENDIF}
   SysUtils;
   uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
 }
@@ -113,7 +122,7 @@ function Time(t: TimeStamp): String;
 {
 type
   String(capacity: integer) = packed array[0..capacity-1] of char;
-} { TODO: Implement ISO 10206 string type; just settling for Short/Ansi strings for now }
+} { TODO: Implement ISO 10206 string type; just settling for Ansistrings for now }
 
 function Index(s1, s2: String): integer;
 function Substr(s: String; i: integer): String;
@@ -130,15 +139,9 @@ function GE(s1, s2: String): Boolean;
   implementation
 
     uses
-{$IFDEF UNIX}
-  clocale,
-{$ENDIF}
       dos, SysUtils;
 {
 import
-{$IFDEF UNIX}
-  clocale; { So that dates will print out in a localized format }  
-{$ENDIF}
   dos;
 }
 
-- 
2.13.5


From e58cc70610a1b3100bb36b85d374743a91025565 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Thu, 12 Oct 2017 17:03:04 -0400
Subject: [PATCH 03/20] Removed the extra whitespaces that seem to bother Git
 so much

---
 rtl/inc/extpas.pp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index c1fe57a840..98c20a94fb 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -45,7 +45,7 @@ uses
 {
 import
 {$IFDEF UNIX}
-  clocale; { So that dates will print out in a localized format }  
+  clocale; { So that dates will print out in a localized format }
 {$ENDIF}
   SysUtils;
   uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
@@ -291,7 +291,7 @@ var
   d: TDateTime;
 begin
   d := EncodeDate(t.year, t.month, t.day);
-  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d); 
+  Date := FormatDateTime(DefaultFormatSettings.LongDateFormat, d);
 end;
 
 function Time(t: TimeStamp): String;
@@ -300,7 +300,7 @@ var
   MSec: word value 0;
 begin
   d := EncodeTime(t.Hour, t.Minute, t.Second, Msec);
-  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d); 
+  Time := FormatDateTime(DefaultFormatSettings.LongTimeFormat, d);
 end;
 
 function Index(s1, s2: String): integer;
-- 
2.13.5


From f9ddb617439c1a81943850d5ea1d55beb631cfc9 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sat, 14 Oct 2017 01:04:30 -0400
Subject: [PATCH 04/20] Otherwise is defined in ISO 10206

---
 compiler/tokens.pas | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/tokens.pas b/compiler/tokens.pas
index 3edfe6e794..6d44f4470e 100644
--- a/compiler/tokens.pas
+++ b/compiler/tokens.pas
@@ -605,7 +605,7 @@ const
       (str:'LOGICALOR'     ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
       (str:'NODEFAULT'     ;special:false;keyword:[m_none];op:NOTOKEN),
       (str:'OBJCCLASS'     ;special:false;keyword:[m_objectivec1];op:NOTOKEN),
-      (str:'OTHERWISE'     ;special:false;keyword:alllanguagemodes-[m_iso,m_extpas];op:NOTOKEN),
+      (str:'OTHERWISE'     ;special:false;keyword:alllanguagemodes-[m_iso];op:NOTOKEN),
       (str:'PROCEDURE'     ;special:false;keyword:alllanguagemodes;op:NOTOKEN),
       (str:'PROTECTED'     ;special:false;keyword:[m_none];op:NOTOKEN),
       (str:'PUBLISHED'     ;special:false;keyword:[m_none];op:NOTOKEN),
-- 
2.13.5


From ecfb0f7189776619f44d5a807a6b3a9e223d8dd7 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sat, 14 Oct 2017 03:08:55 -0400
Subject: [PATCH 05/20] Moved the complex code to shared include files

---
 packages/Makefile                      | 436 ++++++++++++++--------------
 packages/Makefile.fpc                  |   3 +
 packages/rtl-extra/src/inc/ucomplex.pp | 515 +--------------------------------
 rtl/Makefile                           |   6 +-
 rtl/Makefile.fpc                       |   6 -
 rtl/inc/complex.inc                    | 367 +++++++++++++++++++++++
 rtl/inc/complexh.inc                   |  89 ++++++
 rtl/inc/extpas.pp                      |  34 ++-
 8 files changed, 709 insertions(+), 747 deletions(-)
 create mode 100644 rtl/inc/complex.inc
 create mode 100644 rtl/inc/complexh.inc

diff --git a/packages/Makefile b/packages/Makefile
index 2443b4ce93..bf9e7db547 100644
--- a/packages/Makefile
+++ b/packages/Makefile
@@ -1,11 +1,11 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2017-08-22 rev 37024]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2014/10/17]
 #
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-aros x86_64-dragonfly arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-darwin wasm-wasm sparc64-linux
-BSDs = freebsd netbsd openbsd darwin dragonfly
-UNIXs = linux $(BSDs) solaris qnx haiku aix
-LIMIT83fs = go32v2 os2 emx watcom msdos win16
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx haiku
+LIMIT83fs = go32v2 os2 emx watcom
 OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 .PHONY: FORCE
@@ -178,24 +178,6 @@ else
 ARCH=$(CPU_TARGET)
 endif
 endif
-ifeq ($(FULL_TARGET),arm-embedded)
-ifeq ($(SUBARCH),)
-$(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t or SUBARCH=armv7m) must be defined)
-endif
-override FPCOPT+=-Cp$(SUBARCH)
-endif
-ifeq ($(FULL_TARGET),avr-embedded)
-ifeq ($(SUBARCH),)
-$(error When compiling for avr-embedded, a sub-architecture (e.g. SUBARCH=avr25 or SUBARCH=avr35) must be defined)
-endif
-override FPCOPT+=-Cp$(SUBARCH)
-endif
-ifeq ($(FULL_TARGET),mipsel-embedded)
-ifeq ($(SUBARCH),)
-$(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
-endif
-override FPCOPT+=-Cp$(SUBARCH)
-endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 TARGETSUFFIX=$(OS_TARGET)
 SOURCESUFFIX=$(OS_SOURCE)
@@ -221,18 +203,10 @@ endif
 ifeq ($(OS_TARGET),linux)
 linuxHier=1
 endif
-ifndef CROSSCOMPILE
-BUILDFULLNATIVE=1
-export BUILDFULLNATIVE
-endif
-ifdef BUILDFULLNATIVE
-BUILDNATIVE=1
-export BUILDNATIVE
-endif
 export OS_TARGET OS_SOURCE ARCH CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
 ifdef FPCDIR
 override FPCDIR:=$(subst \,/,$(FPCDIR))
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
 override FPCDIR=wrong
 endif
 else
@@ -241,7 +215,7 @@ endif
 ifdef DEFAULT_FPCDIR
 ifeq ($(FPCDIR),wrong)
 override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
 override FPCDIR=wrong
 endif
 endif
@@ -255,11 +229,11 @@ endif
 else
 override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
 override FPCDIR:=$(FPCDIR)/..
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
 override FPCDIR:=$(FPCDIR)/..
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
 override FPCDIR:=$(BASEDIR)
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
 override FPCDIR=c:/pp
 endif
 endif
@@ -277,27 +251,8 @@ endif
 ifndef BINUTILSPREFIX
 ifndef CROSSBINDIR
 ifdef CROSSCOMPILE
-ifneq ($(OS_TARGET),msdos)
 ifndef DARWIN2DARWIN
-ifneq ($(CPU_TARGET),jvm)
 BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
-ifeq ($(OS_TARGET),android)
-ifeq ($(CPU_TARGET),arm)
-BINUTILSPREFIX=arm-linux-androideabi-
-else
-ifeq ($(CPU_TARGET),i386)
-BINUTILSPREFIX=i686-linux-android-
-else
-ifeq ($(CPU_TARGET),mipsel)
-BINUTILSPREFIX=mipsel-linux-android-
-endif
-endif
-endif
-endif
-endif
-endif
-else
-BINUTILSPREFIX=$(OS_TARGET)-
 endif
 endif
 endif
@@ -306,7 +261,7 @@ UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
 ifeq ($(UNITSDIR),)
 UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
 endif
-PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages)
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
 ifndef FPCFPMAKE
 ifdef CROSSCOMPILE
 ifeq ($(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR)))),)
@@ -363,6 +318,201 @@ endif
 SUB_FPMAKE_SRCS=$(wildcard */fpmake.pp)
 override INSTALL_FPCPACKAGE=y
 override INSTALL_FPCSUBDIR=packages
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc-wii)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
 ifdef REQUIRE_UNITSDIR
 override UNITSDIR+=$(REQUIRE_UNITSDIR)
 endif
@@ -591,26 +741,12 @@ SHAREDLIBEXT=.dll
 SHORTSUFFIX=wat
 IMPORTLIBPREFIX=
 endif
-ifneq ($(CPU_TARGET),jvm)
-ifeq ($(OS_TARGET),android)
-BATCHEXT=.sh
-EXEEXT=
-HASSHAREDLIB=1
-SHORTSUFFIX=lnx
-endif
-endif
 ifeq ($(OS_TARGET),linux)
 BATCHEXT=.sh
 EXEEXT=
 HASSHAREDLIB=1
 SHORTSUFFIX=lnx
 endif
-ifeq ($(OS_TARGET),dragonfly)
-BATCHEXT=.sh
-EXEEXT=
-HASSHAREDLIB=1
-SHORTSUFFIX=df
-endif
 ifeq ($(OS_TARGET),freebsd)
 BATCHEXT=.sh
 EXEEXT=
@@ -656,11 +792,6 @@ EXEEXT=
 SHAREDLIBEXT=.library
 SHORTSUFFIX=amg
 endif
-ifeq ($(OS_TARGET),aros)
-EXEEXT=
-SHAREDLIBEXT=.library
-SHORTSUFFIX=aros
-endif
 ifeq ($(OS_TARGET),morphos)
 EXEEXT=
 SHAREDLIBEXT=.library
@@ -734,45 +865,6 @@ EXEEXT=.dol
 SHAREDLIBEXT=.so
 SHORTSUFFIX=wii
 endif
-ifeq ($(OS_TARGET),aix)
-BATCHEXT=.sh
-EXEEXT=
-SHORTSUFFIX=aix
-endif
-ifeq ($(OS_TARGET),java)
-OEXT=.class
-ASMEXT=.j
-SHAREDLIBEXT=.jar
-SHORTSUFFIX=java
-endif
-ifeq ($(CPU_TARGET),jvm)
-ifeq ($(OS_TARGET),android)
-OEXT=.class
-ASMEXT=.j
-SHAREDLIBEXT=.jar
-SHORTSUFFIX=android
-endif
-endif
-ifeq ($(OS_TARGET),msdos)
-STATICLIBPREFIX=
-STATICLIBEXT=.a
-SHORTSUFFIX=d16
-endif
-ifeq ($(OS_TARGET),embedded)
-ifeq ($(CPU_TARGET),i8086)
-STATICLIBPREFIX=
-STATICLIBEXT=.a
-else
-EXEEXT=.bin
-endif
-SHORTSUFFIX=emb
-endif
-ifeq ($(OS_TARGET),win16)
-STATICLIBPREFIX=
-STATICLIBEXT=.a
-SHAREDLIBEXT=.dll
-SHORTSUFFIX=w16
-endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -962,7 +1054,6 @@ ASNAME=$(BINUTILSPREFIX)as
 LDNAME=$(BINUTILSPREFIX)ld
 ARNAME=$(BINUTILSPREFIX)ar
 RCNAME=$(BINUTILSPREFIX)rc
-NASMNAME=$(BINUTILSPREFIX)nasm
 ifndef ASPROG
 ifdef CROSSBINDIR
 ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
@@ -991,23 +1082,11 @@ else
 ARPROG=$(ARNAME)
 endif
 endif
-ifndef NASMPROG
-ifdef CROSSBINDIR
-NASMPROG=$(CROSSBINDIR)/$(NASMNAME)$(SRCEXEEXT)
-else
-NASMPROG=$(NASMNAME)
-endif
-endif
 AS=$(ASPROG)
 LD=$(LDPROG)
 RC=$(RCPROG)
 AR=$(ARPROG)
-NASM=$(NASMPROG)
-ifdef inUnix
-PPAS=./ppas$(SRCBATCHEXT)
-else
 PPAS=ppas$(SRCBATCHEXT)
-endif
 ifdef inUnix
 LDCONFIG=ldconfig
 else
@@ -1055,6 +1134,9 @@ endif
 ifeq ($(FULL_TARGET),i386-solaris)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),i386-netware)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1091,13 +1173,10 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),i386-android)
+ifeq ($(FULL_TARGET),m68k-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),i386-aros)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),m68k-linux)
+ifeq ($(FULL_TARGET),m68k-freebsd)
 REQUIRE_PACKAGES_RTL=1
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
@@ -1109,10 +1188,10 @@ endif
 ifeq ($(FULL_TARGET),m68k-atari)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),m68k-palmos)
+ifeq ($(FULL_TARGET),m68k-openbsd)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),m68k-macos)
+ifeq ($(FULL_TARGET),m68k-palmos)
 REQUIRE_PACKAGES_RTL=1
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
@@ -1142,9 +1221,6 @@ endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),powerpc-aix)
-REQUIRE_PACKAGES_RTL=1
-endif
 ifeq ($(FULL_TARGET),sparc-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1181,15 +1257,6 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),x86_64-iphonesim)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),x86_64-aros)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),x86_64-dragonfly)
-REQUIRE_PACKAGES_RTL=1
-endif
 ifeq ($(FULL_TARGET),arm-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1214,12 +1281,6 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),arm-android)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),arm-aros)
-REQUIRE_PACKAGES_RTL=1
-endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1229,9 +1290,6 @@ endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),powerpc64-aix)
-REQUIRE_PACKAGES_RTL=1
-endif
 ifeq ($(FULL_TARGET),avr-embedded)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1241,45 +1299,9 @@ endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),mips-linux)
-REQUIRE_PACKAGES_RTL=1
-endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),mipsel-embedded)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),mipsel-android)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),jvm-java)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),jvm-android)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),i8086-embedded)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),i8086-msdos)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),i8086-win16)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),aarch64-linux)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),aarch64-darwin)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),wasm-wasm)
-REQUIRE_PACKAGES_RTL=1
-endif
-ifeq ($(FULL_TARGET),sparc64-linux)
-REQUIRE_PACKAGES_RTL=1
-endif
 ifdef REQUIRE_PACKAGES_RTL
 PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
 ifneq ($(PACKAGEDIR_RTL),)
@@ -1330,7 +1352,6 @@ endif
 ifeq ($(OS_SOURCE),openbsd)
 override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
 override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
-override FPMAKE_BUILD_OPT+=-FD$(NEW_BINUTILS_PATH)
 endif
 ifndef CROSSBOOTSTRAP
 ifneq ($(BINUTILSPREFIX),)
@@ -1343,7 +1364,6 @@ endif
 ifndef CROSSCOMPILE
 ifneq ($(BINUTILSPREFIX),)
 override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
-override FPMAKE_BUILD_OPT+=-XP$(BINUTILSPREFIX)
 endif
 endif
 ifdef UNITDIR
@@ -1432,20 +1452,22 @@ endif
 endif
 ifdef CREATESHARED
 override FPCOPT+=-Cg
+ifeq ($(CPU_TARGET),i386)
+override FPCOPT+=-Aas
+endif
 endif
-ifneq ($(findstring $(OS_TARGET),dragonfly freebsd openbsd netbsd linux solaris),)
-ifneq ($(findstring $(CPU_TARGET),x86_64 mips mipsel),)
+ifeq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris),)
+ifeq ($(CPU_TARGET),x86_64)
 override FPCOPT+=-Cg
 endif
 endif
+endif
 ifdef LINKSHARED
 endif
 ifdef OPT
 override FPCOPT+=$(OPT)
 endif
-ifdef FPMAKEBUILDOPT
-override FPMAKE_BUILD_OPT+=$(FPMAKEBUILDOPT)
-endif
 ifdef FPCOPTDEF
 override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
 endif
@@ -1465,24 +1487,18 @@ endif
 ifdef ACROSSCOMPILE
 override FPCOPT+=$(CROSSOPT)
 endif
-override COMPILER:=$(strip $(FPC) $(FPCOPT))
-ifneq (,$(findstring -sh ,$(COMPILER)))
-UseEXECPPAS=1
-endif
-ifneq (,$(findstring -s ,$(COMPILER)))
-ifeq ($(FULL_SOURCE),$(FULL_TARGET))
-UseEXECPPAS=1
-endif
-endif
-ifneq ($(UseEXECPPAS),1)
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
 EXECPPAS=
 else
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
 ifdef RUNBATCH
 EXECPPAS:=@$(RUNBATCH) $(PPAS)
 else
 EXECPPAS:=@$(PPAS)
 endif
 endif
+endif
 ifdef TARGET_RSTS
 override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
 override CLEANRSTFILES+=$(RSTFILES)
@@ -1563,10 +1579,6 @@ endif
 ifdef DEBUGSYMEXT
 	-$(DEL) *$(DEBUGSYMEXT)
 endif
-ifdef LOCALFPMAKEBIN
-	-$(DEL) $(LOCALFPMAKEBIN)
-	-$(DEL) $(FPMAKEBINOBJ)
-endif
 fpc_distclean: cleanall
 .PHONY: fpc_baseinfo
 override INFORULES+=fpc_baseinfo
diff --git a/packages/Makefile.fpc b/packages/Makefile.fpc
index 1a856db5cb..e886a37c1f 100644
--- a/packages/Makefile.fpc
+++ b/packages/Makefile.fpc
@@ -12,6 +12,9 @@ fpcsubdir=packages
 [default]
 fpcdir=..
 
+[compiler]
+includedir=../rtl/inc
+
 [prerules]
 # Translate INSTALL_UNITDIR to fpmake's --unitinstalldir parameter
 ifdef INSTALL_UNITDIR
diff --git a/packages/rtl-extra/src/inc/ucomplex.pp b/packages/rtl-extra/src/inc/ucomplex.pp
index 87127218a9..fc70785c8c 100644
--- a/packages/rtl-extra/src/inc/ucomplex.pp
+++ b/packages/rtl-extra/src/inc/ucomplex.pp
@@ -12,8 +12,6 @@
 
  **********************************************************************}
 Unit UComplex;
-{$INLINE ON}
-{$define TEST_INLINE}
 
 { created for FPC by Pierre Muller }
 { inpired from the complex unit from  JD GAYRARD mai 95 }
@@ -25,135 +23,14 @@ Unit UComplex;
 {$ifndef FPUNONE}
     uses math;
 
-    type complex = record
-                     re : real;
-                     im : real;
-                   end;
+  {$I complexh.inc}
 
+  type
     pcomplex = ^complex;
 
-    const i : complex = (re : 0.0; im : 1.0);
-          _0 : complex = (re : 0.0; im : 0.0);
-
-
-    { assignment overloading is also used in type conversions
-      (beware also in implicit type conversions)
-      after this operator any real can be passed to a function
-      as a complex arg !! }
-
-    operator := (r : real) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
 
     { operator := (i : longint) z : complex;
       not needed because longint can be converted to real }
-
-
-    { four operator : +, -, * , /  and comparison = }
-    operator + (z1, z2 : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    { these ones are created because the code
-      is simpler and thus faster }
-    operator + (z1 : complex; r : real) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator + (r : real; z1 : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-
-    operator - (z1, z2 : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator - (z1 : complex;r : real) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator - (r : real; z1 : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-
-    operator * (z1, z2 : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator * (z1 : complex; r : real) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator * (r : real; z1 : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-
-    operator / (znum, zden : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator / (znum : complex; r : real) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator / (r : real; zden : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    { ** is the exponentiation operator }
-    operator ** (z1, z2 : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator ** (z1 : complex; r : real) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator ** (r : real; z1 : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-
-    operator = (z1, z2 : complex) b : boolean;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator = (z1 : complex;r : real) b : boolean;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator = (r : real; z1 : complex) b : boolean;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    operator - (z1 : complex) z : complex;
-    {$ifdef TEST_INLINE}
-    inline;
-    {$endif TEST_INLINE}
-
-    function cinit(_re,_im : real) : complex;inline;
     function csamevalue(z1, z2 : complex) : boolean;
 
     { complex functions }
@@ -162,36 +39,11 @@ Unit UComplex;
     { inverse function 1/z }
     function cinv (z : complex) : complex;
 
-    { complex functions with real return values }
-    function cmod (z : complex) : real;           { module }
-    function carg (z : complex) : real;           { argument : a / z = p.e^ia }
-
-    { fonctions elementaires }
-    function cexp (z : complex) : complex;       { exponential }
-    function cln (z : complex) : complex;        { natural logarithm }
-    function csqr (z: complex) : complex;        { square }
-    function csqrt (z : complex) : complex;      { square root }
-
-    { complex trigonometric functions  }
-    function ccos (z : complex) : complex;       { cosinus }
-    function csin (z : complex) : complex;       { sinus }
-    function ctg  (z : complex) : complex;       { tangent }
-
-    { inverse complex trigonometric functions }
-    function carc_cos (z : complex) : complex;   { arc cosinus }
-    function carc_sin (z : complex) : complex;   { arc sinus }
-    function carc_tg  (z : complex) : complex;   { arc tangent }
-
     { hyperbolic complex functions }
     function cch (z : complex) : complex;        { hyperbolic cosinus }
     function csh (z : complex) : complex;        { hyperbolic sinus }
     function cth (z : complex) : complex;        { hyperbolic tangent }
 
-    { inverse hyperbolic complex functions }
-    function carg_ch (z : complex) : complex;    { hyperbolic arc cosinus }
-    function carg_sh (z : complex) : complex;    { hyperbolic arc sinus }
-    function carg_th (z : complex) : complex;    { hyperbolic arc tangente }
-
     { functions to write out a complex value }
     function cstr(z : complex) : string;
     function cstr(z:complex;len : integer) : string;
@@ -199,204 +51,13 @@ Unit UComplex;
 
   implementation
 
-    function cinit(_re,_im : real) : complex;inline;
-    begin
-      cinit.re:=_re;
-      cinit.im:=_im;
-    end;
+  {$I complex.inc}
 
     function csamevalue(z1, z2: complex): boolean;
     begin
       csamevalue:=SameValue(z1.re, z2.re) and SameValue(z1.im, z2.im);
     end;
 
-  operator := (r : real) z : complex;
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-
-    begin
-       z.re:=r;
-       z.im:=0.0;
-    end;
-
-  { four base operations  +, -, * , / }
-
-  operator + (z1, z2 : complex) z : complex;
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-    { addition : z := z1 + z2 }
-    begin
-       z.re := z1.re + z2.re;
-       z.im := z1.im + z2.im;
-    end;
-
-  operator + (z1 : complex; r : real) z : complex;
-  { addition : z := z1 + r }
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-    begin
-       z.re := z1.re + r;
-       z.im := z1.im;
-    end;
-
-  operator + (r : real; z1 : complex) z : complex;
-  { addition : z := r + z1 }
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-
-    begin
-       z.re := z1.re + r;
-       z.im := z1.im;
-    end;
-
-  operator - (z1, z2 : complex) z : complex;
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-    { substraction : z := z1 - z2 }
-    begin
-       z.re := z1.re - z2.re;
-       z.im := z1.im - z2.im;
-    end;
-
-  operator - (z1 : complex; r : real) z : complex;
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-    { substraction : z := z1 - r }
-    begin
-       z.re := z1.re - r;
-       z.im := z1.im;
-    end;
-
-  operator - (z1 : complex) z : complex;
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-    { substraction : z := - z1 }
-    begin
-       z.re := -z1.re;
-       z.im := -z1.im;
-    end;
-
-  operator - (r : real; z1 : complex) z : complex;
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-    { substraction : z := r - z1 }
-    begin
-       z.re := r - z1.re;
-       z.im := - z1.im;
-    end;
-
-  operator * (z1, z2 : complex) z : complex;
-  { multiplication : z := z1 * z2 }
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-    begin
-       z.re := (z1.re * z2.re) - (z1.im * z2.im);
-       z.im := (z1.re * z2.im) + (z1.im * z2.re);
-    end;
-
-  operator * (z1 : complex; r : real) z : complex;
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-    { multiplication : z := z1 * r }
-    begin
-       z.re := z1.re * r;
-       z.im := z1.im * r;
-    end;
-
-  operator * (r : real; z1 : complex) z : complex;
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-  { multiplication : z := r * z1 }
-    begin
-       z.re := z1.re * r;
-       z.im := z1.im * r;
-    end;
-
-  operator / (znum, zden : complex) z : complex;
-  {$ifdef TEST_INLINE}
-  inline;
-  {$endif TEST_INLINE}
-    { division : z := znum / zden }
-    { The following algorithm is used to properly handle
-      denominator overflow:
-
-                 |  a + b(d/c)   c - a(d/c)
-                 |  ---------- + ---------- I     if |d| < |c|
-      a + b I    |  c + d(d/c)   a + d(d/c)
-      -------  = |
-      c + d I    |  b + a(c/d)   -a+ b(c/d)
-                 |  ---------- + ---------- I     if |d| >= |c|
-                 |  d + c(c/d)   d + c(c/d)
-    }
-     var
-       tmp, denom : real;
-     begin
-       if ( abs(zden.re) > abs(zden.im) ) then
-       begin
-          tmp := zden.im / zden.re;
-          denom := zden.re + zden.im * tmp;
-          z.re := (znum.re + znum.im * tmp) / denom;
-          z.im := (znum.im - znum.re * tmp) / denom;
-       end
-       else
-       begin
-          tmp := zden.re / zden.im;
-          denom := zden.im + zden.re * tmp;
-          z.re := (znum.im + znum.re * tmp) / denom;
-          z.im := (-znum.re + znum.im * tmp) / denom;
-       end;
-     end;
-
-    operator / (znum : complex; r : real) z : complex;
-      { division : z := znum / r }
-      begin
-         z.re := znum.re / r;
-         z.im := znum.im / r;
-      end;
-
-  operator / (r : real; zden : complex) z : complex;
-    { division : z := r / zden }
-    var denom : real;
-    begin
-       with zden do denom := (re * re) + (im * im);
-       { generates a fpu exception if denom=0 as for reals }
-       z.re := (r * zden.re) / denom;
-       z.im := - (r * zden.im) / denom;
-    end;
-
-  function cmod (z : complex): real;
-    { module : r = |z| }
-    begin
-       with z do
-         cmod := sqrt((re * re) + (im * im));
-    end;
-
-  function carg (z : complex): real;
-    { argument : 0 / z = p ei0 }
-    begin
-       carg := arctan2(z.im, z.re);
-    end;
-
-  function cong (z : complex) : complex;
-    { complex conjugee :
-       if z := x + i.y
-       then cong is x - i.y }
-    begin
-       cong.re := z.re;
-       cong.im := - z.im;
-    end;
-
   function cinv (z : complex) : complex;
     { inverse : r := 1 / z }
     var
@@ -408,151 +69,6 @@ Unit UComplex;
        cinv.im:=-z.im/denom;
     end;
 
-  operator = (z1, z2 : complex) b : boolean;
-    { returns TRUE if z1 = z2 }
-    begin
-       b := (z1.re = z2.re) and (z1.im = z2.im);
-    end;
-
-  operator = (z1 : complex; r :real) b : boolean;
-    { returns TRUE if z1 = r }
-    begin
-       b := (z1.re = r) and (z1.im = 0.0)
-    end;
-
-  operator = (r : real; z1 : complex) b : boolean;
-    { returns TRUE if z1 = r }
-    begin
-       b := (z1.re = r) and (z1.im = 0.0)
-    end;
-
-
-  { fonctions elementaires }
-
-  function cexp (z : complex) : complex;
-    { exponantial : r := exp(z) }
-    { exp(x + iy) = exp(x).exp(iy) = exp(x).[cos(y) + i sin(y)] }
-    var expz : real;
-    begin
-       expz := exp(z.re);
-       cexp.re := expz * cos(z.im);
-       cexp.im := expz * sin(z.im);
-    end;
-
-  function cln (z : complex) : complex;
-    { natural logarithm : r := ln(z) }
-    { ln( p exp(i0)) = ln(p) + i0 + 2kpi }
-    begin
-       cln.re := ln(cmod(z));
-       cln.im := arctan2(z.im, z.re);
-    end;
-
-  function csqr(z: complex): complex;
-    { square : r := z*z }
-    begin
-      csqr.re := z.re * z.re - z.im * z.im;
-      csqr.im := 2 * z.re * z.im;
-    end;
-
-  function csqrt (z : complex) : complex;
-    { square root : r := sqrt(z) }
-    var
-       root, q : real;
-    begin
-      if (z.re<>0.0) or (z.im<>0.0) then
-        begin
-           root := sqrt(0.5 * (abs(z.re) + cmod(z)));
-           q := z.im / (2.0 * root);
-           if z.re >= 0.0 then
-             begin
-                csqrt.re := root;
-                csqrt.im := q;
-             end
-           else if z.im < 0.0 then
-             begin
-                csqrt.re := - q;
-                csqrt.im := - root
-             end
-           else
-             begin
-                csqrt.re :=  q;
-                csqrt.im :=  root
-             end
-        end
-       else csqrt := z;
-    end;
-
-
-  operator ** (z1, z2 : complex) z : complex;
-    { exp : z := z1 ** z2 }
-    begin
-       z := cexp(z2*cln(z1));
-    end;
-
-  operator ** (z1 : complex; r : real) z : complex;
-    { multiplication : z := z1 * r }
-    begin
-       z := cexp( r *cln(z1));
-    end;
-
-  operator ** (r : real; z1 : complex) z : complex;
-    { multiplication : z := r + z1 }
-    begin
-       z := cexp(z1*ln(r));
-    end;
-
-  { direct trigonometric functions }
-
-  function ccos (z : complex) : complex;
-    { complex cosinus }
-    { cos(x+iy) = cos(x).cos(iy) - sin(x).sin(iy) }
-    { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
-    begin
-       ccos.re := cos(z.re) * cosh(z.im);
-       ccos.im := - sin(z.re) * sinh(z.im);
-    end;
-
-  function csin (z : complex) : complex;
-    { sinus complex }
-    { sin(x+iy) = sin(x).cos(iy) + cos(x).sin(iy) }
-    { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
-    begin
-       csin.re := sin(z.re) * cosh(z.im);
-       csin.im := cos(z.re) * sinh(z.im);
-    end;
-
-  function ctg (z : complex) : complex;
-    { tangente }
-    var ccosz, temp : complex;
-    begin
-       ccosz := ccos(z);
-       temp := csin(z);
-       ctg := temp / ccosz;
-    end;
-
-  { fonctions trigonometriques inverses }
-
-  function carc_cos (z : complex) : complex;
-    { arc cosinus complex }
-    { arccos(z) = -i.argch(z) }
-    begin
-       carc_cos := -i*carg_ch(z);
-    end;
-
-  function carc_sin (z : complex) : complex;
-    { arc sinus complex }
-    { arcsin(z) = -i.argsh(i.z) }
-    begin
-       carc_sin := -i*carg_sh(i*z);
-    end;
-
-  function carc_tg (z : complex) : complex;
-    { arc tangente complex }
-    { arctg(z) = -i.argth(i.z) }
-    begin
-       carc_tg := -i*carg_th(i*z);
-    end;
-
   { hyberbolic complex functions }
 
   function cch (z : complex) : complex;
@@ -584,31 +100,6 @@ Unit UComplex;
        cth := z / temp;
     end;
 
-  { inverse complex hyperbolic functions }
-
-  function carg_ch (z : complex) : complex;
-    {   hyberbolic arg cosinus }
-    {                          _________  }
-    { argch(z) = -/+ ln(z + i.V 1 - z.z)  }
-    begin
-       carg_ch:=-cln(z+i*csqrt(1.0-z*z));
-    end;
-
-  function carg_sh (z : complex) : complex;
-    {   hyperbolic arc sinus       }
-    {                    ________  }
-    { argsh(z) = ln(z + V 1 + z.z) }
-    begin
-       carg_sh:=cln(z+csqrt(z*z+1.0));
-    end;
-
-  function carg_th (z : complex) : complex;
-    { hyperbolic arc tangent }
-    { argth(z) = 1/2 ln((z + 1) / (1 - z)) }
-    begin
-       carg_th:=cln((z+1.0)/(1.0-z))/2.0;
-    end;
-
   { functions to write out a complex value }
   function cstr(z : complex) : string;
     var
diff --git a/rtl/Makefile b/rtl/Makefile
index 8e6952095c..259b7374c5 100644
--- a/rtl/Makefile
+++ b/rtl/Makefile
@@ -3625,6 +3625,7 @@ win16:
 	$(MAKE) -C win16 all
 .PHONY: win16_all win16_debug win16_smart win16_release win16_units win16_examples win16_shared win16_install win16_sourceinstall win16_exampleinstall win16_distinstall win16_zipinstall win16_zipsourceinstall win16_zipexampleinstall win16_zipdistinstall win16_clean win16_distclean win16_cleanall win16_info win16_makefiles win16
 endif
+all: $(addsuffix _all,$(TARGET_DIRS))
 debug: $(addsuffix _debug,$(TARGET_DIRS))
 smart: $(addsuffix _smart,$(TARGET_DIRS))
 release: $(addsuffix _release,$(TARGET_DIRS))
@@ -3644,11 +3645,8 @@ distclean: fpc_distclean $(addsuffix _distclean,$(TARGET_DIRS))
 cleanall: fpc_cleanall $(addsuffix _cleanall,$(TARGET_DIRS))
 info: fpc_info
 makefiles: fpc_makefiles
-.PHONY: debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
 ifneq ($(wildcard fpcmake.loc),)
 include fpcmake.loc
 endif
 .NOTPARALLEL:
-.PHONY: all
-all: $(addsuffix _all,$(TARGET_DIRS))
-	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
diff --git a/rtl/Makefile.fpc b/rtl/Makefile.fpc
index 7d6f28f4d9..bd8267252d 100644
--- a/rtl/Makefile.fpc
+++ b/rtl/Makefile.fpc
@@ -57,9 +57,3 @@ fpcdir=..
 
 [rules]
 .NOTPARALLEL:
-.PHONY: all
-
-# uComplex has to be built for extpas, but the compiled version becomes unusable on the next pass
-# So, we need to delete it after the build
-all: $(addsuffix _all,$(TARGET_DIRS))
-	-$(DEL) units/$(CPU_TARGET)-$(OS_TARGET)/ucomplex.*
diff --git a/rtl/inc/complex.inc b/rtl/inc/complex.inc
new file mode 100644
index 0000000000..7dd3dff5cb
--- /dev/null
+++ b/rtl/inc/complex.inc
@@ -0,0 +1,367 @@
+{ ISO 10206 complex numbers implementation }
+const
+  Zero = {$IFNDEF FPUNONE}0.0{$ELSE}0{$ENDIF};
+  One = {$IFNDEF FPUNONE}1.0{$ELSE}1{$ENDIF};
+  Two = {$IFNDEF FPUNONE}2.0{$ELSE}2{$ENDIF};
+
+    function cinit(_re,_im : real) : complex;inline;
+    begin
+      cinit.re:=_re;
+      cinit.im:=_im;
+    end;
+
+  operator := (r : real) z : complex; inline;
+    begin
+       z.re:=r;
+       z.im:=Zero;
+    end;
+
+  { four base operations  +, -, * , / }
+
+  operator + (z1, z2 : complex) z : complex; inline;
+    { addition : z := z1 + z2 }
+    begin
+       z.re := z1.re + z2.re;
+       z.im := z1.im + z2.im;
+    end;
+
+  operator + (z1 : complex; r : real) z : complex; inline;
+  { addition : z := z1 + r }
+    begin
+       z.re := z1.re + r;
+       z.im := z1.im;
+    end;
+
+  operator + (r : real; z1 : complex) z : complex; inline;
+  { addition : z := r + z1 }
+    begin
+       z.re := z1.re + r;
+       z.im := z1.im;
+    end;
+
+  operator - (z1, z2 : complex) z : complex; inline;
+    { substraction : z := z1 - z2 }
+    begin
+       z.re := z1.re - z2.re;
+       z.im := z1.im - z2.im;
+    end;
+
+  operator - (z1 : complex; r : real) z : complex; inline;
+    { substraction : z := z1 - r }
+    begin
+       z.re := z1.re - r;
+       z.im := z1.im;
+    end;
+
+  operator - (z1 : complex) z : complex; inline;
+    { substraction : z := - z1 }
+    begin
+       z.re := -z1.re;
+       z.im := -z1.im;
+    end;
+
+  operator - (r : real; z1 : complex) z : complex; inline;
+    { substraction : z := r - z1 }
+    begin
+       z.re := r - z1.re;
+       z.im := - z1.im;
+    end;
+
+  operator * (z1, z2 : complex) z : complex; inline;
+  { multiplication : z := z1 * z2 }
+    begin
+       z.re := (z1.re * z2.re) - (z1.im * z2.im);
+       z.im := (z1.re * z2.im) + (z1.im * z2.re);
+    end;
+
+  operator * (z1 : complex; r : real) z : complex; inline;
+    { multiplication : z := z1 * r }
+    begin
+       z.re := z1.re * r;
+       z.im := z1.im * r;
+    end;
+
+  operator * (r : real; z1 : complex) z : complex; inline;
+  { multiplication : z := r * z1 }
+    begin
+       z.re := z1.re * r;
+       z.im := z1.im * r;
+    end;
+
+  operator / (znum, zden : complex) z : complex; inline;
+    { division : z := znum / zden }
+    { The following algorithm is used to properly handle
+      denominator overflow:
+
+                 |  a + b(d/c)   c - a(d/c)
+                 |  ---------- + ---------- I     if |d| < |c|
+      a + b I    |  c + d(d/c)   a + d(d/c)
+      -------  = |
+      c + d I    |  b + a(c/d)   -a+ b(c/d)
+                 |  ---------- + ---------- I     if |d| >= |c|
+                 |  d + c(c/d)   d + c(c/d)
+    }
+     var
+       tmp, denom : real;
+     begin
+       if ( abs(zden.re) > abs(zden.im) ) then
+       begin
+          tmp := zden.im / zden.re;
+          denom := zden.re + zden.im * tmp;
+          z.re := (znum.re + znum.im * tmp) / denom;
+          z.im := (znum.im - znum.re * tmp) / denom;
+       end
+       else
+       begin
+          tmp := zden.re / zden.im;
+          denom := zden.im + zden.re * tmp;
+          z.re := (znum.im + znum.re * tmp) / denom;
+          z.im := (-znum.re + znum.im * tmp) / denom;
+       end;
+     end;
+
+    operator / (znum : complex; r : real) z : complex;
+      { division : z := znum / r }
+      begin
+         z.re := znum.re / r;
+         z.im := znum.im / r;
+      end;
+
+  operator / (r : real; zden : complex) z : complex;
+    { division : z := r / zden }
+    var denom : real;
+    begin
+       with zden do denom := (re * re) + (im * im);
+       { generates a fpu exception if denom=0 as for reals }
+       z.re := (r * zden.re) / denom;
+       z.im := - (r * zden.im) / denom;
+    end;
+
+  function cmod (z : complex): real;
+    { module : r = |z| }
+    begin
+       with z do
+         cmod := sqrt((re * re) + (im * im));
+    end;
+
+  function carg (z : complex): real;
+    { argument : 0 / z = p ei0 }
+    begin
+      {$IFNDEF FPUNONE}
+       carg := arctan2(z.im, z.re);
+       {$ELSE}
+       carg := Zero;
+       {$ENDIF}
+    end;
+
+  function cong (z : complex) : complex;
+    { complex conjugee :
+       if z := x + i.y
+       then cong is x - i.y }
+    begin
+       cong.re := z.re;
+       cong.im := - z.im;
+    end;
+
+  operator = (z1, z2 : complex) b : boolean;
+    { returns TRUE if z1 = z2 }
+    begin
+       b := (z1.re = z2.re) and (z1.im = z2.im);
+    end;
+
+  operator = (z1 : complex; r :real) b : boolean;
+    { returns TRUE if z1 = r }
+    begin
+       b := (z1.re = r) and (z1.im = Zero)
+    end;
+
+  operator = (r : real; z1 : complex) b : boolean;
+    { returns TRUE if z1 = r }
+    begin
+       b := (z1.re = r) and (z1.im = Zero)
+    end;
+
+
+  { fonctions elementaires }
+
+  function cexp (z : complex) : complex;
+    { exponantial : r := exp(z) }
+    { exp(x + iy) = exp(x).exp(iy) = exp(x).[cos(y) + i sin(y)] }
+    var expz : real;
+    begin
+       expz := exp(z.re);
+       cexp.re := expz * cos(z.im);
+       cexp.im := expz * sin(z.im);
+    end;
+
+  function cln (z : complex) : complex;
+    { natural logarithm : r := ln(z) }
+    { ln( p exp(i0)) = ln(p) + i0 + 2kpi }
+    begin
+       cln.re := ln(cmod(z));
+       {$IFNDEF FPUNONE}
+       cln.im := arctan2(z.im, z.re);
+       {$ELSE}
+       cln.im := Zero;
+       {$ENDIF}
+    end;
+
+  function csqr(z: complex): complex;
+    { square : r := z*z }
+    begin
+      csqr.re := z.re * z.re - z.im * z.im;
+      csqr.im := 2 * z.re * z.im;
+    end;
+
+  function csqrt (z : complex) : complex;
+    { square root : r := sqrt(z) }
+    var
+       root, q : real;
+    begin
+      if (z.re<>Zero) or (z.im<>Zero) then
+        begin
+          {$IFNDEF FPUNONE}
+           root := sqrt(0.5 * (abs(z.re) + cmod(z)));
+           q := z.im / (Two * root);
+           {$ELSE}
+           root := 1;
+           q := z.im div (2 * root);
+           {$ENDIF}
+           if z.re >= Zero then
+             begin
+                csqrt.re := root;
+                csqrt.im := q;
+             end
+           else if z.im < Zero then
+             begin
+                csqrt.re := - q;
+                csqrt.im := - root
+             end
+           else
+             begin
+                csqrt.re :=  q;
+                csqrt.im :=  root
+             end
+        end
+       else csqrt := z;
+    end;
+
+
+  operator ** (z1, z2 : complex) z : complex;
+    { exp : z := z1 ** z2 }
+    begin
+       z := cexp(z2*cln(z1));
+    end;
+
+  operator ** (z1 : complex; r : real) z : complex;
+    { multiplication : z := z1 * r }
+    begin
+       z := cexp( r *cln(z1));
+    end;
+
+  operator ** (r : real; z1 : complex) z : complex;
+    { multiplication : z := r + z1 }
+    begin
+       z := cexp(z1*ln(r));
+    end;
+
+  { direct trigonometric functions }
+
+  function ccos (z : complex) : complex;
+    { complex cosinus }
+    { cos(x+iy) = cos(x).cos(iy) - sin(x).sin(iy) }
+    { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
+    begin
+      {$IFNDEF FPUNONE}
+       ccos.re := cos(z.re) * cosh(z.im);
+       ccos.im := - sin(z.re) * sinh(z.im);
+       {$ELSE}
+       ccos := _0;
+       {$ENDIF}
+    end;
+
+  function csin (z : complex) : complex;
+    { sinus complex }
+    { sin(x+iy) = sin(x).cos(iy) + cos(x).sin(iy) }
+    { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
+    begin
+      {$IFNDEF FPUNONE}
+       csin.re := sin(z.re) * cosh(z.im);
+       csin.im := cos(z.re) * sinh(z.im);
+       {$ELSE}
+       csin := _0;
+       {$ENDIF}
+    end;
+
+  function ctg (z : complex) : complex;
+    { tangente }
+    var ccosz, temp : complex;
+    begin
+       ccosz := ccos(z);
+       temp := csin(z);
+       ctg := temp / ccosz;
+    end;
+
+  { fonctions trigonometriques inverses }
+
+  function carc_cos (z : complex) : complex;
+    { arc cosinus complex }
+    { arccos(z) = -i.argch(z) }
+    begin
+      {$IFNDEF FPUNONE}
+       carc_cos := -i*carg_ch(z);
+       {$ELSE}
+       carc_cos := _0;
+       {$ENDIF}
+    end;
+
+  function carc_sin (z : complex) : complex;
+    { arc sinus complex }
+    { arcsin(z) = -i.argsh(i.z) }
+    begin
+      {$IFNDEF FPUNONE}
+       carc_sin := -i*carg_sh(i*z);
+       {$ELSE}
+       carc_sin := _0;
+       {$ENDIF}
+    end;
+
+  function carc_tg (z : complex) : complex;
+    { arc tangente complex }
+    { arctg(z) = -i.argth(i.z) }
+    begin
+      {$IFNDEF FPUNONE}
+       carc_tg := -i*carg_th(i*z);
+       {$ELSE}
+       carc_tg := _0;
+       {$ENDIF}
+    end;
+
+  { inverse complex hyperbolic functions }
+
+  function carg_ch (z : complex) : complex;
+    {   hyberbolic arg cosinus }
+    {                          _________  }
+    { argch(z) = -/+ ln(z + i.V 1 - z.z)  }
+    begin
+      {$IFNDEF CPUNONE}
+       carg_ch:=-cln(z+i*csqrt(One-z*z));
+      {$ELSE}
+       carg_ch := _0;
+       {$ENDIF}
+    end;
+
+  function carg_sh (z : complex) : complex;
+    {   hyperbolic arc sinus       }
+    {                    ________  }
+    { argsh(z) = ln(z + V 1 + z.z) }
+    begin
+       carg_sh:=cln(z+csqrt(z*z+One));
+    end;
+
+  function carg_th (z : complex) : complex;
+    { hyperbolic arc tangent }
+    { argth(z) = 1/2 ln((z + 1) / (1 - z)) }
+    begin
+       carg_th:=cln((z+One)/(One-z))/Two;
+    end;
diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
new file mode 100644
index 0000000000..29ce0b0f3a
--- /dev/null
+++ b/rtl/inc/complexh.inc
@@ -0,0 +1,89 @@
+{ ISO 10206 complex numbers definitions }
+{$INLINE ON}
+    type complex = record
+                     re : real;
+                     im : real;
+                   end;
+
+    const i : complex = (re : 0.0; im : 1.0);
+          _0 : complex = (re : 0.0; im : 0.0);
+
+    { assignment overloading is also used in type conversions
+      (beware also in implicit type conversions)
+      after this operator any real can be passed to a function
+      as a complex arg !! }
+
+    operator := (r : real) z : complex; inline;
+
+    { four operator : +, -, * , /  and comparison = }
+    operator + (z1, z2 : complex) z : complex; inline;
+
+    { these ones are created because the code
+      is simpler and thus faster }
+    operator + (z1 : complex; r : real) z : complex; inline;
+
+    operator + (r : real; z1 : complex) z : complex; inline;
+
+
+    operator - (z1, z2 : complex) z : complex; inline;
+
+    operator - (z1 : complex;r : real) z : complex; inline;
+
+    operator - (r : real; z1 : complex) z : complex; inline;
+
+
+    operator * (z1, z2 : complex) z : complex; inline;
+
+    operator * (z1 : complex; r : real) z : complex; inline;
+
+    operator * (r : real; z1 : complex) z : complex; inline;
+
+
+    operator / (znum, zden : complex) z : complex; inline;
+
+    operator / (znum : complex; r : real) z : complex; inline;
+
+    operator / (r : real; zden : complex) z : complex; inline;
+
+    { ** is the exponentiation operator }
+    operator ** (z1, z2 : complex) z : complex; inline;
+
+    operator ** (z1 : complex; r : real) z : complex; inline;
+
+    operator ** (r : real; z1 : complex) z : complex; inline;
+
+
+    operator = (z1, z2 : complex) b : boolean; inline;
+
+    operator = (z1 : complex;r : real) b : boolean; inline;
+
+    operator = (r : real; z1 : complex) b : boolean; inline;
+
+    operator - (z1 : complex) z : complex; inline;
+
+    function cinit(_re,_im : real) : complex;inline;
+
+    { complex functions with real return values }
+    function cmod (z : complex) : real;           { module }
+    function carg (z : complex) : real;           { argument : a / z = p.e^ia }
+
+    { fonctions elementaires }
+    function cexp (z : complex) : complex;       { exponential }
+    function cln (z : complex) : complex;        { natural logarithm }
+    function csqr (z: complex) : complex;        { square }
+    function csqrt (z : complex) : complex;      { square root }
+
+    { complex trigonometric functions  }
+    function ccos (z : complex) : complex;       { cosinus }
+    function csin (z : complex) : complex;       { sinus }
+    function ctg  (z : complex) : complex;       { tangent }
+
+    { inverse complex trigonometric functions }
+    function carc_cos (z : complex) : complex;   { arc cosinus }
+    function carc_sin (z : complex) : complex;   { arc sinus }
+    function carc_tg  (z : complex) : complex;   { arc tangent }
+
+    { inverse hyperbolic complex functions }
+    function carg_ch (z : complex) : complex;    { hyperbolic arc cosinus }
+    function carg_sh (z : complex) : complex;    { hyperbolic arc sinus }
+    function carg_th (z : complex) : complex;    { hyperbolic arc tangente }
diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 98c20a94fb..6e6cc01022 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -16,10 +16,6 @@
 
 {$H+}
 
-{ Make sure uComplex can be found }
-{ Should we perhaps move the complex-number code here and then let the uComplex unit import these? }
-{$UNITPATH ../../packages/rtl-extra/src/inc}
-
 unit extpas; { TODO: Make a module }
 
 { TODO: Implement these things to make macros unnecessary }
@@ -39,35 +35,40 @@ export
 
   interface
 
-uses
-  uComplex; { Do I need to also import the definitions from iso7185 ? }
-
 {
 import
 {$IFDEF UNIX}
   clocale; { So that dates will print out in a localized format }
 {$ENDIF}
   SysUtils;
-  uComplex only (complex, carc_tg => arctan, ccos => cos, cexp => exp, cln => ln, csin =>sin, csqr => sqr, csqrt => sqrt);
 }
 
 { Implement as much of ISO 10206 as is possible }
 
 type
+{$IFNDEF FPUNONE}
   real = double;
+{$ELSE}
+  real = integer;
+{$ENDIF}
+
+{$I complexh.inc}
 
 { Required constants }
 const
   maxchar = Chr(255); { Should this depend on the codepage? }
 
+{$IFNDEF FPUNONE}
   maxreal = 1.7E308;
   minreal = 5.0E-324;
   epsreal = 1 + 5.0E-15 - 1.0;
+{$ELSE}
+  maxreal = maxint;
+  minreal = 0 - maxint - 1;
+  epsreal = 0;
+{$ENDIF}
 
-type
 { Complex numbers}
-  Complex = uComplex.complex; { TODO: Implement as an opaque type }
-
 function Cmplx(re, im: real): Complex;
 function Im(x: Complex): real;
 function Re(x: Complex): real;
@@ -86,7 +87,6 @@ function sqrt(x: Complex): Complex; overload;
 function arg(x: Complex): real;
 function polar(r, t: real): Complex;
 
-{ TODO: Operators?  Are these importable from uComplex, or must I rewrite them? E.g. uComplex.+ doesn't work. }
 { TODO: Implement the required operator pow (non-real powers) }
 
 { File routines }
@@ -139,12 +139,20 @@ function GE(s1, s2: String): Boolean;
   implementation
 
     uses
-      dos, SysUtils;
+      dos, SysUtils
+      {$IFNDEF FPUNONE}
+      , Math
+      {$ENDIF};
 {
 import
   dos;
+  {$IFNDEF FPUNONE}
+  Math;
+  {$ENDIF}
 }
 
+{$I complex.inc}
+
 function Cmplx(re, im: real): Complex;
 begin
   Cmplx := cinit(re, im);
-- 
2.13.5


From 0c84189e4052cf1b74ac794335150dc338c8f69f Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sat, 14 Oct 2017 03:32:42 -0400
Subject: [PATCH 06/20] Implemented the ** operator

---
 rtl/inc/extpas.pp | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 6e6cc01022..42279ddd5b 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -68,6 +68,8 @@ const
   epsreal = 0;
 {$ENDIF}
 
+operator ** (r1, r2: real) z: real;
+
 { Complex numbers}
 function Cmplx(re, im: real): Complex;
 function Im(x: Complex): real;
@@ -151,6 +153,23 @@ import
   {$ENDIF}
 }
 
+operator ** (r1, r2: real) z: real;
+{$IFDEF FPUNONE}
+var
+  i: real;
+{$ENDIF}
+begin
+  {$IFNDEF FPUNONE}
+  z := Power(r1, r2);
+  {$ELSE}
+  z := 1;
+  for i := 1 to r2 do
+  begin
+    z := z * r1;
+  end;
+  {$ENDIF}
+end;
+
 {$I complex.inc}
 
 function Cmplx(re, im: real): Complex;
-- 
2.13.5


From 0a6d05dda593eb5d3a2a1efdc71dc2ac94d3fbff Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sat, 14 Oct 2017 05:39:53 -0400
Subject: [PATCH 07/20] Removed my version of GetTimeStamp

---
 rtl/inc/extpas.pp | 41 -----------------------------------------
 1 file changed, 41 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 42279ddd5b..17a763390a 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -249,47 +249,6 @@ begin
   Append(f);
 end;
 
-{ Keith Bowes's implementation, yielded to Florian Klämpfl's }
-{
-procedure GetTimeStamp(var t: TimeStamp);
-var
-  day, month, year: word;
-  hour, minute, second: word;
-  Millisecond: word;
-begin
-  DecodeDate(SysUtils.Date, year, day, month);
-  DecodeTime(SysUtils.Time, hour, minute, second, Millisecond);
-
-  t.DateValid := (day > 0) and (month > 0) and (year >= 1900);
-  if t.DateValid then
-  begin
-    t.day := day;
-    t.month := month;
-    t.year := year;
-  end
-  else
-  begin
-    t.day := 1;
-    t.month := 1;
-    t.year := 1;
-  end;
-
-  t.TimeValid := (hour > 0) and (minute > 0) and (second > 0);
-  if t.TimeValid then
-  begin
-    t.hour := hour;
-    t.minute := minute;
-    t.second := second;
-  end
-  else
-  begin
-    t.hour := 0;
-    t.minute := 0;
-    t.second := 0;
-  end;
-end;
-}
-
     procedure GetTimeStamp(var ts : TimeStamp);
       var
         year1,month1,mday1,wday1,
-- 
2.13.5


From 1d442221126710062c3970fba139a3ec75fc7d61 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sun, 15 Oct 2017 16:16:06 -0400
Subject: [PATCH 08/20] Implemented ISO 10206 file routines

---
 rtl/inc/extpas.pp | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 160 insertions(+), 3 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 17a763390a..42e7c9d5e2 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -28,7 +28,7 @@ unit extpas; { TODO: Make a module }
 export
   iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
     Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
-    BindingType, Extend, { files },
+    BindingType, Extend, Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty { files },
     TimeStamp, GetTimeStamp, Date, Time, { date/time }
     String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
 }
@@ -94,12 +94,27 @@ function polar(r, t: real): Complex;
 { File routines }
 type
   BindingType = packed record
-    Name: String;
+    Name: String{(TextRecNameLength)};
     Bound: Boolean;
   end;
 
+procedure Bind(var f: text; b: BindingType);
+procedure Bind(var f: TypedFile; b: BindingType);
+procedure Unbind(var f: text);
+procedure Unbind(var f: TypedFile);
+
+function Binding(var f: text): BindingType;
+function Binding(var f: TypedFile): BindingType;
+
 procedure Extend(var f: text);
-{ TODO: Implement other file functions: Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty, and the bindable keyword }
+
+procedure Update(var f: TypedFile);
+procedure SeekRead(var f: TypedFile; pos: integer);
+procedure SeekWrite(var f: TypedFile; pos: integer);
+procedure SeekUpdate(var f: TypedFile; pos: integer);
+function Position(var f: TypedFile): integer;
+function LastPosition(var f: TypedFile): integer;
+function Empty(var f: TypedFile): Boolean;
 
 { date/time }
     type
@@ -244,11 +259,153 @@ begin
   polar := c;{}
 end;
 
+procedure Bind(var f: text; b: BindingType);
+begin
+  Assign(f, b.Name);
+end;
+
+procedure Bind(var f: TypedFile; b: BindingType);
+begin
+  Assign(f, b.Name);
+end;
+
+procedure Unbind(var f: text);
+begin
+  if TextRec(f).Mode <> fmClosed then
+  begin
+    Close(f);
+  end;
+end;
+
+procedure Unbind(var f: TypedFile);
+begin
+  if FileRec(f).Mode <> fmClosed then
+  begin
+    Close(f);
+  end;
+end;
+
+function Binding(var f: text): BindingType;
+var
+  fe: Boolean;
+  Mode: longint;
+begin
+  Binding.Name := TextRec(f).Name;
+
+  Mode := TextRec(f).Mode;
+  case Mode of
+    fmClosed:
+    begin
+      fe := FileExists(Binding.Name);
+      { If we can't extend the file, it's obviously not bound}
+      {$I-}
+      Append(f); { Has to be Append rather than Extend to catch the IO Error, if any }
+      Binding.Bound := IOResult = 0;
+      {$I+}
+
+      { If the file didn't already exist, erase it }
+      if Binding.Bound and not fe then
+      begin
+        Erase(f);
+      end;
+      
+      { Unbind the file again }
+      if Binding.Bound then
+      begin
+        Unbind(f);
+      end;
+    end;
+    otherwise
+    begin
+      { If the file isn't closed, we can assume it's bound }
+      Binding.Bound := true;
+    end;
+  end;
+end;
+
+function Binding(var f: TypedFile): BindingType;
+var
+  Mode: longint;
+begin
+  Binding.Name := FileRec(f).Name;
+
+  Mode := FileRec(f).Mode;
+  case Mode of
+    fmClosed:
+    begin
+      {$I-}
+      { If the file exists, try renaming it }
+      if FileExists(Binding.Name) then
+      begin
+        Rename(f, Binding.Name + '.binding');
+        Rename(f, Binding.Name);
+        Binding.Bound := IOResult = 0;
+      end
+      { If not, let's try writing to it }
+      else
+      begin
+        Rewrite(f);
+        Binding.Bound := IOResult = 0;
+
+        { Restore to previous state }
+        if Binding.Bound then
+        begin
+          Erase(f);
+          Unbind(f);
+        end;
+      end;
+      {$I+}
+    end;
+    otherwise
+    begin
+      { If the file isn't closed, we can assume it's bound }
+      Binding.Bound := true;
+    end;
+  end;
+end;
+
 procedure Extend(var f: text);
 begin
   Append(f);
 end;
 
+procedure Update(var f: TypedFile);
+begin
+  SeekWrite(f, 0);
+end;
+
+procedure SeekRead(var f: TypedFile; pos: integer);
+begin
+  Reset(f);
+  Seek(f, pos);
+end;
+
+procedure SeekWrite(var f: TypedFile; pos: integer);
+begin
+  Seek(f, pos);
+  Truncate(f);
+end;
+
+procedure SeekUpdate(var f: TypedFile; pos: integer);
+begin
+  Seek(f, pos);
+end;
+
+function Position(var f: TypedFile): integer;
+begin
+  Position := FilePos(f);
+end;
+
+function LastPosition(var f: TypedFile): integer;
+begin
+  LastPosition := 0; { Proper implementation depends on features that haven't been implemented yet }
+end;
+
+function Empty(var f: TypedFile): Boolean;
+begin
+  Empty := Eof(f);
+end;
+
     procedure GetTimeStamp(var ts : TimeStamp);
       var
         year1,month1,mday1,wday1,
-- 
2.13.5


From 105d54d8b1c1ddb106d49da5cf2df77b7275ec3d Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sun, 15 Oct 2017 16:49:52 -0400
Subject: [PATCH 09/20] At least attempt to use an FPU

---
 rtl/inc/complexh.inc | 6 ++++++
 rtl/inc/extpas.pp    | 1 +
 2 files changed, 7 insertions(+)

diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
index 29ce0b0f3a..d7a9642eeb 100644
--- a/rtl/inc/complexh.inc
+++ b/rtl/inc/complexh.inc
@@ -1,5 +1,11 @@
 { ISO 10206 complex numbers definitions }
 {$INLINE ON}
+
+{ Try to use at least some FPU, even an emulated one, if possible }
+{$IFDEF FPUNONE}
+{$FPUTYPE SOFT}
+{$ENDIF}
+
     type complex = record
                      re : real;
                      im : real;
diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 42e7c9d5e2..f78411bea5 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -52,6 +52,7 @@ type
   real = integer;
 {$ENDIF}
 
+{ This has to be included after the real redefinition, or you get errors about unresolved forward references }
 {$I complexh.inc}
 
 { Required constants }
-- 
2.13.5


From 8dfd34e85f24c035b479e9ccebd4a5ef4405d140 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sun, 15 Oct 2017 17:15:35 -0400
Subject: [PATCH 10/20] Alternative to defaulting to longstrings, so that
 Write/WriteLn will work in extpas programs (of course, a true ISO 10206
 string type is planned)

---
 rtl/inc/extpas.pp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index f78411bea5..d8d65bb6fb 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -14,8 +14,6 @@
 
  **********************************************************************}
 
-{$H+}
-
 unit extpas; { TODO: Make a module }
 
 { TODO: Implement these things to make macros unnecessary }
@@ -459,7 +457,9 @@ end;
 
 function Substr(s: String; i, j: integer): String;
 begin
-  Substr := s[i..i+j-1];
+  { The type casting is not part of the standard, but it's necessary for this to be compilable.
+    Hopefully, the future implementation of the ISO 10206 string type will alleviate this problem. }
+  Substr := String(AnsiString(s[i..i+j-1]));
 end;
 
 function Trim(protected s: String): String;
-- 
2.13.5


From 760bd5d3cfafdaa0f918cc40c3236ffbf1e1fd50 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sun, 15 Oct 2017 19:36:08 -0400
Subject: [PATCH 11/20] Hm, {$FPUTYPE SOFT} generates a fatal error instead of
 a warning. Disabling until it's implemented.

---
 rtl/inc/complexh.inc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
index d7a9642eeb..f514216f05 100644
--- a/rtl/inc/complexh.inc
+++ b/rtl/inc/complexh.inc
@@ -3,7 +3,8 @@
 
 { Try to use at least some FPU, even an emulated one, if possible }
 {$IFDEF FPUNONE}
-{$FPUTYPE SOFT}
+{ $FPUTYPE SOFT}
+{$WARNING No FPU is being used.  Please set one or complex numbers won't work correctly.}
 {$ENDIF}
 
     type complex = record
-- 
2.13.5


From 7a6914267b215af0d62d7e7c6a69dae7ee191d5a Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sun, 15 Oct 2017 19:40:20 -0400
Subject: [PATCH 12/20] Exporting in the right order

---
 rtl/inc/extpas.pp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index d8d65bb6fb..a837659c7d 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -26,7 +26,7 @@ unit extpas; { TODO: Make a module }
 export
   iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
     Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
-    BindingType, Extend, Bind, Unbind, Binding, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty { files },
+    BindingType, Bind, Unbind, Binding, Extend, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty { files },
     TimeStamp, GetTimeStamp, Date, Time, { date/time }
     String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
 }
-- 
2.13.5


From c55451b0307918ee0a441e6f6205ae9bd4825489 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sun, 15 Oct 2017 19:55:58 -0400
Subject: [PATCH 13/20] Makefile regenerated with latest fpcmake, as to not
 disable some targets

---
 packages/Makefile | 312 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 276 insertions(+), 36 deletions(-)

diff --git a/packages/Makefile b/packages/Makefile
index bf9e7db547..e419ea8365 100644
--- a/packages/Makefile
+++ b/packages/Makefile
@@ -1,11 +1,11 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2014/10/17]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2017-09-21 rev 37286]
 #
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
-BSDs = freebsd netbsd openbsd darwin
-UNIXs = linux $(BSDs) solaris qnx haiku
-LIMIT83fs = go32v2 os2 emx watcom
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-aros x86_64-dragonfly arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-darwin wasm-wasm sparc64-linux
+BSDs = freebsd netbsd openbsd darwin dragonfly
+UNIXs = linux $(BSDs) solaris qnx haiku aix
+LIMIT83fs = go32v2 os2 emx watcom msdos win16
 OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 .PHONY: FORCE
@@ -178,6 +178,24 @@ else
 ARCH=$(CPU_TARGET)
 endif
 endif
+ifeq ($(FULL_TARGET),arm-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t or SUBARCH=armv7m) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for avr-embedded, a sub-architecture (e.g. SUBARCH=avr25 or SUBARCH=avr35) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
+ifeq ($(FULL_TARGET),mipsel-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 TARGETSUFFIX=$(OS_TARGET)
 SOURCESUFFIX=$(OS_SOURCE)
@@ -203,10 +221,18 @@ endif
 ifeq ($(OS_TARGET),linux)
 linuxHier=1
 endif
+ifndef CROSSCOMPILE
+BUILDFULLNATIVE=1
+export BUILDFULLNATIVE
+endif
+ifdef BUILDFULLNATIVE
+BUILDNATIVE=1
+export BUILDNATIVE
+endif
 export OS_TARGET OS_SOURCE ARCH CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
 ifdef FPCDIR
 override FPCDIR:=$(subst \,/,$(FPCDIR))
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
 override FPCDIR=wrong
 endif
 else
@@ -215,7 +241,7 @@ endif
 ifdef DEFAULT_FPCDIR
 ifeq ($(FPCDIR),wrong)
 override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
 override FPCDIR=wrong
 endif
 endif
@@ -229,11 +255,11 @@ endif
 else
 override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
 override FPCDIR:=$(FPCDIR)/..
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
 override FPCDIR:=$(FPCDIR)/..
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
 override FPCDIR:=$(BASEDIR)
-ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl)),)
 override FPCDIR=c:/pp
 endif
 endif
@@ -251,8 +277,27 @@ endif
 ifndef BINUTILSPREFIX
 ifndef CROSSBINDIR
 ifdef CROSSCOMPILE
+ifneq ($(OS_TARGET),msdos)
 ifndef DARWIN2DARWIN
+ifneq ($(CPU_TARGET),jvm)
 BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+ifeq ($(OS_TARGET),android)
+ifeq ($(CPU_TARGET),arm)
+BINUTILSPREFIX=arm-linux-androideabi-
+else
+ifeq ($(CPU_TARGET),i386)
+BINUTILSPREFIX=i686-linux-android-
+else
+ifeq ($(CPU_TARGET),mipsel)
+BINUTILSPREFIX=mipsel-linux-android-
+endif
+endif
+endif
+endif
+endif
+endif
+else
+BINUTILSPREFIX=$(OS_TARGET)-
 endif
 endif
 endif
@@ -261,7 +306,7 @@ UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
 ifeq ($(UNITSDIR),)
 UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
 endif
-PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages)
 ifndef FPCFPMAKE
 ifdef CROSSCOMPILE
 ifeq ($(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR)))),)
@@ -345,9 +390,6 @@ endif
 ifeq ($(FULL_TARGET),i386-solaris)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
-ifeq ($(FULL_TARGET),i386-qnx)
-override COMPILER_INCLUDEDIR+=../rtl/inc
-endif
 ifeq ($(FULL_TARGET),i386-netware)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
@@ -384,10 +426,13 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
-ifeq ($(FULL_TARGET),m68k-linux)
+ifeq ($(FULL_TARGET),i386-android)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i386-aros)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
-ifeq ($(FULL_TARGET),m68k-freebsd)
+ifeq ($(FULL_TARGET),m68k-linux)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
@@ -399,10 +444,10 @@ endif
 ifeq ($(FULL_TARGET),m68k-atari)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
-ifeq ($(FULL_TARGET),m68k-openbsd)
+ifeq ($(FULL_TARGET),m68k-palmos)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
-ifeq ($(FULL_TARGET),m68k-palmos)
+ifeq ($(FULL_TARGET),m68k-macos)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
@@ -432,6 +477,9 @@ endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
 ifeq ($(FULL_TARGET),sparc-linux)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
@@ -468,6 +516,15 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
+ifeq ($(FULL_TARGET),x86_64-iphonesim)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
@@ -492,6 +549,12 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
+ifeq ($(FULL_TARGET),arm-android)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),arm-aros)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
@@ -501,6 +564,9 @@ endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
 ifeq ($(FULL_TARGET),avr-embedded)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
@@ -510,9 +576,45 @@ endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
+ifeq ($(FULL_TARGET),mips-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 override COMPILER_INCLUDEDIR+=../rtl/inc
 endif
+ifeq ($(FULL_TARGET),mipsel-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),mipsel-android)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i8086-embedded)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),i8086-win16)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),aarch64-darwin)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),wasm-wasm)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
+ifeq ($(FULL_TARGET),sparc64-linux)
+override COMPILER_INCLUDEDIR+=../rtl/inc
+endif
 ifdef REQUIRE_UNITSDIR
 override UNITSDIR+=$(REQUIRE_UNITSDIR)
 endif
@@ -741,12 +843,26 @@ SHAREDLIBEXT=.dll
 SHORTSUFFIX=wat
 IMPORTLIBPREFIX=
 endif
+ifneq ($(CPU_TARGET),jvm)
+ifeq ($(OS_TARGET),android)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+endif
 ifeq ($(OS_TARGET),linux)
 BATCHEXT=.sh
 EXEEXT=
 HASSHAREDLIB=1
 SHORTSUFFIX=lnx
 endif
+ifeq ($(OS_TARGET),dragonfly)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=df
+endif
 ifeq ($(OS_TARGET),freebsd)
 BATCHEXT=.sh
 EXEEXT=
@@ -792,6 +908,11 @@ EXEEXT=
 SHAREDLIBEXT=.library
 SHORTSUFFIX=amg
 endif
+ifeq ($(OS_TARGET),aros)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=aros
+endif
 ifeq ($(OS_TARGET),morphos)
 EXEEXT=
 SHAREDLIBEXT=.library
@@ -865,6 +986,45 @@ EXEEXT=.dol
 SHAREDLIBEXT=.so
 SHORTSUFFIX=wii
 endif
+ifeq ($(OS_TARGET),aix)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=aix
+endif
+ifeq ($(OS_TARGET),java)
+OEXT=.class
+ASMEXT=.j
+SHAREDLIBEXT=.jar
+SHORTSUFFIX=java
+endif
+ifeq ($(CPU_TARGET),jvm)
+ifeq ($(OS_TARGET),android)
+OEXT=.class
+ASMEXT=.j
+SHAREDLIBEXT=.jar
+SHORTSUFFIX=android
+endif
+endif
+ifeq ($(OS_TARGET),msdos)
+STATICLIBPREFIX=
+STATICLIBEXT=.a
+SHORTSUFFIX=d16
+endif
+ifeq ($(OS_TARGET),embedded)
+ifeq ($(CPU_TARGET),i8086)
+STATICLIBPREFIX=
+STATICLIBEXT=.a
+else
+EXEEXT=.bin
+endif
+SHORTSUFFIX=emb
+endif
+ifeq ($(OS_TARGET),win16)
+STATICLIBPREFIX=
+STATICLIBEXT=.a
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w16
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -1054,6 +1214,7 @@ ASNAME=$(BINUTILSPREFIX)as
 LDNAME=$(BINUTILSPREFIX)ld
 ARNAME=$(BINUTILSPREFIX)ar
 RCNAME=$(BINUTILSPREFIX)rc
+NASMNAME=$(BINUTILSPREFIX)nasm
 ifndef ASPROG
 ifdef CROSSBINDIR
 ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
@@ -1082,11 +1243,23 @@ else
 ARPROG=$(ARNAME)
 endif
 endif
+ifndef NASMPROG
+ifdef CROSSBINDIR
+NASMPROG=$(CROSSBINDIR)/$(NASMNAME)$(SRCEXEEXT)
+else
+NASMPROG=$(NASMNAME)
+endif
+endif
 AS=$(ASPROG)
 LD=$(LDPROG)
 RC=$(RCPROG)
 AR=$(ARPROG)
+NASM=$(NASMPROG)
+ifdef inUnix
+PPAS=./ppas$(SRCBATCHEXT)
+else
 PPAS=ppas$(SRCBATCHEXT)
+endif
 ifdef inUnix
 LDCONFIG=ldconfig
 else
@@ -1134,9 +1307,6 @@ endif
 ifeq ($(FULL_TARGET),i386-solaris)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),i386-qnx)
-REQUIRE_PACKAGES_RTL=1
-endif
 ifeq ($(FULL_TARGET),i386-netware)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1173,10 +1343,13 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),m68k-linux)
+ifeq ($(FULL_TARGET),i386-android)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),m68k-freebsd)
+ifeq ($(FULL_TARGET),i386-aros)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
@@ -1188,10 +1361,10 @@ endif
 ifeq ($(FULL_TARGET),m68k-atari)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),m68k-openbsd)
+ifeq ($(FULL_TARGET),m68k-palmos)
 REQUIRE_PACKAGES_RTL=1
 endif
-ifeq ($(FULL_TARGET),m68k-palmos)
+ifeq ($(FULL_TARGET),m68k-macos)
 REQUIRE_PACKAGES_RTL=1
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
@@ -1221,6 +1394,9 @@ endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),sparc-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1257,6 +1433,15 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),x86_64-iphonesim)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1281,6 +1466,12 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),arm-android)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-aros)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1290,6 +1481,9 @@ endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),avr-embedded)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -1299,9 +1493,45 @@ endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),mips-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),mipsel-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),mipsel-android)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i8086-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i8086-win16)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),aarch64-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),wasm-wasm)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifdef REQUIRE_PACKAGES_RTL
 PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
 ifneq ($(PACKAGEDIR_RTL),)
@@ -1352,6 +1582,7 @@ endif
 ifeq ($(OS_SOURCE),openbsd)
 override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
 override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
+override FPMAKE_BUILD_OPT+=-FD$(NEW_BINUTILS_PATH)
 endif
 ifndef CROSSBOOTSTRAP
 ifneq ($(BINUTILSPREFIX),)
@@ -1364,6 +1595,7 @@ endif
 ifndef CROSSCOMPILE
 ifneq ($(BINUTILSPREFIX),)
 override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
+override FPMAKE_BUILD_OPT+=-XP$(BINUTILSPREFIX)
 endif
 endif
 ifdef UNITDIR
@@ -1452,22 +1684,20 @@ endif
 endif
 ifdef CREATESHARED
 override FPCOPT+=-Cg
-ifeq ($(CPU_TARGET),i386)
-override FPCOPT+=-Aas
 endif
-endif
-ifeq ($(findstring 2.0.,$(FPC_VERSION)),)
-ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris),)
-ifeq ($(CPU_TARGET),x86_64)
+ifneq ($(findstring $(OS_TARGET),dragonfly freebsd openbsd netbsd linux solaris),)
+ifneq ($(findstring $(CPU_TARGET),x86_64 mips mipsel),)
 override FPCOPT+=-Cg
 endif
 endif
-endif
 ifdef LINKSHARED
 endif
 ifdef OPT
 override FPCOPT+=$(OPT)
 endif
+ifdef FPMAKEBUILDOPT
+override FPMAKE_BUILD_OPT+=$(FPMAKEBUILDOPT)
+endif
 ifdef FPCOPTDEF
 override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
 endif
@@ -1487,18 +1717,24 @@ endif
 ifdef ACROSSCOMPILE
 override FPCOPT+=$(CROSSOPT)
 endif
-override COMPILER:=$(FPC) $(FPCOPT)
-ifeq (,$(findstring -s ,$(COMPILER)))
+override COMPILER:=$(strip $(FPC) $(FPCOPT))
+ifneq (,$(findstring -sh ,$(COMPILER)))
+UseEXECPPAS=1
+endif
+ifneq (,$(findstring -s ,$(COMPILER)))
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+UseEXECPPAS=1
+endif
+endif
+ifneq ($(UseEXECPPAS),1)
 EXECPPAS=
 else
-ifeq ($(FULL_SOURCE),$(FULL_TARGET))
 ifdef RUNBATCH
 EXECPPAS:=@$(RUNBATCH) $(PPAS)
 else
 EXECPPAS:=@$(PPAS)
 endif
 endif
-endif
 ifdef TARGET_RSTS
 override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
 override CLEANRSTFILES+=$(RSTFILES)
@@ -1579,6 +1815,10 @@ endif
 ifdef DEBUGSYMEXT
 	-$(DEL) *$(DEBUGSYMEXT)
 endif
+ifdef LOCALFPMAKEBIN
+	-$(DEL) $(LOCALFPMAKEBIN)
+	-$(DEL) $(FPMAKEBINOBJ)
+endif
 fpc_distclean: cleanall
 .PHONY: fpc_baseinfo
 override INFORULES+=fpc_baseinfo
-- 
2.13.5


From a3625f6d154526f630c5f1b957555d8c4fed7b70 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Sun, 15 Oct 2017 20:53:06 -0400
Subject: [PATCH 14/20] Less iffy empty function

---
 rtl/inc/extpas.pp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index a837659c7d..9bb848616b 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -402,7 +402,7 @@ end;
 
 function Empty(var f: TypedFile): Boolean;
 begin
-  Empty := Eof(f);
+  Empty := FileSize(f) = 0;
 end;
 
     procedure GetTimeStamp(var ts : TimeStamp);
-- 
2.13.5


From cd5077d6381ea9b204a3632bf6bd3068cbcd122e Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Mon, 16 Oct 2017 22:47:33 -0400
Subject: [PATCH 15/20] Further changes for FPU-less systems

---
 rtl/inc/complex.inc  | 5 -----
 rtl/inc/complexh.inc | 9 +++++++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/rtl/inc/complex.inc b/rtl/inc/complex.inc
index 7dd3dff5cb..3e67c63b3a 100644
--- a/rtl/inc/complex.inc
+++ b/rtl/inc/complex.inc
@@ -1,9 +1,4 @@
 { ISO 10206 complex numbers implementation }
-const
-  Zero = {$IFNDEF FPUNONE}0.0{$ELSE}0{$ENDIF};
-  One = {$IFNDEF FPUNONE}1.0{$ELSE}1{$ENDIF};
-  Two = {$IFNDEF FPUNONE}2.0{$ELSE}2{$ENDIF};
-
     function cinit(_re,_im : real) : complex;inline;
     begin
       cinit.re:=_re;
diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
index f514216f05..86859fc068 100644
--- a/rtl/inc/complexh.inc
+++ b/rtl/inc/complexh.inc
@@ -6,14 +6,19 @@
 { $FPUTYPE SOFT}
 {$WARNING No FPU is being used.  Please set one or complex numbers won't work correctly.}
 {$ENDIF}
+const
+  Zero = {$IFNDEF FPUNONE}0.0{$ELSE}0{$ENDIF};
+  One = {$IFNDEF FPUNONE}1.0{$ELSE}1{$ENDIF};
+  Two = {$IFNDEF FPUNONE}2.0{$ELSE}2{$ENDIF};
+
 
     type complex = record
                      re : real;
                      im : real;
                    end;
 
-    const i : complex = (re : 0.0; im : 1.0);
-          _0 : complex = (re : 0.0; im : 0.0);
+    const i : complex = (re : Zero; im : One);
+          _0 : complex = (re : Zero; im : Zero);
 
     { assignment overloading is also used in type conversions
       (beware also in implicit type conversions)
-- 
2.13.5


From 1212c930cfca20f4cc125eb863f07a9bec6f4717 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Mon, 16 Oct 2017 22:48:26 -0400
Subject: [PATCH 16/20] Fixed Binding.Bound returning false for nonexistent
 text files and a crash with SeekRead

---
 rtl/inc/extpas.pp | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 9bb848616b..fa8d1f3bb4 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -298,7 +298,15 @@ begin
       fe := FileExists(Binding.Name);
       { If we can't extend the file, it's obviously not bound}
       {$I-}
-      Append(f); { Has to be Append rather than Extend to catch the IO Error, if any }
+      if fe then
+      begin
+        Append(f); { Has to be Append rather than Extend to catch the IO Error, if any }
+      end
+      else
+      begin
+        Rewrite(f);
+      end;
+
       Binding.Bound := IOResult = 0;
       {$I+}
 
@@ -375,8 +383,9 @@ end;
 
 procedure SeekRead(var f: TypedFile; pos: integer);
 begin
-  Reset(f);
-  Seek(f, pos);
+  { f has to be cast to file or calling this function causes a crash }
+  Reset(file(f));
+  Seek(file(f), pos);
 end;
 
 procedure SeekWrite(var f: TypedFile; pos: integer);
-- 
2.13.5


From fb47b910866194442be192f979a49cdcbbbf32cf Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Tue, 17 Oct 2017 00:01:13 -0400
Subject: [PATCH 17/20] Switched to exceptions as to not propagate the I/O
 errors

---
 rtl/inc/extpas.pp | 107 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 58 insertions(+), 49 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index fa8d1f3bb4..758ba4bc01 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -14,6 +14,8 @@
 
  **********************************************************************}
 
+{$modeswitch exceptions}
+
 unit extpas; { TODO: Make a module }
 
 { TODO: Implement these things to make macros unnecessary }
@@ -290,43 +292,46 @@ var
   Mode: longint;
 begin
   Binding.Name := TextRec(f).Name;
+  Binding.Bound := true;
 
   Mode := TextRec(f).Mode;
   case Mode of
     fmClosed:
     begin
       fe := FileExists(Binding.Name);
-      { If we can't extend the file, it's obviously not bound}
-      {$I-}
-      if fe then
-      begin
-        Append(f); { Has to be Append rather than Extend to catch the IO Error, if any }
-      end
-      else
-      begin
-        Rewrite(f);
-      end;
-
-      Binding.Bound := IOResult = 0;
-      {$I+}
+      try
+        try
+          { If we can't extend the file, it's obviously not bound}
+          if fe then
+          begin
+            Extend(f);
+          end
+          else
+          begin
+            Rewrite(f);
+          end;
+        except
+          Binding.Bound := false;
+        end;
+      finally
+        { If the file didn't already exist, erase it }
+        try
+          if not fe then
+          begin
+            Unbind(f);
+            Erase(f);
+          end;
+        except
+          { If this fails, it can be silently ignored }
+        end;
 
-      { If the file didn't already exist, erase it }
-      if Binding.Bound and not fe then
-      begin
-        Erase(f);
-      end;
-      
-      { Unbind the file again }
-      if Binding.Bound then
-      begin
-        Unbind(f);
+        { Unbind the file again }
+        if Binding.Bound then
+        begin
+          Unbind(f);
+        end;
       end;
     end;
-    otherwise
-    begin
-      { If the file isn't closed, we can assume it's bound }
-      Binding.Bound := true;
-    end;
   end;
 end;
 
@@ -335,38 +340,42 @@ var
   Mode: longint;
 begin
   Binding.Name := FileRec(f).Name;
+  Binding.Bound := true;
 
   Mode := FileRec(f).Mode;
   case Mode of
     fmClosed:
     begin
-      {$I-}
-      { If the file exists, try renaming it }
-      if FileExists(Binding.Name) then
-      begin
-        Rename(f, Binding.Name + '.binding');
-        Rename(f, Binding.Name);
-        Binding.Bound := IOResult = 0;
-      end
-      { If not, let's try writing to it }
-      else
-      begin
-        Rewrite(f);
-        Binding.Bound := IOResult = 0;
-
+      try
+        try
+          { If the file exists, try renaming it }
+          if FileExists(Binding.Name) then
+          begin
+            Rename(f, Binding.Name + '.binding');
+            Rename(f, Binding.Name);
+          end
+          { If not, let's try writing to it }
+          else
+          begin
+            Rewrite(file(f)); { Must be cast in order to work }
+
+            try
+              Unbind(f);
+              Erase(f);
+            except
+              { We can silently ignore if the file can't be erased }
+            end;
+          end;
+        except
+          Binding.Bound := false;
+        end;
+      finally
         { Restore to previous state }
         if Binding.Bound then
         begin
-          Erase(f);
           Unbind(f);
         end;
       end;
-      {$I+}
-    end;
-    otherwise
-    begin
-      { If the file isn't closed, we can assume it's bound }
-      Binding.Bound := true;
     end;
   end;
 end;
-- 
2.13.5


From e964461e7c0e6605e402f3ad5a535f6a00ca17de Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Tue, 17 Oct 2017 01:39:34 -0400
Subject: [PATCH 18/20] Implemented Trim according to the standard

---
 rtl/inc/extpas.pp | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 758ba4bc01..028f4c5541 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -145,7 +145,7 @@ type
 function Index(s1, s2: String): integer;
 function Substr(s: String; i: integer): String;
 function Substr(s: String; i, j: integer): String;
-function Trim(protected s: String): String; { It's not marked as protected in the spec; it's just to show the syntax }
+function Trim(s: String): String;
 
 function EQ(s1, s2: String): Boolean;
 function LT(s1, s2: String): Boolean;
@@ -480,9 +480,30 @@ begin
   Substr := String(AnsiString(s[i..i+j-1]));
 end;
 
-function Trim(protected s: String): String;
+function Trim(s: String): String;
+var
+  n, p: integer;
 begin
-  Trim := SysUtils.Trim(s);
+  n := Length(s);
+
+  if n = 0 then
+  begin
+    Trim := '';
+  end
+  else if s[n] <> ' ' then
+  begin
+    Trim := s;
+  end
+  else
+  begin
+    p := n;
+    while s[p - 1] = ' ' do
+    begin
+      p := Pred(p);
+    end;
+
+    Trim := Substr(s, 1, p - 1);
+  end;
 end;
 
 function EQ(s1, s2: String): Boolean;
-- 
2.13.5


From 6cefc9793f0ea5231860e1442f920aba00f2b524 Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Tue, 17 Oct 2017 02:31:01 -0400
Subject: [PATCH 19/20] Implemented Index according to the standard

---
 rtl/inc/extpas.pp | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 028f4c5541..2d4822c0df 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -464,8 +464,35 @@ begin
 end;
 
 function Index(s1, s2: String): integer;
+var
+  i: integer;
+  iexists: Boolean;
 begin
-  Index := Pos(s2, s1);
+  if s2 = '' then
+  begin
+    Index := 1;
+  end
+  else if s1 = '' then
+  begin
+    Index := 0;
+  end
+  else
+  begin
+    i := 0;
+    repeat
+      i := Succ(i);
+      iexists := Substr(s1, i, Length(s2)) = s2;
+    until iexists or (i = Length(s1));
+
+    if iexists then
+    begin
+      Index := i;
+    end
+    else
+    begin
+      Index := 0;
+    end;
+  end;
 end;
 
 function Substr(s: String; i: integer): String;
-- 
2.13.5


From 3cf9914f6d6f46e4181fa76820cd6fbbb2b3c59c Mon Sep 17 00:00:00 2001
From: Keith Bowes <keithbowes@users.noreply.github.com>
Date: Wed, 18 Oct 2017 22:17:20 -0400
Subject: [PATCH 20/20] Finishing touches for difficulty level 2

---
 packages/rtl-extra/src/inc/ucomplex.pp |   5 +-
 rtl/inc/complex.inc                    |  66 ++++----------
 rtl/inc/complexh.inc                   |  27 +++---
 rtl/inc/extpas.pp                      | 152 ++++++++++++++-------------------
 4 files changed, 95 insertions(+), 155 deletions(-)

diff --git a/packages/rtl-extra/src/inc/ucomplex.pp b/packages/rtl-extra/src/inc/ucomplex.pp
index fc70785c8c..9cff0bbc7b 100644
--- a/packages/rtl-extra/src/inc/ucomplex.pp
+++ b/packages/rtl-extra/src/inc/ucomplex.pp
@@ -28,14 +28,13 @@ Unit UComplex;
   type
     pcomplex = ^complex;
 
+  const
+    _0 : complex = (re : 0.0; im : 0.0);
 
     { operator := (i : longint) z : complex;
       not needed because longint can be converted to real }
     function csamevalue(z1, z2 : complex) : boolean;
 
-    { complex functions }
-    function cong (z : complex) : complex;      { conjuge }
-
     { inverse function 1/z }
     function cinv (z : complex) : complex;
 
diff --git a/rtl/inc/complex.inc b/rtl/inc/complex.inc
index 3e67c63b3a..e2923a5d00 100644
--- a/rtl/inc/complex.inc
+++ b/rtl/inc/complex.inc
@@ -1,4 +1,5 @@
-{ ISO 10206 complex numbers implementation }
+{ Complex numbers implementation }
+{$IFNDEF FPUNONE}
     function cinit(_re,_im : real) : complex;inline;
     begin
       cinit.re:=_re;
@@ -8,7 +9,7 @@
   operator := (r : real) z : complex; inline;
     begin
        z.re:=r;
-       z.im:=Zero;
+       z.im:=0.0;
     end;
 
   { four base operations  +, -, * , / }
@@ -142,11 +143,7 @@
   function carg (z : complex): real;
     { argument : 0 / z = p ei0 }
     begin
-      {$IFNDEF FPUNONE}
        carg := arctan2(z.im, z.re);
-       {$ELSE}
-       carg := Zero;
-       {$ENDIF}
     end;
 
   function cong (z : complex) : complex;
@@ -167,13 +164,13 @@
   operator = (z1 : complex; r :real) b : boolean;
     { returns TRUE if z1 = r }
     begin
-       b := (z1.re = r) and (z1.im = Zero)
+       b := (z1.re = r) and (z1.im = 0.0)
     end;
 
   operator = (r : real; z1 : complex) b : boolean;
     { returns TRUE if z1 = r }
     begin
-       b := (z1.re = r) and (z1.im = Zero)
+       b := (z1.re = r) and (z1.im = 0.0)
     end;
 
 
@@ -194,11 +191,7 @@
     { ln( p exp(i0)) = ln(p) + i0 + 2kpi }
     begin
        cln.re := ln(cmod(z));
-       {$IFNDEF FPUNONE}
        cln.im := arctan2(z.im, z.re);
-       {$ELSE}
-       cln.im := Zero;
-       {$ENDIF}
     end;
 
   function csqr(z: complex): complex;
@@ -213,21 +206,15 @@
     var
        root, q : real;
     begin
-      if (z.re<>Zero) or (z.im<>Zero) then
+      if (z.re<>0.0) or (z.im<>0.0) then
         begin
-          {$IFNDEF FPUNONE}
            root := sqrt(0.5 * (abs(z.re) + cmod(z)));
-           q := z.im / (Two * root);
-           {$ELSE}
-           root := 1;
-           q := z.im div (2 * root);
-           {$ENDIF}
-           if z.re >= Zero then
+           if z.re >= 0.0 then
              begin
                 csqrt.re := root;
                 csqrt.im := q;
              end
-           else if z.im < Zero then
+           else if z.im < 0.0 then
              begin
                 csqrt.re := - q;
                 csqrt.im := - root
@@ -267,12 +254,8 @@
     { cos(x+iy) = cos(x).cos(iy) - sin(x).sin(iy) }
     { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
     begin
-      {$IFNDEF FPUNONE}
        ccos.re := cos(z.re) * cosh(z.im);
        ccos.im := - sin(z.re) * sinh(z.im);
-       {$ELSE}
-       ccos := _0;
-       {$ENDIF}
     end;
 
   function csin (z : complex) : complex;
@@ -280,12 +263,8 @@
     { sin(x+iy) = sin(x).cos(iy) + cos(x).sin(iy) }
     { cos(ix) = cosh(x) et sin(ix) = i.sinh(x) }
     begin
-      {$IFNDEF FPUNONE}
        csin.re := sin(z.re) * cosh(z.im);
        csin.im := cos(z.re) * sinh(z.im);
-       {$ELSE}
-       csin := _0;
-       {$ENDIF}
     end;
 
   function ctg (z : complex) : complex;
@@ -303,33 +282,21 @@
     { arc cosinus complex }
     { arccos(z) = -i.argch(z) }
     begin
-      {$IFNDEF FPUNONE}
        carc_cos := -i*carg_ch(z);
-       {$ELSE}
-       carc_cos := _0;
-       {$ENDIF}
     end;
 
   function carc_sin (z : complex) : complex;
     { arc sinus complex }
     { arcsin(z) = -i.argsh(i.z) }
     begin
-      {$IFNDEF FPUNONE}
        carc_sin := -i*carg_sh(i*z);
-       {$ELSE}
-       carc_sin := _0;
-       {$ENDIF}
     end;
 
   function carc_tg (z : complex) : complex;
     { arc tangente complex }
     { arctg(z) = -i.argth(i.z) }
     begin
-      {$IFNDEF FPUNONE}
        carc_tg := -i*carg_th(i*z);
-       {$ELSE}
-       carc_tg := _0;
-       {$ENDIF}
     end;
 
   { inverse complex hyperbolic functions }
@@ -339,11 +306,7 @@
     {                          _________  }
     { argch(z) = -/+ ln(z + i.V 1 - z.z)  }
     begin
-      {$IFNDEF CPUNONE}
-       carg_ch:=-cln(z+i*csqrt(One-z*z));
-      {$ELSE}
-       carg_ch := _0;
-       {$ENDIF}
+       carg_ch:=-cln(z+i*csqrt(1.0-z*z));
     end;
 
   function carg_sh (z : complex) : complex;
@@ -351,12 +314,19 @@
     {                    ________  }
     { argsh(z) = ln(z + V 1 + z.z) }
     begin
-       carg_sh:=cln(z+csqrt(z*z+One));
+       carg_sh:=cln(z+csqrt(z*z+1.0));
     end;
 
   function carg_th (z : complex) : complex;
     { hyperbolic arc tangent }
     { argth(z) = 1/2 ln((z + 1) / (1 - z)) }
     begin
-       carg_th:=cln((z+One)/(One-z))/Two;
+       carg_th:=cln((z+1.0)/(1.0-z))/2.0;
     end;
+
+  function cpolar(r, t: real): complex;
+  begin
+    cpolar.re := r * cos(t);
+    cpolar.im := r * sin(t);
+  end;
+{$ENDIF}
diff --git a/rtl/inc/complexh.inc b/rtl/inc/complexh.inc
index 86859fc068..a51ca07c9a 100644
--- a/rtl/inc/complexh.inc
+++ b/rtl/inc/complexh.inc
@@ -1,24 +1,14 @@
-{ ISO 10206 complex numbers definitions }
+{ Complex numbers definitions }
 {$INLINE ON}
-
-{ Try to use at least some FPU, even an emulated one, if possible }
-{$IFDEF FPUNONE}
-{ $FPUTYPE SOFT}
-{$WARNING No FPU is being used.  Please set one or complex numbers won't work correctly.}
-{$ENDIF}
-const
-  Zero = {$IFNDEF FPUNONE}0.0{$ELSE}0{$ENDIF};
-  One = {$IFNDEF FPUNONE}1.0{$ELSE}1{$ENDIF};
-  Two = {$IFNDEF FPUNONE}2.0{$ELSE}2{$ENDIF};
-
-
+{$IFNDEF FPUNONE}
     type complex = record
                      re : real;
                      im : real;
                    end;
 
-    const i : complex = (re : Zero; im : One);
-          _0 : complex = (re : Zero; im : Zero);
+    const i : complex = (re : 0.0; im : 1.0);
+          Zero : complex = (re : 0.0; im : 0.0);
+          One : complex = (re : 1.0; im : 0.0);
 
     { assignment overloading is also used in type conversions
       (beware also in implicit type conversions)
@@ -79,6 +69,9 @@ const
     function cmod (z : complex) : real;           { module }
     function carg (z : complex) : real;           { argument : a / z = p.e^ia }
 
+    { complex functions }
+    function cong (z : complex) : complex;      { conjuge }
+
     { fonctions elementaires }
     function cexp (z : complex) : complex;       { exponential }
     function cln (z : complex) : complex;        { natural logarithm }
@@ -99,3 +92,7 @@ const
     function carg_ch (z : complex) : complex;    { hyperbolic arc cosinus }
     function carg_sh (z : complex) : complex;    { hyperbolic arc sinus }
     function carg_th (z : complex) : complex;    { hyperbolic arc tangente }
+
+    { polar }
+    function cpolar (r, t : real) : complex;
+{$ENDIF}
diff --git a/rtl/inc/extpas.pp b/rtl/inc/extpas.pp
index 2d4822c0df..0d065ac5cc 100644
--- a/rtl/inc/extpas.pp
+++ b/rtl/inc/extpas.pp
@@ -27,7 +27,9 @@ unit extpas; { TODO: Make a module }
 {
 export
   iso10206 = (maxchar, maxreal, minreal, epsreal, { required constants}
-    Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, arg, polar, { complex numbers },
+{$IFNDEF FPUNONE}
+    Complex, Cmplx, Im, Re, abs, arctan, cos, exp, ln, sin, sqr, sqrt, carg => arg, cpolar => polar, { complex numbers },
+{$ENDIF}
     BindingType, Bind, Unbind, Binding, Extend, Update, SeekRead, SeekWrite, SeekUpdate, Position, LastPosition, Empty { files },
     TimeStamp, GetTimeStamp, Date, Time, { date/time }
     String, Index, Substr, Trim, EQ, LT, GT, NE, LE, GE { Strings });
@@ -37,20 +39,14 @@ export
 
 {
 import
-{$IFDEF UNIX}
-  clocale; { So that dates will print out in a localized format }
-{$ENDIF}
   SysUtils;
 }
 
 { Implement as much of ISO 10206 as is possible }
 
-type
 {$IFNDEF FPUNONE}
+type
   real = double;
-{$ELSE}
-  real = integer;
-{$ENDIF}
 
 { This has to be included after the real redefinition, or you get errors about unresolved forward references }
 {$I complexh.inc}
@@ -59,36 +55,32 @@ type
 const
   maxchar = Chr(255); { Should this depend on the codepage? }
 
-{$IFNDEF FPUNONE}
   maxreal = 1.7E308;
   minreal = 5.0E-324;
   epsreal = 1 + 5.0E-15 - 1.0;
-{$ELSE}
-  maxreal = maxint;
-  minreal = 0 - maxint - 1;
-  epsreal = 0;
-{$ENDIF}
 
-operator ** (r1, r2: real) z: real;
+operator ** (r1, r2: real) z: real; inline;
 
 { Complex numbers}
-function Cmplx(re, im: real): Complex;
-function Im(x: Complex): real;
-function Re(x: Complex): real;
+function Cmplx(re, im: real): Complex; inline;
+function Im(x: Complex): real; inline;
+function Re(x: Complex): real; inline;
 
 { The real and integer versions should be handled by System }
-function abs(x: Complex): real; overload;
-function arctan(x: Complex): Complex; overload;
-function cos(x: Complex): Complex; overload;
-function exp(x: Complex): Complex; overload;
-function ln(x: Complex): Complex; overload;
-function sin(x: Complex): Complex; overload;
-function sqr(x: Complex): Complex; overload;
-function sqrt(x: Complex): Complex; overload;
+{ The overload directive has to be used so that the integer/real variants can also be used }
+function abs(x: Complex): real; overload; inline;
+function arctan(x: Complex): Complex; overload; inline;
+function cos(x: Complex): Complex; overload; inline;
+function exp(x: Complex): Complex; overload; inline;
+function ln(x: Complex): Complex; overload; inline;
+function sin(x: Complex): Complex; overload; inline;
+function sqr(x: Complex): Complex; overload; inline;
+function sqrt(x: Complex): Complex; overload; inline;
 
 { AFAIK, not provided in System }
-function arg(x: Complex): real;
-function polar(r, t: real): Complex;
+function arg(x: Complex): real; inline;
+function polar(r, t: real): Complex; inline;
+{$ENDIF}
 
 { TODO: Implement the required operator pow (non-real powers) }
 
@@ -99,23 +91,23 @@ type
     Bound: Boolean;
   end;
 
-procedure Bind(var f: text; b: BindingType);
-procedure Bind(var f: TypedFile; b: BindingType);
-procedure Unbind(var f: text);
-procedure Unbind(var f: TypedFile);
+procedure Bind(var f: text; b: BindingType); inline;
+procedure Bind(var f: file; b: BindingType); inline;
+procedure Unbind(var f: text); inline;
+procedure Unbind(var f: file); inline;
 
 function Binding(var f: text): BindingType;
-function Binding(var f: TypedFile): BindingType;
+function Binding(var f: file): BindingType;
 
-procedure Extend(var f: text);
+procedure Extend(var f: text); inline;
 
-procedure Update(var f: TypedFile);
-procedure SeekRead(var f: TypedFile; pos: integer);
-procedure SeekWrite(var f: TypedFile; pos: integer);
-procedure SeekUpdate(var f: TypedFile; pos: integer);
-function Position(var f: TypedFile): integer;
-function LastPosition(var f: TypedFile): integer;
-function Empty(var f: TypedFile): Boolean;
+procedure Update(var f: file); inline;
+procedure SeekRead(var f: file; pos: integer); inline;
+procedure SeekWrite(var f: file; pos: integer); inline;
+procedure SeekUpdate(var f: file; pos: integer); inline;
+function Position(var f: file): integer; inline;
+function LastPosition(var f: file): integer; inline;
+function Empty(var f: file): Boolean; inline;
 
 { date/time }
     type
@@ -140,19 +132,19 @@ function Time(t: TimeStamp): String;
 {
 type
   String(capacity: integer) = packed array[0..capacity-1] of char;
-} { TODO: Implement ISO 10206 string type; just settling for Ansistrings for now }
+} { TODO: Implement ISO 10206 string type; just settling for ShortStrings for now }
 
 function Index(s1, s2: String): integer;
-function Substr(s: String; i: integer): String;
-function Substr(s: String; i, j: integer): String;
+function Substr(s: String; i: integer): String; inline;
+function Substr(s: String; i, j: integer): String; inline;
 function Trim(s: String): String;
 
-function EQ(s1, s2: String): Boolean;
+function EQ(s1, s2: String): Boolean; inline;
 function LT(s1, s2: String): Boolean;
-function GT(s1, s2: String): Boolean;
-function NE(s1, s2: String): Boolean;
-function LE(s1, s2: String): Boolean;
-function GE(s1, s2: String): Boolean;
+function GT(s1, s2: String): Boolean; inline;
+function NE(s1, s2: String): Boolean; inline;
+function LE(s1, s2: String): Boolean; inline;
+function GE(s1, s2: String): Boolean; inline;
 
   implementation
 
@@ -169,21 +161,10 @@ import
   {$ENDIF}
 }
 
+{$IFNDEF FPUNONE}
 operator ** (r1, r2: real) z: real;
-{$IFDEF FPUNONE}
-var
-  i: real;
-{$ENDIF}
 begin
-  {$IFNDEF FPUNONE}
   z := Power(r1, r2);
-  {$ELSE}
-  z := 1;
-  for i := 1 to r2 do
-  begin
-    z := z * r1;
-  end;
-  {$ENDIF}
 end;
 
 {$I complex.inc}
@@ -205,8 +186,7 @@ end;
 
 function abs(x: Complex): real;
 begin
-  { Thanks, Wikipedia! }
-  abs := abs(sqrt(sqr(x.re) + sqr(x.im)));
+  abs := abs(cmod(x));
 end;
 
 function arctan(x: Complex): Complex;
@@ -249,23 +229,18 @@ begin
   arg := carg(x);
 end;
 
-function polar(r, t: real){ = c}: Complex;
-var
-  c: Complex;
+function polar(r, t: real): Complex;
 begin
-  { Thanks, Wikipedia!  Math gives me a headache, but I somehow figured out how
-  to convert the equations to Pascal code on my first try }
-  c.re := r * cos(t);
-  c.im := r * sin(t);
-  polar := c;{}
+  polar := cpolar(r, t);
 end;
+{$ENDIF}
 
 procedure Bind(var f: text; b: BindingType);
 begin
   Assign(f, b.Name);
 end;
 
-procedure Bind(var f: TypedFile; b: BindingType);
+procedure Bind(var f: file; b: BindingType);
 begin
   Assign(f, b.Name);
 end;
@@ -278,7 +253,7 @@ begin
   end;
 end;
 
-procedure Unbind(var f: TypedFile);
+procedure Unbind(var f: file);
 begin
   if FileRec(f).Mode <> fmClosed then
   begin
@@ -335,7 +310,7 @@ begin
   end;
 end;
 
-function Binding(var f: TypedFile): BindingType;
+function Binding(var f: file): BindingType;
 var
   Mode: longint;
 begin
@@ -357,7 +332,7 @@ begin
           { If not, let's try writing to it }
           else
           begin
-            Rewrite(file(f)); { Must be cast in order to work }
+            Rewrite(f);
 
             try
               Unbind(f);
@@ -385,40 +360,39 @@ begin
   Append(f);
 end;
 
-procedure Update(var f: TypedFile);
+procedure Update(var f: file);
 begin
   SeekWrite(f, 0);
 end;
 
-procedure SeekRead(var f: TypedFile; pos: integer);
+procedure SeekRead(var f: file; pos: integer);
 begin
-  { f has to be cast to file or calling this function causes a crash }
-  Reset(file(f));
-  Seek(file(f), pos);
+  Reset(f);
+  Seek(f, pos);
 end;
 
-procedure SeekWrite(var f: TypedFile; pos: integer);
+procedure SeekWrite(var f: file; pos: integer);
 begin
-  Seek(f, pos);
+  SeekUpdate(f, pos);
   Truncate(f);
 end;
 
-procedure SeekUpdate(var f: TypedFile; pos: integer);
+procedure SeekUpdate(var f: file; pos: integer);
 begin
   Seek(f, pos);
 end;
 
-function Position(var f: TypedFile): integer;
+function Position(var f: file): integer;
 begin
   Position := FilePos(f);
 end;
 
-function LastPosition(var f: TypedFile): integer;
+function LastPosition(var f: file): integer;
 begin
   LastPosition := 0; { Proper implementation depends on features that haven't been implemented yet }
 end;
 
-function Empty(var f: TypedFile): Boolean;
+function Empty(var f: file): Boolean;
 begin
   Empty := FileSize(f) = 0;
 end;
@@ -504,7 +478,7 @@ function Substr(s: String; i, j: integer): String;
 begin
   { The type casting is not part of the standard, but it's necessary for this to be compilable.
     Hopefully, the future implementation of the ISO 10206 string type will alleviate this problem. }
-  Substr := String(AnsiString(s[i..i+j-1]));
+  Substr := String(AnsiString(s[i..(i)+(j)-1]));
 end;
 
 function Trim(s: String): String;
@@ -526,7 +500,7 @@ begin
     p := n;
     while s[p - 1] = ' ' do
     begin
-      p := Pred(p);
+      p := p - 1;
     end;
 
     Trim := Substr(s, 1, p - 1);
@@ -562,7 +536,7 @@ end;
 
 function NE(s1, s2: String): Boolean;
 begin
-  NE := not EQ(s1, s2);
+  NE := (not EQ(s1, s2));
 end;
 
 function LE(s1, s2: String): Boolean;
-- 
2.13.5

bind-and-co.patch (122,436 bytes)

Adriaan van Os

2017-11-07 11:56

developer   ~0103942

I suggest you have a look at the GNU Pascal test-suite

Thaddy de Koning

2017-11-13 17:46

reporter   ~0104078

Last edited: 2017-11-13 17:49

View 4 revisions

As a starter? Yes. But GNU pascal has not been maintained for many years..2005?
Also note ISO/IEC 10206 is at least last confirmed in 2008....

Some nix maintainers consider it code-rot.

Thaddy de Koning

2017-11-13 17:51

reporter   ~0104079

What I mean: what's the point? How laudable it is, just organize support to update the legacy to FPC standards...

Adriaan van Os

2017-11-13 18:38

developer   ~0104080

Some commenters are code-rot too. Here is somebody who likes to put effort into the FPC extended Pascal mode. Whether you like that or not, is not the question.

The GNU Pascal test-suite has many excellent tests that catch possible errors. To be compatible with FPC licensing however, you have grab a GPL2-licensed version of GPC.

Florian

2017-11-13 22:18

administrator   ~0104085

> How much of the EP features that require changes to the compiler should I make available to other modes? I know some EP features (like ReadStr/WriteStr) are already available to other modes, but I'm wondering what the best policy about this is.

If it is an important feature, make it a separate mode swithc, so people can enable it if they want it.

@Thaddy: The idea of FPC is to support all kind of flavours of pascal. If somebody works on EP support, great!

@Adriaan: When did GPC change its license or under which different license is it available?

Thaddy de Koning

2017-11-16 11:35

reporter   ~0104132

Adriaan, I *explicitly* wrote "How laudable it is" to cover your type of comment beforehand.

I agree with all that if one can put in the effort it has merit to some.

Florian

2017-11-17 18:45

administrator   ~0104163

Just a question: as the patches are git exports, is your git tree publicily available? Then I can get the patches directly from there.

Issue History

Date Modified Username Field Change
2017-10-14 11:33 Keith Bowes New Issue
2017-10-14 11:33 Keith Bowes File Added: 0001-Complex-numbers-date-time-and-string-routines.patch
2017-10-15 22:18 Florian Note Added: 0103453
2017-10-19 04:46 Keith Bowes Note Added: 0103582
2017-10-19 04:47 Keith Bowes File Added: bind-and-co.patch
2017-11-07 11:56 Adriaan van Os Note Added: 0103942
2017-11-13 17:46 Thaddy de Koning Note Added: 0104078
2017-11-13 17:48 Thaddy de Koning Note Edited: 0104078 View Revisions
2017-11-13 17:49 Thaddy de Koning Note Edited: 0104078 View Revisions
2017-11-13 17:49 Thaddy de Koning Note Edited: 0104078 View Revisions
2017-11-13 17:51 Thaddy de Koning Note Added: 0104079
2017-11-13 18:38 Adriaan van Os Note Added: 0104080
2017-11-13 22:18 Florian Note Added: 0104085
2017-11-16 11:35 Thaddy de Koning Note Added: 0104132
2017-11-17 18:45 Florian Note Added: 0104163