From 264c50509e5d06c0cfbc624b3e3a317654f35e4e Mon Sep 17 00:00:00 2001 From: Curle Date: Sun, 13 Sep 2020 23:41:46 +0100 Subject: [PATCH] Allow global-scope declarations Function-local scope is still WIP, but you can now define things outside of function blocks. --- .gitignore | 6 ++++++ include/Defs.h | 9 ++++++--- src/Lexer.c | 4 ++++ src/Main.c | 9 ++------- src/Parser.c | 38 ++++++++++++++++++++++++++++++++++++-- src/Pointers.c | 7 ++++--- src/Statements.c | 34 +++++++++++++++++++++------------- tests/globals | 16 ++++++++++++++++ 8 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 .gitignore create mode 100644 tests/globals diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e42c6f5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.idea +.vscode + +out +bin + diff --git a/include/Defs.h b/include/Defs.h index 2b35bc6..b63797d 100644 --- a/include/Defs.h +++ b/include/Defs.h @@ -51,6 +51,7 @@ enum TokenTypes { LI_RPARE, // ) LI_AMP, // & + LI_COM, // , TY_IDENTIFIER, // Identifier name. Variable, function, etc. TY_NONE, // No return type. Literal void. @@ -229,14 +230,16 @@ struct ASTNode* ParsePrimary(void); struct ASTNode* ParseStatement(void); struct ASTNode* PrefixStatement(); -struct ASTNode* ParseFunction(); +void ParseGlobals(); + +struct ASTNode* ParseFunction(int Type); struct ASTNode* ParseCompound(); struct ASTNode* CallFunction(); struct ASTNode* ReturnStatement(); -int ParsePointer(); +int ParseOptionalPointer(); int ValueAt(int Type); int PointerTo(int Type); @@ -331,7 +334,7 @@ void AsFunctionEpilogue(int ID); * * * * D E C L A R A T I O N * * * * * * * * * * * * * * * * * * * * * * * * * * */ -void BeginVariableDeclaration(void); +void BeginVariableDeclaration(int Type); struct ASTNode* ParseIdentifier(void); struct ASTNode* IfStatement(); diff --git a/src/Lexer.c b/src/Lexer.c index dbc17c0..4e3ab40 100644 --- a/src/Lexer.c +++ b/src/Lexer.c @@ -223,6 +223,10 @@ int Tokenise(struct Token* Token) { Token->type = LI_AMP; break; + case ',': + Token->type = LI_COM; + break; + case '=': Char = NextChar(); // If the next char is =, we have ==, the compare equality token. diff --git a/src/Main.c b/src/Main.c index c2d5082..c62e5c8 100644 --- a/src/Main.c +++ b/src/Main.c @@ -79,14 +79,9 @@ int main(int argc, char* argv[]) { AssemblerPreamble(); - while(1) { - Node = ParseFunction(); - printf("\nBeginning assembler creation of new function %s\n", Symbols[Node->Value.ID].Name); - AssembleTree(Node, -1, 0); + ParseGlobals(); - if(CurrentToken.type == LI_EOF) - break; - } + //AsFunctionEpilogue(); //Node = ParsePrecedenceASTNode(); //printf("%d\n", ParseAST(Node)); diff --git a/src/Parser.c b/src/Parser.c index 2621ac5..0d1b2bd 100644 --- a/src/Parser.c +++ b/src/Parser.c @@ -333,7 +333,7 @@ struct ASTNode* CallFunction() { * * * * * * * * * * * * * * * * * * * * * */ struct ASTNode* ParseStatement(void) { - + int Type; switch(CurrentToken.type) { @@ -344,7 +344,9 @@ struct ASTNode* ParseStatement(void) { case TY_LONG: case TY_INT: printf("\t\tNew Variable: %s\n", CurrentIdentifier); - BeginVariableDeclaration(); + Type = ParseOptionalPointer(CurrentToken.type); + VerifyToken(TY_IDENTIFIER, "ident"); + BeginVariableDeclaration(Type); return NULL; case TY_IDENTIFIER: @@ -403,6 +405,38 @@ struct ASTNode* ParseCompound() { } } +void ParseGlobals() { + struct ASTNode* Tree; + int Type, FunctionComing; + + printf("Parsing global definitions\n"); + + while(1) { + Type = ParseOptionalPointer(); + + //TODO: converge pathways on this block? + if(CurrentToken.type == KW_FUNC) { + VerifyToken(KW_FUNC, "::"); + FunctionComing = 1; + } + + VerifyToken(TY_IDENTIFIER, "ident"); + + if(FunctionComing && CurrentToken.type == LI_LPARE) { + printf("\tParsing function"); + Tree = ParseFunction(Type); + printf("\nBeginning assembler creation of new function %s\n", Symbols[Tree->Value.ID].Name); + AssembleTree(Tree, -1, 0); + } else { + printf("\tParsing global variable declaration\n"); + BeginVariableDeclaration(Type); + } + + if(CurrentToken.type == LI_EOF) + break; + + } +} /* void ParseStatements() { diff --git a/src/Pointers.c b/src/Pointers.c index d708201..afb9157 100644 --- a/src/Pointers.c +++ b/src/Pointers.c @@ -36,15 +36,16 @@ int ValueAt(int Type) { return -1; } -int ParsePointer() { +int ParseOptionalPointer() { int Type; // TODO: THIS IS WRONG AND SHOULD NOT EXIST - // TY_CHAR is 21, RET_CHAR is 1. + // TY_CHAR is 22, RET_CHAR is 1. // Offset is 20. Rest are in order if(CurrentToken.type >= TY_CHAR && CurrentToken.type <= TY_VOID) { - Type = CurrentToken.type - 20; + Type = CurrentToken.type - 21; + printf("\t\tConverting a %d type to a %d type.\n", CurrentToken.type, Type); } else { DieDecimal("Illegal type for pointerisation", CurrentToken.type); } diff --git a/src/Statements.c b/src/Statements.c index 94d0d1c..6aa8bd3 100644 --- a/src/Statements.c +++ b/src/Statements.c @@ -126,29 +126,37 @@ int TypesCompatible(int* Left, int* Right, int STRICT) { * //TODO: int i = 5; * */ -void BeginVariableDeclaration(void) { +void BeginVariableDeclaration(int Type) { int ID; - int Type = ParsePointer(CurrentToken.type); //printf("type: %s\n", Types[Type]); - VerifyToken(TY_IDENTIFIER, "ident"); + 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); - 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; + } - VerifyToken(LI_SEMIC, ";"); + 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); + } } -struct ASTNode* ParseFunction() { +struct ASTNode* ParseFunction(int Type) { struct ASTNode* Tree; struct ASTNode* FinalStatement; - int SymbolSlot, BreakLabel, Type; - - Type = ParsePointer(CurrentToken.type); - - VerifyToken(KW_FUNC, "::"); - VerifyToken(TY_IDENTIFIER, "ident"); + int SymbolSlot, BreakLabel; printf("\nIdentified function %s\n", CurrentIdentifier); diff --git a/tests/globals b/tests/globals new file mode 100644 index 0000000..75cc54d --- /dev/null +++ b/tests/globals @@ -0,0 +1,16 @@ +int x, y; +int* z; + +void :: main() { + int a, b, c; + + b = 3; c = 8; + a = b + c * 10; + PrintInteger(a); + + x = 12; PrintInteger(x); + z = &x; + y = *z; + PrintInteger(y); + +} \ No newline at end of file