123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 |
- {
- This file is part of the Pas2JS run time library.
- Copyright (c) 2017 by Mattias Gaertner
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit System;
- {$mode objfpc}
- {$modeswitch externalclass}
- interface
- const
- LineEnding = #10;
- sLineBreak = LineEnding;
- MaxSmallint = 32767;
- MinSmallint = -32768;
- MaxShortInt = 127;
- MinShortInt = -128;
- MaxByte = $FF;
- MaxWord = $FFFF;
- MaxLongint = $7fffffff;
- MaxCardinal = LongWord($ffffffff);
- Maxint = MaxLongint;
- IsMultiThread = false;
- {*****************************************************************************
- Base types
- *****************************************************************************}
- type
- Integer = LongInt;
- Cardinal = LongWord;
- DWord = LongWord;
- SizeInt = NativeInt;
- SizeUInt = NativeUInt;
- PtrInt = NativeInt;
- PtrUInt = NativeUInt;
- ValSInt = NativeInt;
- ValUInt = NativeUInt;
- ValReal = Double;
- Real = Double;
- Extended = Double;
- Int64 = NativeInt unimplemented; // only 53 bits at runtime
- UInt64 = NativeUInt unimplemented; // only 52 bits at runtime
- QWord = NativeUInt unimplemented; // only 52 bits at runtime
- Single = Double unimplemented;
- Comp = NativeInt unimplemented;
- NativeLargeInt = NativeInt;
- NativeLargeUInt = NativeUInt;
- UnicodeString = String;
- WideString = String;
- WideChar = char;
- TDynArrayIndex = NativeInt;
- TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR);
- {*****************************************************************************
- TObject, TClass
- *****************************************************************************}
- type
- TClass = class of TObject;
- { TObject }
- TObject = class
- private
- class var FClassName: String; external name '$classname';
- class var FClassParent: TClass; external name '$ancestor';
- class var FUnitName: String; external name '$module.$name';
- public
- constructor Create;
- destructor Destroy; virtual;
- // Free is using compiler magic.
- // Reasons:
- // 1. In JS calling obj.Free when obj=nil crashes.
- // 2. In JS freeing memory requires to set all references to nil.
- // Therefore any obj.free call is replaced by the compiler with some rtl magic.
- procedure Free;
- class function ClassType: TClass; assembler;
- class property ClassName: String read FClassName;
- class function ClassNameIs(const Name: string): boolean;
- class property ClassParent: TClass read FClassParent;
- class function InheritsFrom(aClass: TClass): boolean; assembler;
- class property UnitName: String read FUnitName;
- procedure AfterConstruction; virtual;
- procedure BeforeDestruction; virtual;
- function Equals(Obj: TObject): boolean; virtual;
- function ToString: String; virtual;
- end;
- Const
- DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
- {*****************************************************************************
- Init / Exit / ExitProc
- *****************************************************************************}
- var
- ExitCode: Integer; external name 'rtl.exitcode';
- IsConsole: Boolean = {$IFDEF NodeJS}true{$ELSE}false{$ENDIF};
- type
- TOnParamCount = function: Longint;
- TOnParamStr = function(Index: Longint): String;
- var
- OnParamCount: TOnParamCount;
- OnParamStr: TOnParamStr;
- function ParamCount: Longint;
- function ParamStr(Index: Longint): String;
- {*****************************************************************************
- Math
- *****************************************************************************}
- var // ToDo: make these const
- PI: Double; external name 'Math.PI';
- MathE: Double; external name 'Math.E'; // Euler's number
- MathLN10: Double; external name 'Math.LN10'; // ln(10)
- MathLN2: Double; external name 'Math.LN2'; // ln(2)
- MathLog10E: Double; external name 'Math.Log10E'; // log10(e)
- MathLog2E: Double; external name 'Math.LOG2E'; // log2(e)
- MathSQRT1_2: Double; external name 'Math.SQRT1_2'; // sqrt(0.5)
- MathSQRT2: Double; external name 'Math.SQRT2'; // sqrt(2)
- function Abs(const A: integer): integer; overload; external name 'Math.abs';
- function Abs(const A: NativeInt): integer; overload; external name 'Math.abs';
- function Abs(const A: Double): Double; overload; external name 'Math.abs';
- function ArcTan(const A, B: Double): Double; external name 'Math.atan';
- function Cos(const A: Double): Double; external name 'Math.cos';
- function Exp(const A: Double): Double; external name 'Math.exp';
- function Frac(const A: Double): Double; assembler;
- function Ln(const A: Double): Double; external name 'Math.log';
- function Odd(const A: Integer): Boolean; assembler;
- function Random(const Range: Integer): Integer; overload; assembler;
- function Random: Double; overload; external name 'Math.random';
- function Round(const A: Double): NativeInt; external name 'Math.round';
- function Sin(const A: Double): Double; external name 'Math.sin';
- function Sqr(const A: Integer): Integer; assembler; overload;
- function Sqr(const A: Double): Double; assembler; overload;
- function sqrt(const A: Double): Double; external name 'Math.sqrt';
- function Trunc(const A: Double): NativeInt; external name 'Math.trunc'; // not on IE
- {*****************************************************************************
- String functions
- *****************************************************************************}
- function Int(const A: Double): double;
- function Copy(const S: string; Index, Size: Integer): String; assembler; overload;
- function Copy(const S: string; Index: Integer): String; assembler; overload;
- procedure Delete(var S: String; Index, Size: Integer); assembler; overload;
- function Pos(const Search, InString: String): Integer; assembler; overload;
- procedure Insert(const Insertion: String; var Target: String; Index: Integer); overload;
- function upcase(c : char) : char; assembler;
- procedure val(const S: String; out NI : NativeInt; out Code: Integer); overload;
- procedure val(const S: String; out SI : ShortInt; out Code: Integer); overload;
- procedure val(const S: String; out B : Byte; out Code: Integer); overload;
- procedure val(const S: String; out SI : smallint; out Code: Integer); overload;
- procedure val(const S: String; out W : word; out Code : Integer); overload;
- procedure val(const S: String; out I : integer; out Code : Integer); overload;
- procedure val(const S: String; out C : Cardinal; out Code: Integer); overload;
- procedure val(const S: String; out d : double; out Code : Integer); overload;
- function StringOfChar(c: Char; l: NativeInt): String;
- {*****************************************************************************
- Other functions
- *****************************************************************************}
- procedure Write; varargs; // ToDo: should be compiler built-in function
- procedure Writeln; varargs; // ToDo: should be compiler built-in function
- Type
- TConsoleHandler = Procedure (S : JSValue; NewLine : Boolean);
- Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
- function Assigned(const V: JSValue): boolean; assembler; overload;
- function StrictEqual(const A: JSValue; const B): boolean; assembler;
- function StrictInequal(const A: JSValue; const B): boolean; assembler;
- implementation
- // function parseInt(s: String; Radix: NativeInt): NativeInt; external name 'parseInt'; // may result NaN
- function isNaN(i: JSValue): boolean; external name 'isNaN'; // may result NaN
- // needed by ClassNameIs, the real SameText is in SysUtils
- function SameText(const s1, s2: String): Boolean; assembler;
- asm
- return s1.toLowerCase() == s2.toLowerCase();
- end;
- function ParamCount: Longint;
- begin
- if Assigned(OnParamCount) then
- Result:=OnParamCount()
- else
- Result:=0;
- end;
- function ParamStr(Index: Longint): String;
- begin
- if Assigned(OnParamStr) then
- Result:=OnParamStr(Index)
- else if Index=0 then
- Result:='js'
- else
- Result:='';
- end;
- function Frac(const A: Double): Double; assembler;
- asm
- return A % 1;
- end;
- function Odd(const A: Integer): Boolean; assembler;
- asm
- return A&1 != 0;
- end;
- function Random(const Range: Integer): Integer; assembler;
- asm
- return Math.floor(Math.random()*Range);
- end;
- function Sqr(const A: Integer): Integer; assembler;
- asm
- return A*A;
- end;
- function Sqr(const A: Double): Double; assembler;
- asm
- return A*A;
- end;
- function Copy(const S: string; Index, Size: Integer): String; assembler;
- asm
- if (Index<1) Index = 1;
- return (Size>0) ? S.substring(Index-1,Index+Size-1) : "";
- end;
- function Copy(const S: string; Index: Integer): String; assembler;
- asm
- if (Index<1) Index = 1;
- return S.substr(Index-1);
- end;
- procedure Delete(var S: String; Index, Size: Integer);
- var
- h: String;
- begin
- if (Index<1) or (Index>length(S)) or (Size<=0) then exit;
- h:=S;
- S:=copy(h,1,Index-1)+copy(h,Index+Size);
- end;
- function Pos(const Search, InString: String): Integer; assembler;
- asm
- return InString.indexOf(Search)+1;
- end;
- procedure Insert(const Insertion: String; var Target: String; Index: Integer);
- var
- t: String;
- begin
- if Insertion='' then exit;
- t:=Target;
- if Index<1 then
- Target:=Insertion+t
- else if Index>length(t) then
- Target:=t+Insertion
- else
- Target:=copy(t,1,Index-1)+Insertion+copy(t,Index,length(t));
- end;
- var
- WriteBuf: String;
- JSArguments: array of JSValue; external name 'arguments';
- WriteCallBack : TConsoleHandler;
- Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
- begin
- Result:=WriteCallBack;
- WriteCallBack:=H;
- end;
- procedure Write;
- var
- i: Integer;
- begin
- for i:=0 to length(JSArguments)-1 do
- if Assigned(WriteCallBack) then
- WriteCallBack(JSArguments[i],False)
- else
- WriteBuf:=WriteBuf+String(JSArguments[i]);
- end;
- procedure Writeln;
- var
- i,l: Integer;
- s: String;
- begin
- L:=length(JSArguments)-1;
- if Assigned(WriteCallBack) then
- begin
- for i:=0 to L do
- WriteCallBack(JSArguments[i],I=L);
- end
- else
- begin
- s:=WriteBuf;
- for i:=0 to L do
- s:=s+String(JSArguments[i]);
- asm
- console.log(s);
- end;
- WriteBuf:='';
- end;
- end;
- function Int(const A: Double): double;
- function FTrunc(const A: Double): double; overload; external name 'Math.trunc';
- begin
- Result:=FTrunc(A);
- end;
- function Number(S: String): Double; external name 'Number';
- procedure val(const S: String; out NI : NativeInt; out Code: Integer);
- var
- x : double;
- begin
- Code:=0;
- x:=Number(S);
- if isNaN(x) or (X<>Int(X)) then
- Code:=1
- else
- NI:=Trunc(x);
- end;
- procedure val(const S: String; out SI : ShortInt; out Code: Integer);
- var
- X:Double;
- begin
- Code:=0;
- x:=Number(S);
- if isNaN(x) or (X<>Int(X)) then
- Code:=1
- else if (x<MinShortInt) or (x>MaxShortInt) then
- Code:=2
- else
- SI:=Trunc(x);
- end;
- procedure val(const S: String; out SI: smallint; out Code: Integer);
- var
- x: double;
- begin
- Code:=0;
- x:=Number(S);
- if isNaN(x) or (X<>Int(X)) then
- Code:=1
- else if (x<MinSmallint) or (x>MaxSmallint) then
- Code:=2
- else
- SI:=Trunc(x);
- end;
- procedure val(const S: String; out C: Cardinal; out Code: Integer);
- var
- x: double;
- begin
- Code:=0;
- x:=Number(S);
- if isNaN(x) or (X<>Int(X)) then
- Code:=1
- else if (x<0) or (x>MaxCardinal) then
- Code:=2
- else
- C:=trunc(x);
- end;
- procedure val(const S: String; out B: Byte; out Code: Integer);
- var
- x: double;
- begin
- Code:=0;
- x:=Number(S);
- if isNaN(x) or (X<>Int(X)) then
- Code:=1
- else if (x<0) or (x>MaxByte) then
- Code:=2
- else
- B:=Trunc(x);
- end;
- procedure val(const S: String; out W: word; out Code: Integer);
- var
- x: double;
- begin
- Code:=0;
- x:=Number(S);
- if isNaN(x) then
- Code:=1
- else if (x<0) or (x>MaxWord) then
- Code:=2
- else
- W:=Trunc(x);
- end;
- procedure val(const S : String; out I : integer; out Code : Integer);
- var
- x: double;
- begin
- Code:=0;
- x:=Number(S);
- if isNaN(x) then
- Code:=1
- else if x>MaxInt then
- Code:=2
- else
- I:=Trunc(x);
- end;
- procedure val(const S : String; out d : double; out Code : Integer);
- Var
- x: double;
- begin
- x:=Number(S);
- if isNaN(x) then
- Code:=1
- else
- begin
- Code:=0;
- d:=x;
- end;
- end;
- function upcase(c : char) : char; assembler;
- asm
- return c.toUpperCase();
- end;
- function StringOfChar(c: Char; l: NativeInt): String;
- var
- i: Integer;
- begin
- Result:='';
- for i:=1 to l do Result:=Result+c;
- end;
- function Assigned(const V: JSValue): boolean; assembler;
- asm
- return (V!=undefined) && (V!=null) && (!rtl.isArray(V) || (V.length > 0));
- end;
- function StrictEqual(const A: JSValue; const B): boolean; assembler;
- asm
- return A === B;
- end;
- function StrictInequal(const A: JSValue; const B): boolean; assembler;
- asm
- return A !== B;
- end;
- { TObject }
- constructor TObject.Create;
- begin
- end;
- destructor TObject.Destroy;
- begin
- end;
- procedure TObject.Free;
- begin
- Destroy;
- end;
- class function TObject.ClassType: TClass; assembler;
- asm
- return this;
- end;
- class function TObject.ClassNameIs(const Name: string): boolean;
- begin
- Result:=SameText(Name,ClassName);
- end;
- class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;
- asm
- return (aClass!=null) && ((this==aClass) || aClass.isPrototypeOf(this));
- end;
- procedure TObject.AfterConstruction;
- begin
- end;
- procedure TObject.BeforeDestruction;
- begin
- end;
- function TObject.Equals(Obj: TObject): boolean;
- begin
- Result:=Obj=Self;
- end;
- function TObject.ToString: String;
- begin
- Result:=ClassName;
- end;
- initialization
- ExitCode:=0; // set it here, so that WPO does not remove it
- end.
|