mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2024-05-29 04:41:27 +00:00
Initial support for compound literals.
Compound literals outside of functions should work at this point. Compound literals inside of functions are not fully implemented, so they are disabled for now. (There is some code to support them, but the code to actually initialize them at the appropriate time is not written yet.)
This commit is contained in:
parent
3c3697535e
commit
7ae830ae7e
|
@ -360,10 +360,11 @@ type
|
||||||
isForwardDeclared: boolean; {does this var use a forward declared type?}
|
isForwardDeclared: boolean; {does this var use a forward declared type?}
|
||||||
class: tokenEnum; {storage class}
|
class: tokenEnum; {storage class}
|
||||||
case storage: storageType of
|
case storage: storageType of
|
||||||
stackFrame: (lln: integer); {local label #}
|
stackFrame: (lln: integer; {local label #}
|
||||||
parameter: (pln: integer; {paramater label #}
|
clnext: identPtr); {next compound literal}
|
||||||
pdisp: integer; {disp of parameter}
|
parameter: (pln: integer; {paramater label #}
|
||||||
pnext: identPtr); {next parameter}
|
pdisp: integer; {disp of parameter}
|
||||||
|
pnext: identPtr); {next parameter}
|
||||||
external: ();
|
external: ();
|
||||||
global,private: ();
|
global,private: ();
|
||||||
none: ();
|
none: ();
|
||||||
|
|
|
@ -268,6 +268,14 @@ function MakeFuncIdentifier: identPtr; extern;
|
||||||
{ }
|
{ }
|
||||||
{ This must only be called within a function body. }
|
{ This must only be called within a function body. }
|
||||||
|
|
||||||
|
|
||||||
|
function MakeCompoundLiteral(tp: typePtr): identPtr; extern;
|
||||||
|
|
||||||
|
{ Make the identifier for a compound literal. }
|
||||||
|
{ }
|
||||||
|
{ parameters: }
|
||||||
|
{ tp - the type of the compound literal }
|
||||||
|
|
||||||
{-- External unsigned math routines ----------------------------}
|
{-- External unsigned math routines ----------------------------}
|
||||||
|
|
||||||
function lshr (x,y: longint): longint; extern;
|
function lshr (x,y: longint): longint; extern;
|
||||||
|
@ -2001,6 +2009,49 @@ var
|
||||||
end; {DoGeneric}
|
end; {DoGeneric}
|
||||||
|
|
||||||
|
|
||||||
|
procedure DoCompoundLiteral;
|
||||||
|
|
||||||
|
{ process a compound literal expression }
|
||||||
|
|
||||||
|
label 1;
|
||||||
|
|
||||||
|
var
|
||||||
|
id: identPtr;
|
||||||
|
sp: tokenPtr;
|
||||||
|
|
||||||
|
begin {DoCompoundLiteral}
|
||||||
|
if kind in [preprocessorExpression,arrayExpression] then begin
|
||||||
|
op := opStack;
|
||||||
|
while op <> nil do begin
|
||||||
|
if op^.token.kind = sizeofsy then
|
||||||
|
goto 1;
|
||||||
|
op := op^.next;
|
||||||
|
end; {while}
|
||||||
|
Error(41);
|
||||||
|
errorFound := true;
|
||||||
|
end; {if}
|
||||||
|
1:
|
||||||
|
id := MakeCompoundLiteral(opStack^.castType);
|
||||||
|
opStack := opStack^.next;
|
||||||
|
|
||||||
|
{create an operand on the stack}
|
||||||
|
new(sp);
|
||||||
|
sp^.token.kind := ident;
|
||||||
|
sp^.token.class := identifier;
|
||||||
|
sp^.token.symbolPtr := id;
|
||||||
|
sp^.token.name := id^.name;
|
||||||
|
sp^.id := id;
|
||||||
|
sp^.next := stack;
|
||||||
|
sp^.left := nil;
|
||||||
|
sp^.middle := nil;
|
||||||
|
sp^.right := nil;
|
||||||
|
stack := sp;
|
||||||
|
|
||||||
|
ComplexTerm;
|
||||||
|
expectingTerm := false;
|
||||||
|
end; {DoCompoundLiteral}
|
||||||
|
|
||||||
|
|
||||||
begin {ExpressionTree}
|
begin {ExpressionTree}
|
||||||
opStack := nil;
|
opStack := nil;
|
||||||
stack := nil;
|
stack := nil;
|
||||||
|
@ -2147,6 +2198,10 @@ if token.kind in startExpression then begin
|
||||||
parenCount := parenCount+1;
|
parenCount := parenCount+1;
|
||||||
end;
|
end;
|
||||||
end {else if}
|
end {else if}
|
||||||
|
else if (token.kind = lbracech) {handle a compound literal}
|
||||||
|
and (opstack <> nil) and (opStack^.token.kind = castoper) then begin
|
||||||
|
DoCompoundLiteral
|
||||||
|
end {else if}
|
||||||
else if token.kind = _Genericsy then {handle _Generic}
|
else if token.kind = _Genericsy then {handle _Generic}
|
||||||
DoGeneric
|
DoGeneric
|
||||||
else begin {handle an operation...}
|
else begin {handle an operation...}
|
||||||
|
|
57
Parser.pas
57
Parser.pas
|
@ -69,6 +69,14 @@ function MakeFuncIdentifier: identPtr;
|
||||||
{ This must only be called within a function body. }
|
{ This must only be called within a function body. }
|
||||||
|
|
||||||
|
|
||||||
|
function MakeCompoundLiteral(tp: typePtr): identPtr;
|
||||||
|
|
||||||
|
{ Make the identifier for a compound literal. }
|
||||||
|
{ }
|
||||||
|
{ parameters: }
|
||||||
|
{ tp - the type of the compound literal }
|
||||||
|
|
||||||
|
|
||||||
procedure InitParser;
|
procedure InitParser;
|
||||||
|
|
||||||
{ Initialize the parser }
|
{ Initialize the parser }
|
||||||
|
@ -176,6 +184,8 @@ var
|
||||||
statementList: statementPtr; {list of open statements}
|
statementList: statementPtr; {list of open statements}
|
||||||
savedVolatile: boolean; {saved copy of volatile}
|
savedVolatile: boolean; {saved copy of volatile}
|
||||||
doingForLoopClause1: boolean; {doing the first clause of a for loop?}
|
doingForLoopClause1: boolean; {doing the first clause of a for loop?}
|
||||||
|
compoundLiteralNumber: integer; {number of compound literal}
|
||||||
|
compoundLiteralToAllocate: identPtr; {compound literal that needs space allocated}
|
||||||
|
|
||||||
{parameter processing variables}
|
{parameter processing variables}
|
||||||
{------------------------------}
|
{------------------------------}
|
||||||
|
@ -325,6 +335,11 @@ var
|
||||||
stPtr: statementPtr; {work pointer}
|
stPtr: statementPtr; {work pointer}
|
||||||
|
|
||||||
begin {EndCompoundStatement}
|
begin {EndCompoundStatement}
|
||||||
|
while compoundLiteralToAllocate <> nil do begin {allocate compound literals}
|
||||||
|
Gen2(dc_loc, compoundLiteralToAllocate^.lln,
|
||||||
|
long(compoundLiteralToAllocate^.itype^.size).lsw);
|
||||||
|
compoundLiteralToAllocate := compoundLiteralToAllocate^.clnext;
|
||||||
|
end {while};
|
||||||
dumpLocal := false;
|
dumpLocal := false;
|
||||||
stPtr := statementList; {pop the statement record}
|
stPtr := statementList; {pop the statement record}
|
||||||
statementList := stPtr^.next;
|
statementList := stPtr^.next;
|
||||||
|
@ -4093,7 +4108,7 @@ begin {TypeName}
|
||||||
DeclarationSpecifiers(specifierQualifierListElement, rparench);
|
DeclarationSpecifiers(specifierQualifierListElement, rparench);
|
||||||
|
|
||||||
{_Alignas is not allowed in most uses of type names. }
|
{_Alignas is not allowed in most uses of type names. }
|
||||||
{It would be allowed in compound literals, if we supported them.}
|
{TODO: _Alignas should be allowed in compound literals. }
|
||||||
if _Alignassy in declarationModifiers then
|
if _Alignassy in declarationModifiers then
|
||||||
Error(142);
|
Error(142);
|
||||||
|
|
||||||
|
@ -4534,6 +4549,44 @@ MakeFuncIdentifier := id;
|
||||||
end; {MakeFuncIdentifier}
|
end; {MakeFuncIdentifier}
|
||||||
|
|
||||||
|
|
||||||
|
function MakeCompoundLiteral{tp: typePtr): identPtr};
|
||||||
|
|
||||||
|
{ Make the identifier for a compound literal. }
|
||||||
|
{ }
|
||||||
|
{ parameters: }
|
||||||
|
{ tp - the type of the compound literal }
|
||||||
|
|
||||||
|
type
|
||||||
|
nameString = packed array [0..24] of char;
|
||||||
|
|
||||||
|
var
|
||||||
|
id: identPtr; {the identifier for the literal}
|
||||||
|
name: ^nameString; {the name for the identifier}
|
||||||
|
class: tokenEnum; {storage class}
|
||||||
|
|
||||||
|
begin {MakeCompoundLiteral}
|
||||||
|
if functionTable <> nil then begin
|
||||||
|
Error(164);
|
||||||
|
class := autosy
|
||||||
|
end {if}
|
||||||
|
else
|
||||||
|
class := staticsy;
|
||||||
|
name := pointer(Malloc(25));
|
||||||
|
name^ := concat('~CompoundLiteral', cnvis(compoundLiteralNumber));
|
||||||
|
id := NewSymbol(name, tp, class, variableSpace, defined);
|
||||||
|
Initializer(id);
|
||||||
|
MakeCompoundLiteral := id;
|
||||||
|
compoundLiteralNumber := compoundLiteralNumber + 1;
|
||||||
|
if compoundLiteralNumber = 0 then
|
||||||
|
Error(57);
|
||||||
|
if class = autosy then begin
|
||||||
|
id^.lln := GetLocalLabel;
|
||||||
|
id^.clnext := compoundLiteralToAllocate;
|
||||||
|
compoundLiteralToAllocate := id;
|
||||||
|
end;
|
||||||
|
end; {MakeFuncIdentifier}
|
||||||
|
|
||||||
|
|
||||||
procedure InitParser;
|
procedure InitParser;
|
||||||
|
|
||||||
{ Initialize the parser }
|
{ Initialize the parser }
|
||||||
|
@ -4554,6 +4607,8 @@ statementList := nil; {no open statements}
|
||||||
codegenStarted := false; {code generator is not started}
|
codegenStarted := false; {code generator is not started}
|
||||||
doingForLoopClause1 := false; {not doing a for loop}
|
doingForLoopClause1 := false; {not doing a for loop}
|
||||||
fIsNoreturn := false; {not doing a noreturn function}
|
fIsNoreturn := false; {not doing a noreturn function}
|
||||||
|
compoundLiteralNumber := 1; {no compound literals yet}
|
||||||
|
compoundLiteralToAllocate := nil; {no compound literals needing space yet}
|
||||||
|
|
||||||
{init syntactic classes of tokens}
|
{init syntactic classes of tokens}
|
||||||
{See C17 section 6.7 ff.}
|
{See C17 section 6.7 ff.}
|
||||||
|
|
|
@ -720,6 +720,7 @@ if list or (numErr <> 0) then begin
|
||||||
161: msg := @'illegal operator in a constant expression';
|
161: msg := @'illegal operator in a constant expression';
|
||||||
162: msg := @'invalid escape sequence';
|
162: msg := @'invalid escape sequence';
|
||||||
163: msg := @'pointer assignment discards qualifier(s)';
|
163: msg := @'pointer assignment discards qualifier(s)';
|
||||||
|
164: msg := @'compound literals within functions are not supported by ORCA/C';
|
||||||
otherwise: Error(57);
|
otherwise: Error(57);
|
||||||
end; {case}
|
end; {case}
|
||||||
writeln(msg^);
|
writeln(msg^);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user