mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-01-07 22:32:05 +00:00
Allow mixed declarations and statements (C99).
This commit is contained in:
parent
24bf693985
commit
14adcd6a80
578
Parser.pas
578
Parser.pas
@ -7,6 +7,7 @@
|
|||||||
{ }
|
{ }
|
||||||
{ DoDeclaration - process a variable or function declaration }
|
{ DoDeclaration - process a variable or function declaration }
|
||||||
{ DoStatement - process a statement from a function }
|
{ DoStatement - process a statement from a function }
|
||||||
|
{ AutoInit - generate code to initialize an auto variable }
|
||||||
{ InitParser - initialize the parser }
|
{ InitParser - initialize the parser }
|
||||||
{ Match - insure that the next token is of the specified type }
|
{ Match - insure that the next token is of the specified type }
|
||||||
{ TermParser - shut down the parser }
|
{ TermParser - shut down the parser }
|
||||||
@ -39,6 +40,14 @@ procedure DoStatement;
|
|||||||
{ process a statement from a function }
|
{ process a statement from a function }
|
||||||
|
|
||||||
|
|
||||||
|
procedure AutoInit (variable: identPtr);
|
||||||
|
|
||||||
|
{ generate code to initialize an auto variable }
|
||||||
|
{ }
|
||||||
|
{ parameters: }
|
||||||
|
{ variable - the variable to initialize }
|
||||||
|
|
||||||
|
|
||||||
procedure InitParser;
|
procedure InitParser;
|
||||||
|
|
||||||
{ Initialize the parser }
|
{ Initialize the parser }
|
||||||
@ -72,6 +81,7 @@ implementation
|
|||||||
|
|
||||||
const
|
const
|
||||||
maxBitField = 32; {max # of bits in a bit field}
|
maxBitField = 32; {max # of bits in a bit field}
|
||||||
|
allowMixedDeclarations = true;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -145,7 +155,6 @@ var
|
|||||||
doingMain: boolean; {are we processing the main function?}
|
doingMain: boolean; {are we processing the main function?}
|
||||||
firstCompoundStatement: boolean; {are we doing a function level compound statement?}
|
firstCompoundStatement: boolean; {are we doing a function level compound statement?}
|
||||||
fType: typePtr; {return type of the current function}
|
fType: typePtr; {return type of the current function}
|
||||||
initializerList: identList; {list of initialized identifiers}
|
|
||||||
isForwardDeclared: boolean; {is the field list component }
|
isForwardDeclared: boolean; {is the field list component }
|
||||||
{ referenceing a forward struct/union? }
|
{ referenceing a forward struct/union? }
|
||||||
isFunction: boolean; {is the declaration a function?}
|
isFunction: boolean; {is the declaration a function?}
|
||||||
@ -273,7 +282,6 @@ stPtr^.kind := compoundSt;
|
|||||||
if makeSymbols then {create a symbol table}
|
if makeSymbols then {create a symbol table}
|
||||||
PushTable;
|
PushTable;
|
||||||
stPtr^.doingDeclaration := true; {allow declarations}
|
stPtr^.doingDeclaration := true; {allow declarations}
|
||||||
initializerList := nil; {no initializers, yet}
|
|
||||||
end; {CompoundStatement}
|
end; {CompoundStatement}
|
||||||
|
|
||||||
|
|
||||||
@ -2432,10 +2440,6 @@ while iPtr <> nil do begin
|
|||||||
variable^.iPtr := jPtr;
|
variable^.iPtr := jPtr;
|
||||||
if errorFound then {eliminate bad initializers}
|
if errorFound then {eliminate bad initializers}
|
||||||
variable^.state := defined;
|
variable^.state := defined;
|
||||||
new(ip); {place the initializer in the list}
|
|
||||||
ip^.next := initializerList;
|
|
||||||
ip^.id := variable;
|
|
||||||
initializerList := ip;
|
|
||||||
useGlobalPool := luseGlobalPool; {restore useGlobalPool}
|
useGlobalPool := luseGlobalPool; {restore useGlobalPool}
|
||||||
end; {Initializer}
|
end; {Initializer}
|
||||||
|
|
||||||
@ -3598,6 +3602,8 @@ else {if not isFunction then} begin
|
|||||||
if variable^.storage = stackFrame then begin
|
if variable^.storage = stackFrame then begin
|
||||||
variable^.lln := GetLocalLabel;
|
variable^.lln := GetLocalLabel;
|
||||||
Gen2(dc_loc, variable^.lln, long(variable^.itype^.size).lsw);
|
Gen2(dc_loc, variable^.lln, long(variable^.itype^.size).lsw);
|
||||||
|
if variable^.state = initialized then
|
||||||
|
AutoInit(variable); {initialize auto variable}
|
||||||
end; {if}
|
end; {if}
|
||||||
if (token.kind = commach) and (not doingPrototypes) then begin
|
if (token.kind = commach) and (not doingPrototypes) then begin
|
||||||
done := false; {allow multiple variables on one line}
|
done := false; {allow multiple variables on one line}
|
||||||
@ -3646,300 +3652,14 @@ procedure DoStatement;
|
|||||||
|
|
||||||
{ process a statement from a function }
|
{ process a statement from a function }
|
||||||
|
|
||||||
|
|
||||||
procedure AutoInit;
|
|
||||||
|
|
||||||
{ initialize auto variables }
|
|
||||||
|
|
||||||
var
|
|
||||||
count: integer; {initializer counter}
|
|
||||||
ip: identPtr; {pointer to a symbol table entry}
|
|
||||||
lp1,lp2: identList; {used to reverse, track the list}
|
|
||||||
iPtr: initializerPtr; {pointer to the next initializer}
|
|
||||||
|
|
||||||
|
|
||||||
procedure Initialize (id: identPtr; disp: longint; itype: typePtr);
|
|
||||||
|
|
||||||
{ initialize a variable }
|
|
||||||
{ }
|
|
||||||
{ parameters: }
|
|
||||||
{ id - pointer to the identifier }
|
|
||||||
{ disp - disp past the identifier to initialize }
|
|
||||||
{ itype - type of the variable to initialize }
|
|
||||||
{ }
|
|
||||||
{ variables: }
|
|
||||||
{ count - number of times to re-use the initializer }
|
|
||||||
{ ip - pointer to the initializer record to use }
|
|
||||||
|
|
||||||
label 1;
|
|
||||||
|
|
||||||
var
|
|
||||||
elements: longint; {# array elements}
|
|
||||||
fp: identPtr; {for tracing field lists}
|
|
||||||
size: integer; {fill size}
|
|
||||||
union: boolean; {are we doing a union?}
|
|
||||||
|
|
||||||
{bit field manipulation}
|
|
||||||
{----------------------}
|
|
||||||
bitcount: integer; {# if bits so far}
|
|
||||||
bitsize,bitdisp: integer; {defines size, location of a bit field}
|
|
||||||
|
|
||||||
{assignment conversion}
|
|
||||||
{---------------------}
|
|
||||||
tree: tokenPtr; {expression tree}
|
|
||||||
val: longint; {constant expression value}
|
|
||||||
isConstant: boolean; {is the expression a constant?}
|
|
||||||
|
|
||||||
|
|
||||||
procedure LoadAddress;
|
|
||||||
|
|
||||||
{ Load the address of the operand }
|
|
||||||
|
|
||||||
begin {LoadAddress}
|
|
||||||
with id^ do {load the base address}
|
|
||||||
case storage of
|
|
||||||
stackFrame: Gen2(pc_lda, lln, 0);
|
|
||||||
parameter: if itype^.kind = arrayType then
|
|
||||||
Gen2t(pc_lod, pln, 0, cgULong)
|
|
||||||
else
|
|
||||||
Gen2(pc_lda, pln, 0);
|
|
||||||
external,
|
|
||||||
global,
|
|
||||||
private: Gen1Name(pc_lao, 0, name);
|
|
||||||
otherwise: ;
|
|
||||||
end; {case}
|
|
||||||
if disp <> 0 then
|
|
||||||
Gen1t(pc_inc, long(disp).lsw, cgULong)
|
|
||||||
end; {LoadAddress}
|
|
||||||
|
|
||||||
|
|
||||||
function ZeroFill (elements: longint; itype: typePtr;
|
|
||||||
count: integer; iPtr: initializerPtr): boolean;
|
|
||||||
|
|
||||||
{ See if an array can be zero filled }
|
|
||||||
{ }
|
|
||||||
{ parameters: }
|
|
||||||
{ elements - elements in the array }
|
|
||||||
{ itype - type of each array element }
|
|
||||||
{ count - remaining initializer repititions }
|
|
||||||
{ iPtr - initializer record }
|
|
||||||
|
|
||||||
begin {ZeroFill}
|
|
||||||
ZeroFill := false;
|
|
||||||
if not iPtr^.isConstant then
|
|
||||||
if itype^.kind in [scalarType,enumType] then
|
|
||||||
if count >= elements then
|
|
||||||
with iPtr^.itree^ do
|
|
||||||
if token.kind = intconst then
|
|
||||||
if token.ival = 0 then
|
|
||||||
{don't call ~ZERO for very small arrays}
|
|
||||||
if elements * itype^.size > 10 then
|
|
||||||
ZeroFill := true;
|
|
||||||
end; {ZeroFill}
|
|
||||||
|
|
||||||
|
|
||||||
begin {Initialize}
|
|
||||||
case itype^.kind of
|
|
||||||
|
|
||||||
scalarType,pointerType,enumType,functionType: begin
|
|
||||||
LoadAddress; {load the destination address}
|
|
||||||
doDispose := count = 1; {generate the expression value}
|
|
||||||
tree := iptr^.itree; {see if this is a constant}
|
|
||||||
{do assignment conversions}
|
|
||||||
while tree^.token.kind = castoper do
|
|
||||||
tree := tree^.left;
|
|
||||||
isConstant := tree^.token.class in [intConstant,longConstant];
|
|
||||||
if isConstant then
|
|
||||||
if tree^.token.class = intConstant then
|
|
||||||
val := tree^.token.ival
|
|
||||||
else
|
|
||||||
val := tree^.token.lval;
|
|
||||||
|
|
||||||
{ if isConstant then
|
|
||||||
if tree^.token.class = intConstant then
|
|
||||||
Writeln('loc 2: bitsize = ', iPtr^.bitsize:1, '; ival = ', tree^.token.ival:1) {debug}
|
|
||||||
{ else
|
|
||||||
Writeln('loc 2: bitsize = ', iPtr^.bitsize:1, '; lval = ', tree^.token.lval:1) {debug}
|
|
||||||
{ else
|
|
||||||
Writeln('loc 2: bitsize = ', iPtr^.bitsize:1); {debug}
|
|
||||||
|
|
||||||
GenerateCode(iptr^.iTree);
|
|
||||||
AssignmentConversion(itype, expressionType, isConstant, val, true,
|
|
||||||
false);
|
|
||||||
case itype^.kind of {save the value}
|
|
||||||
scalarType:
|
|
||||||
if iptr^.bitsize <> 0 then
|
|
||||||
Gen2t(pc_sbf, iptr^.bitdisp, iptr^.bitsize, itype^.basetype)
|
|
||||||
else
|
|
||||||
Gen0t(pc_sto, itype^.baseType);
|
|
||||||
enumType:
|
|
||||||
Gen0t(pc_sto, cgWord);
|
|
||||||
pointerType,functionType:
|
|
||||||
Gen0t(pc_sto, cgULong);
|
|
||||||
end; {case}
|
|
||||||
end;
|
|
||||||
|
|
||||||
arrayType: begin
|
|
||||||
if itype^.aType^.kind = scalarType then
|
|
||||||
if itype^.aType^.baseType in [cgByte,cgUByte] then
|
|
||||||
if iPtr^.iTree^.token.kind = stringConst then begin
|
|
||||||
GenLdcLong(itype^.elements);
|
|
||||||
Gen0t(pc_stk, cgULong);
|
|
||||||
GenS(pc_lca, iPtr^.iTree^.token.sval);
|
|
||||||
Gen0t(pc_stk, cgULong);
|
|
||||||
Gen0t(pc_bno, cgULong);
|
|
||||||
LoadAddress;
|
|
||||||
Gen0t(pc_stk, cgULong);
|
|
||||||
Gen0t(pc_bno, cgULong);
|
|
||||||
Gen1tName(pc_cup, 0, cgVoid, @'strncpy');
|
|
||||||
iPtr := iPtr^.next;
|
|
||||||
goto 1;
|
|
||||||
end; {if}
|
|
||||||
elements := itype^.elements;
|
|
||||||
itype := itype^.atype;
|
|
||||||
if ZeroFill(elements, itype, count, iPtr) then begin
|
|
||||||
if itype^.kind = enumType then
|
|
||||||
size := cgWordSize
|
|
||||||
else
|
|
||||||
size := TypeSize(itype^.baseType);
|
|
||||||
size := size * long(elements).lsw;
|
|
||||||
LoadAddress;
|
|
||||||
Gen0t(pc_stk, cgULong);
|
|
||||||
Gen1t(pc_ldc, size, cgWord);
|
|
||||||
Gen0t(pc_stk, cgWord);
|
|
||||||
Gen0t(pc_bno, cgULong);
|
|
||||||
Gen1tName(pc_cup, 0, cgVoid, @'~ZERO');
|
|
||||||
disp := disp + size;
|
|
||||||
count := count - long(elements).lsw;
|
|
||||||
if count = 0 then begin
|
|
||||||
iPtr := iPtr^.next;
|
|
||||||
count := iPtr^.count;
|
|
||||||
end; {if}
|
|
||||||
end {if}
|
|
||||||
else begin
|
|
||||||
while elements <> 0 do begin
|
|
||||||
Initialize(id, disp, itype);
|
|
||||||
if itype^.kind in [scalarType,pointerType,enumType] then begin
|
|
||||||
count := count-1;
|
|
||||||
if count = 0 then begin
|
|
||||||
iPtr := iPtr^.next;
|
|
||||||
count := iPtr^.count;
|
|
||||||
end; {if}
|
|
||||||
end; {if}
|
|
||||||
disp := disp+itype^.size;
|
|
||||||
elements := elements-1;
|
|
||||||
end; {while}
|
|
||||||
end; {else}
|
|
||||||
1: end;
|
|
||||||
|
|
||||||
structType,unionType: begin
|
|
||||||
if iPtr^.isStructOrUnion then begin
|
|
||||||
LoadAddress; {load the destination address}
|
|
||||||
GenerateCode(iptr^.iTree); {load the stuct address}
|
|
||||||
{do the assignment}
|
|
||||||
AssignmentConversion(itype, expressionType, isConstant, val,
|
|
||||||
true, false);
|
|
||||||
with expressionType^ do
|
|
||||||
Gen2(pc_mov, long(size).msw, long(size).lsw);
|
|
||||||
Gen0t(pc_pop, UsualUnaryConversions);
|
|
||||||
end {if}
|
|
||||||
else begin
|
|
||||||
union := itype^.kind = unionType;
|
|
||||||
fp := itype^.fieldList;
|
|
||||||
bitsize := iPtr^.bitsize;
|
|
||||||
bitdisp := iPtr^.bitdisp;
|
|
||||||
bitcount := 0;
|
|
||||||
while fp <> nil do begin
|
|
||||||
itype := fp^.itype;
|
|
||||||
{ writeln('Initialize: disp = ', disp:3, '; fp^. Disp = ', fp^.disp:3, 'itype^.size = ', itype^.size:1); {debug}
|
|
||||||
{ writeln(' bitDisp = ', bitDisp:3, '; fp^.bitDisp = ', fp^.bitDisp:3); {debug}
|
|
||||||
{ writeln(' bitSize = ', bitSize:3, '; fp^.bitSize = ', fp^.bitSize:3); {debug}
|
|
||||||
Initialize(id, disp, itype);
|
|
||||||
if bitsize = 0 then begin
|
|
||||||
if bitcount <> 0 then begin
|
|
||||||
disp := disp + (bitcount+7) div 8;
|
|
||||||
bitcount := 0;
|
|
||||||
end {if}
|
|
||||||
else if fp^.bitSize <> 0 then begin
|
|
||||||
bitcount := 8;
|
|
||||||
while (fp <> nil) and (bitcount > 0) do begin
|
|
||||||
bitcount := bitcount - fp^.bitSize;
|
|
||||||
if bitcount > 0 then
|
|
||||||
if fp^.next <> nil then
|
|
||||||
if fp^.next^.bitSize <> 0 then
|
|
||||||
fp := fp^.next
|
|
||||||
else
|
|
||||||
bitcount := 0;
|
|
||||||
end; {while}
|
|
||||||
bitcount := 0;
|
|
||||||
disp := disp + 1;
|
|
||||||
end {else if}
|
|
||||||
else
|
|
||||||
disp := disp + itype^.size;
|
|
||||||
end {if}
|
|
||||||
else if fp^.bitSize = 0 then begin
|
|
||||||
bitsize := 0;
|
|
||||||
disp := disp + itype^.size;
|
|
||||||
end {else if}
|
|
||||||
else begin
|
|
||||||
if bitsize + bitdisp < bitcount then
|
|
||||||
disp := disp + (bitcount + 7) div 8;
|
|
||||||
bitcount := bitsize + bitdisp;
|
|
||||||
end; {else}
|
|
||||||
if itype^.kind in [scalarType,pointerType,enumType] then begin
|
|
||||||
count := count-1;
|
|
||||||
if count = 0 then begin
|
|
||||||
iPtr := iPtr^.next;
|
|
||||||
count := iPtr^.count;
|
|
||||||
bitsize := iPtr^.bitsize;
|
|
||||||
bitdisp := iPtr^.bitdisp;
|
|
||||||
end; {if}
|
|
||||||
end; {if}
|
|
||||||
if union then
|
|
||||||
fp := nil
|
|
||||||
else
|
|
||||||
fp := fp^.next;
|
|
||||||
end; {while}
|
|
||||||
end; {else}
|
|
||||||
end;
|
|
||||||
|
|
||||||
otherwise: Error(57);
|
|
||||||
end; {case}
|
|
||||||
end; {Initialize}
|
|
||||||
|
|
||||||
|
|
||||||
begin {AutoInit}
|
|
||||||
lp1 := nil; {reverse the list}
|
|
||||||
while initializerList <> nil do begin
|
|
||||||
lp2 := initializerList;
|
|
||||||
initializerList := lp2^.next;
|
|
||||||
lp2^.next := lp1;
|
|
||||||
lp1 := lp2;
|
|
||||||
end; {while}
|
|
||||||
while lp1 <> nil do begin {initialize the variables}
|
|
||||||
ip := lp1^.id;
|
|
||||||
iPtr := ip^.iPtr;
|
|
||||||
count := iPtr^.count;
|
|
||||||
if ip^.class <> staticsy then
|
|
||||||
Initialize(ip, 0, ip^.itype);
|
|
||||||
lp2 := lp1;
|
|
||||||
lp1 := lp1^.next;
|
|
||||||
dispose(lp2);
|
|
||||||
end; {while}
|
|
||||||
end; {AutoInit}
|
|
||||||
|
|
||||||
|
|
||||||
begin {DoStatement}
|
begin {DoStatement}
|
||||||
case statementList^.kind of
|
case statementList^.kind of
|
||||||
|
|
||||||
compoundSt: begin
|
compoundSt: begin
|
||||||
if token.kind = rbracech then begin
|
if token.kind = rbracech then begin
|
||||||
if statementList^.doingDeclaration then
|
|
||||||
if initializerList <> nil then
|
|
||||||
AutoInit;
|
|
||||||
EndCompoundStatement;
|
EndCompoundStatement;
|
||||||
end {if}
|
end {if}
|
||||||
else if (statementList^.doingDeclaration = true)
|
else if (statementList^.doingDeclaration or allowMixedDeclarations)
|
||||||
and (token.kind in [autosy,externsy,registersy,staticsy,typedefsy,
|
and (token.kind in [autosy,externsy,registersy,staticsy,typedefsy,
|
||||||
unsignedsy,signedsy,intsy,longsy,charsy,shortsy,
|
unsignedsy,signedsy,intsy,longsy,charsy,shortsy,
|
||||||
floatsy,doublesy,compsy,extendedsy,enumsy,
|
floatsy,doublesy,compsy,extendedsy,enumsy,
|
||||||
@ -3954,8 +3674,6 @@ case statementList^.kind of
|
|||||||
Gen1Name(dc_sym, ord(doingMain), pointer(table));
|
Gen1Name(dc_sym, ord(doingMain), pointer(table));
|
||||||
firstCompoundStatement := false;
|
firstCompoundStatement := false;
|
||||||
end; {if}
|
end; {if}
|
||||||
if initializerList <> nil then
|
|
||||||
AutoInit;
|
|
||||||
end; {if}
|
end; {if}
|
||||||
Statement;
|
Statement;
|
||||||
end; {else}
|
end; {else}
|
||||||
@ -3984,6 +3702,276 @@ case statementList^.kind of
|
|||||||
end; {DoStatement}
|
end; {DoStatement}
|
||||||
|
|
||||||
|
|
||||||
|
procedure AutoInit {variable: identPtr};
|
||||||
|
|
||||||
|
{ generate code to initialize an auto variable }
|
||||||
|
{ }
|
||||||
|
{ parameters: }
|
||||||
|
{ variable - the variable to initialize }
|
||||||
|
|
||||||
|
var
|
||||||
|
count: integer; {initializer counter}
|
||||||
|
iPtr: initializerPtr; {pointer to the next initializer}
|
||||||
|
|
||||||
|
|
||||||
|
procedure Initialize (id: identPtr; disp: longint; itype: typePtr);
|
||||||
|
|
||||||
|
{ initialize a variable }
|
||||||
|
{ }
|
||||||
|
{ parameters: }
|
||||||
|
{ id - pointer to the identifier }
|
||||||
|
{ disp - disp past the identifier to initialize }
|
||||||
|
{ itype - type of the variable to initialize }
|
||||||
|
{ }
|
||||||
|
{ variables: }
|
||||||
|
{ count - number of times to re-use the initializer }
|
||||||
|
{ ip - pointer to the initializer record to use }
|
||||||
|
|
||||||
|
label 1;
|
||||||
|
|
||||||
|
var
|
||||||
|
elements: longint; {# array elements}
|
||||||
|
fp: identPtr; {for tracing field lists}
|
||||||
|
size: integer; {fill size}
|
||||||
|
union: boolean; {are we doing a union?}
|
||||||
|
|
||||||
|
{bit field manipulation}
|
||||||
|
{----------------------}
|
||||||
|
bitcount: integer; {# if bits so far}
|
||||||
|
bitsize,bitdisp: integer; {defines size, location of a bit field}
|
||||||
|
|
||||||
|
{assignment conversion}
|
||||||
|
{---------------------}
|
||||||
|
tree: tokenPtr; {expression tree}
|
||||||
|
val: longint; {constant expression value}
|
||||||
|
isConstant: boolean; {is the expression a constant?}
|
||||||
|
|
||||||
|
|
||||||
|
procedure LoadAddress;
|
||||||
|
|
||||||
|
{ Load the address of the operand }
|
||||||
|
|
||||||
|
begin {LoadAddress}
|
||||||
|
with id^ do {load the base address}
|
||||||
|
case storage of
|
||||||
|
stackFrame: Gen2(pc_lda, lln, 0);
|
||||||
|
parameter: if itype^.kind = arrayType then
|
||||||
|
Gen2t(pc_lod, pln, 0, cgULong)
|
||||||
|
else
|
||||||
|
Gen2(pc_lda, pln, 0);
|
||||||
|
external,
|
||||||
|
global,
|
||||||
|
private: Gen1Name(pc_lao, 0, name);
|
||||||
|
otherwise: ;
|
||||||
|
end; {case}
|
||||||
|
if disp <> 0 then
|
||||||
|
Gen1t(pc_inc, long(disp).lsw, cgULong)
|
||||||
|
end; {LoadAddress}
|
||||||
|
|
||||||
|
|
||||||
|
function ZeroFill (elements: longint; itype: typePtr;
|
||||||
|
count: integer; iPtr: initializerPtr): boolean;
|
||||||
|
|
||||||
|
{ See if an array can be zero filled }
|
||||||
|
{ }
|
||||||
|
{ parameters: }
|
||||||
|
{ elements - elements in the array }
|
||||||
|
{ itype - type of each array element }
|
||||||
|
{ count - remaining initializer repititions }
|
||||||
|
{ iPtr - initializer record }
|
||||||
|
|
||||||
|
begin {ZeroFill}
|
||||||
|
ZeroFill := false;
|
||||||
|
if not iPtr^.isConstant then
|
||||||
|
if itype^.kind in [scalarType,enumType] then
|
||||||
|
if count >= elements then
|
||||||
|
with iPtr^.itree^ do
|
||||||
|
if token.kind = intconst then
|
||||||
|
if token.ival = 0 then
|
||||||
|
{don't call ~ZERO for very small arrays}
|
||||||
|
if elements * itype^.size > 10 then
|
||||||
|
ZeroFill := true;
|
||||||
|
end; {ZeroFill}
|
||||||
|
|
||||||
|
|
||||||
|
begin {Initialize}
|
||||||
|
case itype^.kind of
|
||||||
|
|
||||||
|
scalarType,pointerType,enumType,functionType: begin
|
||||||
|
LoadAddress; {load the destination address}
|
||||||
|
doDispose := count = 1; {generate the expression value}
|
||||||
|
tree := iptr^.itree; {see if this is a constant}
|
||||||
|
{do assignment conversions}
|
||||||
|
while tree^.token.kind = castoper do
|
||||||
|
tree := tree^.left;
|
||||||
|
isConstant := tree^.token.class in [intConstant,longConstant];
|
||||||
|
if isConstant then
|
||||||
|
if tree^.token.class = intConstant then
|
||||||
|
val := tree^.token.ival
|
||||||
|
else
|
||||||
|
val := tree^.token.lval;
|
||||||
|
|
||||||
|
{ if isConstant then
|
||||||
|
if tree^.token.class = intConstant then
|
||||||
|
Writeln('loc 2: bitsize = ', iPtr^.bitsize:1, '; ival = ', tree^.token.ival:1) {debug}
|
||||||
|
{ else
|
||||||
|
Writeln('loc 2: bitsize = ', iPtr^.bitsize:1, '; lval = ', tree^.token.lval:1) {debug}
|
||||||
|
{ else
|
||||||
|
Writeln('loc 2: bitsize = ', iPtr^.bitsize:1); {debug}
|
||||||
|
|
||||||
|
GenerateCode(iptr^.iTree);
|
||||||
|
AssignmentConversion(itype, expressionType, isConstant, val, true,
|
||||||
|
false);
|
||||||
|
case itype^.kind of {save the value}
|
||||||
|
scalarType:
|
||||||
|
if iptr^.bitsize <> 0 then
|
||||||
|
Gen2t(pc_sbf, iptr^.bitdisp, iptr^.bitsize, itype^.basetype)
|
||||||
|
else
|
||||||
|
Gen0t(pc_sto, itype^.baseType);
|
||||||
|
enumType:
|
||||||
|
Gen0t(pc_sto, cgWord);
|
||||||
|
pointerType,functionType:
|
||||||
|
Gen0t(pc_sto, cgULong);
|
||||||
|
end; {case}
|
||||||
|
end;
|
||||||
|
|
||||||
|
arrayType: begin
|
||||||
|
if itype^.aType^.kind = scalarType then
|
||||||
|
if itype^.aType^.baseType in [cgByte,cgUByte] then
|
||||||
|
if iPtr^.iTree^.token.kind = stringConst then begin
|
||||||
|
GenLdcLong(itype^.elements);
|
||||||
|
Gen0t(pc_stk, cgULong);
|
||||||
|
GenS(pc_lca, iPtr^.iTree^.token.sval);
|
||||||
|
Gen0t(pc_stk, cgULong);
|
||||||
|
Gen0t(pc_bno, cgULong);
|
||||||
|
LoadAddress;
|
||||||
|
Gen0t(pc_stk, cgULong);
|
||||||
|
Gen0t(pc_bno, cgULong);
|
||||||
|
Gen1tName(pc_cup, 0, cgVoid, @'strncpy');
|
||||||
|
iPtr := iPtr^.next;
|
||||||
|
goto 1;
|
||||||
|
end; {if}
|
||||||
|
elements := itype^.elements;
|
||||||
|
itype := itype^.atype;
|
||||||
|
if ZeroFill(elements, itype, count, iPtr) then begin
|
||||||
|
if itype^.kind = enumType then
|
||||||
|
size := cgWordSize
|
||||||
|
else
|
||||||
|
size := TypeSize(itype^.baseType);
|
||||||
|
size := size * long(elements).lsw;
|
||||||
|
LoadAddress;
|
||||||
|
Gen0t(pc_stk, cgULong);
|
||||||
|
Gen1t(pc_ldc, size, cgWord);
|
||||||
|
Gen0t(pc_stk, cgWord);
|
||||||
|
Gen0t(pc_bno, cgULong);
|
||||||
|
Gen1tName(pc_cup, 0, cgVoid, @'~ZERO');
|
||||||
|
disp := disp + size;
|
||||||
|
count := count - long(elements).lsw;
|
||||||
|
if count = 0 then begin
|
||||||
|
iPtr := iPtr^.next;
|
||||||
|
count := iPtr^.count;
|
||||||
|
end; {if}
|
||||||
|
end {if}
|
||||||
|
else begin
|
||||||
|
while elements <> 0 do begin
|
||||||
|
Initialize(id, disp, itype);
|
||||||
|
if itype^.kind in [scalarType,pointerType,enumType] then begin
|
||||||
|
count := count-1;
|
||||||
|
if count = 0 then begin
|
||||||
|
iPtr := iPtr^.next;
|
||||||
|
count := iPtr^.count;
|
||||||
|
end; {if}
|
||||||
|
end; {if}
|
||||||
|
disp := disp+itype^.size;
|
||||||
|
elements := elements-1;
|
||||||
|
end; {while}
|
||||||
|
end; {else}
|
||||||
|
1: end;
|
||||||
|
|
||||||
|
structType,unionType: begin
|
||||||
|
if iPtr^.isStructOrUnion then begin
|
||||||
|
LoadAddress; {load the destination address}
|
||||||
|
GenerateCode(iptr^.iTree); {load the stuct address}
|
||||||
|
{do the assignment}
|
||||||
|
AssignmentConversion(itype, expressionType, isConstant, val,
|
||||||
|
true, false);
|
||||||
|
with expressionType^ do
|
||||||
|
Gen2(pc_mov, long(size).msw, long(size).lsw);
|
||||||
|
Gen0t(pc_pop, UsualUnaryConversions);
|
||||||
|
end {if}
|
||||||
|
else begin
|
||||||
|
union := itype^.kind = unionType;
|
||||||
|
fp := itype^.fieldList;
|
||||||
|
bitsize := iPtr^.bitsize;
|
||||||
|
bitdisp := iPtr^.bitdisp;
|
||||||
|
bitcount := 0;
|
||||||
|
while fp <> nil do begin
|
||||||
|
itype := fp^.itype;
|
||||||
|
{ writeln('Initialize: disp = ', disp:3, '; fp^. Disp = ', fp^.disp:3, 'itype^.size = ', itype^.size:1); {debug}
|
||||||
|
{ writeln(' bitDisp = ', bitDisp:3, '; fp^.bitDisp = ', fp^.bitDisp:3); {debug}
|
||||||
|
{ writeln(' bitSize = ', bitSize:3, '; fp^.bitSize = ', fp^.bitSize:3); {debug}
|
||||||
|
Initialize(id, disp, itype);
|
||||||
|
if bitsize = 0 then begin
|
||||||
|
if bitcount <> 0 then begin
|
||||||
|
disp := disp + (bitcount+7) div 8;
|
||||||
|
bitcount := 0;
|
||||||
|
end {if}
|
||||||
|
else if fp^.bitSize <> 0 then begin
|
||||||
|
bitcount := 8;
|
||||||
|
while (fp <> nil) and (bitcount > 0) do begin
|
||||||
|
bitcount := bitcount - fp^.bitSize;
|
||||||
|
if bitcount > 0 then
|
||||||
|
if fp^.next <> nil then
|
||||||
|
if fp^.next^.bitSize <> 0 then
|
||||||
|
fp := fp^.next
|
||||||
|
else
|
||||||
|
bitcount := 0;
|
||||||
|
end; {while}
|
||||||
|
bitcount := 0;
|
||||||
|
disp := disp + 1;
|
||||||
|
end {else if}
|
||||||
|
else
|
||||||
|
disp := disp + itype^.size;
|
||||||
|
end {if}
|
||||||
|
else if fp^.bitSize = 0 then begin
|
||||||
|
bitsize := 0;
|
||||||
|
disp := disp + itype^.size;
|
||||||
|
end {else if}
|
||||||
|
else begin
|
||||||
|
if bitsize + bitdisp < bitcount then
|
||||||
|
disp := disp + (bitcount + 7) div 8;
|
||||||
|
bitcount := bitsize + bitdisp;
|
||||||
|
end; {else}
|
||||||
|
if itype^.kind in [scalarType,pointerType,enumType] then begin
|
||||||
|
count := count-1;
|
||||||
|
if count = 0 then begin
|
||||||
|
iPtr := iPtr^.next;
|
||||||
|
count := iPtr^.count;
|
||||||
|
bitsize := iPtr^.bitsize;
|
||||||
|
bitdisp := iPtr^.bitdisp;
|
||||||
|
end; {if}
|
||||||
|
end; {if}
|
||||||
|
if union then
|
||||||
|
fp := nil
|
||||||
|
else
|
||||||
|
fp := fp^.next;
|
||||||
|
end; {while}
|
||||||
|
end; {else}
|
||||||
|
end;
|
||||||
|
|
||||||
|
otherwise: Error(57);
|
||||||
|
end; {case}
|
||||||
|
end; {Initialize}
|
||||||
|
|
||||||
|
|
||||||
|
begin {AutoInit}
|
||||||
|
iPtr := variable^.iPtr;
|
||||||
|
count := iPtr^.count;
|
||||||
|
if variable^.class <> staticsy then
|
||||||
|
Initialize(variable, 0, variable^.itype);
|
||||||
|
end; {AutoInit}
|
||||||
|
|
||||||
|
|
||||||
procedure InitParser;
|
procedure InitParser;
|
||||||
|
|
||||||
{ Initialize the parser }
|
{ Initialize the parser }
|
||||||
|
Loading…
Reference in New Issue
Block a user