From 985f02723ebb3f8f1f0b5b0a56adc597233c15d8 Mon Sep 17 00:00:00 2001 From: Curle Date: Wed, 18 Nov 2020 20:49:08 +0000 Subject: [PATCH] Start work on array parsing --- include/Defs.h | 9 ++++++++- src/Assembler.c | 14 ++++++++----- src/Lexer.c | 8 ++++++++ src/Parser.c | 14 +++++++++++++ src/Statements.c | 52 +++++++++++++++++++++++++++++++----------------- src/Symbols.c | 7 +++++++ tests/arrays | 3 +++ 7 files changed, 83 insertions(+), 24 deletions(-) create mode 100644 tests/arrays diff --git a/include/Defs.h b/include/Defs.h index 41e6133..7e7deae 100644 --- a/include/Defs.h +++ b/include/Defs.h @@ -47,6 +47,9 @@ enum TokenTypes { LI_LBRAC, // { LI_RBRAC, // } + LI_LBRAS, // [ + LI_RBRAS, // ] + LI_LPARE, // ( LI_RPARE, // ) @@ -150,6 +153,7 @@ struct SymbolTable { int Type; // An entry in DataTypes, referring to the type of this data int Structure; // An entry in StructureType - metadata on how to process the data int EndLabel; // The number of the label to jump to, in order to exit this function (if applicable) + int Length; // The length of the symbol in units of 1 element -- the size of an array, for example. }; @@ -179,7 +183,8 @@ enum DataTypes { enum StructureType { ST_VAR, // This is variable - ST_FUNC // This is a function + ST_FUNC, // This is a function + ST_ARR // This is an array // This is an enum // This is a struct // This is a typedef @@ -269,6 +274,8 @@ int AddSymbol(char* Name, int Type, int Structure); int AddFunctionSymbol(char* Name, int Type, int Structure, int EndLabel); +int AddArraySymbol(char* Name, int Type, int Structure, int EndLabel, int Size); + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/src/Assembler.c b/src/Assembler.c index a63a941..d447284 100644 --- a/src/Assembler.c +++ b/src/Assembler.c @@ -487,12 +487,16 @@ void AsNewSymb(int ID) { fprintf(OutputFile, "\t.data\n" "\t.globl\t%s\n", Symbols[ID].Name); + + fprintf(OutputFile, "%s:", Symbols[ID].Name); - switch(TypeSize) { - case 1: fprintf(OutputFile, "%s:\t.byte\t0\n", Symbols[ID].Name); break; - case 4: fprintf(OutputFile, "%s:\t.long\t0\n", Symbols[ID].Name); break; - case 8: fprintf(OutputFile, "%s:\t.quad\t0\n", Symbols[ID].Name); break; - default: DieDecimal("Unknown type in AsNewSymbol", TypeSize); break; + for(int i = 0; i < Symbols[ID].Length; i++) { + switch(TypeSize) { + case 1: fprintf(OutputFile, "%s:\t.byte\t0\n", Symbols[ID].Name); break; + case 4: fprintf(OutputFile, "%s:\t.long\t0\n", Symbols[ID].Name); break; + case 8: fprintf(OutputFile, "%s:\t.quad\t0\n", Symbols[ID].Name); break; + default: DieDecimal("Unknown type in AsNewSymbol", TypeSize); break; + } } } diff --git a/src/Lexer.c b/src/Lexer.c index 4e3ab40..7dce4f1 100644 --- a/src/Lexer.c +++ b/src/Lexer.c @@ -289,6 +289,14 @@ int Tokenise(struct Token* Token) { Token->type = LI_RBRAC; break; + case '[': + Token->type = LI_LBRAS; + break; + + case ']': + Token->type = LI_RBRAS; + break; + case ':': Char = NextChar(); diff --git a/src/Parser.c b/src/Parser.c index 38f94ed..13f8ef2 100644 --- a/src/Parser.c +++ b/src/Parser.c @@ -138,6 +138,20 @@ struct ASTNode* ParsePrimary(void) { Node = ConstructASTLeaf(REF_IDENT, Symbols[ID].Type, ID); break; + case LI_LPARE: + // We're expecting a primary encased in parentheses. + // That means, we tokenise the next item + Tokenise(&CurrentToken); + // Then, we expect a valid expression + Node = ParsePrecedenceASTNode(0); + + // Then, after the expression is parsed, we're returned here. + // since the expression is ENCASED in parens, we expect another. + VerifyToken(LI_RPARE, ")"); + + // Skip the next tokenise and return early + return Node; + default: DieDecimal("Unable to parse primary type", CurrentToken.type); } diff --git a/src/Statements.c b/src/Statements.c index da311f3..b01370e 100644 --- a/src/Statements.c +++ b/src/Statements.c @@ -25,28 +25,44 @@ void BeginVariableDeclaration(int Type) { int ID; //printf("type: %s\n", Types[Type]); + + if(CurrentToken.type == LI_LBRAS) { + Tokenise(&CurrentToken); + 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); + } + + 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); - AsNewSymb(ID); + while(1) { + //printf("Identifier: %s\n", CurrentIdentifier); + printf("Adding symbol %s of type %s.\n", CurrentIdentifier, TypeNames[Type]); + ID = AddSymbol(CurrentIdentifier, Type, ST_VAR); + AsNewSymb(ID); - if(CurrentToken.type == LI_SEMIC) { - printf("\tEnd of variables to declare in this statement\n"); - Tokenise(&CurrentToken); - return; + 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; + } + + DieDecimal("\nExpected ; after identifier, found", CurrentToken.type); } - - if(CurrentToken.type == LI_COM) { - printf("\t\tStatement appears to continue. Integrating new variable.\n"); - Tokenise(&CurrentToken); - VerifyToken(TY_IDENTIFIER, "ident"); - continue; - } - - DieDecimal("\nExpected ; after identifier, found", CurrentToken.type); } + + VerifyToken(LI_SEMIC, ";"); } struct ASTNode* ParseFunction(int Type) { diff --git a/src/Symbols.c b/src/Symbols.c index 4e221ce..f679a88 100644 --- a/src/Symbols.c +++ b/src/Symbols.c @@ -45,6 +45,13 @@ static int NewSymbol(void) { // TODO: this is going weird! +int AddArraySymbol(char* Name, int Type, int Structure, int EndLabel, int Size) { + int Slot; + Slot = AddFunctionSymbol(Name, Type, Structure, EndLabel); + Symbols[Slot].Length = Size; + return Slot; +} + int AddFunctionSymbol(char* Name, int Type, int Structure, int EndLabel) { int Slot; Slot = AddSymbol(Name, Type, Structure); diff --git a/tests/arrays b/tests/arrays new file mode 100644 index 0000000..e80f3fd --- /dev/null +++ b/tests/arrays @@ -0,0 +1,3 @@ +int a[51]; +char b[100]; +long c[5000]; \ No newline at end of file