Browse Source

pastojs: static array const

git-svn-id: trunk@37204 -
Mattias Gaertner 8 years ago
parent
commit
df00b30f92
2 changed files with 54 additions and 73 deletions
  1. 46 73
      packages/pastojs/src/fppas2js.pp
  2. 8 0
      packages/pastojs/tests/tcmodules.pas

+ 46 - 73
packages/pastojs/src/fppas2js.pp

@@ -766,15 +766,6 @@ type
   end;
   TPas2JsElementDataClass = class of TPas2JsElementData;
 
-  { TP2JConstExprData - CustomData of a const TPasExpr }
-
-  TP2JConstExprData = Class(TPas2JsElementData)
-  public
-    // Element is TPasExpr
-    Value: TJSValue;
-    destructor Destroy; override;
-  end;
-
   TPas2JSClassScope = class(TPasClassScope)
   public
     NewInstanceFunction: TPasClassFunction;
@@ -934,7 +925,7 @@ type
     property JSBaseTypes[aBaseType: TPas2jsBaseType]: TPasUnresolvedSymbolRef read GetJSBaseTypes;
     // compute literals and constants
     function ExtractPasStringLiteral(El: TPasElement; const S: String): TJSString; virtual;
-    function ComputeConst(Expr: TPasExpr; StoreCustomData: boolean): TJSValue; virtual;
+    function ResolverToJSValue(Value: TResEvalValue; ErrorEl: TPasElement): TJSValue; virtual;
     function ComputeConstString(Expr: TPasExpr; StoreCustomData, NotEmpty: boolean): String; virtual;
     procedure CheckAssignExprRangeToCustom(
       const LeftResolved: TPasResolverResult; RValue: TResEvalValue;
@@ -1212,7 +1203,7 @@ type
     Function CreateUsesList(UsesSection: TPasSection; AContext : TConvertContext): TJSArrayLiteral;
     Procedure AddToStatementList(var First, Last: TJSStatementList;
       Add: TJSElement; Src: TPasElement);
-    Function CreateValInit(PasType: TPasType; Expr: TPasElement; El: TPasElement;
+    Function CreateValInit(PasType: TPasType; Expr: TPasExpr; El: TPasElement;
       AContext: TConvertContext): TJSElement; virtual;
     Function CreateVarInit(El: TPasVariable; AContext: TConvertContext): TJSElement; virtual;
     Function CreateVarStatement(const aName: String; Init: TJSElement;
@@ -1228,7 +1219,7 @@ type
     Function ClonePrimaryExpression(El: TJSPrimaryExpression; Src: TPasElement): TJSPrimaryExpression;
     Function CreateRecordInit(aRecord: TPasRecordType; Expr: TPasElement;
       El: TPasElement; AContext: TConvertContext): TJSElement; virtual;
-    Function CreateArrayInit(ArrayType: TPasArrayType; Expr: TPasElement;
+    Function CreateArrayInit(ArrayType: TPasArrayType; Expr: TPasExpr;
       El: TPasElement; AContext: TConvertContext): TJSElement; virtual;
     Function CreateCmpArrayWithNil(El: TPasElement; JSArray: TJSElement;
       OpCode: TExprOpCode): TJSElement; virtual;
@@ -2976,67 +2967,50 @@ begin
   {$ENDIF}
 end;
 
-function TPas2JSResolver.ComputeConst(Expr: TPasExpr; StoreCustomData: boolean
-  ): TJSValue;
-var
-  Prim: TPrimitiveExpr;
-  V: TJSValue;
-  ConstData: TP2JConstExprData;
+function TPas2JSResolver.ResolverToJSValue(Value: TResEvalValue;
+  ErrorEl: TPasElement): TJSValue;
 begin
   Result:=nil;
-  if Expr=nil then
-    RaiseInternalError(20170215123600);
-  if StoreCustomData and (Expr.CustomData is TPasElementBase) then
-    begin
-    ConstData:=TP2JConstExprData(GetElementData(
-                           TPasElementBase(Expr.CustomData),TP2JConstExprData));
-    if ConstData<>nil then
-      begin
-      // use stored result
-      Result:=ConstData.Value;
-      exit;
-      end;
-    end;
-
-  V:=nil;
-  try
-    if Expr.ClassType=TPrimitiveExpr then
-      begin
-      Prim:=TPrimitiveExpr(Expr);
-      if Prim.Kind=pekString then
-        V:=TJSValue.Create(ExtractPasStringLiteral(Prim,Prim.Value))
-      else
-        RaiseNotYetImplemented(20170215124733,Prim);
-      end
-    else
-      RaiseNotYetImplemented(20170215124746,Expr);
-    Result:=V;
-
-    if StoreCustomData then
-      begin
-      // store result
-      ConstData:=TP2JConstExprData(CreateElementData(TP2JConstExprData,Expr));
-      ConstData.Value:=V;
-      end;
-  finally
-    if Result=nil then
-      V.Free;
+  if Value=nil then exit;
+  case Value.Kind of
+  revkBool: Result:=TJSValue.Create(TResEvalBool(Value).B);
+  revkInt: Result:=TJSValue.Create(TJSNumber(TResEvalInt(Value).Int));
+  revkUInt: Result:=TJSValue.Create(TJSNumber(TResEvalUInt(Value).UInt));
+  revkFloat: Result:=TJSValue.Create(TJSNumber(TResEvalFloat(Value).FloatValue));
+  revkString: Result:=TJSValue.Create(TJSString(
+    ExprEvaluator.GetUnicodeStr(TResEvalString(Value).S,ErrorEl)));
+  revkUnicodeString: Result:=TJSValue.Create(TJSString(TResEvalUTF16(Value).S));
+  else
+    {$IFDEF VerbosePas2JS}
+    writeln('TPas2JSResolver.ResolverToJSValue ',Value.AsDebugString);
+    {$ENDIF}
+    RaiseNotYetImplemented(20170914092413,ErrorEl,'');
   end;
 end;
 
 function TPas2JSResolver.ComputeConstString(Expr: TPasExpr; StoreCustomData,
   NotEmpty: boolean): String;
 var
-  V: TJSValue;
+  Value: TResEvalValue;
 begin
-  V:=ComputeConst(Expr,StoreCustomData);
-  if V.ValueType<>jsbase.jstString then
-    RaiseNotYetImplemented(20170320220728,Expr,'expected string constant');
-  if V.ValueType<>jstString then
-    RaiseMsg(20170211221121,nExpectedXButFoundY,sExpectedXButFoundY,['string literal',JSTypeCaptions[V.ValueType]],Expr);
-  if NotEmpty and (V.AsString='') then
+  Result:='';
+  if Expr=nil then
+    RaiseInternalError(20170215123600);
+  Value:=Eval(Expr,[refAutoConst],StoreCustomData);
+  try
+    case Value.Kind of
+    revkString: Result:=ExprEvaluator.GetUTF8Str(TResEvalString(Value).S,Expr);
+    revkUnicodeString: Result:=UTF8Encode(TResEvalUTF16(Value).S);
+    else
+      str(Value.Kind,Result);
+      RaiseMsg(20170211221121,nExpectedXButFoundY,sExpectedXButFoundY,['string literal',Result],Expr);
+    end;
+  finally
+    ReleaseEvalValue(Value);
+  end;
+
+  if NotEmpty and (Result='') then
     RaiseMsg(20170321085318,nExpectedXButFoundY,sExpectedXButFoundY,['string literal','empty'],Expr);
-  Result:=String(V.AsString);
 end;
 
 procedure TPas2JSResolver.CheckAssignExprRangeToCustom(
@@ -3150,14 +3124,6 @@ begin
   Result:=ExtName=ExtClassBracketAccessor;
 end;
 
-{ TP2JConstExprData }
-
-destructor TP2JConstExprData.Destroy;
-begin
-  FreeAndNil(Value);
-  inherited Destroy;
-end;
-
 { TParamContext }
 
 constructor TParamContext.Create(PasEl: TPasElement; JSEl: TJSElement;
@@ -10594,7 +10560,7 @@ begin
     end;
 end;
 
-function TPasToJSConverter.CreateValInit(PasType: TPasType; Expr: TPasElement;
+function TPasToJSConverter.CreateValInit(PasType: TPasType; Expr: TPasExpr;
   El: TPasElement; AContext: TConvertContext): TJSElement;
 var
   T: TPasType;
@@ -10889,7 +10855,7 @@ begin
 end;
 
 function TPasToJSConverter.CreateArrayInit(ArrayType: TPasArrayType;
-  Expr: TPasElement; El: TPasElement; AContext: TConvertContext): TJSElement;
+  Expr: TPasExpr; El: TPasElement; AContext: TConvertContext): TJSElement;
 var
   Call: TJSCallExpression;
   DimArray, ArrLit: TJSArrayLiteral;
@@ -10900,6 +10866,7 @@ var
   CurArrayType: TPasArrayType;
   DefaultValue: TJSElement;
   ArrayValues: TPasExprArray;
+  US: TJSString;
 begin
   if Assigned(Expr) then
     begin
@@ -10916,6 +10883,12 @@ begin
         for i:=0 to length(ArrayValues)-1 do
           ArrLit.Elements.AddElement.Expr:=ConvertElement(ArrayValues[i],AContext);
         end
+      else if ExprResolved.BaseType in btAllStringAndChars then
+        begin
+        US:=TJSString(AContext.Resolver.ComputeConstString(Expr,false,true));
+        for i:=1 to length(US) do
+          ArrLit.Elements.AddElement.Expr:=CreateLiteralJSString(Expr,US[i]);
+        end
       else
         RaiseNotSupported(Expr,AContext,20170223133034);
       Result:=ArrLit;

+ 8 - 0
packages/pastojs/tests/tcmodules.pas

@@ -4896,6 +4896,7 @@ begin
   Add('  TArrayInt = array[2..4] of longint;');
   Add('var');
   Add('  Arr: TArrayInt;');
+  Add('  Arr2: TArrayInt = (5,6,7);');
   Add('  i: longint;');
   Add('  b: boolean;');
   Add('begin');
@@ -4910,6 +4911,7 @@ begin
   CheckSource('TestArray_StaticInt',
     LinesToStr([ // statements
     'this.Arr = rtl.arrayNewMultiDim([3],0);',
+    'this.Arr2 = [5, 6, 7];',
     'this.i = 0;',
     'this.b = false;'
     ]),
@@ -4933,6 +4935,7 @@ begin
   Add('var');
   Add('  Arr: TBools;');
   Add('  Arr2: TBool2;');
+  Add('  Arr3: TBools = (true,false);');
   Add('  b: boolean;');
   Add('begin');
   Add('  b:=low(arr);');
@@ -4952,6 +4955,7 @@ begin
     LinesToStr([ // statements
     'this.Arr = rtl.arrayNewMultiDim([2],false);',
     'this.Arr2 = rtl.arrayNewMultiDim([1],false);',
+    'this.Arr3 = [true, false];',
     'this.b = false;'
     ]),
     LinesToStr([ // $mod.$main
@@ -4979,6 +4983,8 @@ begin
   Add('var');
   Add('  Arr: TChars;');
   Add('  Arr2: TChars2;');
+  Add('  Arr3: array[2..4] of char = (''p'',''a'',''s'');');
+  Add('  Arr4: array[11..13] of char = ''pas'';');
   Add('  c: char;');
   Add('  b: boolean;');
   Add('begin');
@@ -4999,6 +5005,8 @@ begin
     LinesToStr([ // statements
     'this.Arr = rtl.arrayNewMultiDim([65536], "");',
     'this.Arr2 = rtl.arrayNewMultiDim([26], "");',
+    'this.Arr3 = ["p", "a", "s"];',
+    'this.Arr4 = ["p", "a", "s"];',
     'this.c = "";',
     'this.b = false;',
     '']),