Browse Source

pastojs: read/write modeswitches

git-svn-id: trunk@38093 -
Mattias Gaertner 7 years ago
parent
commit
8d64a23bd2

+ 6 - 0
packages/pastojs/src/fppas2js.pp

@@ -880,6 +880,12 @@ const
     bsObjectChecks
     bsObjectChecks
     ];
     ];
 
 
+  // default parser+scanner options
+  po_pas2js = [
+    po_AsmWhole,
+    po_ResolveStandardTypes,
+    po_ExtClassConstWithoutExpr];
+
   btAllJSBaseTypes = [
   btAllJSBaseTypes = [
     btChar,
     btChar,
     btWideChar,
     btWideChar,

+ 644 - 61
packages/pastojs/src/pas2jsfiler.pp

@@ -14,7 +14,7 @@
  **********************************************************************
  **********************************************************************
 
 
 Abstract:
 Abstract:
-  Write and read a precompiled module.
+  Write and read a precompiled module (pju).
 
 
   Store whole unit, except all
   Store whole unit, except all
     procedure declarations, proc bodies, finalization/initialization sections are
     procedure declarations, proc bodies, finalization/initialization sections are
@@ -34,12 +34,61 @@ unit Pas2JsFiler;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, contnrs, FPPas2Js, Pas2jsFileUtils, PasTree,
-  PScanner, PParser, PasResolveEval, PasResolver;
+  Classes, SysUtils, contnrs, crc,
+  PasTree, PScanner, PParser, PasResolveEval, PasResolver,
+  Pas2jsFileUtils, FPPas2Js;
 
 
 const
 const
   PJUMagic = 'Pas2JSCache';
   PJUMagic = 'Pas2JSCache';
   PJUVersion = 1;
   PJUVersion = 1;
+  PJUDefaultParserOptions: TPOptions = [
+    po_KeepScannerError,
+    po_ResolveStandardTypes,
+    po_AsmWhole,
+    po_NoOverloadedProcs,
+    po_KeepClassForward,
+    po_ArrayRangeExpr,
+    po_CheckModeSwitches,
+    po_CheckCondFunction,
+    po_ExtClassConstWithoutExpr];
+  PJUDefaultModeSwitches: TModeSwitches = [
+    msObjfpc,
+    msClass,
+    msResult,
+    msNestedComment,
+    msRepeatForward,
+    msInitFinal,
+    msOut,
+    msDefaultPara,
+    msHintDirective,
+    msProperty,
+    msExcept,
+    msDefaultUnicodestring,
+    msCBlocks];
+  PJUDefaultBoolSwitches: TBoolSwitches = [
+    bsHints,
+    bsNotes,
+    bsWarnings
+    ];
+  PJUDefaultConvertOptions: TPasToJsConverterOptions = [];
+  PJUDefaultTargetPlatform = PlatformBrowser;
+  PJUDefaultTargetProcessor = ProcessorECMAScript5;
+
+type
+  { TPJUInitialFlags }
+
+  TPJUInitialFlags = class
+  public
+    ParserOptions: TPOptions;
+    ModeSwitches: TModeSwitches;
+    BoolSwitches: TBoolSwitches;
+    ConverterOptions: TPasToJsConverterOptions;
+    TargetPlatform: TPasToJsPlatform;
+    TargetProcessor: TPasToJsProcessor;
+    // ToDo: defines
+    constructor Create;
+    procedure Clear;
+  end;
 
 
 type
 type
   TPJUSourceFileKind = (
   TPJUSourceFileKind = (
@@ -47,7 +96,7 @@ type
     sfkInclude // 1
     sfkInclude // 1
   );
   );
   TPJUSourceFileKinds = set of TPJUSourceFileKind;
   TPJUSourceFileKinds = set of TPJUSourceFileKind;
-  TPJUSourceFileChecksum = longint;
+  TPJUSourceFileChecksum = cardinal;
 
 
   { TPJUSourceFile }
   { TPJUSourceFile }
 
 
@@ -59,23 +108,15 @@ type
     Index: integer;
     Index: integer;
   end;
   end;
 
 
-  TPJUInitialFlags = class
-  public
-    ParserOptions: TPOptions;
-    ModeSwitches: TModeSwitches;
-    BoolSwitches: TBoolSwitches;
-    ResolverOptions: TPasResolverOptions;
-    PasTojsOptions: TPasToJsConverterOptions;
-    TargetPlatform: TPasToJsPlatform;
-    TargetProcessor: TPasToJsProcessor;
-    // ToDo: defines
-  end;
+  TPJUGetSrcEvent = procedure(Sender: TObject; aFilename: string;
+    out p: PChar; out Count: integer) of object;
 
 
-  { TPasToJsWriter }
+  { TPJUWriter }
 
 
-  TPasToJsWriter = class
+  TPJUWriter = class
   private
   private
     FInitialFlags: TPJUInitialFlags;
     FInitialFlags: TPJUInitialFlags;
+    FOnGetSrc: TPJUGetSrcEvent;
     FParser: TPasParser;
     FParser: TPasParser;
     FResolver: TPasResolver;
     FResolver: TPasResolver;
     FScanner: TPascalScanner;
     FScanner: TPascalScanner;
@@ -83,12 +124,17 @@ type
     FSourceFilesSorted: array of TPJUSourceFile;
     FSourceFilesSorted: array of TPJUSourceFile;
     FStream: TStream;
     FStream: TStream;
   protected
   protected
+    function GetSrcCheckSum(aFilename: string): TPJUSourceFileChecksum;
     procedure WriteStr(const s: string);
     procedure WriteStr(const s: string);
     procedure WriteInt(const i: MaxPrecInt);
     procedure WriteInt(const i: MaxPrecInt);
     procedure WriteText(const s: string);
     procedure WriteText(const s: string);
     procedure WriteHeaderMagic; virtual;
     procedure WriteHeaderMagic; virtual;
     procedure WriteHeaderVersion; virtual;
     procedure WriteHeaderVersion; virtual;
     procedure WriteInitialFlags; virtual;
     procedure WriteInitialFlags; virtual;
+    procedure WriteParserOptions(const Value, DefaultValue: TPOptions); virtual;
+    procedure WriteModeSwitches(const Value, DefaultValue: TModeSwitches); virtual;
+    procedure WriteBoolSwitches(const Value, DefaultValue: TBoolSwitches); virtual;
+    procedure WriteConvertOptions(const Value, DefaultValue: TPasToJsConverterOptions); virtual;
     procedure WriteSrcFiles; virtual;
     procedure WriteSrcFiles; virtual;
   public
   public
     constructor Create; virtual;
     constructor Create; virtual;
@@ -101,6 +147,7 @@ type
     property Parser: TPasParser read FParser;
     property Parser: TPasParser read FParser;
     property Scanner: TPascalScanner read FScanner;
     property Scanner: TPascalScanner read FScanner;
     property InitialFlags: TPJUInitialFlags read FInitialFlags;
     property InitialFlags: TPJUInitialFlags read FInitialFlags;
+    property OnGetSrc: TPJUGetSrcEvent read FOnGetSrc write FOnGetSrc;
   end;
   end;
 
 
   EPas2JsReadError = class(Exception)
   EPas2JsReadError = class(Exception)
@@ -108,9 +155,9 @@ type
     Owner: TObject;
     Owner: TObject;
   end;
   end;
 
 
-  { TPasToJsReader }
+  { TPJUReader }
 
 
-  TPasToJsReader = class
+  TPJUReader = class
   private
   private
     FCur: PByte;
     FCur: PByte;
     FEnd: PByte;
     FEnd: PByte;
@@ -132,6 +179,10 @@ type
     procedure ReadHeaderMagic; virtual;
     procedure ReadHeaderMagic; virtual;
     procedure ReadHeaderVersion; virtual;
     procedure ReadHeaderVersion; virtual;
     procedure ReadInitialFlags; virtual;
     procedure ReadInitialFlags; virtual;
+    function ReadParserOptions(const DefaultValue: TPOptions): TPOptions; virtual;
+    function ReadModeSwitches(const DefaultValue: TModeSwitches): TModeSwitches; virtual;
+    function ReadBoolSwitches(const DefaultValue: TBoolSwitches): TBoolSwitches; virtual;
+    function ReadConverterOptions(const DefaultValue: TPasToJsConverterOptions): TPasToJsConverterOptions; virtual;
     procedure ReadSrcFiles; virtual;
     procedure ReadSrcFiles; virtual;
   public
   public
     constructor Create; virtual;
     constructor Create; virtual;
@@ -152,6 +203,8 @@ function EncodeVLQ(i: MaxPrecUInt): string; overload;
 function DecodeVLQ(const s: string): MaxPrecInt; // base256 Variable Length Quantity
 function DecodeVLQ(const s: string): MaxPrecInt; // base256 Variable Length Quantity
 function DecodeVLQ(var p: PByte): MaxPrecInt; // base256 Variable Length Quantity
 function DecodeVLQ(var p: PByte): MaxPrecInt; // base256 Variable Length Quantity
 
 
+function ComputeChecksum(p: PChar; Cnt: integer): TPJUSourceFileChecksum;
+
 function ModeSwitchToInt(ms: TModeSwitch): byte;
 function ModeSwitchToInt(ms: TModeSwitch): byte;
 
 
 function dbgmem(const s: string): string; overload;
 function dbgmem(const s: string): string; overload;
@@ -274,6 +327,45 @@ begin
     Result:=-Result;
     Result:=-Result;
 end;
 end;
 
 
+function ComputeChecksum(p: PChar; Cnt: integer): TPJUSourceFileChecksum;
+var
+  SrcP, SrcEndP, SrcLineEndP, SrcLineStartP: PChar;
+  l: PtrInt;
+  CheckSum, CurLen: Cardinal;
+begin
+  if Cnt=0 then exit(0);
+
+  // ignore trailing spaces and unify line endings
+  SrcP:=p;
+  SrcEndP:=p+Cnt;
+  while (SrcEndP>SrcP) and (SrcEndP[-1] in [#9,#10,#13,' ']) do
+    dec(SrcEndP);
+  CheckSum:=crc32(0,nil,0);
+  while SrcP<SrcEndP do
+    begin
+    SrcLineStartP:=SrcP;
+    while (SrcP<SrcEndP) and not (SrcP^ in [#10,#13]) do
+      inc(SrcP);
+    SrcLineEndP:=SrcP;
+    while (SrcLineEndP>SrcLineStartP) and (SrcLineEndP[-1] in [#9,' ']) do
+      dec(SrcLineEndP);
+    l:=SrcLineEndP-SrcLineStartP;
+    while l>0 do
+      begin
+      if l<$8000 then
+        CurLen:=l
+      else
+        CurLen:=$8000;
+      CheckSum:=crc32(CheckSum, PByte(SrcLineStartP), CurLen);
+      inc(SrcLineStartP,CurLen);
+      dec(l,CurLen);
+      end;
+    while (SrcP<SrcEndP) and (SrcP^ in [#10,#13]) do
+      inc(SrcP);
+    end;
+  Result:=CheckSum;
+end;
+
 function ModeSwitchToInt(ms: TModeSwitch): byte;
 function ModeSwitchToInt(ms: TModeSwitch): byte;
 begin
 begin
   case ms of
   case ms of
@@ -384,19 +476,36 @@ begin
     AddLine(Line);
     AddLine(Line);
 end;
 end;
 
 
-{ TPasToJsReader }
+{ TPJUInitialFlags }
 
 
-procedure TPasToJsReader.RaiseMsg(Id: int64; const Msg: string);
+constructor TPJUInitialFlags.Create;
+begin
+  Clear;
+end;
+
+procedure TPJUInitialFlags.Clear;
+begin
+  ParserOptions:=PJUDefaultParserOptions;
+  ModeSwitches:=PJUDefaultModeSwitches;
+  BoolSwitches:=PJUDefaultBoolSwitches;
+  ConverterOptions:=PJUDefaultConvertOptions;
+  TargetPlatform:=PJUDefaultTargetPlatform;
+  TargetProcessor:=PJUDefaultTargetProcessor;
+end;
+
+{ TPJUReader }
+
+procedure TPJUReader.RaiseMsg(Id: int64; const Msg: string);
 begin
 begin
   raise EPas2JsReadError.Create('['+IntToStr(Id)+'] '+Msg);
   raise EPas2JsReadError.Create('['+IntToStr(Id)+'] '+Msg);
 end;
 end;
 
 
-procedure TPasToJsReader.RaiseEOF(Id: int64);
+procedure TPJUReader.RaiseEOF(Id: int64);
 begin
 begin
   RaiseMsg(Id,'unexpected EOF');
   RaiseMsg(Id,'unexpected EOF');
 end;
 end;
 
 
-function TPasToJsReader.ReadStr(Cnt: integer): string;
+function TPJUReader.ReadStr(Cnt: integer): string;
 begin
 begin
   if Cnt=0 then exit('');
   if Cnt=0 then exit('');
   if Cnt>0 then
   if Cnt>0 then
@@ -411,7 +520,7 @@ begin
     RaiseMsg(20180130193811);
     RaiseMsg(20180130193811);
 end;
 end;
 
 
-function TPasToJsReader.CheckStr(const s: string): boolean;
+function TPJUReader.CheckStr(const s: string): boolean;
 var
 var
   l: Integer;
   l: Integer;
 begin
 begin
@@ -424,7 +533,7 @@ begin
   Result:=true;
   Result:=true;
 end;
 end;
 
 
-function TPasToJsReader.ReadInt: MaxPrecInt;
+function TPJUReader.ReadInt: MaxPrecInt;
 begin
 begin
   if FCur=FEnd then
   if FCur=FEnd then
     RaiseMsg(20180130201047);
     RaiseMsg(20180130201047);
@@ -436,7 +545,7 @@ begin
     end;
     end;
 end;
 end;
 
 
-function TPasToJsReader.ReadInt(LowBound, UpBound: MaxPrecInt): MaxPrecInt;
+function TPJUReader.ReadInt(LowBound, UpBound: MaxPrecInt): MaxPrecInt;
 begin
 begin
   Result:=ReadInt();
   Result:=ReadInt();
   if Result<LowBound then
   if Result<LowBound then
@@ -445,7 +554,7 @@ begin
     RaiseMsg(20180130203413);
     RaiseMsg(20180130203413);
 end;
 end;
 
 
-function TPasToJsReader.ReadText: string;
+function TPJUReader.ReadText: string;
 var
 var
   l: MaxPrecInt;
   l: MaxPrecInt;
 begin
 begin
@@ -461,13 +570,13 @@ begin
   inc(FCur,l);
   inc(FCur,l);
 end;
 end;
 
 
-procedure TPasToJsReader.ReadHeaderMagic;
+procedure TPJUReader.ReadHeaderMagic;
 begin
 begin
   if not CheckStr(PJUMagic) then
   if not CheckStr(PJUMagic) then
     RaiseMsg(20180130201710,'not a pju file');
     RaiseMsg(20180130201710,'not a pju file');
 end;
 end;
 
 
-procedure TPasToJsReader.ReadHeaderVersion;
+procedure TPJUReader.ReadHeaderVersion;
 begin
 begin
   FFileVersion:=ReadInt;
   FFileVersion:=ReadInt;
   if FFileVersion<1 then
   if FFileVersion<1 then
@@ -476,16 +585,281 @@ begin
     RaiseMsg(20180130201822,'pju file was created by a newer compiler.');
     RaiseMsg(20180130201822,'pju file was created by a newer compiler.');
 end;
 end;
 
 
-procedure TPasToJsReader.ReadInitialFlags;
+procedure TPJUReader.ReadInitialFlags;
 begin
 begin
-  // Write modeswitches
-  //for ms in InitialFlags.Modeswitches do
-  //  WriteInt(ModeSwitchToInt(ms));
-  //WriteInt(-1);
+  InitialFlags.ParserOptions:=ReadParserOptions(PJUDefaultParserOptions);
+  InitialFlags.ModeSwitches:=ReadModeSwitches(PJUDefaultModeSwitches);
+  InitialFlags.BoolSwitches:=ReadBoolSwitches(PJUDefaultBoolSwitches);
+  InitialFlags.ConverterOptions:=ReadConverterOptions(PJUDefaultConvertOptions);
+  case ReadInt of
+    1: InitialFlags.TargetPlatform:=PlatformBrowser;
+    2: InitialFlags.TargetPlatform:=PlatformNodeJS;
+  else
+    RaiseMsg(20180131170539,'invalid target platform');
+  end;
+  case ReadInt of
+    1: InitialFlags.TargetProcessor:=ProcessorECMAScript5;
+    2: InitialFlags.TargetProcessor:=ProcessorECMAScript6;
+  else
+    RaiseMsg(20180131170622,'invalid target processor');
+  end;
   // ToDo: write initial flags: BoolSwitches, used defines, used macros
   // ToDo: write initial flags: BoolSwitches, used defines, used macros
 end;
 end;
 
 
-procedure TPasToJsReader.ReadSrcFiles;
+function TPJUReader.ReadParserOptions(const DefaultValue: TPOptions): TPOptions;
+var
+  i: integer;
+begin
+  Result:=DefaultValue;
+  repeat
+    i:=ReadInt(-100,100);
+    case i of
+    0: exit;
+    +1: Include(Result,po_KeepScannerError);
+    -1: Exclude(Result,po_KeepScannerError);
+    +2: Include(Result,po_CAssignments);
+    -2: Exclude(Result,po_CAssignments);
+    +3: Include(Result,po_ResolveStandardTypes);
+    -3: Exclude(Result,po_ResolveStandardTypes);
+    +4: Include(Result,po_AsmWhole);
+    -4: Exclude(Result,po_AsmWhole);
+    +5: Include(Result,po_NoOverloadedProcs);
+    -5: Exclude(Result,po_NoOverloadedProcs);
+    +6: Include(Result,po_KeepClassForward);
+    -6: Exclude(Result,po_KeepClassForward);
+    +7: Include(Result,po_ArrayRangeExpr);
+    -7: Exclude(Result,po_ArrayRangeExpr);
+    +8: Include(Result,po_SelfToken);
+    -8: Exclude(Result,po_SelfToken);
+    +9: Include(Result,po_CheckModeSwitches);
+    -9: Exclude(Result,po_CheckModeSwitches);
+    +10: Include(Result,po_CheckCondFunction);
+    -10: Exclude(Result,po_CheckCondFunction);
+    +11: Include(Result,po_StopOnErrorDirective);
+    -11: Exclude(Result,po_StopOnErrorDirective);
+    +12: Include(Result,po_ExtClassConstWithoutExpr);
+    -12: Exclude(Result,po_ExtClassConstWithoutExpr);
+    else
+      RaiseMsg(20180131163751,'po='+IntToStr(i));
+    end;
+  until false;
+end;
+
+function TPJUReader.ReadModeSwitches(const DefaultValue: TModeSwitches
+  ): TModeSwitches;
+var
+  i: integer;
+begin
+  Result:=DefaultValue;
+  repeat
+    i:=ReadInt(-100,100);
+    case i of
+    0: exit;
+    -1: Exclude(Result,msNone);
+    +1: Include(Result,msNone);
+    // mode
+    -2: Exclude(Result,msFpc);
+    +2: Include(Result,msFpc);
+    -3: Exclude(Result,msObjfpc);
+    +3: Include(Result,msObjfpc);
+    -4: Exclude(Result,msDelphi);
+    +4: Include(Result,msDelphi);
+    -5: Exclude(Result,msDelphiUnicode);
+    +5: Include(Result,msDelphiUnicode);
+    -6: Exclude(Result,msTP7);
+    +6: Include(Result,msTP7);
+    -7: Exclude(Result,msMac);
+    +7: Include(Result,msMac);
+    -8: Exclude(Result,msIso);
+    +8: Include(Result,msIso);
+    -9: Exclude(Result,msExtpas);
+    +9: Include(Result,msExtpas);
+    -10: Exclude(Result,msGPC);
+    +10: Include(Result,msGPC);
+    // switches
+    -31: Exclude(Result,msClass);
+    +31: Include(Result,msClass);
+    -32: Exclude(Result,msObjpas);
+    +32: Include(Result,msObjpas);
+    -33: Exclude(Result,msResult);
+    +33: Include(Result,msResult);
+    -34: Exclude(Result,msStringPchar);
+    +34: Include(Result,msStringPchar);
+    -35: Exclude(Result,msCVarSupport);
+    +35: Include(Result,msCVarSupport);
+    -36: Exclude(Result,msNestedComment);
+    +36: Include(Result,msNestedComment);
+    -37: Exclude(Result,msTPProcVar);
+    +37: Include(Result,msTPProcVar);
+    -38: Exclude(Result,msMacProcVar);
+    +38: Include(Result,msMacProcVar);
+    -39: Exclude(Result,msRepeatForward);
+    +39: Include(Result,msRepeatForward);
+    -40: Exclude(Result,msPointer2Procedure);
+    +40: Include(Result,msPointer2Procedure);
+    -41: Exclude(Result,msAutoDeref);
+    +41: Include(Result,msAutoDeref);
+    -42: Exclude(Result,msInitFinal);
+    +42: Include(Result,msInitFinal);
+    -43: Exclude(Result,msDefaultAnsistring);
+    +43: Include(Result,msDefaultAnsistring);
+    -44: Exclude(Result,msOut);
+    +44: Include(Result,msOut);
+    -45: Exclude(Result,msDefaultPara);
+    +45: Include(Result,msDefaultPara);
+    -46: Exclude(Result,msHintDirective);
+    +46: Include(Result,msHintDirective);
+    -47: Exclude(Result,msDuplicateNames);
+    +47: Include(Result,msDuplicateNames);
+    -48: Exclude(Result,msProperty);
+    +48: Include(Result,msProperty);
+    -49: Exclude(Result,msDefaultInline);
+    +49: Include(Result,msDefaultInline);
+    -50: Exclude(Result,msExcept);
+    +50: Include(Result,msExcept);
+    -51: Exclude(Result,msObjectiveC1);
+    +51: Include(Result,msObjectiveC1);
+    -52: Exclude(Result,msObjectiveC2);
+    +52: Include(Result,msObjectiveC2);
+    -53: Exclude(Result,msNestedProcVars);
+    +53: Include(Result,msNestedProcVars);
+    -54: Exclude(Result,msNonLocalGoto);
+    +54: Include(Result,msNonLocalGoto);
+    -55: Exclude(Result,msAdvancedRecords);
+    +55: Include(Result,msAdvancedRecords);
+    -56: Exclude(Result,msISOLikeUnaryMinus);
+    +56: Include(Result,msISOLikeUnaryMinus);
+    -57: Exclude(Result,msSystemCodePage);
+    +57: Include(Result,msSystemCodePage);
+    -58: Exclude(Result,msFinalFields);
+    +58: Include(Result,msFinalFields);
+    -59: Exclude(Result,msDefaultUnicodestring);
+    +59: Include(Result,msDefaultUnicodestring);
+    -60: Exclude(Result,msTypeHelpers);
+    +60: Include(Result,msTypeHelpers);
+    -61: Exclude(Result,msCBlocks);
+    +61: Include(Result,msCBlocks);
+    -62: Exclude(Result,msISOLikeIO);
+    +62: Include(Result,msISOLikeIO);
+    -63: Exclude(Result,msISOLikeProgramsPara);
+    +63: Include(Result,msISOLikeProgramsPara);
+    -64: Exclude(Result,msISOLikeMod);
+    +64: Include(Result,msISOLikeMod);
+    -65: Exclude(Result,msExternalClass);
+    +65: Include(Result,msExternalClass);
+    -66: Exclude(Result,msPrefixedAttributes);
+    +66: Include(Result,msPrefixedAttributes);
+    -67: Exclude(Result,msIgnoreInterfaces);
+    +67: Include(Result,msIgnoreInterfaces);
+    -68: Exclude(Result,msIgnoreAttributes);
+    +68: Include(Result,msIgnoreAttributes);
+    else
+      RaiseMsg(20180131152915,'ms='+IntToStr(i));
+    end;
+  until false;
+end;
+
+function TPJUReader.ReadBoolSwitches(const DefaultValue: TBoolSwitches
+  ): TBoolSwitches;
+var
+  i: integer;
+begin
+  Result:=DefaultValue;
+  repeat
+    i:=ReadInt(-100,100);
+    case i of
+    0: exit;
+    +1: Include(Result,bsNone);
+    -1: Exclude(Result,bsNone);
+    +2: Include(Result,bsAlign);
+    -2: Exclude(Result,bsAlign);
+    +3: Include(Result,bsBoolEval);
+    -3: Exclude(Result,bsBoolEval);
+    +4: Include(Result,bsAssertions);
+    -4: Exclude(Result,bsAssertions);
+    +5: Include(Result,bsDebugInfo);
+    -5: Exclude(Result,bsDebugInfo);
+    +6: Include(Result,bsExtension);
+    -6: Exclude(Result,bsExtension);
+    +7: Include(Result,bsImportedData);
+    -7: Exclude(Result,bsImportedData);
+    +8: Include(Result,bsLongStrings);
+    -8: Exclude(Result,bsLongStrings);
+    +9: Include(Result,bsIOChecks);
+    -9: Exclude(Result,bsIOChecks);
+    +10: Include(Result,bsWriteableConst);
+    -10: Exclude(Result,bsWriteableConst);
+    +11: Include(Result,bsLocalSymbols);
+    -11: Exclude(Result,bsLocalSymbols);
+    +12: Include(Result,bsTypeInfo);
+    -12: Exclude(Result,bsTypeInfo);
+    +13: Include(Result,bsOptimization);
+    -13: Exclude(Result,bsOptimization);
+    +14: Include(Result,bsOpenStrings);
+    -14: Exclude(Result,bsOpenStrings);
+    +15: Include(Result,bsOverflowChecks);
+    -15: Exclude(Result,bsOverflowChecks);
+    +16: Include(Result,bsRangeChecks);
+    -16: Exclude(Result,bsRangeChecks);
+    +17: Include(Result,bsTypedAddress);
+    -17: Exclude(Result,bsTypedAddress);
+    +18: Include(Result,bsSafeDivide);
+    -18: Exclude(Result,bsSafeDivide);
+    +19: Include(Result,bsVarStringChecks);
+    -19: Exclude(Result,bsVarStringChecks);
+    +20: Include(Result,bsStackframes);
+    -20: Exclude(Result,bsStackframes);
+    +21: Include(Result,bsExtendedSyntax);
+    -21: Exclude(Result,bsExtendedSyntax);
+    +22: Include(Result,bsReferenceInfo);
+    -22: Exclude(Result,bsReferenceInfo);
+    +23: Include(Result,bsHints);
+    -23: Exclude(Result,bsHints);
+    +24: Include(Result,bsNotes);
+    -24: Exclude(Result,bsNotes);
+    +25: Include(Result,bsWarnings);
+    -25: Exclude(Result,bsWarnings);
+    +26: Include(Result,bsMacro);
+    -26: Exclude(Result,bsMacro);
+    +27: Include(Result,bsScopedEnums);
+    -27: Exclude(Result,bsScopedEnums);
+    +28: Include(Result,bsObjectChecks);
+    -28: Exclude(Result,bsObjectChecks);
+    else
+      RaiseMsg(20180131170303,'bs='+IntToStr(i));
+    end;
+  until false;
+end;
+
+function TPJUReader.ReadConverterOptions(
+  const DefaultValue: TPasToJsConverterOptions): TPasToJsConverterOptions;
+var
+  i: integer;
+begin
+  Result:=DefaultValue;
+  repeat
+    i:=ReadInt(-100,100);
+    case i of
+    0: exit;
+    +1: Exclude(Result,coLowerCase);
+    -1: Include(Result,coLowerCase);
+    +2: Exclude(Result,coSwitchStatement);
+    -2: Include(Result,coSwitchStatement);
+    +3: Exclude(Result,coEnumNumbers);
+    -3: Include(Result,coEnumNumbers);
+    +4: Exclude(Result,coUseStrict);
+    -4: Include(Result,coUseStrict);
+    +5: Exclude(Result,coNoTypeInfo);
+    -5: Include(Result,coNoTypeInfo);
+    +6: Exclude(Result,coEliminateDeadCode);
+    -6: Include(Result,coEliminateDeadCode);
+    else
+      RaiseMsg(20180131170301,'co='+IntToStr(i));
+    end;
+  until false;
+end;
+
+procedure TPJUReader.ReadSrcFiles;
 var
 var
   Cnt: MaxPrecInt;
   Cnt: MaxPrecInt;
   i: Integer;
   i: Integer;
@@ -515,29 +889,28 @@ begin
     end;
     end;
 end;
 end;
 
 
-constructor TPasToJsReader.Create;
+constructor TPJUReader.Create;
 begin
 begin
   FSourceFiles:=TObjectList.Create(true);
   FSourceFiles:=TObjectList.Create(true);
   FInitialFlags:=TPJUInitialFlags.Create;
   FInitialFlags:=TPJUInitialFlags.Create;
 end;
 end;
 
 
-destructor TPasToJsReader.Destroy;
+destructor TPJUReader.Destroy;
 begin
 begin
   FreeAndNil(FInitialFlags);
   FreeAndNil(FInitialFlags);
   FreeAndNil(FSourceFiles);
   FreeAndNil(FSourceFiles);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
-procedure TPasToJsReader.Clear;
+procedure TPJUReader.Clear;
 begin
 begin
   FSourceFiles.Clear;
   FSourceFiles.Clear;
   FResolver:=nil;
   FResolver:=nil;
   FPJU:='';
   FPJU:='';
-  FInitialFlags.Free;
-  FInitialFlags:=TPJUInitialFlags.Create;
+  FInitialFlags.Clear;
 end;
 end;
 
 
-procedure TPasToJsReader.ReadModule(aResolver: TPasResolver; aPJU: String);
+procedure TPJUReader.ReadModule(aResolver: TPasResolver; aPJU: String);
 begin
 begin
   FResolver:=aResolver;
   FResolver:=aResolver;
   FParser:=Resolver.CurrentParser;
   FParser:=Resolver.CurrentParser;
@@ -548,51 +921,260 @@ begin
 
 
   ReadHeaderMagic;
   ReadHeaderMagic;
   ReadHeaderVersion;
   ReadHeaderVersion;
-  ReadSrcFiles;
   ReadInitialFlags;
   ReadInitialFlags;
+  ReadSrcFiles;
 end;
 end;
 
 
-{ TPasToJsWriter }
+{ TPJUWriter }
 
 
-procedure TPasToJsWriter.WriteStr(const s: string);
+function TPJUWriter.GetSrcCheckSum(aFilename: string): TPJUSourceFileChecksum;
+var
+  p: PChar;
+  Cnt: integer;
+begin
+  OnGetSrc(Self,aFilename,p,Cnt);
+  Result:=ComputeChecksum(p,Cnt);
+end;
+
+procedure TPJUWriter.WriteStr(const s: string);
 begin
 begin
   if s='' then exit;
   if s='' then exit;
   FStream.Write(s[1],length(s));
   FStream.Write(s[1],length(s));
 end;
 end;
 
 
-procedure TPasToJsWriter.WriteInt(const i: MaxPrecInt);
+procedure TPJUWriter.WriteInt(const i: MaxPrecInt);
 begin
 begin
   WriteStr(EncodeVLQ(i));
   WriteStr(EncodeVLQ(i));
   //writeln('TPasToJsWriter.WriteInt ',i,' ',dbgmem(EncodeVLQ(i)));
   //writeln('TPasToJsWriter.WriteInt ',i,' ',dbgmem(EncodeVLQ(i)));
 end;
 end;
 
 
-procedure TPasToJsWriter.WriteText(const s: string);
+procedure TPJUWriter.WriteText(const s: string);
 begin
 begin
   WriteInt(length(s));
   WriteInt(length(s));
   if s<>'' then
   if s<>'' then
     WriteStr(s);
     WriteStr(s);
 end;
 end;
 
 
-procedure TPasToJsWriter.WriteHeaderMagic;
+procedure TPJUWriter.WriteHeaderMagic;
 begin
 begin
   WriteStr(PJUMagic);
   WriteStr(PJUMagic);
 end;
 end;
 
 
-procedure TPasToJsWriter.WriteHeaderVersion;
+procedure TPJUWriter.WriteHeaderVersion;
 begin
 begin
   WriteInt(PJUVersion);
   WriteInt(PJUVersion);
 end;
 end;
 
 
-procedure TPasToJsWriter.WriteInitialFlags;
+procedure TPJUWriter.WriteInitialFlags;
 begin
 begin
-  // Write modeswitches
-  //for ms in InitialFlags.Modeswitches do
-  //  WriteInt(ModeSwitchToInt(ms));
-  //WriteInt(-1);
-  // ToDo: write initial flags: BoolSwitches, used defines, used macros
+  WriteParserOptions(InitialFlags.ParserOptions,PJUDefaultParserOptions);
+  WriteModeSwitches(InitialFlags.Modeswitches,PJUDefaultModeSwitches);
+  WriteBoolSwitches(InitialFlags.BoolSwitches,PJUDefaultBoolSwitches);
+  WriteConvertOptions(InitialFlags.ConverterOptions,PJUDefaultConvertOptions);
+  case InitialFlags.TargetPlatform of
+    PlatformBrowser: WriteInt(1);
+    PlatformNodeJS: WriteInt(2);
+  end;
+  case InitialFlags.TargetProcessor of
+    ProcessorECMAScript5: WriteInt(1);
+    ProcessorECMAScript6: WriteInt(2);
+  end;
+  // ToDo: write initial flags: used defines, used macros
+end;
+
+procedure TPJUWriter.WriteParserOptions(const Value, DefaultValue: TPOptions);
+
+  procedure AddDiff(s: TPOption; Int: MaxPrecInt);
+  begin
+    if s in Value then
+      begin
+      if not (s in DefaultValue) then
+        begin
+        WriteInt(Int);
+        //writeln('TPJUWriter.WriteParserOptions.AddDiff ',s);
+        end;
+      end
+    else
+      begin
+      if s in DefaultValue then
+        WriteInt(-Int);
+      end;
+  end;
+
+begin
+  AddDiff(po_KeepScannerError,1);
+  AddDiff(po_CAssignments,2);
+  AddDiff(po_ResolveStandardTypes,3);
+  AddDiff(po_AsmWhole,4);
+  AddDiff(po_NoOverloadedProcs,5);
+  AddDiff(po_KeepClassForward,6);
+  AddDiff(po_ArrayRangeExpr,7);
+  AddDiff(po_SelfToken,8);
+  AddDiff(po_CheckModeSwitches,9);
+  AddDiff(po_CheckCondFunction,10);
+  AddDiff(po_StopOnErrorDirective,11);
+  AddDiff(po_ExtClassConstWithoutExpr,12);
+  WriteInt(0);
+end;
+
+procedure TPJUWriter.WriteModeSwitches(const Value,
+  DefaultValue: TModeSwitches);
+
+  procedure AddDiff(s: TModeSwitch; Int: MaxPrecInt);
+  begin
+    if s in Value then
+      begin
+      if not (s in DefaultValue) then
+        begin
+        WriteInt(Int);
+        //writeln('TPJUWriter.WriteModeSwitches.AddDiff ',s);
+        end;
+      end
+    else
+      begin
+      if s in DefaultValue then
+        WriteInt(-Int);
+      end;
+  end;
+
+begin
+  AddDiff(msNone,1);
+  // mode
+  AddDiff(msFpc,2);
+  AddDiff(msObjfpc,3);
+  AddDiff(msDelphi,4);
+  AddDiff(msDelphiUnicode,5);
+  AddDiff(msTP7,6);
+  AddDiff(msMac,7);
+  AddDiff(msIso,8);
+  AddDiff(msExtpas,9);
+  AddDiff(msGPC,10);
+  // switches
+  AddDiff(msClass,31);
+  AddDiff(msObjpas,32);
+  AddDiff(msResult,33);
+  AddDiff(msStringPchar,34);
+  AddDiff(msCVarSupport,35);
+  AddDiff(msNestedComment,36);
+  AddDiff(msTPProcVar,37);
+  AddDiff(msMacProcVar,38);
+  AddDiff(msRepeatForward,39);
+  AddDiff(msPointer2Procedure,40);
+  AddDiff(msAutoDeref,41);
+  AddDiff(msInitFinal,42);
+  AddDiff(msDefaultAnsistring,43);
+  AddDiff(msOut,44);
+  AddDiff(msDefaultPara,45);
+  AddDiff(msHintDirective,46);
+  AddDiff(msDuplicateNames,47);
+  AddDiff(msProperty,48);
+  AddDiff(msDefaultInline,49);
+  AddDiff(msExcept,50);
+  AddDiff(msObjectiveC1,51);
+  AddDiff(msObjectiveC2,52);
+  AddDiff(msNestedProcVars,53);
+  AddDiff(msNonLocalGoto,54);
+  AddDiff(msAdvancedRecords,55);
+  AddDiff(msISOLikeUnaryMinus,56);
+  AddDiff(msSystemCodePage,57);
+  AddDiff(msFinalFields,58);
+  AddDiff(msDefaultUnicodestring,59);
+  AddDiff(msTypeHelpers,60);
+  AddDiff(msCBlocks,61);
+  AddDiff(msISOLikeIO,62);
+  AddDiff(msISOLikeProgramsPara,63);
+  AddDiff(msISOLikeMod,64);
+  AddDiff(msExternalClass,65);
+  AddDiff(msPrefixedAttributes,66);
+  AddDiff(msIgnoreInterfaces,67);
+  AddDiff(msIgnoreAttributes,68);
+  // stop byte
+  WriteInt(0);
+end;
+
+procedure TPJUWriter.WriteBoolSwitches(const Value,
+  DefaultValue: TBoolSwitches);
+
+  procedure AddDiff(s: TBoolSwitch; Int: MaxPrecInt);
+  begin
+    if s in Value then
+      begin
+      if not (s in DefaultValue) then
+        begin
+        WriteInt(Int);
+        //writeln('TPJUWriter.WriteBoolSwitches.AddDiff ',s);
+        end;
+      end
+    else
+      begin
+      if s in DefaultValue then
+        WriteInt(-Int);
+      end;
+  end;
+
+begin
+  AddDiff(bsNone,1);
+  AddDiff(bsAlign,2);
+  AddDiff(bsBoolEval,3);
+  AddDiff(bsAssertions,4);
+  AddDiff(bsDebugInfo,5);
+  AddDiff(bsExtension,6);
+  AddDiff(bsImportedData,7);
+  AddDiff(bsLongStrings,8);
+  AddDiff(bsIOChecks,9);
+  AddDiff(bsWriteableConst,10);
+  AddDiff(bsLocalSymbols,11);
+  AddDiff(bsTypeInfo,12);
+  AddDiff(bsOptimization,13);
+  AddDiff(bsOpenStrings,14);
+  AddDiff(bsOverflowChecks,15);
+  AddDiff(bsRangeChecks,16);
+  AddDiff(bsTypedAddress,17);
+  AddDiff(bsSafeDivide,18);
+  AddDiff(bsVarStringChecks,19);
+  AddDiff(bsStackframes,20);
+  AddDiff(bsExtendedSyntax,21);
+  AddDiff(bsReferenceInfo,22);
+  AddDiff(bsHints,23);
+  AddDiff(bsNotes,24);
+  AddDiff(bsWarnings,25);
+  AddDiff(bsMacro,26);
+  AddDiff(bsScopedEnums,27);
+  AddDiff(bsObjectChecks,28);
+  WriteInt(0);
+end;
+
+procedure TPJUWriter.WriteConvertOptions(const Value,
+  DefaultValue: TPasToJsConverterOptions);
+
+  procedure AddDiff(s: TPasToJsConverterOption; Int: MaxPrecInt);
+  begin
+    if s in Value then
+      begin
+      if not (s in DefaultValue) then
+        begin
+        WriteInt(Int);
+        //writeln('TPJUWriter.WriteConvertOptions.AddDiff ',s);
+        end;
+      end
+    else
+      begin
+      if s in DefaultValue then
+        WriteInt(-Int);
+      end;
+  end;
+
+begin
+  AddDiff(coLowerCase,1);
+  AddDiff(coSwitchStatement,2);
+  AddDiff(coEnumNumbers,3);
+  AddDiff(coUseStrict,4);
+  AddDiff(coNoTypeInfo,5);
+  AddDiff(coEliminateDeadCode,6);
+  WriteInt(0);
 end;
 end;
 
 
-procedure TPasToJsWriter.WriteSrcFiles;
+procedure TPJUWriter.WriteSrcFiles;
 var
 var
   CurFile: TPJUSourceFile;
   CurFile: TPJUSourceFile;
   List: TFPList;
   List: TFPList;
@@ -610,11 +1192,12 @@ begin
         CurFile.Kind:=sfkUnit
         CurFile.Kind:=sfkUnit
       else
       else
         CurFile.Kind:=sfkInclude;
         CurFile.Kind:=sfkInclude;
-      // ToDo: checksum
+      FSourceFiles.Add(CurFile);
+      CurFile.Checksum:=GetSrcCheckSum(CurFile.Filename);
       List.Add(CurFile);
       List.Add(CurFile);
       end;
       end;
 
 
-    // create FSourceFilesSorted;
+    // create FSourceFilesSorted
     List.Sort(@ComparePJUSrcFiles);
     List.Sort(@ComparePJUSrcFiles);
     SetLength(FSourceFilesSorted,List.Count);
     SetLength(FSourceFilesSorted,List.Count);
     for i:=0 to List.Count-1 do
     for i:=0 to List.Count-1 do
@@ -635,19 +1218,19 @@ begin
   end;
   end;
 end;
 end;
 
 
-constructor TPasToJsWriter.Create;
+constructor TPJUWriter.Create;
 begin
 begin
   FSourceFiles:=TObjectList.Create(true);
   FSourceFiles:=TObjectList.Create(true);
 end;
 end;
 
 
-destructor TPasToJsWriter.Destroy;
+destructor TPJUWriter.Destroy;
 begin
 begin
   Clear;
   Clear;
   FreeAndNil(FSourceFiles);
   FreeAndNil(FSourceFiles);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
-procedure TPasToJsWriter.Clear;
+procedure TPJUWriter.Clear;
 begin
 begin
   FSourceFiles.Clear;
   FSourceFiles.Clear;
   FResolver:=nil;
   FResolver:=nil;
@@ -657,7 +1240,7 @@ begin
   FInitialFlags:=nil;
   FInitialFlags:=nil;
 end;
 end;
 
 
-procedure TPasToJsWriter.WriteModule(aResolver: TPasResolver; aStream: TStream;
+procedure TPJUWriter.WriteModule(aResolver: TPasResolver; aStream: TStream;
   InitFlags: TPJUInitialFlags);
   InitFlags: TPJUInitialFlags);
 begin
 begin
   FResolver:=aResolver;
   FResolver:=aResolver;

+ 1 - 1
packages/pastojs/src/pas2jspparser.pp

@@ -109,7 +109,7 @@ constructor TPas2jsPasParser.Create(AScanner: TPascalScanner;
   AFileResolver: TBaseFileResolver; AEngine: TPasTreeContainer);
   AFileResolver: TBaseFileResolver; AEngine: TPasTreeContainer);
 begin
 begin
   inherited Create(AScanner,AFileResolver,AEngine);
   inherited Create(AScanner,AFileResolver,AEngine);
-  Options:=Options+[po_AsmWhole,po_ResolveStandardTypes,po_ExtClassConstWithoutExpr];
+  Options:=Options+po_pas2js;
 end;
 end;
 
 
 procedure TPas2jsPasParser.SetLastMsg(MsgType: TMessageType;
 procedure TPas2jsPasParser.SetLastMsg(MsgType: TMessageType;

+ 28 - 9
packages/pastojs/tests/tcfiler.pas

@@ -35,16 +35,18 @@ type
   TCustomTestPrecompile = Class(TCustomTestModule)
   TCustomTestPrecompile = Class(TCustomTestModule)
   private
   private
     FInitialFlags: TPJUInitialFlags;
     FInitialFlags: TPJUInitialFlags;
-    FPJUReader: TPasToJsReader;
-    FPJUWriter: TPasToJsWriter;
+    FPJUReader: TPJUReader;
+    FPJUWriter: TPJUWriter;
+    procedure OnFilerGetSrc(Sender: TObject; aFilename: string; out p: PChar;
+      out Count: integer);
   protected
   protected
     procedure SetUp; override;
     procedure SetUp; override;
     procedure TearDown; override;
     procedure TearDown; override;
     procedure WriteReadUnit; virtual;
     procedure WriteReadUnit; virtual;
     procedure StartParsing; override;
     procedure StartParsing; override;
   public
   public
-    property PJUWriter: TPasToJsWriter read FPJUWriter write FPJUWriter;
-    property PJUReader: TPasToJsReader read FPJUReader write FPJUReader;
+    property PJUWriter: TPJUWriter read FPJUWriter write FPJUWriter;
+    property PJUReader: TPJUReader read FPJUReader write FPJUReader;
     property InitialFlags: TPJUInitialFlags read FInitialFlags;
     property InitialFlags: TPJUInitialFlags read FInitialFlags;
   end;
   end;
 
 
@@ -60,6 +62,23 @@ implementation
 
 
 { TCustomTestPrecompile }
 { TCustomTestPrecompile }
 
 
+procedure TCustomTestPrecompile.OnFilerGetSrc(Sender: TObject;
+  aFilename: string; out p: PChar; out Count: integer);
+var
+  i: Integer;
+  aModule: TTestEnginePasResolver;
+  Src: String;
+begin
+  for i:=0 to ResolverCount-1 do
+    begin
+    aModule:=Resolvers[i];
+    if aModule.Filename<>aFilename then continue;
+    Src:=aModule.Source;
+    p:=PChar(Src);
+    Count:=length(Src);
+    end;
+end;
+
 procedure TCustomTestPrecompile.SetUp;
 procedure TCustomTestPrecompile.SetUp;
 begin
 begin
   inherited SetUp;
   inherited SetUp;
@@ -83,11 +102,12 @@ var
   ReadScanner: TPascalScanner;
   ReadScanner: TPascalScanner;
   ReadParser: TPasParser;
   ReadParser: TPasParser;
 begin
 begin
-  FPJUWriter:=TPasToJsWriter.Create;
-  FPJUReader:=TPasToJsReader.Create;
+  FPJUWriter:=TPJUWriter.Create;
+  FPJUReader:=TPJUReader.Create;
   ms:=TMemoryStream.Create;
   ms:=TMemoryStream.Create;
   try
   try
     try
     try
+      PJUWriter.OnGetSrc:=@OnFilerGetSrc;
       PJUWriter.WriteModule(Engine,ms,InitialFlags);
       PJUWriter.WriteModule(Engine,ms,InitialFlags);
     except
     except
       on E: Exception do
       on E: Exception do
@@ -140,11 +160,10 @@ begin
   FInitialFlags.ParserOptions:=Parser.Options;
   FInitialFlags.ParserOptions:=Parser.Options;
   FInitialFlags.ModeSwitches:=Scanner.CurrentModeSwitches;
   FInitialFlags.ModeSwitches:=Scanner.CurrentModeSwitches;
   FInitialFlags.BoolSwitches:=Scanner.CurrentBoolSwitches;
   FInitialFlags.BoolSwitches:=Scanner.CurrentBoolSwitches;
-  // ToDo: defines
-  FInitialFlags.ResolverOptions:=Engine.Options;
-  FInitialFlags.PasTojsOptions:=Converter.Options;
+  FInitialFlags.ConverterOptions:=Converter.Options;
   FInitialFlags.TargetPlatform:=Converter.TargetPlatform;
   FInitialFlags.TargetPlatform:=Converter.TargetPlatform;
   FInitialFlags.TargetProcessor:=Converter.TargetProcessor;
   FInitialFlags.TargetProcessor:=Converter.TargetProcessor;
+  // ToDo: defines
 end;
 end;
 
 
 { TTestPrecompile }
 { TTestPrecompile }