|
@@ -36,11 +36,13 @@ resourcestring
|
|
|
SParserExpectedCommaRBracket = 'Expected "," or ")"';
|
|
|
SParserExpectedCommaSemicolon = 'Expected "," or ";"';
|
|
|
SParserExpectedCommaColon = 'Expected "," or ":"';
|
|
|
+ SParserOnlyOneArgumentCanHaveDefault = 'A default value can only be assigned to 1 parameter';
|
|
|
SParserExpectedLBracketColon = 'Expected "(" or ":"';
|
|
|
SParserExpectedLBracketSemicolon = 'Expected "(" or ";"';
|
|
|
SParserExpectedColonSemicolon = 'Expected ":" or ";"';
|
|
|
SParserExpectedSemiColonEnd = 'Expected ";" or "End"';
|
|
|
SParserExpectedConstVarID = 'Expected "const", "var" or identifier';
|
|
|
+ SParserExpectedNested = 'Expected nested keyword';
|
|
|
SParserExpectedColonID = 'Expected ":" or identifier';
|
|
|
SParserSyntaxError = 'Syntax error';
|
|
|
SParserTypeSyntaxError = 'Syntax error in type';
|
|
@@ -54,6 +56,7 @@ resourcestring
|
|
|
|
|
|
SLogStartImplementation = 'Start parsing implementation section.';
|
|
|
SLogStartInterface = 'Start parsing interface section';
|
|
|
+ SParsingUsedUnit = 'Parsing used unit "%s" with commandLine "%s"';
|
|
|
|
|
|
type
|
|
|
TPasParserLogHandler = Procedure (Sender : TObject; Const Msg : String) of object;
|
|
@@ -196,7 +199,8 @@ type
|
|
|
function ParseSpecializeType(Parent: TPasElement; Const TypeName: String): TPasClassType;
|
|
|
Function ParseClassDecl(Parent: TPasElement; const AClassName: String; AObjKind: TPasObjKind; PackMode : TPackMode= pmNone): TPasType;
|
|
|
Function ParseProperty(Parent : TPasElement; Const AName : String; AVisibility : TPasMemberVisibility; IsClass : Boolean) : TPasProperty;
|
|
|
- function ParseRangeType(AParent: TPasElement; Const TypeName: String): TPasRangeType;
|
|
|
+ function ParseRangeType(AParent: TPasElement; Const TypeName: String; Full : Boolean = True): TPasRangeType;
|
|
|
+ procedure ParseExportDecl(Parent: TPasElement; List: TFPList);
|
|
|
// Constant declarations
|
|
|
function ParseConstDecl(Parent: TPasElement): TPasConst;
|
|
|
function ParseResourcestringDecl(Parent: TPasElement): TPasResString;
|
|
@@ -206,7 +210,8 @@ type
|
|
|
// Main scope parsing
|
|
|
procedure ParseMain(var Module: TPasModule);
|
|
|
procedure ParseUnit(var Module: TPasModule);
|
|
|
- procedure ParseProgram(var Module: TPasModule);
|
|
|
+ procedure ParseProgram(var Module: TPasModule; SkipHeader : Boolean = False);
|
|
|
+ procedure ParseLibrary(var Module: TPasModule);
|
|
|
procedure ParseUsesList(ASection: TPasSection);
|
|
|
procedure ParseInterface;
|
|
|
procedure ParseImplementation;
|
|
@@ -249,7 +254,8 @@ const
|
|
|
WhitespaceTokensToIgnore = [tkWhitespace, tkComment, tkLineEnding, tkTab];
|
|
|
|
|
|
type
|
|
|
- TDeclType = (declNone, declConst, declResourcestring, declType, declVar, declThreadvar, declProperty);
|
|
|
+ TDeclType = (declNone, declConst, declResourcestring, declType,
|
|
|
+ declVar, declThreadvar, declProperty, declExports);
|
|
|
|
|
|
Function IsHintToken(T : String; Out AHint : TPasMemberHint) : boolean;
|
|
|
|
|
@@ -348,7 +354,7 @@ var
|
|
|
begin
|
|
|
case s[2] of
|
|
|
'd': // -d define
|
|
|
- Scanner.Defines.Append(UpperCase(Copy(s, 3, Length(s))));
|
|
|
+ Scanner.AddDefine(UpperCase(Copy(s, 3, Length(s))));
|
|
|
'F': // -F
|
|
|
if (length(s)>2) and (s[3] = 'i') then // -Fi include path
|
|
|
FileResolver.AddIncludePath(Copy(s, 4, Length(s)));
|
|
@@ -378,42 +384,42 @@ begin
|
|
|
FileResolver := TFileResolver.Create;
|
|
|
FileResolver.UseStreams:=UseStreams;
|
|
|
Scanner := TPascalScanner.Create(FileResolver);
|
|
|
- Scanner.Defines.Append('FPK');
|
|
|
- Scanner.Defines.Append('FPC');
|
|
|
+ Scanner.AddDefine('FPK');
|
|
|
+ Scanner.AddDefine('FPC');
|
|
|
SCanner.LogEvents:=AEngine.ScannerLogEvents;
|
|
|
SCanner.OnLog:=AEngine.Onlog;
|
|
|
|
|
|
// TargetOS
|
|
|
s := UpperCase(OSTarget);
|
|
|
- Scanner.Defines.Append(s);
|
|
|
+ Scanner.AddDefine(s);
|
|
|
if s = 'LINUX' then
|
|
|
- Scanner.Defines.Append('UNIX')
|
|
|
+ Scanner.AddDefine('UNIX')
|
|
|
else if s = 'FREEBSD' then
|
|
|
begin
|
|
|
- Scanner.Defines.Append('BSD');
|
|
|
- Scanner.Defines.Append('UNIX');
|
|
|
+ Scanner.AddDefine('BSD');
|
|
|
+ Scanner.AddDefine('UNIX');
|
|
|
end else if s = 'NETBSD' then
|
|
|
begin
|
|
|
- Scanner.Defines.Append('BSD');
|
|
|
- Scanner.Defines.Append('UNIX');
|
|
|
+ Scanner.AddDefine('BSD');
|
|
|
+ Scanner.AddDefine('UNIX');
|
|
|
end else if s = 'SUNOS' then
|
|
|
begin
|
|
|
- Scanner.Defines.Append('SOLARIS');
|
|
|
- Scanner.Defines.Append('UNIX');
|
|
|
+ Scanner.AddDefine('SOLARIS');
|
|
|
+ Scanner.AddDefine('UNIX');
|
|
|
end else if s = 'GO32V2' then
|
|
|
- Scanner.Defines.Append('DPMI')
|
|
|
+ Scanner.AddDefine('DPMI')
|
|
|
else if s = 'BEOS' then
|
|
|
- Scanner.Defines.Append('UNIX')
|
|
|
+ Scanner.AddDefine('UNIX')
|
|
|
else if s = 'QNX' then
|
|
|
- Scanner.Defines.Append('UNIX');
|
|
|
+ Scanner.AddDefine('UNIX');
|
|
|
|
|
|
// TargetCPU
|
|
|
s := UpperCase(CPUTarget);
|
|
|
- Scanner.Defines.Append('CPU'+s);
|
|
|
+ Scanner.AddDefine('CPU'+s);
|
|
|
if (s='x86_64') then
|
|
|
- Scanner.Defines.Append('CPU64')
|
|
|
+ Scanner.AddDefine('CPU64')
|
|
|
else
|
|
|
- Scanner.Defines.Append('CPU32');
|
|
|
+ Scanner.AddDefine('CPU32');
|
|
|
|
|
|
Parser := TPasParser.Create(Scanner, FileResolver, AEngine);
|
|
|
Filename := '';
|
|
@@ -656,7 +662,17 @@ begin
|
|
|
NextToken;
|
|
|
Found:=IsCurTokenHint(h);
|
|
|
If Found then
|
|
|
- Include(Result,h)
|
|
|
+ begin
|
|
|
+ Include(Result,h);
|
|
|
+ if (h=hDeprecated) then
|
|
|
+ begin
|
|
|
+ NextToken;
|
|
|
+ if (Curtoken<>tkString) then
|
|
|
+ UnGetToken
|
|
|
+ else
|
|
|
+ Element.HintMessage:=CurTokenString;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
Until Not Found;
|
|
|
UnGetToken;
|
|
|
If Assigned(Element) then
|
|
@@ -783,7 +799,7 @@ begin
|
|
|
stkRange:
|
|
|
begin
|
|
|
UnGetToken;
|
|
|
- Result:=ParseRangeType(Parent,TypeName);
|
|
|
+ Result:=ParseRangeType(Parent,TypeName,False);
|
|
|
end;
|
|
|
stkAlias:
|
|
|
begin
|
|
@@ -920,7 +936,7 @@ begin
|
|
|
tkRecord: Result := ParseRecordDecl(Parent,TypeName,PM);
|
|
|
else
|
|
|
UngetToken;
|
|
|
- Result:=ParseRangeType(Parent,TypeName);
|
|
|
+ Result:=ParseRangeType(Parent,TypeName,Full);
|
|
|
end;
|
|
|
if CH then
|
|
|
CheckHint(Result,True);
|
|
@@ -1120,21 +1136,29 @@ begin
|
|
|
NextToken;
|
|
|
if (length(CurTokenText)>0) and (CurTokenText[1] in ['A'..'_']) then begin
|
|
|
b:=TBinaryExpr.Create(AParent,x, DoParseExpression(AParent), eopNone);
|
|
|
- if not Assigned(b.right) then Exit; // error
|
|
|
+ if not Assigned(b.right) then
|
|
|
+ begin
|
|
|
+ B.Free;
|
|
|
+ Exit; // error
|
|
|
+ end;
|
|
|
x:=b;
|
|
|
UngetToken;
|
|
|
end
|
|
|
else UngetToken;
|
|
|
end;
|
|
|
tkself: begin
|
|
|
- x:=TPrimitiveExpr.Create(AParent,pekString, CurTokenText); //function(self);
|
|
|
+ //x:=TPrimitiveExpr.Create(AParent,pekString, CurTokenText); //function(self);
|
|
|
x:=TSelfExpr.Create(AParent);
|
|
|
NextToken;
|
|
|
if CurToken = tkDot then begin // self.Write(EscapeText(AText));
|
|
|
optk:=CurToken;
|
|
|
NextToken;
|
|
|
b:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(optk));
|
|
|
- if not Assigned(b.right) then Exit; // error
|
|
|
+ if not Assigned(b.right) then
|
|
|
+ begin
|
|
|
+ B.Free;
|
|
|
+ Exit; // error
|
|
|
+ end;
|
|
|
x:=b;
|
|
|
end
|
|
|
else UngetToken;
|
|
@@ -1190,7 +1214,11 @@ begin
|
|
|
optk:=CurToken;
|
|
|
NextToken;
|
|
|
b:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(optk));
|
|
|
- if not Assigned(b.right) then Exit; // error
|
|
|
+ if not Assigned(b.right) then
|
|
|
+ begin
|
|
|
+ b.free;
|
|
|
+ Exit; // error
|
|
|
+ end;
|
|
|
x:=b;
|
|
|
end;
|
|
|
end;
|
|
@@ -1198,7 +1226,11 @@ begin
|
|
|
if CurToken = tkDotDot then begin
|
|
|
NextToken;
|
|
|
b:=TBinaryExpr.CreateRange(AParent,x, DoParseExpression(AParent));
|
|
|
- if not Assigned(b.right) then Exit; // error
|
|
|
+ if not Assigned(b.right) then
|
|
|
+ begin
|
|
|
+ b.free;
|
|
|
+ Exit; // error
|
|
|
+ end;
|
|
|
x:=b;
|
|
|
end;
|
|
|
|
|
@@ -1236,7 +1268,7 @@ var
|
|
|
|
|
|
const
|
|
|
PrefixSym = [tkPlus, tkMinus, tknot, tkAt]; // + - not @
|
|
|
- BinaryOP = [tkMul, tkDivision, tkdiv, tkmod,
|
|
|
+ BinaryOP = [tkMul, tkDivision, tkdiv, tkmod, tkDotDot,
|
|
|
tkand, tkShl,tkShr, tkas, tkPower,
|
|
|
tkPlus, tkMinus, tkor, tkxor, tkSymmetricalDifference,
|
|
|
tkEqual, tkNotEqual, tkLessThan, tkLessEqualThan,
|
|
@@ -1288,7 +1320,6 @@ begin
|
|
|
repeat
|
|
|
NotBinary:=True;
|
|
|
pcount:=0;
|
|
|
-
|
|
|
if not Assigned(InitExpr) then
|
|
|
begin
|
|
|
// the first part of the expression has been parsed externally.
|
|
@@ -1313,7 +1344,11 @@ begin
|
|
|
if CurToken = tkBraceOpen then begin
|
|
|
NextToken;
|
|
|
x:=DoParseExpression(AParent);
|
|
|
- if CurToken<>tkBraceClose then Exit;
|
|
|
+ if CurToken<>tkBraceClose then
|
|
|
+ begin
|
|
|
+ x.free;
|
|
|
+ Exit;
|
|
|
+ end;
|
|
|
NextToken;
|
|
|
|
|
|
// for the expression like (TObject(m)).Free;
|
|
@@ -1328,9 +1363,17 @@ begin
|
|
|
|
|
|
if not Assigned(x) then Exit;
|
|
|
expstack.Add(x);
|
|
|
+
|
|
|
for i:=1 to pcount do begin
|
|
|
tempop:=PopOper;
|
|
|
- expstack.Add( TUnaryExpr.Create(AParent, PopExp, TokenToExprOp(tempop) ));
|
|
|
+ x:=popexp;
|
|
|
+ if (tempop=tkMinus) and (X.Kind=pekRange) then
|
|
|
+ begin
|
|
|
+ TBinaryExpr(x).Left:=TUnaryExpr.Create(x, TBinaryExpr(X).left, eopSubtract);
|
|
|
+ expstack.Add(x);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ expstack.Add( TUnaryExpr.Create(AParent, PopExp, TokenToExprOp(tempop) ));
|
|
|
end;
|
|
|
|
|
|
end else
|
|
@@ -1338,7 +1381,6 @@ begin
|
|
|
expstack.Add(InitExpr);
|
|
|
InitExpr:=nil;
|
|
|
end;
|
|
|
-
|
|
|
if (CurToken in BinaryOP) then begin
|
|
|
// Adjusting order of the operations
|
|
|
NotBinary:=False;
|
|
@@ -1591,10 +1633,16 @@ begin
|
|
|
Module:=nil;
|
|
|
NextToken;
|
|
|
case CurToken of
|
|
|
- tkUnit: ParseUnit(Module);
|
|
|
- tkProgram: ParseProgram(Module);
|
|
|
- else
|
|
|
- ParseExc(Format(SParserExpectTokenError, ['unit']));
|
|
|
+ tkUnit:
|
|
|
+ ParseUnit(Module);
|
|
|
+ tkProgram:
|
|
|
+ ParseProgram(Module);
|
|
|
+ tkLibrary:
|
|
|
+ ParseLibrary(Module);
|
|
|
+ else
|
|
|
+ ungettoken;
|
|
|
+ ParseProgram(Module,True);
|
|
|
+ // ParseExc(Format(SParserExpectTokenError, ['unit']));
|
|
|
end;
|
|
|
end;
|
|
|
|
|
@@ -1623,11 +1671,62 @@ begin
|
|
|
end;
|
|
|
|
|
|
// Starts after the "program" token
|
|
|
-procedure TPasParser.ParseProgram(var Module: TPasModule);
|
|
|
+procedure TPasParser.ParseProgram(var Module: TPasModule; SkipHeader : Boolean = False);
|
|
|
+
|
|
|
+Var
|
|
|
+ PP : TPasProgram;
|
|
|
+ Section : TProgramSection;
|
|
|
+ N : String;
|
|
|
+
|
|
|
begin
|
|
|
+ if SkipHeader then
|
|
|
+ N:=ChangeFileExt(Scanner.CurFilename,'')
|
|
|
+ else
|
|
|
+ N:=ExpectIdentifier;
|
|
|
Module := nil;
|
|
|
- Module := TPasModule(CreateElement(TPasProgram, ExpectIdentifier,
|
|
|
- Engine.Package));
|
|
|
+ PP:=TPasProgram(CreateElement(TPasProgram, N, Engine.Package));
|
|
|
+ Module :=PP;
|
|
|
+ FCurModule:=Module;
|
|
|
+ try
|
|
|
+ if Assigned(Engine.Package) then
|
|
|
+ begin
|
|
|
+ Module.PackageName := Engine.Package.Name;
|
|
|
+ Engine.Package.Modules.Add(Module);
|
|
|
+ end;
|
|
|
+ if not SkipHeader then
|
|
|
+ begin
|
|
|
+ NextToken;
|
|
|
+ If (CurToken=tkBraceOpen) then
|
|
|
+ begin
|
|
|
+ PP.InputFile:=ExpectIdentifier;
|
|
|
+ NextToken;
|
|
|
+ if Not (CurToken in [tkBraceClose,tkComma]) then
|
|
|
+ ParseExc(SParserExpectedCommaRBracket);
|
|
|
+ If (CurToken=tkComma) then
|
|
|
+ PP.OutPutFile:=ExpectIdentifier;
|
|
|
+ ExpectToken(tkBraceClose);
|
|
|
+ NextToken;
|
|
|
+ end;
|
|
|
+ if (CurToken<>tkSemicolon) then
|
|
|
+ ParseExc(Format(SParserExpectTokenError,[';']));
|
|
|
+ end;
|
|
|
+ Section := TProgramSection(CreateElement(TProgramSection, '', CurModule));
|
|
|
+ PP.ProgramSection := Section;
|
|
|
+ ParseDeclarations(Section);
|
|
|
+ finally
|
|
|
+ FCurModule:=nil;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TPasParser.ParseLibrary(var Module: TPasModule);
|
|
|
+Var
|
|
|
+ PP : TPasLibrary;
|
|
|
+ Section : TLibrarySection;
|
|
|
+
|
|
|
+begin
|
|
|
+ Module := nil;
|
|
|
+ PP:=TPasLibrary(CreateElement(TPasLibrary, ExpectIdentifier, Engine.Package));
|
|
|
+ Module :=PP;
|
|
|
FCurModule:=Module;
|
|
|
try
|
|
|
if Assigned(Engine.Package) then
|
|
@@ -1636,7 +1735,11 @@ begin
|
|
|
Engine.Package.Modules.Add(Module);
|
|
|
end;
|
|
|
NextToken;
|
|
|
- ParseImplementation;
|
|
|
+ if (CurToken<>tkSemicolon) then
|
|
|
+ ParseExc(Format(SParserExpectTokenError,[';']));
|
|
|
+ Section := TLibrarySection(CreateElement(TLibrarySection, '', CurModule));
|
|
|
+ PP.LibrarySection := Section;
|
|
|
+ ParseDeclarations(Section);
|
|
|
finally
|
|
|
FCurModule:=nil;
|
|
|
end;
|
|
@@ -1751,6 +1854,7 @@ var
|
|
|
List: TFPList;
|
|
|
i,j: Integer;
|
|
|
VarEl: TPasVariable;
|
|
|
+ ExpEl: TPasExportSymbol;
|
|
|
PropEl : TPasProperty;
|
|
|
TypeName: String;
|
|
|
PT : TProcType;
|
|
@@ -1764,11 +1868,13 @@ begin
|
|
|
case CurToken of
|
|
|
tkend:
|
|
|
begin
|
|
|
+ If (CurModule is TPasProgram) and (CurModule.InitializationSection=Nil) then
|
|
|
+ ParseExc(Format(SParserExpectTokenError,['begin']));
|
|
|
ExpectToken(tkDot);
|
|
|
break;
|
|
|
end;
|
|
|
tkimplementation:
|
|
|
- if (CurToken = tkImplementation) and (Declarations is TInterfaceSection) then
|
|
|
+ if (Declarations is TInterfaceSection) then
|
|
|
begin
|
|
|
If Not Engine.InterfaceOnly then
|
|
|
begin
|
|
@@ -1780,14 +1886,14 @@ begin
|
|
|
end;
|
|
|
tkinitialization:
|
|
|
if (Declarations is TInterfaceSection)
|
|
|
- or (Declarations is TImplementationSection) then
|
|
|
+ or ((Declarations is TImplementationSection) and not (Declarations is TProgramSection)) then
|
|
|
begin
|
|
|
ParseInitialization;
|
|
|
break;
|
|
|
end;
|
|
|
tkfinalization:
|
|
|
if (Declarations is TInterfaceSection)
|
|
|
- or (Declarations is TImplementationSection) then
|
|
|
+ or ((Declarations is TImplementationSection) and not (Declarations is TProgramSection)) then
|
|
|
begin
|
|
|
ParseFinalization;
|
|
|
break;
|
|
@@ -1799,6 +1905,8 @@ begin
|
|
|
ParseExc(SParserSyntaxError);
|
|
|
tkConst:
|
|
|
CurBlock := declConst;
|
|
|
+ tkexports:
|
|
|
+ CurBlock := declExports;
|
|
|
tkResourcestring:
|
|
|
CurBlock := declResourcestring;
|
|
|
tkType:
|
|
@@ -1874,6 +1982,27 @@ begin
|
|
|
Declarations.Types.Add(TypeEl);
|
|
|
end;
|
|
|
end;
|
|
|
+ declExports:
|
|
|
+ begin
|
|
|
+ List := TFPList.Create;
|
|
|
+ try
|
|
|
+ try
|
|
|
+ ParseExportDecl(Declarations, List);
|
|
|
+ except
|
|
|
+ for i := 0 to List.Count - 1 do
|
|
|
+ TPasExportSymbol(List[i]).Release;
|
|
|
+ raise;
|
|
|
+ end;
|
|
|
+ for i := 0 to List.Count - 1 do
|
|
|
+ begin
|
|
|
+ ExpEl := TPasExportSymbol(List[i]);
|
|
|
+ Declarations.Declarations.Add(ExpEl);
|
|
|
+ Declarations.ExportSymbols.Add(ExpEl);
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ List.Free;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
declVar, declThreadVar:
|
|
|
begin
|
|
|
List := TFPList.Create;
|
|
@@ -1955,43 +2084,40 @@ end;
|
|
|
// Starts after the "uses" token
|
|
|
procedure TPasParser.ParseUsesList(ASection: TPasSection);
|
|
|
|
|
|
-function CheckUnit(AUnitName : string):TPasElement;
|
|
|
-begin
|
|
|
+ function CheckUnit(AUnitName : string):TPasElement;
|
|
|
+ begin
|
|
|
result := Engine.FindModule(AUnitName); // should we resolve module here when "IN" filename is not known yet?
|
|
|
if Assigned(result) then
|
|
|
result.AddRef
|
|
|
else
|
|
|
- Result := TPasType(CreateElement(TPasUnresolvedTypeRef, AUnitName,
|
|
|
+ Result := TPasType(CreateElement(TPasUnresolvedUnitRef, AUnitName,
|
|
|
ASection));
|
|
|
ASection.UsesList.Add(Result);
|
|
|
-end;
|
|
|
+ end;
|
|
|
|
|
|
var
|
|
|
AUnitName: String;
|
|
|
Element: TPasElement;
|
|
|
begin
|
|
|
- If not (Asection is TImplementationSection) Then // interface,program,library,package
|
|
|
+ If not (Asection.ClassType=TImplementationSection) Then // interface,program,library,package
|
|
|
Element:=CheckUnit('System'); // system always implicitely first.
|
|
|
- while True do
|
|
|
- begin
|
|
|
+ Repeat
|
|
|
AUnitName := ExpectIdentifier;
|
|
|
Element :=CheckUnit(AUnitName);
|
|
|
-
|
|
|
NextToken;
|
|
|
+ if (CurToken=tkin) then
|
|
|
+ begin
|
|
|
+ ExpectToken(tkString);
|
|
|
+ if (Element is TPasModule) and (TPasmodule(Element).filename='') then
|
|
|
+ TPasModule(Element).FileName:=curtokenstring
|
|
|
+ else if (Element is TPasUnresolvedUnitRef) then
|
|
|
+ TPasUnresolvedUnitRef(Element).FileName:=curtokenstring;
|
|
|
+ NextToken;
|
|
|
+ end;
|
|
|
|
|
|
- if CurToken = tkin then begin
|
|
|
- // todo: store unit's file name somewhere
|
|
|
- NextToken; // skip in
|
|
|
- ExpectToken(tkString); // skip unit's real file name
|
|
|
- if (Element is TPasModule) and (TPasmodule(Element).filename<>'') then
|
|
|
- TPasModule(Element).FileName:=curtokenstring;
|
|
|
- end;
|
|
|
-
|
|
|
- if CurToken = tkSemicolon then
|
|
|
- break
|
|
|
- else if CurToken <> tkComma then
|
|
|
+ if Not (CurToken in [tkComma,tkSemicolon]) then
|
|
|
ParseExc(SParserExpectedCommaSemicolon);
|
|
|
- end;
|
|
|
+ Until (CurToken=tkSemicolon);
|
|
|
end;
|
|
|
|
|
|
// Starts after the variable name
|
|
@@ -2058,7 +2184,7 @@ begin
|
|
|
end;
|
|
|
|
|
|
// Starts after the type name
|
|
|
-Function TPasParser.ParseRangeType(AParent : TPasElement; Const TypeName : String) : TPasRangeType;
|
|
|
+Function TPasParser.ParseRangeType(AParent : TPasElement; Const TypeName : String; Full : Boolean = True) : TPasRangeType;
|
|
|
|
|
|
Var
|
|
|
PE : TPasExpr;
|
|
@@ -2066,8 +2192,11 @@ Var
|
|
|
begin
|
|
|
Result := TPasRangeType(CreateElement(TPasRangeType, TypeName, AParent));
|
|
|
try
|
|
|
- If not (CurToken=tkEqual) then
|
|
|
- ParseExc(Format(SParserExpectTokenError,[TokenInfos[tkEqual]]));
|
|
|
+ if Full then
|
|
|
+ begin
|
|
|
+ If not (CurToken=tkEqual) then
|
|
|
+ ParseExc(Format(SParserExpectTokenError,[TokenInfos[tkEqual]]));
|
|
|
+ end;
|
|
|
NextToken;
|
|
|
PE:=DoParseExpression(Result,Nil);
|
|
|
if not ((PE is TBinaryExpr) and (TBinaryExpr(PE).Kind=pekRange)) then
|
|
@@ -2083,6 +2212,30 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+// Starts after Exports, on first identifier.
|
|
|
+procedure TPasParser.ParseExportDecl(Parent: TPasElement; List: TFPList);
|
|
|
+Var
|
|
|
+ E : TPasExportSymbol;
|
|
|
+begin
|
|
|
+ Repeat
|
|
|
+ E:=TPasExportSymbol(CreateElement(TPasExportSymbol,CurtokenString,Parent));
|
|
|
+ List.Add(E);
|
|
|
+ NextToken;
|
|
|
+ if CurTokenIsIdentifier('INDEX') then
|
|
|
+ begin
|
|
|
+ NextToken;
|
|
|
+ E.Exportindex:=DoParseExpression(E,Nil)
|
|
|
+ end
|
|
|
+ else if CurTokenIsIdentifier('NAME') then
|
|
|
+ begin
|
|
|
+ NextToken;
|
|
|
+ E.ExportName:=DoParseExpression(E,Nil)
|
|
|
+ end;
|
|
|
+ if not (CurToken in [tkComma,tkSemicolon]) then
|
|
|
+ ParseExc(SParserExpectedCommaSemicolon);
|
|
|
+ until (CurToken=tkSemicolon);
|
|
|
+end;
|
|
|
+
|
|
|
Function TPasParser.ParseSpecializeType(Parent : TPasElement; Const TypeName : String) : TPasClassType;
|
|
|
|
|
|
begin
|
|
@@ -2294,79 +2447,101 @@ procedure TPasParser.ParseArgList(Parent: TPasElement; Args: TFPList; EndToken:
|
|
|
var
|
|
|
ArgNames: TStringList;
|
|
|
IsUntyped: Boolean;
|
|
|
- Name, Value: String;
|
|
|
+ Name : String;
|
|
|
+ Value : TPasExpr;
|
|
|
i: Integer;
|
|
|
Arg: TPasArgument;
|
|
|
Access: TArgumentAccess;
|
|
|
ArgType: TPasType;
|
|
|
begin
|
|
|
- while True do
|
|
|
- begin
|
|
|
- ArgNames := TStringList.Create;
|
|
|
- Access := argDefault;
|
|
|
- IsUntyped := False;
|
|
|
- ArgType := nil;
|
|
|
+ ArgNames := TStringList.Create;
|
|
|
+ try
|
|
|
while True do
|
|
|
begin
|
|
|
- NextToken;
|
|
|
- if CurToken = tkConst then
|
|
|
+ ArgNames.Clear;
|
|
|
+ Access := argDefault;
|
|
|
+ IsUntyped := False;
|
|
|
+ ArgType := nil;
|
|
|
+ while True do
|
|
|
begin
|
|
|
- Access := argConst;
|
|
|
- Name := ExpectIdentifier;
|
|
|
- end else if CurToken = tkVar then
|
|
|
- begin
|
|
|
- Access := ArgVar;
|
|
|
- Name := ExpectIdentifier;
|
|
|
- end else if (CurToken = tkIdentifier) and (UpperCase(CurTokenString) = 'OUT') then
|
|
|
- begin
|
|
|
- Access := ArgOut;
|
|
|
- Name := ExpectIdentifier;
|
|
|
- end else if CurToken = tkIdentifier then
|
|
|
- Name := CurTokenString
|
|
|
- else
|
|
|
- ParseExc(SParserExpectedConstVarID);
|
|
|
- ArgNames.Add(Name);
|
|
|
- NextToken;
|
|
|
- if CurToken = tkColon then
|
|
|
- break
|
|
|
- else if ((CurToken = tkSemicolon) or (CurToken = tkBraceClose)) and
|
|
|
- (Access <> argDefault) then
|
|
|
- begin
|
|
|
- // found an untyped const or var argument
|
|
|
- UngetToken;
|
|
|
- IsUntyped := True;
|
|
|
- break
|
|
|
- end
|
|
|
- else if CurToken <> tkComma then
|
|
|
- ParseExc(SParserExpectedCommaColon);
|
|
|
- end;
|
|
|
- SetLength(Value, 0);
|
|
|
- if not IsUntyped then
|
|
|
- begin
|
|
|
- ArgType := ParseType(nil);
|
|
|
- NextToken;
|
|
|
- if CurToken = tkEqual then
|
|
|
+ NextToken;
|
|
|
+ if CurToken = tkConst then
|
|
|
+ begin
|
|
|
+ Access := argConst;
|
|
|
+ Name := ExpectIdentifier;
|
|
|
+ end else if CurToken = tkConstRef then
|
|
|
+ begin
|
|
|
+ Access := argConstref;
|
|
|
+ Name := ExpectIdentifier;
|
|
|
+ end else if CurToken = tkVar then
|
|
|
+ begin
|
|
|
+ Access := ArgVar;
|
|
|
+ Name := ExpectIdentifier;
|
|
|
+ end else if (CurToken = tkIdentifier) and (UpperCase(CurTokenString) = 'OUT') then
|
|
|
+ begin
|
|
|
+ Access := ArgOut;
|
|
|
+ Name := ExpectIdentifier;
|
|
|
+ end else if CurToken = tkIdentifier then
|
|
|
+ Name := CurTokenString
|
|
|
+ else
|
|
|
+ ParseExc(SParserExpectedConstVarID);
|
|
|
+ ArgNames.Add(Name);
|
|
|
+ NextToken;
|
|
|
+ if CurToken = tkColon then
|
|
|
+ break
|
|
|
+ else if ((CurToken = tkSemicolon) or (CurToken = tkBraceClose)) and
|
|
|
+ (Access <> argDefault) then
|
|
|
+ begin
|
|
|
+ // found an untyped const or var argument
|
|
|
+ UngetToken;
|
|
|
+ IsUntyped := True;
|
|
|
+ break
|
|
|
+ end
|
|
|
+ else if CurToken <> tkComma then
|
|
|
+ ParseExc(SParserExpectedCommaColon);
|
|
|
+ end;
|
|
|
+ Value:=Nil;
|
|
|
+ if not IsUntyped then
|
|
|
+ begin
|
|
|
+ ArgType := ParseType(nil);
|
|
|
+ try
|
|
|
+ NextToken;
|
|
|
+ if CurToken = tkEqual then
|
|
|
+ begin
|
|
|
+ if (ArgNames.Count>1) then
|
|
|
+ begin
|
|
|
+ FreeAndNil(ArgType);
|
|
|
+ ParseExc(SParserOnlyOneArgumentCanHaveDefault);
|
|
|
+ end;
|
|
|
+ NextToken;
|
|
|
+ Value := DoParseExpression(Parent,Nil);
|
|
|
+ // After this, we're on ), which must be unget.
|
|
|
+ end;
|
|
|
+ UngetToken;
|
|
|
+ except
|
|
|
+ FreeAndNil(ArgType);
|
|
|
+ Raise;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ for i := 0 to ArgNames.Count - 1 do
|
|
|
begin
|
|
|
- Value := ParseExpression(Parent);
|
|
|
- end else
|
|
|
- UngetToken;
|
|
|
- end;
|
|
|
+ Arg := TPasArgument(CreateElement(TPasArgument, ArgNames[i], Parent));
|
|
|
+ Arg.Access := Access;
|
|
|
+ Arg.ArgType := ArgType;
|
|
|
+ if (i > 0) and Assigned(ArgType) then
|
|
|
+ ArgType.AddRef;
|
|
|
+ Arg.ValueExpr := Value;
|
|
|
+ Value:=Nil; // Only the first gets a value. OK, since Var A,B : Integer = 1 is not allowed.
|
|
|
+ Args.Add(Arg);
|
|
|
+ end;
|
|
|
|
|
|
- for i := 0 to ArgNames.Count - 1 do
|
|
|
- begin
|
|
|
- Arg := TPasArgument(CreateElement(TPasArgument, ArgNames[i], Parent));
|
|
|
- Arg.Access := Access;
|
|
|
- Arg.ArgType := ArgType;
|
|
|
- if (i > 0) and Assigned(ArgType) then
|
|
|
- ArgType.AddRef;
|
|
|
- Arg.Value := Value;
|
|
|
- Args.Add(Arg);
|
|
|
+ NextToken;
|
|
|
+ if CurToken = EndToken then
|
|
|
+ break;
|
|
|
end;
|
|
|
-
|
|
|
+ finally
|
|
|
ArgNames.Free;
|
|
|
- NextToken;
|
|
|
- if CurToken = EndToken then
|
|
|
- break;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
@@ -2429,7 +2604,7 @@ begin
|
|
|
begin
|
|
|
NextToken;
|
|
|
if (CurToken = tkSemicolon) or IsCurtokenHint
|
|
|
- or (OfObjectPossible and (CurToken in [tkOf,tkEqual]))
|
|
|
+ or (OfObjectPossible and (CurToken in [tkOf,tkis,tkEqual]))
|
|
|
then
|
|
|
UngetToken
|
|
|
else
|
|
@@ -2454,15 +2629,25 @@ begin
|
|
|
ParseType(nil);
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
- NextToken;
|
|
|
- if OfObjectPossible and (CurToken = tkOf) then
|
|
|
- begin
|
|
|
- ExpectToken(tkObject);
|
|
|
- Element.IsOfObject := True;
|
|
|
- end else
|
|
|
- UngetToken;
|
|
|
-
|
|
|
+
|
|
|
+ if OfObjectPossible then
|
|
|
+ begin
|
|
|
+ NextToken;
|
|
|
+ if (curToken =tkOf) then
|
|
|
+ begin
|
|
|
+ ExpectToken(tkObject);
|
|
|
+ Element.IsOfObject := True;
|
|
|
+ end
|
|
|
+ else if (curToken = tkIs) then
|
|
|
+ begin
|
|
|
+ expectToken(tkIdentifier);
|
|
|
+ if (lowerCase(CurTokenString)<>'nested') then
|
|
|
+ ParseExc(SParserExpectedNested);
|
|
|
+ Element.isNested:=True;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ UnGetToken;
|
|
|
+ end;
|
|
|
NextToken;
|
|
|
if CurToken = tkEqual then
|
|
|
begin
|
|
@@ -2538,6 +2723,14 @@ begin
|
|
|
if IsCurTokenHint(ahint) then // deprecated,platform,experimental,library, unimplemented etc
|
|
|
begin
|
|
|
element.hints:=element.hints+[ahint];
|
|
|
+ if aHint=hDeprecated then
|
|
|
+ begin
|
|
|
+ nextToken;
|
|
|
+ if (CurToken<>tkString) then
|
|
|
+ UnGetToken
|
|
|
+ else
|
|
|
+ element.HintMessage:=curtokenstring;
|
|
|
+ end;
|
|
|
consumesemi;
|
|
|
end
|
|
|
else if (tok = 'PUBLIC') then
|
|
@@ -2806,6 +2999,7 @@ var
|
|
|
|
|
|
procedure CreateBlock(NewBlock: TPasImplBlock);
|
|
|
begin
|
|
|
+ CurBlock.AddElement(NewBlock);
|
|
|
CurBlock:=NewBlock;
|
|
|
if NewImplElement=nil then NewImplElement:=CurBlock;
|
|
|
end;
|
|
@@ -2822,6 +3016,8 @@ var
|
|
|
ForDownTo: Boolean;
|
|
|
left: TPasExpr;
|
|
|
right: TPasExpr;
|
|
|
+ el : TPasImplElement;
|
|
|
+
|
|
|
begin
|
|
|
NewImplElement:=nil;
|
|
|
CurBlock := Parent;
|
|
@@ -2831,14 +3027,22 @@ begin
|
|
|
//WriteLn(i,'Token=',CurTokenText);
|
|
|
case CurToken of
|
|
|
tkbegin:
|
|
|
- CreateBlock(CurBlock.AddBeginBlock);
|
|
|
+ begin
|
|
|
+ el:=TPasImplElement(CreateElement(TPasImplBeginBlock,'',CurBlock));
|
|
|
+ CreateBlock(TPasImplBeginBlock(el));
|
|
|
+ end;
|
|
|
tkrepeat:
|
|
|
- CreateBlock(CurBlock.AddRepeatUntil);
|
|
|
+ begin
|
|
|
+ el:=TPasImplRepeatUntil(CreateElement(TPasImplRepeatUntil,'',CurBlock));
|
|
|
+ CreateBlock(TPasImplRepeatUntil(el));
|
|
|
+ end;
|
|
|
tkIf:
|
|
|
begin
|
|
|
- Condition:=ParseExpression(Parent);
|
|
|
+ Condition:=ParseExpression(CurBlock);
|
|
|
+ el:=TPasImplIfElse(CreateElement(TPasImplIfElse,'',CurBlock));
|
|
|
+ TPasImplIfElse(el).Condition:=Condition;
|
|
|
//WriteLn(i,'IF Condition="',Condition,'" Token=',CurTokenText);
|
|
|
- CreateBlock(CurBlock.AddIfElse(Condition));
|
|
|
+ CreateBlock(TPasImplIfElse(el));
|
|
|
ExpectToken(tkthen);
|
|
|
end;
|
|
|
tkelse:
|
|
@@ -2846,8 +3050,8 @@ begin
|
|
|
begin
|
|
|
if TPasImplIfElse(CurBlock).IfBranch=nil then
|
|
|
begin
|
|
|
- // empty then => add dummy command
|
|
|
- CurBlock.AddCommand('');
|
|
|
+ el:=TPasImplCommand(CreateElement(TPasImplCommand,'', CurBlock));
|
|
|
+ CurBlock.AddElement(el);
|
|
|
end;
|
|
|
if TPasImplIfElse(CurBlock).ElseBranch<>nil then
|
|
|
begin
|
|
@@ -2873,7 +3077,9 @@ begin
|
|
|
end else if (CurBlock is TPasImplTryExcept) then
|
|
|
begin
|
|
|
CloseBlock;
|
|
|
- CurBlock:=TPasImplTry(CurBlock).AddExceptElse;
|
|
|
+ el:=TPasImplTryExceptElse(CreateElement(TPasImplTryExceptElse,'',CurBlock));
|
|
|
+ TPasImplTry(CurBlock).ElseBranch:=TPasImplTryExceptElse(el);
|
|
|
+ CurBlock:=TPasImplTryExceptElse(el);
|
|
|
end else
|
|
|
ParseExc(SParserSyntaxError);
|
|
|
tkwhile:
|
|
@@ -2881,7 +3087,9 @@ begin
|
|
|
// while Condition do
|
|
|
Condition:=ParseExpression(Parent);
|
|
|
//WriteLn(i,'WHILE Condition="',Condition,'" Token=',CurTokenText);
|
|
|
- CreateBlock(CurBlock.AddWhileDo(Condition));
|
|
|
+ el:=TPasImplWhileDo(CreateElement(TPasImplWhileDo,'',CurBlock));
|
|
|
+ TPasImplWhileDo(el).Condition:=Condition;
|
|
|
+ CreateBlock(TPasImplWhileDo(el));
|
|
|
ExpectToken(tkdo);
|
|
|
end;
|
|
|
tkgoto:
|
|
@@ -2906,7 +3114,12 @@ begin
|
|
|
else
|
|
|
ParseExc(Format(SParserExpectTokenError, [TokenInfos[tkTo]]));
|
|
|
EndValue:=ParseExpression(Parent);
|
|
|
- CreateBlock(CurBlock.AddForLoop(VarName,StartValue,EndValue,ForDownTo));
|
|
|
+ el:=TPasImplForLoop(CreateElement(TPasImplForLoop,'',CurBlock));
|
|
|
+ TPasImplForLoop(el).VariableName:=VarName;
|
|
|
+ TPasImplForLoop(el).StartValue:=StartValue;
|
|
|
+ TPasImplForLoop(el).EndValue:=EndValue;
|
|
|
+ TPasImplForLoop(el).Down:=forDownto;
|
|
|
+ CreateBlock(TPasImplForLoop(el));
|
|
|
//WriteLn(i,'FOR "',VarName,'" := ',StartValue,' to ',EndValue,' Token=',CurTokenText);
|
|
|
ExpectToken(tkdo);
|
|
|
end;
|
|
@@ -2916,7 +3129,9 @@ begin
|
|
|
// with Expr, Expr do
|
|
|
Expr:=ParseExpression(Parent);
|
|
|
//writeln(i,'WITH Expr="',Expr,'" Token=',CurTokenText);
|
|
|
- CreateBlock(CurBlock.AddWithDo(Expr));
|
|
|
+ el:=TPasImplWithDo(CreateElement(TPasImplWithDo,'',CurBlock));
|
|
|
+ TPasImplWithDo(el).AddExpression(expr);
|
|
|
+ CreateBlock(TPasImplWithDo(el));
|
|
|
repeat
|
|
|
NextToken;
|
|
|
if CurToken=tkdo then break;
|
|
@@ -2932,7 +3147,9 @@ begin
|
|
|
Expr:=ParseExpression(Parent);
|
|
|
//writeln(i,'CASE OF Expr="',Expr,'" Token=',CurTokenText);
|
|
|
ExpectToken(tkof);
|
|
|
- CreateBlock(CurBlock.AddCaseOf(Expr));
|
|
|
+ el:=TPasImplCaseOf(CreateElement(TPasImplCaseOf,'',CurBlock));
|
|
|
+ TPasImplCaseOf(el).Expression:=Expr;
|
|
|
+ CreateBlock(TPasImplCaseOf(el));
|
|
|
repeat
|
|
|
NextToken;
|
|
|
//writeln(i,'CASE OF Token=',CurTokenText);
|
|
@@ -2961,7 +3178,12 @@ begin
|
|
|
if CurBlock is TPasImplCaseStatement then
|
|
|
TPasImplCaseStatement(CurBlock).Expressions.Add(Expr)
|
|
|
else
|
|
|
- CurBlock:=TPasImplCaseOf(CurBlock).AddCase(Expr);
|
|
|
+ begin
|
|
|
+ el:=TPasImplCaseStatement(CreateElement(TPasImplCaseStatement,'',CurBlock));
|
|
|
+ TPasImplCaseStatement(el).AddExpression(Expr);
|
|
|
+ CurBlock.AddElement(el);
|
|
|
+ CurBlock:=TPasImplCaseStatement(el);
|
|
|
+ end;
|
|
|
//writeln(i,'CASE after value Token=',CurTokenText);
|
|
|
if CurToken=tkColon then break;
|
|
|
if CurToken<>tkComma then
|
|
@@ -2987,7 +3209,10 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
tktry:
|
|
|
- CreateBlock(CurBlock.AddTry);
|
|
|
+ begin
|
|
|
+ el:=TPasImplTry(CreateElement(TPasImplTry,'',Curblock));
|
|
|
+ CreateBlock(TPasImplTry(el));
|
|
|
+ end;
|
|
|
tkfinally:
|
|
|
begin
|
|
|
if CloseStatement(true) then
|
|
@@ -2997,7 +3222,10 @@ begin
|
|
|
end;
|
|
|
if CurBlock is TPasImplTry then
|
|
|
begin
|
|
|
- CurBlock:=TPasImplTry(CurBlock).AddFinally;
|
|
|
+ el:=TPasImplTryFinally(CreateElement(TPasImplTryFinally,'',Curblock));
|
|
|
+ TPasImplTry(CurBlock).FinallyExcept:=TPasImplTryFinally(el);
|
|
|
+ CurBlock.AddElement(el);
|
|
|
+ CurBlock:=TPasImplTryFinally(el);
|
|
|
end else
|
|
|
ParseExc(SParserSyntaxError);
|
|
|
end;
|
|
@@ -3011,7 +3239,10 @@ begin
|
|
|
if CurBlock is TPasImplTry then
|
|
|
begin
|
|
|
//writeln(i,'EXCEPT');
|
|
|
- CurBlock:=TPasImplTry(CurBlock).AddExcept;
|
|
|
+ el:=TPasImplTryExcept(CreateElement(TPasImplTryExcept,'',CurBlock));
|
|
|
+ TPasImplTry(CurBlock).FinallyExcept:=TPasImplTryExcept(el);
|
|
|
+// CurBlock.AddElement(el);
|
|
|
+ CurBlock:=TPasImplTryExcept(el);
|
|
|
end else
|
|
|
ParseExc(SParserSyntaxError);
|
|
|
end;
|
|
@@ -3033,13 +3264,20 @@ begin
|
|
|
//writeln(i,'ON v=',VarName,' t=',TypeName,' Token=',CurTokenText);
|
|
|
end else
|
|
|
UngetToken;
|
|
|
- CurBlock:=TPasImplTryExcept(CurBlock).AddExceptOn(VarName,TypeName);
|
|
|
+ el:=TPasImplExceptOn(CreateElement(TPasImplExceptOn,'',CurBlock));
|
|
|
+ TPasImplExceptOn(el).VariableName:=VarName;
|
|
|
+ TPasImplExceptOn(el).TypeName:=TypeName;
|
|
|
+ CurBlock.AddElement(el);
|
|
|
+ CurBlock:=TPasImplExceptOn(el);
|
|
|
ExpectToken(tkDo);
|
|
|
end else
|
|
|
ParseExc(SParserSyntaxError);
|
|
|
end;
|
|
|
tkraise:
|
|
|
- CreateBlock(CurBlock.AddRaise);
|
|
|
+ begin
|
|
|
+ el:=TPasImplRaise(CreateElement(TPasImplRaise,'',CurBlock));
|
|
|
+ CreateBlock(TPasImplRaise(el));
|
|
|
+ end;
|
|
|
tkend:
|
|
|
begin
|
|
|
if CloseStatement(true) then
|
|
@@ -3090,7 +3328,11 @@ begin
|
|
|
// assign statement
|
|
|
NextToken;
|
|
|
right:=DoParseExpression(nil); // this may solve TPasImplWhileDo.AddElement BUG
|
|
|
- CmdElem:=CurBlock.AddAssign(left, right);
|
|
|
+ el:=TPasImplAssign(CreateElement(TPasImplAssign,'',CurBlock));
|
|
|
+ TPasImplAssign(el).left:=Left;
|
|
|
+ TPasImplAssign(el).right:=Right;
|
|
|
+ CurBlock.AddElement(el);
|
|
|
+ CmdElem:=TPasImplAssign(el);
|
|
|
UngetToken;
|
|
|
end;
|
|
|
tkColon:
|
|
@@ -3098,12 +3340,18 @@ begin
|
|
|
if not (left is TPrimitiveExpr) then
|
|
|
ParseExc(Format(SParserExpectTokenError, [TokenInfos[tkSemicolon]]));
|
|
|
// label mark. todo: check mark identifier in the list of labels
|
|
|
- CmdElem:=CurBlock.AddLabelMark(TPrimitiveExpr(left).Value);
|
|
|
+ el:=TPasImplLabelMark(CreateElement(TPasImplLabelMark,'', CurBlock));
|
|
|
+ TPasImplLabelMark(el).LabelId:=TPrimitiveExpr(left).Value;
|
|
|
+ CurBlock.AddElement(el);
|
|
|
+ CmdElem:=TPasImplLabelMark(el);
|
|
|
left.Free;
|
|
|
end;
|
|
|
else
|
|
|
// simple statement (function call)
|
|
|
- CmdElem:=CurBlock.AddSimple(left);
|
|
|
+ el:=TPasImplSimple(CreateElement(TPasImplSimple,'',CurBlock));
|
|
|
+ TPasImplSimple(el).expr:=Left;
|
|
|
+ CurBlock.AddElement(el);
|
|
|
+ CmdElem:=TPasImplSimple(el);
|
|
|
UngetToken;
|
|
|
end;
|
|
|
|