From 86b1688035d60baf8375e03f86d58fd07e0e892d Mon Sep 17 00:00:00 2001 From: Curle Date: Sun, 22 Nov 2020 01:44:54 +0000 Subject: [PATCH] Start work on string parsing. Generates a valid AST tree, but the program segfaults. Need to look into it. --- include/Defs.h | 5 +++++ src/Assembler.c | 22 ++++++++++++++++++++++ src/Dump.c | 1 + src/Lexer.c | 21 +++++++++++++++++++++ src/Main.c | 1 + src/Parser.c | 6 ++++++ tests/strings | 10 ++++++++++ 7 files changed, 66 insertions(+) create mode 100644 tests/strings diff --git a/include/Defs.h b/include/Defs.h index 31f64e2..748b072 100644 --- a/include/Defs.h +++ b/include/Defs.h @@ -106,6 +106,7 @@ enum SyntaxOps { OP_DEREF, // Get the value of the address in a pointer TERM_INTLITERAL, // Integer Literal. This is a virtual operation, so it's a terminal. + TERM_STRLITERAL, // String Literal. Also terminal. REF_IDENT, // Reference (read) an identifier (variable). @@ -322,6 +323,10 @@ int AsStrDeref(int Register1, int Register2, int Type); int AsAddr(int ID); void AsNewSymb(int ID); +int AsNewString(char* Value); + + +int AsLoadString(int ID); int AsEqual(int Left, int Right); int AsIneq(int Left, int Right); diff --git a/src/Assembler.c b/src/Assembler.c index 0b82bf4..08acaf3 100644 --- a/src/Assembler.c +++ b/src/Assembler.c @@ -166,6 +166,9 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) { case TERM_INTLITERAL: return AsLoad(Node->Value.IntValue); + + case TERM_STRLITERAL: + return AsLoadString(Node->Value.ID); case OP_PRINT: AssemblerPrint(LeftVal); @@ -290,6 +293,25 @@ void AsLabel(int Label) { fprintf(OutputFile, "L%d:\n", Label); } +int AsNewString(char* Value) { + int Label = NewLabel(); + char* CharPtr; + + AsLabel(Label); + + for(CharPtr = Value; *CharPtr; CharPtr++) + fprintf(OutputFile, "\t.byte\t%d\r\n", *CharPtr); + fprintf(OutputFile, "\t.byte\t0\r\n"); + + return Label; +} + +int AsLoadString(int ID) { + int Register = RetrieveRegister(); + fprintf(OutputFile, "\tleaq\tL%d(\%%rip), %s\r\n", ID, Registers[Register]); + return Register; +} + int AsWhile(struct ASTNode* Node) { int BodyLabel, BreakLabel; diff --git a/src/Dump.c b/src/Dump.c index 423dfb7..8bf25d8 100644 --- a/src/Dump.c +++ b/src/Dump.c @@ -74,6 +74,7 @@ void DumpTree(struct ASTNode* node, int level) { case OP_LESSE: fprintf(stdout, "OP_LESSE\n"); return; case OP_GREATE: fprintf(stdout, "OP_GREATE\n"); return; case TERM_INTLITERAL: fprintf(stdout, "TERM_INTLITERAL %d\n", node->Value.IntValue); return; + case TERM_STRLITERAL: fprintf(stdout, "TERM_STRLITERAL rval L%d\n", node->Value.IntValue); return; case REF_IDENT: if(node->RVal) fprintf(stdout, "REF_IDENT rval %s\n", Symbols[node->Value.ID].Name); diff --git a/src/Lexer.c b/src/Lexer.c index e7a83af..9767aa5 100644 --- a/src/Lexer.c +++ b/src/Lexer.c @@ -131,6 +131,22 @@ static int ReadCharLiteral() { return Char; } + +static int ReadStringLiteral(char* Buffer) { + int Char; + + for(int i = 0; i < TEXTLEN - 1; i++) { + if((Char = ReadCharLiteral()) == '"') { + Buffer[i] = 0; return i; + } + + Buffer[i] = Char; + } + + Die("String Literal Too Long"); + return 0; +} + /* * This function is what defines the valid keywords for the language * //TODO: move this to a static list? @@ -338,6 +354,11 @@ int Tokenise(struct Token* Token) { Die("Expected '\\'' at the end of a character."); break; + case '"': + ReadStringLiteral(CurrentIdentifier); + Token->type = LI_STR; + break; + default: if(isdigit(Char)) { diff --git a/src/Main.c b/src/Main.c index aff0f0e..ada9294 100644 --- a/src/Main.c +++ b/src/Main.c @@ -81,6 +81,7 @@ int main(int argc, char* argv[]) { } AddFunctionSymbol("PrintInteger", RET_CHAR, ST_FUNC, 0); + AddFunctionSymbol("PrintString", RET_CHAR, ST_FUNC, 1); //AddSymbol("forgecord", PTR_CHAR, ST_VAR); Tokenise(&CurrentToken); diff --git a/src/Parser.c b/src/Parser.c index a8682a8..41e039b 100644 --- a/src/Parser.c +++ b/src/Parser.c @@ -116,6 +116,12 @@ struct ASTNode* ParsePrimary(void) { Node = ConstructASTLeaf(TERM_INTLITERAL, RET_INT, CurrentToken.value); break; + case LI_STR: + + ID = AsNewString(CurrentIdentifier); + Node = ConstructASTLeaf(TERM_STRLITERAL, PTR_CHAR, ID); + break; + case TY_IDENTIFIER: // A variable or a function? diff --git a/tests/strings b/tests/strings new file mode 100644 index 0000000..04fdbba --- /dev/null +++ b/tests/strings @@ -0,0 +1,10 @@ +int :: main() { + char* str; + int x; + str = "Testingggs"; + x = 14; + + PrintString(str); + PrintInteger(x); + return (0); +} \ No newline at end of file