Browse Source

pastojs: ord, pred, succ on boolean

git-svn-id: trunk@37370 -
Mattias Gaertner 7 years ago
parent
commit
c93a5438b2
2 changed files with 90 additions and 40 deletions
  1. 43 38
      packages/pastojs/src/fppas2js.pp
  2. 47 2
      packages/pastojs/tests/tcmodules.pas

+ 43 - 38
packages/pastojs/src/fppas2js.pp

@@ -140,7 +140,7 @@ Works:
   - option to write numbers instead of variables
   - option to write numbers instead of variables
   - ord(), low(), high(), pred(), succ()
   - ord(), low(), high(), pred(), succ()
   - type cast alias to enumtype
   - type cast alias to enumtype
-  - type cast number to enumtype
+  - type cast number to enumtype, enumtype to number
   - const aliasname = enumvalue
   - const aliasname = enumvalue
 - sets
 - sets
   - set of enum
   - set of enum
@@ -1284,8 +1284,7 @@ type
     Function ConvertBuiltIn_Chr(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_Chr(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_Ord(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_Ord(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_LowHigh(El: TParamsExpr; AContext: TConvertContext; IsLow: boolean): TJSElement; virtual;
     Function ConvertBuiltIn_LowHigh(El: TParamsExpr; AContext: TConvertContext; IsLow: boolean): TJSElement; virtual;
-    Function ConvertBuiltIn_Pred(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
-    Function ConvertBuiltIn_Succ(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
+    Function ConvertBuiltIn_PredSucc(El: TParamsExpr; AContext: TConvertContext; IsPred: boolean): TJSElement; virtual;
     Function ConvertBuiltIn_StrProc(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_StrProc(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
     Function ConvertBuiltIn_StrFunc(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 ConvertBuiltInStrParam(El: TPasExpr; AContext: TConvertContext; IsStrFunc, IsFirst: boolean): TJSElement; virtual;
@@ -5652,8 +5651,8 @@ begin
           bfOrd: Result:=ConvertBuiltIn_Ord(El,AContext);
           bfOrd: Result:=ConvertBuiltIn_Ord(El,AContext);
           bfLow: Result:=ConvertBuiltIn_LowHigh(El,AContext,true);
           bfLow: Result:=ConvertBuiltIn_LowHigh(El,AContext,true);
           bfHigh: Result:=ConvertBuiltIn_LowHigh(El,AContext,false);
           bfHigh: Result:=ConvertBuiltIn_LowHigh(El,AContext,false);
-          bfPred: Result:=ConvertBuiltIn_Pred(El,AContext);
-          bfSucc: Result:=ConvertBuiltIn_Succ(El,AContext);
+          bfPred: Result:=ConvertBuiltIn_PredSucc(El,AContext,true);
+          bfSucc: Result:=ConvertBuiltIn_PredSucc(El,AContext,false);
           bfStrProc: Result:=ConvertBuiltIn_StrProc(El,AContext);
           bfStrProc: Result:=ConvertBuiltIn_StrProc(El,AContext);
           bfStrFunc: Result:=ConvertBuiltIn_StrFunc(El,AContext);
           bfStrFunc: Result:=ConvertBuiltIn_StrFunc(El,AContext);
           bfConcatArray: Result:=ConvertBuiltIn_ConcatArray(El,AContext);
           bfConcatArray: Result:=ConvertBuiltIn_ConcatArray(El,AContext);
@@ -6724,6 +6723,7 @@ var
   SubParams: TParamsExpr;
   SubParams: TParamsExpr;
   SubParamJS: TJSElement;
   SubParamJS: TJSElement;
   Minus: TJSAdditiveExpressionMinus;
   Minus: TJSAdditiveExpressionMinus;
+  Add: TJSAdditiveExpressionPlus;
 begin
 begin
   Result:=nil;
   Result:=nil;
   if AContext.Resolver=nil then
   if AContext.Resolver=nil then
@@ -6773,6 +6773,17 @@ begin
     Result:=Call;
     Result:=Call;
     exit;
     exit;
     end
     end
+  else if ParamResolved.BaseType in btAllBooleans then
+    begin
+    // ord(bool) ->  bool+0
+    Result:=ConvertElement(Param,AContext);
+    // Note: convert Param first, as it might raise an exception
+    Add:=TJSAdditiveExpressionPlus(CreateElement(TJSAdditiveExpressionPlus,El));
+    Add.A:=Result;
+    Add.B:=CreateLiteralNumber(El,0);
+    Result:=Add;
+    exit;
+    end
   else if ParamResolved.BaseType=btContext then
   else if ParamResolved.BaseType=btContext then
     begin
     begin
     if ParamResolved.TypeEl.ClassType=TPasEnumType then
     if ParamResolved.TypeEl.ClassType=TPasEnumType then
@@ -6970,59 +6981,44 @@ begin
     AContext.Resolver.GetResolverResultDescription(ResolvedEl)],Param);
     AContext.Resolver.GetResolverResultDescription(ResolvedEl)],Param);
 end;
 end;
 
 
-function TPasToJSConverter.ConvertBuiltIn_Pred(El: TParamsExpr;
-  AContext: TConvertContext): TJSElement;
+function TPasToJSConverter.ConvertBuiltIn_PredSucc(El: TParamsExpr;
+  AContext: TConvertContext; IsPred: boolean): TJSElement;
 // pred(enumvalue) -> enumvalue-1
 // pred(enumvalue) -> enumvalue-1
+// succ(enumvalue) -> enumvalue+1
 var
 var
   ResolvedEl: TPasResolverResult;
   ResolvedEl: TPasResolverResult;
   Param: TPasExpr;
   Param: TPasExpr;
   V: TJSElement;
   V: TJSElement;
-  Expr: TJSAdditiveExpressionMinus;
+  Expr: TJSAdditiveExpression;
 begin
 begin
   Result:=nil;
   Result:=nil;
   if AContext.Resolver=nil then
   if AContext.Resolver=nil then
     RaiseInconsistency(20170210120648);
     RaiseInconsistency(20170210120648);
   Param:=El.Params[0];
   Param:=El.Params[0];
   AContext.Resolver.ComputeElement(Param,ResolvedEl,[]);
   AContext.Resolver.ComputeElement(Param,ResolvedEl,[]);
-  if (ResolvedEl.BaseType=btContext)
-      and (ResolvedEl.TypeEl.ClassType=TPasEnumType) then
+  if (ResolvedEl.BaseType in btAllJSInteger)
+      or ((ResolvedEl.BaseType=btContext)
+        and (ResolvedEl.TypeEl.ClassType=TPasEnumType)) then
     begin
     begin
     V:=ConvertElement(Param,AContext);
     V:=ConvertElement(Param,AContext);
-    Expr:=TJSAdditiveExpressionMinus(CreateElement(TJSAdditiveExpressionMinus,El));
+    if IsPred then
+      Expr:=TJSAdditiveExpressionMinus(CreateElement(TJSAdditiveExpressionMinus,El))
+    else
+      Expr:=TJSAdditiveExpressionPlus(CreateElement(TJSAdditiveExpressionPlus,El));
     Expr.A:=V;
     Expr.A:=V;
     Expr.B:=CreateLiteralNumber(El,1);
     Expr.B:=CreateLiteralNumber(El,1);
     Result:=Expr;
     Result:=Expr;
     exit;
     exit;
-    end;
-  DoError(20170210120039,nExpectedXButFoundY,sExpectedXButFoundY,['enum',
-    AContext.Resolver.GetResolverResultDescription(ResolvedEl)],Param);
-end;
-
-function TPasToJSConverter.ConvertBuiltIn_Succ(El: TParamsExpr;
-  AContext: TConvertContext): TJSElement;
-// succ(enumvalue) -> enumvalue+1
-var
-  ResolvedEl: TPasResolverResult;
-  Param: TPasExpr;
-  V: TJSElement;
-  Expr: TJSAdditiveExpressionPlus;
-begin
-  Result:=nil;
-  if AContext.Resolver=nil then
-    RaiseInconsistency(20170210120645);
-  Param:=El.Params[0];
-  AContext.Resolver.ComputeElement(Param,ResolvedEl,[]);
-  if (ResolvedEl.BaseType=btContext)
-      and (ResolvedEl.TypeEl.ClassType=TPasEnumType) then
+    end
+  else if ResolvedEl.BaseType in btAllJSBooleans then
     begin
     begin
-    V:=ConvertElement(Param,AContext);
-    Expr:=TJSAdditiveExpressionPlus(CreateElement(TJSAdditiveExpressionPlus,El));
-    Expr.A:=V;
-    Expr.B:=CreateLiteralNumber(El,1);
-    Result:=Expr;
+    if IsPred then
+      Result:=CreateLiteralBoolean(El,false)
+    else
+      Result:=CreateLiteralBoolean(El,true);
     exit;
     exit;
     end;
     end;
-  DoError(20170210120626,nExpectedXButFoundY,sExpectedXButFoundY,['enum',
+  DoError(20170210120039,nExpectedXButFoundY,sExpectedXButFoundY,['enum',
     AContext.Resolver.GetResolverResultDescription(ResolvedEl)],Param);
     AContext.Resolver.GetResolverResultDescription(ResolvedEl)],Param);
 end;
 end;
 
 
@@ -11047,6 +11043,10 @@ begin
       Call.Expr:=CreateDotExpression(Expr,Result,CreatePrimitiveDotExpr('charCodeAt',Expr));
       Call.Expr:=CreateDotExpression(Expr,Result,CreatePrimitiveDotExpr('charCodeAt',Expr));
       Result:=Call;
       Result:=Call;
       end
       end
+    else if ExprResolved.BaseType in btAllJSInteger then
+      begin
+      // ok
+      end
     else if ExprResolved.BaseType=btContext then
     else if ExprResolved.BaseType=btContext then
       begin
       begin
       if ExprResolved.TypeEl.ClassType=TPasEnumType then
       if ExprResolved.TypeEl.ClassType=TPasEnumType then
@@ -11055,7 +11055,12 @@ begin
         RaiseNotSupported(Expr,AContext,20170415191933);
         RaiseNotSupported(Expr,AContext,20170415191933);
       end
       end
     else
     else
+      begin
+      {$IFDEF VerbosePas2JS}
+      writeln('TPasToJSConverter.CreateSetLiteralElement ',GetResolverResultDbg(ExprResolved));
+      {$ENDIF}
       RaiseNotSupported(Expr,AContext,20170415191822);
       RaiseNotSupported(Expr,AContext,20170415191822);
+      end;
     end;
     end;
 end;
 end;
 
 

+ 47 - 2
packages/pastojs/tests/tcmodules.pas

@@ -275,6 +275,7 @@ type
     Procedure TestSet_BooleanFail;
     Procedure TestSet_BooleanFail;
     Procedure TestSet_ConstEnum;
     Procedure TestSet_ConstEnum;
     Procedure TestSet_ConstChar;
     Procedure TestSet_ConstChar;
+    Procedure TestSet_ConstInt;
 
 
     // statements
     // statements
     Procedure TestNestBegin;
     Procedure TestNestBegin;
@@ -3025,18 +3026,24 @@ begin
   Add('  e: TMyEnum;');
   Add('  e: TMyEnum;');
   Add('  i: longint;');
   Add('  i: longint;');
   Add('  s: string;');
   Add('  s: string;');
+  Add('  b: boolean;');
   Add('begin');
   Add('begin');
   Add('  i:=ord(red);');
   Add('  i:=ord(red);');
   Add('  i:=ord(green);');
   Add('  i:=ord(green);');
   Add('  i:=ord(e);');
   Add('  i:=ord(e);');
+  Add('  i:=ord(b);');
   Add('  e:=low(tmyenum);');
   Add('  e:=low(tmyenum);');
   Add('  e:=low(e);');
   Add('  e:=low(e);');
+  Add('  b:=low(boolean);');
   Add('  e:=high(tmyenum);');
   Add('  e:=high(tmyenum);');
   Add('  e:=high(e);');
   Add('  e:=high(e);');
+  Add('  b:=high(boolean);');
   Add('  e:=pred(green);');
   Add('  e:=pred(green);');
   Add('  e:=pred(e);');
   Add('  e:=pred(e);');
+  Add('  b:=pred(b);');
   Add('  e:=succ(red);');
   Add('  e:=succ(red);');
   Add('  e:=succ(e);');
   Add('  e:=succ(e);');
+  Add('  b:=succ(b);');
   Add('  e:=tmyenum(1);');
   Add('  e:=tmyenum(1);');
   Add('  e:=tmyenum(i);');
   Add('  e:=tmyenum(i);');
   Add('  s:=str(e);');
   Add('  s:=str(e);');
@@ -3055,20 +3062,26 @@ begin
     '  };',
     '  };',
     'this.e = 0;',
     'this.e = 0;',
     'this.i = 0;',
     'this.i = 0;',
-    'this.s = "";'
-    ]),
+    'this.s = "";',
+    'this.b = false;',
+    '']),
     LinesToStr([
     LinesToStr([
     '$mod.i=$mod.TMyEnum.Red;',
     '$mod.i=$mod.TMyEnum.Red;',
     '$mod.i=$mod.TMyEnum.Green;',
     '$mod.i=$mod.TMyEnum.Green;',
     '$mod.i=$mod.e;',
     '$mod.i=$mod.e;',
+    '$mod.i=$mod.b+0;',
     '$mod.e=$mod.TMyEnum.Red;',
     '$mod.e=$mod.TMyEnum.Red;',
     '$mod.e=$mod.TMyEnum.Red;',
     '$mod.e=$mod.TMyEnum.Red;',
+    '$mod.b=false;',
     '$mod.e=$mod.TMyEnum.Green;',
     '$mod.e=$mod.TMyEnum.Green;',
     '$mod.e=$mod.TMyEnum.Green;',
     '$mod.e=$mod.TMyEnum.Green;',
+    '$mod.b=true;',
     '$mod.e=$mod.TMyEnum.Green-1;',
     '$mod.e=$mod.TMyEnum.Green-1;',
     '$mod.e=$mod.e-1;',
     '$mod.e=$mod.e-1;',
+    '$mod.b=false;',
     '$mod.e=$mod.TMyEnum.Red+1;',
     '$mod.e=$mod.TMyEnum.Red+1;',
     '$mod.e=$mod.e+1;',
     '$mod.e=$mod.e+1;',
+    '$mod.b=true;',
     '$mod.e=1;',
     '$mod.e=1;',
     '$mod.e=$mod.i;',
     '$mod.e=$mod.i;',
     '$mod.s = $mod.TMyEnum[$mod.e];',
     '$mod.s = $mod.TMyEnum[$mod.e];',
@@ -3657,6 +3670,7 @@ begin
   '  if blue in teAny then;',
   '  if blue in teAny then;',
   '  if blue in teAny+[e] then;',
   '  if blue in teAny+[e] then;',
   '  if blue in teAny+teRedBlue then;',
   '  if blue in teAny+teRedBlue then;',
+  '  if e in [red,blue] then;',
   '  s:=teAny;',
   '  s:=teAny;',
   '  s:=teAny+[e];',
   '  s:=teAny+[e];',
   '  s:=[e]+teAny;',
   '  s:=[e]+teAny;',
@@ -3683,6 +3697,7 @@ begin
     'if ($mod.TEnum.blue in $mod.teAny) ;',
     'if ($mod.TEnum.blue in $mod.teAny) ;',
     'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, rtl.createSet($mod.e))) ;',
     'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, rtl.createSet($mod.e))) ;',
     'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, $mod.teRedBlue)) ;',
     'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, $mod.teRedBlue)) ;',
+    'if ($mod.e in rtl.createSet($mod.TEnum.red, $mod.TEnum.blue)) ;',
     '$mod.s = rtl.refSet($mod.teAny);',
     '$mod.s = rtl.refSet($mod.teAny);',
     '$mod.s = rtl.unionSet($mod.teAny, rtl.createSet($mod.e));',
     '$mod.s = rtl.unionSet($mod.teAny, rtl.createSet($mod.e));',
     '$mod.s = rtl.unionSet(rtl.createSet($mod.e), $mod.teAny);',
     '$mod.s = rtl.unionSet(rtl.createSet($mod.e), $mod.teAny);',
@@ -3725,6 +3740,36 @@ begin
     '']));
     '']));
 end;
 end;
 
 
+procedure TTestModule.TestSet_ConstInt;
+begin
+  StartProgram(false);
+  Add([
+  'const',
+  '  Months = [1..12];',
+  '  Mirror = [-12..-1]+Months;',
+  'var',
+  '  i: smallint;',
+  'begin',
+  '  if 3 in Months then;',
+  '  if i in Months+[i] then;',
+  '  if i in Months+Mirror then;',
+  '  if i in [4..6,8] then;',
+  '']);
+  ConvertProgram;
+  CheckSource('TestSet_ConstInt',
+    LinesToStr([ // statements
+    'this.Months = rtl.createSet(null, 1, 12);',
+    'this.Mirror = rtl.unionSet(rtl.createSet(null, -12, -1), $mod.Months);',
+    'this.i = 0;',
+    '']),
+    LinesToStr([
+    'if (3 in $mod.Months) ;',
+    'if ($mod.i in rtl.unionSet($mod.Months, rtl.createSet($mod.i))) ;',
+    'if ($mod.i in rtl.unionSet($mod.Months, $mod.Mirror)) ;',
+    'if ($mod.i in rtl.createSet(null, 4, 6, 8)) ;',
+    '']));
+end;
+
 procedure TTestModule.TestNestBegin;
 procedure TTestModule.TestNestBegin;
 begin
 begin
   StartProgram(false);
   StartProgram(false);