From e2120bb171cb85a871f10d0fb5baf3f0fd435983 Mon Sep 17 00:00:00 2001 From: Curle Date: Wed, 25 Nov 2020 22:53:50 +0000 Subject: [PATCH] Working on the refactor for local symbols. --- include/Defs.h | 9 +--- src/Assembler.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++- src/Main.c | 6 +-- src/Parser.c | 9 ++-- src/Statements.c | 38 +++++---------- src/Symbols.c | 2 +- tests/inv_neg | 36 ++++++++++++++ 7 files changed, 179 insertions(+), 42 deletions(-) create mode 100644 tests/inv_neg diff --git a/include/Defs.h b/include/Defs.h index 09e96cd..846d3b4 100644 --- a/include/Defs.h +++ b/include/Defs.h @@ -290,7 +290,7 @@ struct ASTNode* ConstructASTBranch(int Operation, int Type, struct ASTNode* Left //struct ASTNode* ParseAdditiveASTNode(void); struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence); -int ParseAST(struct ASTNode* Node); +//int ParseAST(struct ASTNode* Node); struct ASTNode* ParsePrimary(void); //void ParseStatements(void); @@ -327,11 +327,6 @@ int FindSymbol(char* Symbol); int AddSymbol(char* Name, int Type, int Structure, int Storage, int EndLabel, int Length); -int AddFunctionSymbol(char* Name, int Type, int Structure, int EndLabel, int Size); - -int AddArraySymbol(char* Name, int Type, int Structure, int EndLabel, int Size); - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * C O N T R O L S T A T U S * * * * @@ -423,7 +418,7 @@ void AsFunctionEpilogue(int ID); * * * * D E C L A R A T I O N * * * * * * * * * * * * * * * * * * * * * * * * * * */ -void BeginVariableDeclaration(int Type); +void BeginVariableDeclaration(int Type, int Scope); struct ASTNode* ParseIdentifier(void); struct ASTNode* IfStatement(); diff --git a/src/Assembler.c b/src/Assembler.c index 848543a..83ac411 100644 --- a/src/Assembler.c +++ b/src/Assembler.c @@ -26,6 +26,9 @@ static char* ByteRegisters[4] = { "%r8b", "%r9b", "%r10b", "%r11b" }; static char* Comparisons[6] = { "sete", "setne", "setl", "setg", "setle", "setge" }; static char* InvComparisons[6] = { "jne", "je", "jge", "jle", "jg", "jl"}; +static int LocalVarOffset; +static int StackFrameOffset; + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * R O O T O F A S S E M B L E R * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -255,6 +258,19 @@ void DeallocateRegister(int Register) { UsedRegisters[Register] = 0; } +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * * * * * S T A C K M A N A G E M E N T * * * * * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void AsNewStackFrame() { + LocalVarOffset = 0; +} + +int AsCalcOffset(int Type, int Param) { + LocalVarOffset += PrimitiveSize(Type) > 4 ? PrimitiveSize(Type) : 4; + return -LocalVarOffset; +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * C O D E G E N E R A T I O N * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -436,7 +452,7 @@ int AsShl(int Register, int Val) { return Register; } -int AsLdVar(int ID, int Operation) { +int AsLdGlobalVar(int ID, int Operation) { int Reg = RetrieveRegister(); printf("\tStoring %s's contents into %s\n", Symbols[ID].Name, Registers[Reg]); @@ -509,7 +525,7 @@ int AsLdVar(int ID, int Operation) { return Reg; } -int AsStrVar(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); switch(Symbols[ID].Type) { @@ -537,6 +553,107 @@ int AsStrVar(int Register, int ID) { return Register; } +int AsLdLocalVar(int ID, int Operation) { + int Reg = RetrieveRegister(); + + printf("\tStoring the var at %d's contents into %s\n", Symbols[ID].SinkOffset, Registers[Reg]); + + switch(Symbols[ID].Type) { + case RET_CHAR: + switch(Operation) { + case OP_PREINC: + fprintf(OutputFile, "\tincb\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + case OP_PREDEC: + fprintf(OutputFile, "\tdecb\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + } + + fprintf(OutputFile, "\tmovzbq\t%d(\%%rip), %s\n", Symbols[ID].SinkOffset, Registers[Reg]); + + switch(Operation) { + case OP_POSTINC: + fprintf(OutputFile, "\tincb\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + case OP_POSTDEC: + fprintf(OutputFile, "\tdecb\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + } + + break; + + case RET_INT: + switch(Operation) { + case OP_PREINC: + fprintf(OutputFile, "\tincl\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + case OP_PREDEC: + fprintf(OutputFile, "\tdecl\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + } + + fprintf(OutputFile, "\tmovslq\t%d(\%%rip), %s\n", Symbols[ID].SinkOffset, Registers[Reg]); + + switch(Operation) { + case OP_POSTINC: + fprintf(OutputFile, "\tincl\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + case OP_POSTDEC: + fprintf(OutputFile, "\tdecl\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + } + + break; + case RET_LONG: + case PTR_CHAR: + case PTR_INT: + case PTR_LONG: + case PTR_VOID: + switch(Operation) { + case OP_PREINC: + fprintf(OutputFile, "\tincq\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + case OP_PREDEC: + fprintf(OutputFile, "\tdecq\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + } + + fprintf(OutputFile, "\tmovq\t%d(\%%rip), %s\n", Symbols[ID].SinkOffset, Registers[Reg]); + + switch(Operation) { + case OP_POSTINC: + fprintf(OutputFile, "\tincq\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + case OP_POSTDEC: + fprintf(OutputFile, "\tdecq\t%d(\%%rip)\n", Symbols[ID].SinkOffset); break; + } + + break; + + default: + DieMessage("Bad type for loading", TypeNames[Symbols[ID].Type]); + } + + return Reg; +} + +int AsStrLocalVar(int Register, int ID) { + printf("\tStoring contents of %s into %s, type %d\n", Registers[Register], Symbols[ID].Name, Symbols[ID].Type); + + switch(Symbols[ID].Type) { + case RET_CHAR: + // movzbq zeroes, then moves a byte into the quad register + fprintf(OutputFile, "\tmovb\t%s, %d(\%%rip)\n", ByteRegisters[Register], Symbols[ID].SinkOffset); + break; + + case RET_INT: + fprintf(OutputFile, "\tmovl\t%s, %d(\%%rip)\n", DoubleRegisters[Register], Symbols[ID].SinkOffset); + break; + + case RET_LONG: + case PTR_CHAR: + case PTR_INT: + case PTR_LONG: + case PTR_VOID: + fprintf(OutputFile, "\tmovq\t%s, %d(%%rip)\n", Registers[Register], Symbols[ID].SinkOffset); + break; + + default: + DieMessage("Bad type for saving", TypeNames[Symbols[ID].Type]); + } + + return Register; +} + int AsAddr(int ID) { int Register = RetrieveRegister(); printf("\tSaving pointer of %s into %s\n", Symbols[ID].Name, Registers[Register]); diff --git a/src/Main.c b/src/Main.c index 11701a2..ec241f1 100644 --- a/src/Main.c +++ b/src/Main.c @@ -95,9 +95,9 @@ int main(int argc, char* argv[]) { exit(1); } - AddFunctionSymbol("PrintInteger", RET_CHAR, ST_FUNC, 0, 1); - AddFunctionSymbol("PrintString", RET_CHAR, ST_FUNC, 1, 1); - AddFunctionSymbol("PrintChar", RET_CHAR, ST_FUNC, 2, 1); + AddSymbol("PrintInteger", RET_CHAR, ST_FUNC, SC_GLOBAL, 0, 1); + AddSymbol("PrintString", RET_CHAR, ST_FUNC, SC_GLOBAL, 1, 1); + AddSymbol("PrintChar", RET_CHAR, ST_FUNC, SC_GLOBAL, 2, 1); //AddSymbol("forgecord", PTR_CHAR, ST_VAR); Tokenise(&CurrentToken); diff --git a/src/Parser.c b/src/Parser.c index 6690218..173f17f 100644 --- a/src/Parser.c +++ b/src/Parser.c @@ -320,6 +320,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) { * * * * I N T E R P R E T A T I O N * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* int ParseAST(struct ASTNode* Node) { @@ -336,7 +337,7 @@ int ParseAST(struct ASTNode* Node) { printf("int %d\n", Node->IntValue); else printf("%d %s %d\n", LeftVal, TokenStrings[Node->Operation], RightVal); - */ + switch(Node->Operation) { case OP_ADD: @@ -356,7 +357,7 @@ int ParseAST(struct ASTNode* Node) { exit(1); } } - +*/ /* * * * * * * * * * * * * * * * * * * * * * * * * F U N C T I O N S * * * * @@ -397,7 +398,7 @@ struct ASTNode* ParseStatement(void) { printf("\t\tNew Variable: %s\n", CurrentIdentifier); Type = ParseOptionalPointer(); VerifyToken(TY_IDENTIFIER, "ident"); - BeginVariableDeclaration(Type); + BeginVariableDeclaration(Type, SC_LOCAL); return NULL; /*case TY_IDENTIFIER: @@ -482,7 +483,7 @@ void ParseGlobals() { AssembleTree(Tree, -1, 0); } else { printf("\tParsing global variable declaration\n"); - BeginVariableDeclaration(Type); + BeginVariableDeclaration(Type, SC_GLOBAL); } if(CurrentToken.type == LI_EOF) diff --git a/src/Statements.c b/src/Statements.c index ae03c0e..d2eee00 100644 --- a/src/Statements.c +++ b/src/Statements.c @@ -22,7 +22,7 @@ * //TODO: int i = 5; * */ -void BeginVariableDeclaration(int Type) { +void BeginVariableDeclaration(int Type, int Scope) { int ID; printf("type: %s\n", TypeNames[Type]); @@ -31,34 +31,20 @@ void BeginVariableDeclaration(int Type) { //Type = Type - 2; if(CurrentToken.type == LI_INT) { printf("Adding array %s that is %d x %s.\r\n", CurrentIdentifier, CurrentToken.value, TypeNames[Type]); - ID = AddArraySymbol(CurrentIdentifier, PointerTo(Type), ST_ARR, 0, CurrentToken.value); - AsNewSymb(ID); + if(Scope == SC_LOCAL) { + 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); VerifyToken(LI_RBRAS, "]"); } else { - - while(1) { - //printf("Identifier: %s\n", CurrentIdentifier); - printf("Adding symbol %s of type %s.\n", CurrentIdentifier, TypeNames[Type]); - ID = AddSymbol(CurrentIdentifier, Type, ST_VAR, 1); - AsNewSymb(ID); - - if(CurrentToken.type == LI_SEMIC) { - printf("\tEnd of variables to declare in this statement\n"); - Tokenise(&CurrentToken); - return; - } - - if(CurrentToken.type == LI_COM) { - printf("\t\tStatement appears to continue. Integrating new variable.\n"); - Tokenise(&CurrentToken); - VerifyToken(TY_IDENTIFIER, "ident"); - continue; - } - - DieMessage("\nExpected ; after identifier, found", TokenNames[CurrentToken.type]); + if(Scope == SC_LOCAL) { + AddSymbol(CurrentIdentifier, Type, ST_VAR, SC_LOCAL, 0, 1); + } else if(Scope == SC_GLOBAL) { + AddSymbol(CurrentIdentifier, Type, ST_VAR, SC_GLOBAL, 0, 1); } } @@ -74,9 +60,11 @@ struct ASTNode* ParseFunction(int Type) { BreakLabel = NewLabel(); - SymbolSlot = AddFunctionSymbol(CurrentIdentifier, Type, ST_FUNC, BreakLabel, 1); + SymbolSlot = AddSymbol(CurrentIdentifier, Type, ST_FUNC, SC_GLOBAL, BreakLabel, 1); CurrentFunction = SymbolSlot; + AsNewStackFrame(); + VerifyToken(LI_LPARE, "("); VerifyToken(LI_RPARE, ")"); diff --git a/src/Symbols.c b/src/Symbols.c index 20366b1..10760c8 100644 --- a/src/Symbols.c +++ b/src/Symbols.c @@ -90,7 +90,7 @@ int AddSymbol(char* Name, int Type, int Structure, int Storage, int EndLabel, in int TableSlot; int SinkOffset = 0; - if((TableSlot = FindSymbol(Name, Storage) != -1)) + if((TableSlot = FindSymbolImpl(Name, Storage) != -1)) return TableSlot; // Instaed of spliting this up into AddLocalSymbol and AddGlobalSymbol, diff --git a/tests/inv_neg b/tests/inv_neg new file mode 100644 index 0000000..dfb9d63 --- /dev/null +++ b/tests/inv_neg @@ -0,0 +1,36 @@ +char* str; +int x; + +int :: main() { + x = -23; + PrintInteger(x); + + x = 1; + x = ~x; + PrintInteger(x); + + x = 2 > 5; + PrintInteger(x); + + x = !x; + PrintInteger(x); + + x = !x; + PrintInteger(x); + + x = 13; + if(x) { + PrintInteger(13); + } + + x = 0; + if(!x) { + PrintInteger(14); + } + + for(str = "Hello World\n"; *str; str++) { + PrintChar(*str); + } + + return (0); +} \ No newline at end of file