Bläddra i källkod

pastojs: writestr and -Sm

git-svn-id: trunk@39125 -
Mattias Gaertner 7 år sedan
förälder
incheckning
df71ab3ecf

+ 48 - 5
packages/pastojs/src/fppas2js.pp

@@ -146,7 +146,7 @@ Works:
 - enums
   - type with values and names
   - option to write numbers instead of variables
-  - ord(), low(), high(), pred(), succ()
+  - ord(), low(), high(), pred(), succ(), str(), writestr()
   - type cast alias to enumtype
   - type cast number to enumtype, enumtype to number
   - const aliasname = enumvalue
@@ -346,9 +346,6 @@ Works:
 - typecast byte(longword) -> value & $ff
 
 ToDos:
--Sm        Support macros like C (global)
-- writestr(out s: string; args); varargs;
-- widestrings + FPC_HAS_FEATURE_WIDESTRINGS + FPC_WIDESTRING_EQUAL_UNICODESTRING
 - check rtl.js version
 - 'new', 'Function' -> class var use .prototype
 - btArrayLit
@@ -365,7 +362,6 @@ ToDos:
 - interfaces
   - array of interface
   - record member interface
-- remove cmsIgnoreInterfaces from codetools
 
 Not in Version 1.0:
 - make records more lightweight
@@ -1660,6 +1656,7 @@ type
     Function ConvertBuiltIn_StrProc(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_StrFunc(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltInStrParam(El: TPasExpr; AContext: TConvertContext; IsStrFunc, IsFirst: boolean): TJSElement; virtual;
+    Function ConvertBuiltIn_WriteStr(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_ConcatArray(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_CopyArray(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_InsertArray(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
@@ -7796,6 +7793,7 @@ begin
           bfSucc: Result:=ConvertBuiltIn_PredSucc(El,AContext,false);
           bfStrProc: Result:=ConvertBuiltIn_StrProc(El,AContext);
           bfStrFunc: Result:=ConvertBuiltIn_StrFunc(El,AContext);
+          bfWriteStr: Result:=ConvertBuiltIn_WriteStr(El,AContext);
           bfConcatArray: Result:=ConvertBuiltIn_ConcatArray(El,AContext);
           bfCopyArray: Result:=ConvertBuiltIn_CopyArray(El,AContext);
           bfInsertArray: Result:=ConvertBuiltIn_InsertArray(El,AContext);
@@ -9717,6 +9715,51 @@ begin
   end;
 end;
 
+function TPasToJSConverter.ConvertBuiltIn_WriteStr(El: TParamsExpr;
+  AContext: TConvertContext): TJSElement;
+// convert 'writestr(aString,v:width,p)' to 'aString = <string of v> + (<string of p>+"")'
+// for the conversion see ConvertBuiltInStrParam
+var
+  AssignContext: TAssignContext;
+  StrVar: TPasExpr;
+  TypeEl: TPasType;
+  JS: TJSElement;
+  AddJS: TJSAdditiveExpressionPlus;
+  i: Integer;
+begin
+  Result:=nil;
+  AssignContext:=TAssignContext.Create(El,nil,AContext);
+  try
+    StrVar:=El.Params[0];
+    AContext.Resolver.ComputeElement(StrVar,AssignContext.LeftResolved,[rcNoImplicitProc]);
+
+    // create right side
+    for i:=1 to length(El.Params)-1 do
+      begin
+      JS:=ConvertBuiltInStrParam(El.Params[i],AContext,false,true);
+      if AssignContext.RightSide=nil then
+        AssignContext.RightSide:=JS
+      else
+        begin
+        AddJS:=TJSAdditiveExpressionPlus(CreateElement(TJSAdditiveExpressionPlus,El));
+        AddJS.A:=AssignContext.RightSide;
+        AssignContext.RightSide:=AddJS;
+        AddJS.B:=JS;
+        end;
+      end;
+
+    TypeEl:=AContext.Resolver.BaseTypes[btString];
+    SetResolverValueExpr(AssignContext.RightResolved,btString,
+      TypeEl,TypeEl,El,[rrfReadable]);
+
+    // create 'StrVar = rightside'
+    Result:=CreateAssignStatement(StrVar,AssignContext);
+  finally
+    AssignContext.RightSide.Free;
+    AssignContext.Free;
+  end;
+end;
+
 function TPasToJSConverter.ConvertBuiltIn_ConcatArray(El: TParamsExpr;
   AContext: TConvertContext): TJSElement;
 // concat(array1, array2)

+ 9 - 2
packages/pastojs/src/pas2jscompiler.pp

@@ -102,6 +102,7 @@ type
     coAssertions,
     // features
     coAllowCAssignments,
+    coAllowMacros,
     // output
     coLowerCase,
     coUseStrict,
@@ -145,6 +146,7 @@ const
     'Method call checking',
     'Assertions',
     'Allow C assignments',
+    'Allow macros',
     'Lowercase identifiers',
     'Use strict',
     'Write pas2jsdebug.log',
@@ -794,6 +796,8 @@ var
   bs: TBoolSwitches;
 begin
   bs:=[bsWriteableConst];
+  if coAllowMacros in Compiler.Options then
+    Include(bs,bsMacro);
   if coOverflowChecks in Compiler.Options then
     Include(bs,bsOverflowChecks);
   if coRangeChecks in Compiler.Options then
@@ -3505,17 +3509,19 @@ begin
   for i:=1 to length(Enabled) do begin
     case Enabled[i] of
     'a': Options:=Options+[coAssertions];
-    '2': Mode:=p2jmObjFPC;
     'c': Options:=Options+[coAllowCAssignments];
     'd': Mode:=p2jmDelphi;
+    'm': Options:=Options+[coAllowMacros];
+    '2': Mode:=p2jmObjFPC;
     end;
   end;
   for i:=1 to length(Disabled) do begin
     case Disabled[i] of
     'a': Options:=Options-[coAssertions];
-    '2': ;
     'c': Options:=Options-[coAllowCAssignments];
     'd': ;
+    'm': Options:=Options-[coAllowMacros];
+    '2': ;
     end;
   end;
 end;
@@ -4041,6 +4047,7 @@ begin
   l('    a     : Turn on assertions');
   l('    c     : Support operators like C (*=,+=,/= and -=)');
   l('    d     : Same as -Mdelphi');
+  l('    m     : Support macros');
   l('    2     : Same as -Mobjfpc (default)');
   l('  -SI<x>   : Set interface style to <x>');
   l('    -SIcom   : COM compatible interface (default)');

+ 35 - 30
packages/pastojs/tests/tcmodules.pas

@@ -3811,36 +3811,39 @@ end;
 procedure TTestModule.TestEnum_Functions;
 begin
   StartProgram(false);
-  Add('type TMyEnum = (Red, Green);');
-  Add('var');
-  Add('  e: TMyEnum;');
-  Add('  i: longint;');
-  Add('  s: string;');
-  Add('  b: boolean;');
-  Add('begin');
-  Add('  i:=ord(red);');
-  Add('  i:=ord(green);');
-  Add('  i:=ord(e);');
-  Add('  i:=ord(b);');
-  Add('  e:=low(tmyenum);');
-  Add('  e:=low(e);');
-  Add('  b:=low(boolean);');
-  Add('  e:=high(tmyenum);');
-  Add('  e:=high(e);');
-  Add('  b:=high(boolean);');
-  Add('  e:=pred(green);');
-  Add('  e:=pred(e);');
-  Add('  b:=pred(b);');
-  Add('  e:=succ(red);');
-  Add('  e:=succ(e);');
-  Add('  b:=succ(b);');
-  Add('  e:=tmyenum(1);');
-  Add('  e:=tmyenum(i);');
-  Add('  s:=str(e);');
-  Add('  str(e,s);');
-  Add('  s:=str(e:3);');
-  Add('  e:=TMyEnum(i);');
-  Add('  i:=longint(e);');
+  Add([
+  'type TMyEnum = (Red, Green);',
+  'var',
+  '  e: TMyEnum;',
+  '  i: longint;',
+  '  s: string;',
+  '  b: boolean;',
+  'begin',
+  '  i:=ord(red);',
+  '  i:=ord(green);',
+  '  i:=ord(e);',
+  '  i:=ord(b);',
+  '  e:=low(tmyenum);',
+  '  e:=low(e);',
+  '  b:=low(boolean);',
+  '  e:=high(tmyenum);',
+  '  e:=high(e);',
+  '  b:=high(boolean);',
+  '  e:=pred(green);',
+  '  e:=pred(e);',
+  '  b:=pred(b);',
+  '  e:=succ(red);',
+  '  e:=succ(e);',
+  '  b:=succ(b);',
+  '  e:=tmyenum(1);',
+  '  e:=tmyenum(i);',
+  '  s:=str(e);',
+  '  str(e,s);',
+  '  str(red,s);',
+  '  s:=str(e:3);',
+  '  writestr(s,e:3,red);',
+  '  e:=TMyEnum(i);',
+  '  i:=longint(e);']);
   ConvertProgram;
   CheckSource('TestEnum_Functions',
     LinesToStr([ // statements
@@ -3876,7 +3879,9 @@ begin
     '$mod.e=$mod.i;',
     '$mod.s = $mod.TMyEnum[$mod.e];',
     '$mod.s = $mod.TMyEnum[$mod.e];',
+    '$mod.s = $mod.TMyEnum[$mod.TMyEnum.Red];',
     '$mod.s = rtl.spaceLeft($mod.TMyEnum[$mod.e], 3);',
+    '$mod.s = rtl.spaceLeft($mod.TMyEnum[$mod.e], 3)+$mod.TMyEnum[$mod.TMyEnum.Red];',
     '$mod.e=$mod.i;',
     '$mod.i=$mod.e;',
     '']));

+ 3 - 1
utils/pas2js/docs/translation.html

@@ -186,6 +186,7 @@ Put + after a boolean switch option to enable it, - to disable it
     a     : Turn on assertions
     c     : Support operators like C (*=,+=,/= and -=)
     d     : Same as -Mdelphi
+    m     : Support macros
     2     : Same as -Mobjfpc (default)
   -SI&lt;x&gt;   : Set interface style to &lt;x&gt;
     -SIcom   : COM compatible interface (default)
@@ -2868,12 +2869,13 @@ End.
     e.g. <i>uses unit1 in 'sub/Unit1.pas'</i>.<br>
     In <i>$mode objfpc</i> units can use in-filenames too and
     alias are allowed, e.g. <i>uses foo in 'bar.pas'</i>.</li>
-    <li>The built-in procedure <b>str</b> works with boolean, integer, float and enumvalue.<br>
+    <li>The intrinsic procedure <b>str</b> works with boolean, integer, float and enumvalue.<br>
     Additionally there is <b>str</b> function, that takes an arbitrary number of
     arguments and returns a concatenated string. It supports string as parameter too.
     For example s:=str(i,' ',d:1:5).<br>
     Width and precision is supported. str(i:10) will add spaces to the left to fill up to 10 characters.</b>
     str(aDouble:1:5) returns a string in decimal format with 5 digits for the fraction.</li>
+    <li>Intrinsic procedure WriteStr(out s: string; params...)</li>
     </ul>
     </div>
 

+ 1 - 1
utils/pas2js/pas2js.pp

@@ -1,4 +1,4 @@
-{ Author: Mattias Gaertner  2017  [email protected]
+{ Author: Mattias Gaertner  2018  [email protected]
 
   Abstract:
     Command line interface for the pas2js compiler.