Start work on string parsing.

Generates a valid AST tree, but the program segfaults. Need to look into it.
This commit is contained in:
Curle 2020-11-22 01:44:54 +00:00
parent 0dc444acfc
commit 86b1688035
Signed by: TheCurle
GPG Key ID: 5942F13718443F79
7 changed files with 66 additions and 0 deletions

View File

@ -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);

View File

@ -167,6 +167,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);
DeallocateAllRegisters();
@ -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;

View File

@ -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);

View File

@ -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)) {

View File

@ -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);

View File

@ -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?

10
tests/strings Normal file
View File

@ -0,0 +1,10 @@
int :: main() {
char* str;
int x;
str = "Testingggs";
x = 14;
PrintString(str);
PrintInteger(x);
return (0);
}