diff --git a/components/codetools/ccodeparsertool.pas b/components/codetools/ccodeparsertool.pas index e29dab5ae8..0ec42b9efb 100644 --- a/components/codetools/ccodeparsertool.pas +++ b/components/codetools/ccodeparsertool.pas @@ -382,6 +382,7 @@ function TCCodeParserTool.DirectiveToken: boolean; procedure ReadExpression; var BracketLevel: Integer; + NeedBracket: Boolean; begin BracketLevel:=0; repeat @@ -407,16 +408,22 @@ function TCCodeParserTool.DirectiveToken: boolean; // valid operator end else if IsIdentChar[Src[AtomStart]] then begin if AtomIs('defined') then begin - // read defined(macro) - ReadRawNextCAtom(Src,SrcPos,AtomStart); - if not AtomIsChar('(') then - RaiseExpectedButAtomFound('('); + // read defined(macro) + // or read defined macro ReadRawNextCAtom(Src,SrcPos,AtomStart); + if AtomIsChar('(') then begin + NeedBracket:=true; + ReadRawNextCAtom(Src,SrcPos,AtomStart); + end else begin + NeedBracket:=false; + end; if not AtomIsIdentifier then RaiseExpectedButAtomFound('macro'); - ReadRawNextCAtom(Src,SrcPos,AtomStart); - if not AtomIsChar(')') then - RaiseExpectedButAtomFound(')'); + if NeedBracket then begin + ReadRawNextCAtom(Src,SrcPos,AtomStart); + if not AtomIsChar(')') then + RaiseExpectedButAtomFound(')'); + end; end else begin // constant end; diff --git a/components/codetools/expreval.pas b/components/codetools/expreval.pas index 651ded0e46..6f1a74f86d 100644 --- a/components/codetools/expreval.pas +++ b/components/codetools/expreval.pas @@ -19,6 +19,7 @@ invalid). The function Eval evaluates expressions and understands the operators AND, OR, XOR, NOT, (, ), =, <, >, <=, >=, <> + defined() } unit ExprEval; @@ -85,6 +86,23 @@ type procedure WriteDebugReport; end; + { TExpressionSolver + Checks if expression is always true 1, always false 0, or something } + + TExpressionSolver = class + public + //Defines: TStringToStringTree; + //Undefines: TStringToStringTree; + ErrorMsg: string; // last error message + ErrorPos: integer;// last error position + constructor Create; + destructor Destroy; override; + function Solve(const Expr: string; out ExprResult: string): boolean; + function Solve(const Src: string; StartPos, EndPos: integer; + out ExprResult: string): boolean; + end; + + implementation var @@ -734,6 +752,65 @@ begin dbgs(ConsistencyCheck)); end; + +{ TExpressionSolver } + +constructor TExpressionSolver.Create; +begin + +end; + +destructor TExpressionSolver.Destroy; +begin + inherited Destroy; +end; + +function TExpressionSolver.Solve(const Expr: string; out + ExprResult: string): boolean; +begin + Result:=Solve(Expr,1,length(Expr),ExprResult); +end; + +function TExpressionSolver.Solve(const Src: string; + StartPos, EndPos: integer; out ExprResult: string): boolean; +{ '' -> '' + true = nonzero, false = zero + defined(name) + sizeof(type) + unary operators: not, ! + binary operators: = <> >= <= > < and or xor shl shr + round brackets () +} +var + AtomStart: LongInt; + SrcPos: LongInt; + + function AtomIs(const s: shortstring): boolean; + var + len: Integer; + i: Integer; + begin + len:=length(s); + if (len<>SrcPos-AtomStart) then exit(false); + if SrcPos>EndPos then exit(false); + for i:=1 to len do + if Src[AtomStart+i-1]<>s[i] then exit(false); + Result:=true; + end; + +begin + if StartPos>=EndPos then begin + ExprResult:=''; + exit(true); + end; + SrcPos:=StartPos; + AtomStart:=SrcPos; + //ReadNextCAtom(Source,SrcPos,AtomStart); + if AtomIs('!') then begin + + end; +end; + initialization InternalInit; diff --git a/components/codetools/h2pastool.pas b/components/codetools/h2pastool.pas index edbd7e1edc..d107246284 100644 --- a/components/codetools/h2pastool.pas +++ b/components/codetools/h2pastool.pas @@ -1012,6 +1012,7 @@ var AtomStart: integer; BracketLvl: Integer; LastToken: TTokenType; + NeedBracket: Boolean; function AtomIs(const s: shortstring): boolean; var @@ -1105,12 +1106,12 @@ begin end; if AtomIs('defined') then begin Add(ttValue); - // read defined(name) + // read defined(name) or defined name ReadRawNextCAtom(CCode,p,AtomStart); - if not AtomIs('(') then begin - ErrorExpectedButFound('('); - exit; - end; + if AtomIs('(') then + NeedBracket:=true + else + NeedBracket:=false; Add(ttBracketOpen); ReadRawNextCAtom(CCode,p,AtomStart); if (AtomStart>=EndPos) or (not IsIdentStartChar[CCode[AtomStart]]) @@ -1123,10 +1124,12 @@ begin Add(ttValue,'FPC') else Add(ttValue); - ReadRawNextCAtom(CCode,p,AtomStart); - if not AtomIs(')') then begin - ErrorExpectedButFound(')'); - exit; + if NeedBracket then begin + ReadRawNextCAtom(CCode,p,AtomStart); + if not AtomIs(')') then begin + ErrorExpectedButFound(')'); + exit; + end; end; Add(ttBracketClose); end else begin