mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-04-10 08:38:08 +00:00
Implement support for macros with variable arguments (C99).
This commit is contained in:
parent
1ba25fa704
commit
77dcfdf3ee
@ -18,7 +18,7 @@ uses CCommon, MM, Scanner, Symbol, CGI;
|
||||
{$segment 'SCANNER'}
|
||||
|
||||
const
|
||||
symFileVersion = 6; {version number of .sym file format}
|
||||
symFileVersion = 7; {version number of .sym file format}
|
||||
|
||||
var
|
||||
inhibitHeader: boolean; {should .sym includes be blocked?}
|
||||
@ -733,6 +733,7 @@ procedure EndInclude {chPtr: ptr};
|
||||
mp^.saved := true; {mark this one as saved}
|
||||
WriteString(mp^.name); {write the macroRecord}
|
||||
WriteByte(mp^.parameters);
|
||||
WriteByte(ord(mp^.isVarargs));
|
||||
WriteByte(ord(mp^.readOnly));
|
||||
WriteByte(mp^.algorithm);
|
||||
tp := mp^.tokens; {loop over token list}
|
||||
@ -1350,6 +1351,7 @@ var
|
||||
mp^.parameters := ReadByte;
|
||||
if mp^.parameters & $0080 <> 0 then
|
||||
mp^.parameters := mp^.parameters | $FF00;
|
||||
mp^.isVarargs := boolean(ReadByte);
|
||||
mp^.readOnly := boolean(ReadByte);
|
||||
mp^.algorithm := ReadByte;
|
||||
mp^.tokens := nil;
|
||||
|
33
Scanner.pas
33
Scanner.pas
@ -57,6 +57,7 @@ type
|
||||
saved: boolean;
|
||||
name: stringPtr;
|
||||
parameters: integer;
|
||||
isVarargs: boolean;
|
||||
tokens: tokenListRecordPtr;
|
||||
readOnly: boolean;
|
||||
algorithm: integer;
|
||||
@ -1357,6 +1358,7 @@ var
|
||||
pptr: parameterPtr; {work pointer for tracing parms list}
|
||||
sp: longStringPtr; {work pointer}
|
||||
stringization: boolean; {are we stringizing a parameter?}
|
||||
endParmTokens: tokenSet; {tokens that end a parameter}
|
||||
|
||||
begin {Expand}
|
||||
lPrintMacroExpansions := printMacroExpansions; {inhibit token printing}
|
||||
@ -1371,10 +1373,14 @@ if macro^.parameters >= 0 then begin {find the values of the parameters}
|
||||
NextToken; {skip the '('}
|
||||
paramCount := 0; {process the parameters}
|
||||
parmEnd := nil;
|
||||
endParmTokens := [rparench,commach];
|
||||
repeat
|
||||
done := true;
|
||||
parenCount := 0;
|
||||
paramCount := paramCount+1;
|
||||
if macro^.isVarargs then
|
||||
if paramCount = macro^.parameters then
|
||||
endParmTokens := endParmTokens - [commach];
|
||||
new(newParm);
|
||||
newParm^.next := nil;
|
||||
if parmEnd = nil then
|
||||
@ -1385,7 +1391,7 @@ if macro^.parameters >= 0 then begin {find the values of the parameters}
|
||||
newParm^.tokens := nil;
|
||||
while (token.kind <> eofsy)
|
||||
and ((parenCount <> 0)
|
||||
or (not (token.kind in [rparench,commach]))) do begin
|
||||
or (not (token.kind in endParmTokens))) do begin
|
||||
new(tPtr);
|
||||
tPtr^.next := newParm^.tokens;
|
||||
newParm^.tokens := tPtr;
|
||||
@ -2154,6 +2160,7 @@ var
|
||||
mPtr^.name := token.name; {record the name}
|
||||
mPtr^.saved := false; {not saved in symbol file}
|
||||
mPtr^.tokens := nil; {no tokens yet}
|
||||
mPtr^.isVarargs := false; {not varargs (yet)}
|
||||
charKinds[ord('#')] := ch_pound; {allow # as a token}
|
||||
if ch = '(' then begin {scan the parameter list...}
|
||||
NextToken; {done with the name token...}
|
||||
@ -2186,7 +2193,29 @@ var
|
||||
NextToken;
|
||||
done := false;
|
||||
end; {if}
|
||||
end; {if}
|
||||
end {if}
|
||||
else if token.kind = dotch then begin
|
||||
NextToken;
|
||||
if token.kind = dotch then begin
|
||||
NextToken;
|
||||
if token.kind = dotch then
|
||||
NextToken
|
||||
else
|
||||
Error(89);
|
||||
end
|
||||
else
|
||||
Error(89);
|
||||
new(np);
|
||||
np^.next := nil;
|
||||
np^.str := '__VA_ARGS__';
|
||||
if ple = nil then
|
||||
parameterList := np
|
||||
else
|
||||
ple^.next := np;
|
||||
ple := np;
|
||||
parameters := parameters + 1;
|
||||
mPtr^.isVarargs := true;
|
||||
end; {else}
|
||||
until done;
|
||||
if token.kind = rparench then {insist on a matching ')'}
|
||||
NextToken
|
||||
|
Loading…
x
Reference in New Issue
Block a user