pastojs: ord, pred, succ on boolean

git-svn-id: trunk@37370 -
This commit is contained in:
Mattias Gaertner 2017-10-01 14:47:19 +00:00
parent d7f67d3689
commit c93a5438b2
2 changed files with 91 additions and 41 deletions

View File

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

View File

@ -275,6 +275,7 @@ type
Procedure TestSet_BooleanFail;
Procedure TestSet_ConstEnum;
Procedure TestSet_ConstChar;
Procedure TestSet_ConstInt;
// statements
Procedure TestNestBegin;
@ -3025,18 +3026,24 @@ begin
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);');
@ -3055,20 +3062,26 @@ begin
' };',
'this.e = 0;',
'this.i = 0;',
'this.s = "";'
]),
'this.s = "";',
'this.b = false;',
'']),
LinesToStr([
'$mod.i=$mod.TMyEnum.Red;',
'$mod.i=$mod.TMyEnum.Green;',
'$mod.i=$mod.e;',
'$mod.i=$mod.b+0;',
'$mod.e=$mod.TMyEnum.Red;',
'$mod.e=$mod.TMyEnum.Red;',
'$mod.b=false;',
'$mod.e=$mod.TMyEnum.Green;',
'$mod.e=$mod.TMyEnum.Green;',
'$mod.b=true;',
'$mod.e=$mod.TMyEnum.Green-1;',
'$mod.e=$mod.e-1;',
'$mod.b=false;',
'$mod.e=$mod.TMyEnum.Red+1;',
'$mod.e=$mod.e+1;',
'$mod.b=true;',
'$mod.e=1;',
'$mod.e=$mod.i;',
'$mod.s = $mod.TMyEnum[$mod.e];',
@ -3657,6 +3670,7 @@ begin
' if blue in teAny then;',
' if blue in teAny+[e] then;',
' if blue in teAny+teRedBlue then;',
' if e in [red,blue] then;',
' s:=teAny;',
' s:=teAny+[e];',
' s:=[e]+teAny;',
@ -3683,6 +3697,7 @@ begin
'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, $mod.teRedBlue)) ;',
'if ($mod.e in rtl.createSet($mod.TEnum.red, $mod.TEnum.blue)) ;',
'$mod.s = rtl.refSet($mod.teAny);',
'$mod.s = rtl.unionSet($mod.teAny, rtl.createSet($mod.e));',
'$mod.s = rtl.unionSet(rtl.createSet($mod.e), $mod.teAny);',
@ -3725,6 +3740,36 @@ begin
'']));
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;
begin
StartProgram(false);