|
@@ -260,6 +260,7 @@ Works:
|
|
|
- array[rg], low(array), high(array), length(array)
|
|
|
|
|
|
ToDos:
|
|
|
+- remove hasOwnProperty from rtl set functions
|
|
|
- typecast longint(highprecint) -> (value+0) & $ffffffff
|
|
|
- static arrays
|
|
|
- a[] of record
|
|
@@ -9446,7 +9447,20 @@ begin
|
|
|
Result:=CreateLiteralString(El,TResEvalString(Value).S);
|
|
|
revkUnicodeString:
|
|
|
Result:=CreateLiteralJSString(El,TResEvalUTF16(Value).S);
|
|
|
+ revkSetOfInt:
|
|
|
+ if Value.IdentEl is TPasExpr then
|
|
|
+ Result:=ConvertElement(Value.IdentEl,AContext)
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ {$IFDEF VerbosePas2JS}
|
|
|
+ writeln('TPasToJSConverter.ConvertConstValue Value=',Value.AsDebugString,' IdentEl=',GetObjName(Value.IdentEl));
|
|
|
+ {$ENDIF}
|
|
|
+ RaiseNotSupported(El,AContext,20171221125842);
|
|
|
+ end
|
|
|
else
|
|
|
+ {$IFDEF VerbosePas2JS}
|
|
|
+ writeln('TPasToJSConverter.ConvertConstValue Value=',Value.AsDebugString);
|
|
|
+ {$ENDIF}
|
|
|
RaiseNotSupported(El,AContext,20170910211951);
|
|
|
end;
|
|
|
end;
|
|
@@ -10578,7 +10592,10 @@ type
|
|
|
ikBool,
|
|
|
ikChar,
|
|
|
ikString,
|
|
|
- ikArray
|
|
|
+ ikArray,
|
|
|
+ ikSetInt,
|
|
|
+ ikSetBool,
|
|
|
+ ikSetChar
|
|
|
);
|
|
|
|
|
|
function ConvExpr(Expr: TPasExpr): TJSElement; overload;
|
|
@@ -10649,17 +10666,19 @@ type
|
|
|
end;
|
|
|
|
|
|
var
|
|
|
+ FuncContext: TConvertContext;
|
|
|
ResolvedVar, ResolvedIn: TPasResolverResult;
|
|
|
StartValue, EndValue, InValue: TResEvalValue;
|
|
|
StartInt, EndInt: MaxPrecInt;
|
|
|
HasLoopVar, HasEndVar, HasInVar: Boolean;
|
|
|
InKind: TInKind;
|
|
|
|
|
|
- procedure InitWithResolver;
|
|
|
+ function InitWithResolver: boolean;
|
|
|
var
|
|
|
EnumType: TPasEnumType;
|
|
|
TypeEl: TPasType;
|
|
|
begin
|
|
|
+ Result:=true;
|
|
|
AContext.Resolver.ComputeElement(El.VariableName,ResolvedVar,[rcNoImplicitProc]);
|
|
|
if not (ResolvedVar.IdentEl is TPasVariable) then
|
|
|
DoError(20170213214404,nExpectedXButFoundY,sExpectedXButFoundY,['var',
|
|
@@ -10687,7 +10706,9 @@ var
|
|
|
begin
|
|
|
if length(TPasArrayType(TypeEl).Ranges)=1 then
|
|
|
InValue:=AContext.Resolver.Eval(TPasArrayType(TypeEl).Ranges[0],[refConst]);
|
|
|
- end;
|
|
|
+ end
|
|
|
+ else if TypeEl is TPasSetType then
|
|
|
+ InValue:=AContext.Resolver.EvalTypeRange(TPasSetType(TypeEl).EnumType,[refConst]);
|
|
|
end;
|
|
|
end;
|
|
|
if InValue<>nil then
|
|
@@ -10707,8 +10728,26 @@ var
|
|
|
EndInt:=length(TResEvalUTF16(InValue).S)-1;
|
|
|
ReleaseEvalValue(InValue);
|
|
|
end;
|
|
|
- revkRangeInt:
|
|
|
+ revkRangeInt,revkSetOfInt:
|
|
|
begin
|
|
|
+ if InValue.Kind=revkSetOfInt then
|
|
|
+ begin
|
|
|
+ if length(TResEvalSet(InValue).Ranges)=0 then
|
|
|
+ exit(false);
|
|
|
+ if length(TResEvalSet(InValue).Ranges)>1 then
|
|
|
+ begin
|
|
|
+ // set, non continuous range
|
|
|
+ case TResEvalSet(InValue).ElKind of
|
|
|
+ revskEnum,revskInt: InKind:=ikSetInt;
|
|
|
+ revskChar: InKind:=ikSetChar;
|
|
|
+ revskBool: InKind:=ikSetBool;
|
|
|
+ end;
|
|
|
+ HasInVar:=false;
|
|
|
+ HasLoopVar:=InKind<>ikSetInt;
|
|
|
+ HasEndVar:=false;
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
StartInt:=TResEvalRangeInt(InValue).RangeStart;
|
|
|
EndInt:=TResEvalRangeInt(InValue).RangeEnd;
|
|
|
HasInVar:=false;
|
|
@@ -10724,6 +10763,8 @@ var
|
|
|
StartValue:=GetEnumValue(EnumType,StartInt);
|
|
|
EndValue:=GetEnumValue(EnumType,EndInt);
|
|
|
end;
|
|
|
+ revskInt:
|
|
|
+ InKind:=ikNone;
|
|
|
revskChar:
|
|
|
InKind:=ikChar;
|
|
|
revskBool:
|
|
@@ -10775,6 +10816,26 @@ var
|
|
|
{$ENDIF}
|
|
|
RaiseNotSupported(El.StartExpr,AContext,20171113012226);
|
|
|
end;
|
|
|
+ end
|
|
|
+ else if ResolvedIn.BaseType=btSet then
|
|
|
+ begin
|
|
|
+ if ResolvedIn.SubType in btAllBooleans then
|
|
|
+ InKind:=ikSetBool
|
|
|
+ else if ResolvedIn.SubType in btAllChars then
|
|
|
+ InKind:=ikSetChar
|
|
|
+ else
|
|
|
+ InKind:=ikSetInt;
|
|
|
+ HasInVar:=false;
|
|
|
+ HasLoopVar:=InKind<>ikSetInt;
|
|
|
+ HasEndVar:=false;
|
|
|
+ exit;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ {$IFDEF VerbosePas2JS}
|
|
|
+ writeln('TPasToJSConverter.ConvertForStatement.InitWithResolver ResolvedIn=',GetResolverResultDbg(ResolvedIn));
|
|
|
+ {$ENDIF}
|
|
|
+ RaiseNotSupported(El.StartExpr,AContext,20171220221747);
|
|
|
end;
|
|
|
end
|
|
|
else
|
|
@@ -10818,14 +10879,13 @@ var
|
|
|
end;
|
|
|
|
|
|
Var
|
|
|
- ForSt : TJSForStatement;
|
|
|
+ ForSt : TJSBodyStatement;
|
|
|
List: TJSStatementList;
|
|
|
SimpleAss : TJSSimpleAssignStatement;
|
|
|
Incr: TJSUNaryExpression;
|
|
|
BinExp : TJSBinaryExpression;
|
|
|
VarStat: TJSVariableStatement;
|
|
|
CurLoopVarName, CurEndVarName, CurInVarName: String;
|
|
|
- FuncContext: TConvertContext;
|
|
|
PosEl: TPasElement;
|
|
|
Statements, V: TJSElement;
|
|
|
Call: TJSCallExpression;
|
|
@@ -10863,7 +10923,9 @@ begin
|
|
|
HasEndVar:=true;
|
|
|
HasInVar:=false;
|
|
|
if AContext.Resolver<>nil then
|
|
|
- InitWithResolver;
|
|
|
+ begin
|
|
|
+ if not InitWithResolver then exit;
|
|
|
+ end;
|
|
|
// create unique var names $l, $end, $in
|
|
|
if HasInVar then
|
|
|
CurInVarName:=FuncContext.CreateLocalIdentifier(FBuiltInNames[pbivnLoopIn])
|
|
@@ -10879,8 +10941,12 @@ begin
|
|
|
CurEndVarName:='';
|
|
|
|
|
|
// add "for()"
|
|
|
- ForSt:=TJSForStatement(CreateElement(TJSForStatement,El));
|
|
|
+ if InKind in [ikSetInt,ikSetBool,ikSetChar] then
|
|
|
+ ForSt:=TJSForInStatement(CreateElement(TJSForInStatement,El))
|
|
|
+ else
|
|
|
+ ForSt:=TJSForStatement(CreateElement(TJSForStatement,El));
|
|
|
Statements:=ForSt;
|
|
|
+ PosEl:=El;
|
|
|
|
|
|
// add in front of for(): variable=<startexpr>
|
|
|
if (not HasLoopVar) and (HasEndVar or HasInVar) then
|
|
@@ -10901,16 +10967,31 @@ begin
|
|
|
PosEl:=El.StartExpr;
|
|
|
end;
|
|
|
|
|
|
- if HasLoopVar or HasEndVar or HasInVar then
|
|
|
+ if ForSt.ClassType=TJSForInStatement then
|
|
|
+ begin
|
|
|
+ if HasLoopVar then
|
|
|
+ begin
|
|
|
+ // add for("var $l" in <startexpr>)
|
|
|
+ VarStat:=TJSVariableStatement(CreateElement(TJSVariableStatement,PosEl));
|
|
|
+ VarStat.A:=CreatePrimitiveDotExpr(CurLoopVarName,PosEl);
|
|
|
+ TJSForInStatement(ForSt).LHS:=VarStat;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ // add for("<varname>" in <startexpr>)
|
|
|
+ TJSForInStatement(ForSt).LHS:=ConvertElement(El.VariableName,AContext);
|
|
|
+ // add for(<varname> in "<startexpr>")
|
|
|
+ TJSForInStatement(ForSt).List:=ConvertElement(El.StartExpr,AContext);
|
|
|
+ end
|
|
|
+ else if HasLoopVar or HasEndVar or HasInVar then
|
|
|
begin
|
|
|
// add "for(var ..."
|
|
|
VarStat:=TJSVariableStatement(CreateElement(TJSVariableStatement,El));
|
|
|
- ForSt.Init:=VarStat;
|
|
|
+ TJSForStatement(ForSt).Init:=VarStat;
|
|
|
if HasInVar then
|
|
|
begin
|
|
|
// add "$in=<InExpr>"
|
|
|
PosEl:=El.StartExpr;
|
|
|
- if InValue<>nil then
|
|
|
+ if (InValue<>nil) and (InValue.Kind<>revkSetOfInt) then
|
|
|
V:=ConvertConstValue(InValue,AContext,PosEl)
|
|
|
else
|
|
|
V:=ConvertElement(El.StartExpr,AContext);
|
|
@@ -10973,7 +11054,7 @@ begin
|
|
|
// No new vars. For example:
|
|
|
// for (VariableName = <startexpr>; VariableName <= <EndExpr>; VariableName++)
|
|
|
SimpleAss:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El.VariableName));
|
|
|
- ForSt.Init:=SimpleAss;
|
|
|
+ TJSForStatement(ForSt).Init:=SimpleAss;
|
|
|
SimpleAss.LHS:=ConvertElement(El.VariableName,AContext);
|
|
|
if StartValue<>nil then
|
|
|
SimpleAss.Expr:=CreateLiteralNumber(El.StartExpr,StartInt)
|
|
@@ -10982,33 +11063,36 @@ begin
|
|
|
PosEl:=El.StartExpr;
|
|
|
end;
|
|
|
|
|
|
- // add "$l<=$end"
|
|
|
- if (El.EndExpr<>nil) then
|
|
|
- PosEl:=El.EndExpr;
|
|
|
- if El.Down then
|
|
|
- BinExp:=TJSRelationalExpressionGE(CreateElement(TJSRelationalExpressionGE,PosEl))
|
|
|
- else
|
|
|
- BinExp:=TJSRelationalExpressionLE(CreateElement(TJSRelationalExpressionLE,PosEl));
|
|
|
- ForSt.Cond:=BinExp;
|
|
|
- if HasLoopVar then
|
|
|
- BinExp.A:=CreatePrimitiveDotExpr(CurLoopVarName,PosEl)
|
|
|
- else
|
|
|
- BinExp.A:=ConvertElement(El.VariableName,AContext);
|
|
|
- if HasEndVar then
|
|
|
- BinExp.B:=CreatePrimitiveDotExpr(CurEndVarName,PosEl)
|
|
|
- else
|
|
|
- BinExp.B:=CreateLiteralNumber(PosEl,EndInt);
|
|
|
+ if ForSt.ClassType=TJSForStatement then
|
|
|
+ begin
|
|
|
+ // add "$l<=$end"
|
|
|
+ if (El.EndExpr<>nil) then
|
|
|
+ PosEl:=El.EndExpr;
|
|
|
+ if El.Down then
|
|
|
+ BinExp:=TJSRelationalExpressionGE(CreateElement(TJSRelationalExpressionGE,PosEl))
|
|
|
+ else
|
|
|
+ BinExp:=TJSRelationalExpressionLE(CreateElement(TJSRelationalExpressionLE,PosEl));
|
|
|
+ TJSForStatement(ForSt).Cond:=BinExp;
|
|
|
+ if HasLoopVar then
|
|
|
+ BinExp.A:=CreatePrimitiveDotExpr(CurLoopVarName,PosEl)
|
|
|
+ else
|
|
|
+ BinExp.A:=ConvertElement(El.VariableName,AContext);
|
|
|
+ if HasEndVar then
|
|
|
+ BinExp.B:=CreatePrimitiveDotExpr(CurEndVarName,PosEl)
|
|
|
+ else
|
|
|
+ BinExp.B:=CreateLiteralNumber(PosEl,EndInt);
|
|
|
|
|
|
- // add "$l++"
|
|
|
- if El.Down then
|
|
|
- Incr:=TJSUnaryPostMinusMinusExpression(CreateElement(TJSUnaryPostMinusMinusExpression,PosEl))
|
|
|
- else
|
|
|
- Incr:=TJSUnaryPostPlusPlusExpression(CreateElement(TJSUnaryPostPlusPlusExpression,PosEl));
|
|
|
- ForSt.Incr:=Incr;
|
|
|
- if HasLoopVar then
|
|
|
- Incr.A:=CreatePrimitiveDotExpr(CurLoopVarName,PosEl)
|
|
|
- else
|
|
|
- Incr.A:=ConvertElement(El.VariableName,AContext);
|
|
|
+ // add "$l++"
|
|
|
+ if El.Down then
|
|
|
+ Incr:=TJSUnaryPostMinusMinusExpression(CreateElement(TJSUnaryPostMinusMinusExpression,PosEl))
|
|
|
+ else
|
|
|
+ Incr:=TJSUnaryPostPlusPlusExpression(CreateElement(TJSUnaryPostPlusPlusExpression,PosEl));
|
|
|
+ TJSForStatement(ForSt).Incr:=Incr;
|
|
|
+ if HasLoopVar then
|
|
|
+ Incr.A:=CreatePrimitiveDotExpr(CurLoopVarName,PosEl)
|
|
|
+ else
|
|
|
+ Incr.A:=ConvertElement(El.VariableName,AContext);
|
|
|
+ end;
|
|
|
|
|
|
// add "VariableName:=$l;"
|
|
|
if HasLoopVar then
|
|
@@ -11025,11 +11109,11 @@ begin
|
|
|
begin
|
|
|
if InKind<>ikNone then
|
|
|
case InKind of
|
|
|
- ikEnum: ;
|
|
|
- ikBool:
|
|
|
+ ikEnum,ikSetInt: ;
|
|
|
+ ikBool,ikSetBool:
|
|
|
// $in!==0;
|
|
|
SimpleAss.Expr:=CreateStrictNotEqual0(SimpleAss.Expr,PosEl);
|
|
|
- ikChar:
|
|
|
+ ikChar,ikSetChar:
|
|
|
// String.fromCharCode($l)
|
|
|
SimpleAss.Expr:=CreateCallFromCharCode(SimpleAss.Expr,PosEl);
|
|
|
ikString:
|