Local Variables.
Still got issues with code generation, and for some reason identifier IDs are always 1.
This commit is contained in:
parent
e2120bb171
commit
384f46054a
|
@ -361,15 +361,19 @@ int AsMul(int Left, int Right);
|
||||||
int AsSub(int Left, int Right);
|
int AsSub(int Left, int Right);
|
||||||
int AsDiv(int Left, int Right);
|
int AsDiv(int Left, int Right);
|
||||||
|
|
||||||
int AsLdVar(int ID, int Operation);
|
int AsLdGlobalVar(int ID, int Operation);
|
||||||
int AsStrVar(int Register, int ID);
|
int AsLdLocalVar(int ID, int Operation);
|
||||||
|
int AsStrGlobalVar(int Register, int ID);
|
||||||
|
int AsStrLocalVar(int Register, int ID);
|
||||||
|
|
||||||
|
int AsCalcOffset(int Type, int Param);
|
||||||
|
void AsNewStackFrame();
|
||||||
|
|
||||||
int AsDeref(int Reg, int Type);
|
int AsDeref(int Reg, int Type);
|
||||||
int AsStrDeref(int Register1, int Register2, int Type);
|
int AsStrDeref(int Register1, int Register2, int Type);
|
||||||
int AsAddr(int ID);
|
int AsAddr(int ID);
|
||||||
|
|
||||||
void AsNewSymb(int ID);
|
void AsGlobalSymbol(int ID);
|
||||||
int AsNewString(char* Value);
|
int AsNewString(char* Value);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,12 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
|
||||||
if(Node->Right == NULL)
|
if(Node->Right == NULL)
|
||||||
Die("Fault in assigning a null rvalue");
|
Die("Fault in assigning a null rvalue");
|
||||||
switch(Node->Right->Operation) {
|
switch(Node->Right->Operation) {
|
||||||
case REF_IDENT: return AsStrVar(LeftVal, Node->Right->Value.ID);
|
case REF_IDENT:
|
||||||
|
if(Symbols[Node->Value.ID].Storage == SC_LOCAL)
|
||||||
|
return AsStrLocalVar(Node->Value.ID, Node->Operation);
|
||||||
|
else
|
||||||
|
return AsStrGlobalVar(Node->Value.ID, Node->Operation);
|
||||||
|
|
||||||
case OP_DEREF: return AsStrDeref(LeftVal, RightVal, Node->Right->ExprType);
|
case OP_DEREF: return AsStrDeref(LeftVal, RightVal, Node->Right->ExprType);
|
||||||
default: DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation);
|
default: DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation);
|
||||||
}
|
}
|
||||||
|
@ -162,9 +167,12 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
|
||||||
|
|
||||||
|
|
||||||
case REF_IDENT:
|
case REF_IDENT:
|
||||||
if(Node->RVal || ParentOp == OP_DEREF)
|
if(Node->RVal || ParentOp == OP_DEREF) {
|
||||||
return AsLdVar(Node->Value.ID, Node->Operation);
|
if(Symbols[Node->Value.ID].Storage == SC_LOCAL)
|
||||||
|
return AsLdLocalVar(Node->Value.ID, Node->Operation);
|
||||||
else
|
else
|
||||||
|
return AsLdGlobalVar(Node->Value.ID, Node->Operation);
|
||||||
|
} else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
case TERM_INTLITERAL:
|
case TERM_INTLITERAL:
|
||||||
|
@ -199,16 +207,16 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
|
||||||
return AsShiftRight(LeftVal, RightVal);
|
return AsShiftRight(LeftVal, RightVal);
|
||||||
|
|
||||||
case OP_POSTINC:
|
case OP_POSTINC:
|
||||||
return AsLdVar(Node->Value.IntValue, Node->Operation);
|
return AsLdGlobalVar(Node->Value.IntValue, Node->Operation);
|
||||||
|
|
||||||
case OP_POSTDEC:
|
case OP_POSTDEC:
|
||||||
return AsLdVar(Node->Value.IntValue, Node->Operation);
|
return AsLdGlobalVar(Node->Value.IntValue, Node->Operation);
|
||||||
|
|
||||||
case OP_PREINC:
|
case OP_PREINC:
|
||||||
return AsLdVar(Node->Value.IntValue, Node->Operation);
|
return AsLdGlobalVar(Node->Value.IntValue, Node->Operation);
|
||||||
|
|
||||||
case OP_PREDEC:
|
case OP_PREDEC:
|
||||||
return AsLdVar(Node->Value.IntValue, Node->Operation);
|
return AsLdGlobalVar(Node->Value.IntValue, Node->Operation);
|
||||||
|
|
||||||
case OP_BOOLNOT:
|
case OP_BOOLNOT:
|
||||||
return AsBooleanNOT(LeftVal);
|
return AsBooleanNOT(LeftVal);
|
||||||
|
@ -455,7 +463,7 @@ int AsShl(int Register, int Val) {
|
||||||
int AsLdGlobalVar(int ID, int Operation) {
|
int AsLdGlobalVar(int ID, int Operation) {
|
||||||
int Reg = RetrieveRegister();
|
int Reg = RetrieveRegister();
|
||||||
|
|
||||||
printf("\tStoring %s's contents into %s\n", Symbols[ID].Name, Registers[Reg]);
|
printf("\tStoring %s's contents into %s, globally\n", Symbols[ID].Name, Registers[Reg]);
|
||||||
|
|
||||||
switch(Symbols[ID].Type) {
|
switch(Symbols[ID].Type) {
|
||||||
case RET_CHAR:
|
case RET_CHAR:
|
||||||
|
@ -526,7 +534,7 @@ int AsLdGlobalVar(int ID, int Operation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int AsStrGlobalVar(int Register, int ID) {
|
int AsStrGlobalVar(int Register, int ID) {
|
||||||
printf("\tStoring contents of %s into %s, type %d\n", Registers[Register], Symbols[ID].Name, Symbols[ID].Type);
|
printf("\tStoring contents of %s into %s, type %d, globally: ID %d\n", Registers[Register], Symbols[ID].Name, Symbols[ID].Type, ID);
|
||||||
|
|
||||||
switch(Symbols[ID].Type) {
|
switch(Symbols[ID].Type) {
|
||||||
case RET_CHAR:
|
case RET_CHAR:
|
||||||
|
@ -556,7 +564,7 @@ int AsStrGlobalVar(int Register, int ID) {
|
||||||
int AsLdLocalVar(int ID, int Operation) {
|
int AsLdLocalVar(int ID, int Operation) {
|
||||||
int Reg = RetrieveRegister();
|
int Reg = RetrieveRegister();
|
||||||
|
|
||||||
printf("\tStoring the var at %d's contents into %s\n", Symbols[ID].SinkOffset, Registers[Reg]);
|
printf("\tStoring the var at %d's contents into %s, locally\n", Symbols[ID].SinkOffset, Registers[Reg]);
|
||||||
|
|
||||||
switch(Symbols[ID].Type) {
|
switch(Symbols[ID].Type) {
|
||||||
case RET_CHAR:
|
case RET_CHAR:
|
||||||
|
@ -627,7 +635,7 @@ int AsLdLocalVar(int ID, int Operation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int AsStrLocalVar(int Register, int ID) {
|
int AsStrLocalVar(int Register, int ID) {
|
||||||
printf("\tStoring contents of %s into %s, type %d\n", Registers[Register], Symbols[ID].Name, Symbols[ID].Type);
|
printf("\tStoring contents of %s into %s, type %d, locally\n", Registers[Register], Symbols[ID].Name, Symbols[ID].Type);
|
||||||
|
|
||||||
switch(Symbols[ID].Type) {
|
switch(Symbols[ID].Type) {
|
||||||
case RET_CHAR:
|
case RET_CHAR:
|
||||||
|
@ -698,7 +706,7 @@ int AsStrDeref(int Register1, int Register2, int Type) {
|
||||||
return Register1;
|
return Register1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsNewSymb(int ID) {
|
void AsGlobalSymbol(int ID) {
|
||||||
int TypeSize;
|
int TypeSize;
|
||||||
|
|
||||||
TypeSize = PrimitiveSize(Symbols[ID].Type);
|
TypeSize = PrimitiveSize(Symbols[ID].Type);
|
||||||
|
@ -878,6 +886,8 @@ void AssemblerPreamble() {
|
||||||
void AsFunctionPreamble(int FunctionID) {
|
void AsFunctionPreamble(int FunctionID) {
|
||||||
char* Name = Symbols[FunctionID].Name;
|
char* Name = Symbols[FunctionID].Name;
|
||||||
|
|
||||||
|
StackFrameOffset = (LocalVarOffset + 15) & ~15;
|
||||||
|
|
||||||
fprintf(OutputFile,
|
fprintf(OutputFile,
|
||||||
"\t.text\n"
|
"\t.text\n"
|
||||||
"\t.globl\t%s\n"
|
"\t.globl\t%s\n"
|
||||||
|
@ -885,7 +895,7 @@ void AsFunctionPreamble(int FunctionID) {
|
||||||
"%s:\n"
|
"%s:\n"
|
||||||
"\tpushq\t%%rbp\n"
|
"\tpushq\t%%rbp\n"
|
||||||
"\tmovq\t%%rsp, %%rbp\n"
|
"\tmovq\t%%rsp, %%rbp\n"
|
||||||
"\tsubq\t$32, %%rsp\n", Name, Name, Name);
|
"\taddq\t%d, %%rsp\n", Name, Name, Name, -StackFrameOffset);
|
||||||
|
|
||||||
//PECOFF requires we call the global initialisers
|
//PECOFF requires we call the global initialisers
|
||||||
if(!strcmp(Name, "main"))
|
if(!strcmp(Name, "main"))
|
||||||
|
@ -895,9 +905,9 @@ void AsFunctionPreamble(int FunctionID) {
|
||||||
void AsFunctionEpilogue(int FunctionID) {
|
void AsFunctionEpilogue(int FunctionID) {
|
||||||
AsLabel(Symbols[FunctionID].EndLabel);
|
AsLabel(Symbols[FunctionID].EndLabel);
|
||||||
|
|
||||||
fputs(
|
fprintf(OutputFile,
|
||||||
"\tpopq\t%rbp\n"
|
"\tpopq\t%rbp\n"
|
||||||
"\taddq\t$32, %rsp\n"
|
"\taddq\t%d, %rsp\n"
|
||||||
"\tret\n",
|
"\tret\n",
|
||||||
OutputFile);
|
StackFrameOffset);
|
||||||
}
|
}
|
|
@ -82,6 +82,8 @@ char* TypeNames[9] = { "none", "char", "int", "long", "void", "charptr", "intpt
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
Line = 1;
|
Line = 1;
|
||||||
Overread = '\n';
|
Overread = '\n';
|
||||||
|
CurrentGlobal = 0;
|
||||||
|
CurrentLocal = SYMBOLS - 1;
|
||||||
struct ASTNode* Node;
|
struct ASTNode* Node;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,21 +31,14 @@ void BeginVariableDeclaration(int Type, int Scope) {
|
||||||
//Type = Type - 2;
|
//Type = Type - 2;
|
||||||
if(CurrentToken.type == LI_INT) {
|
if(CurrentToken.type == LI_INT) {
|
||||||
printf("Adding array %s that is %d x %s.\r\n", CurrentIdentifier, CurrentToken.value, TypeNames[Type]);
|
printf("Adding array %s that is %d x %s.\r\n", CurrentIdentifier, CurrentToken.value, TypeNames[Type]);
|
||||||
if(Scope == SC_LOCAL) {
|
AddSymbol(CurrentIdentifier, PointerTo(Type), ST_ARR, Scope, 0, CurrentToken.value);
|
||||||
AddSymbol(CurrentIdentifier, PointerTo(Type), ST_ARR, SC_LOCAL, 0, CurrentToken.value);
|
|
||||||
} else if(Scope == SC_GLOBAL) {
|
|
||||||
AddSymbol(CurrentIdentifier, PointerTo(Type), ST_ARR, SC_GLOBAL, 0, CurrentToken.value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tokenise(&CurrentToken);
|
Tokenise(&CurrentToken);
|
||||||
VerifyToken(LI_RBRAS, "]");
|
VerifyToken(LI_RBRAS, "]");
|
||||||
} else {
|
} else {
|
||||||
if(Scope == SC_LOCAL) {
|
printf("Adding var %s that is a %s\r\n", CurrentIdentifier, TypeNames[Type]);
|
||||||
AddSymbol(CurrentIdentifier, Type, ST_VAR, SC_LOCAL, 0, 1);
|
AddSymbol(CurrentIdentifier, Type, ST_VAR, Scope, 0, 1);
|
||||||
} else if(Scope == SC_GLOBAL) {
|
|
||||||
AddSymbol(CurrentIdentifier, Type, ST_VAR, SC_GLOBAL, 0, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VerifyToken(LI_SEMIC, ";");
|
VerifyToken(LI_SEMIC, ";");
|
||||||
|
|
|
@ -13,14 +13,21 @@ static int GlobalSymbols = 0;
|
||||||
int FindSymbolImpl(char* Symbol, int Storage) {
|
int FindSymbolImpl(char* Symbol, int Storage) {
|
||||||
int Ind;
|
int Ind;
|
||||||
|
|
||||||
for(Ind = 0; Ind < (Storage == SC_GLOBAL /* Are we global scope? */
|
for(Ind = (Storage == SC_GLOBAL /* Are we global scope? */
|
||||||
|
? 0 /* If so, start from the beginning */
|
||||||
|
: CurrentLocal + 1 /* Else, go from the start of the local block */
|
||||||
|
);
|
||||||
|
Ind < (Storage == SC_GLOBAL /* Are we global scope? */
|
||||||
? CurrentGlobal /* If so, start searching at the start */
|
? CurrentGlobal /* If so, start searching at the start */
|
||||||
: SYMBOLS /* Otherwise, start at the end and work backward */
|
: SYMBOLS /* Otherwise, start at the end and work backward */
|
||||||
); Ind++) {
|
);
|
||||||
|
Ind++) {
|
||||||
|
|
||||||
if(*Symbol == *Symbols[Ind].Name && !strcmp(Symbol, Symbols[Ind].Name))
|
if(*Symbol == *Symbols[Ind].Name && !strcmp(Symbol, Symbols[Ind].Name)) {
|
||||||
|
printf("\t\tFound %s at %d\r\n", Symbol, Ind);
|
||||||
return Ind;
|
return Ind;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -52,8 +59,10 @@ int FindSymbol(char* Symbol) {
|
||||||
static int NewGlobalSymbol() {
|
static int NewGlobalSymbol() {
|
||||||
int Pos;
|
int Pos;
|
||||||
|
|
||||||
if((Pos = (CurrentGlobal++)) >= CurrentLocal)
|
if((Pos = (CurrentGlobal++)) >= CurrentLocal) {
|
||||||
|
printf("%d:%d\r\n", CurrentGlobal, CurrentLocal);
|
||||||
Die("Too many Global symbols");
|
Die("Too many Global symbols");
|
||||||
|
}
|
||||||
|
|
||||||
return Pos;
|
return Pos;
|
||||||
}
|
}
|
||||||
|
@ -97,10 +106,12 @@ int AddSymbol(char* Name, int Type, int Structure, int Storage, int EndLabel, in
|
||||||
// we can use this switch to avoid duplicated code.
|
// we can use this switch to avoid duplicated code.
|
||||||
switch(Storage) {
|
switch(Storage) {
|
||||||
case SC_GLOBAL:
|
case SC_GLOBAL:
|
||||||
|
printf("\tCreating new global symbol %s\r\n", Name);
|
||||||
TableSlot = NewGlobalSymbol();
|
TableSlot = NewGlobalSymbol();
|
||||||
AsGlobalSymbol(TableSlot);
|
AsGlobalSymbol(TableSlot);
|
||||||
break;
|
break;
|
||||||
case SC_LOCAL:
|
case SC_LOCAL:
|
||||||
|
printf("\tCreating new local symbol %s\r\n", Name);
|
||||||
TableSlot = NewLocalSymbol();
|
TableSlot = NewLocalSymbol();
|
||||||
SinkOffset = AsCalcOffset(Type, 0);
|
SinkOffset = AsCalcOffset(Type, 0);
|
||||||
break;
|
break;
|
||||||
|
|
10
tests/locals
Normal file
10
tests/locals
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
int a; int b; int c;
|
||||||
|
|
||||||
|
int :: main()
|
||||||
|
{
|
||||||
|
char z; int y; int x;
|
||||||
|
x= 10; y= 20; z= 30;
|
||||||
|
a= 5; b= 15; c= 25;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user