From 33309a27599d4a34092591dfbd0154aacdc3284f Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Tue, 4 Oct 2022 20:37:47 +0000 Subject: [PATCH] Updated the Instruction's structure and updated the Parser accordingly. --- includes/opcodes.h | 30 ++++++++-------- src/opcodes.c | 18 ++++++++-- src/parser.c | 85 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 97 insertions(+), 36 deletions(-) diff --git a/includes/opcodes.h b/includes/opcodes.h index b9cae7c..cd0f996 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -20,31 +20,29 @@ typedef enum { RegisterParameter } OpcodeParameter; +typedef struct { + OpcodeParameter ParameterType; + OpcodeParameter InterpretedAs; + + union { + int Number; //ConstanrParam + Registers Register; //Register param + Symbol* Symbol; //Address param + } Value; +} Parameter; + typedef struct { Mnemonic Mnemonic; - OpcodeParameter ParameterOneType; - OpcodeParameter ParameterTwoType; - int LineNumber; - - union { - int Constant; - Symbol* Symbol; - } ParameterOne; - - union { - int Constant; - Symbol* Symbol; - } ParameterTwo; + Parameter* ParameterOne; + Parameter* ParameterTwo; } Instruction; -//extern Instruction instructions[OPCODECOUNT]; - Instruction* CreateInstruction(Mnemonic mnemonic); +Parameter* CreateParameter(OpcodeParameter parameterType); void FreeInstruction(Instruction* instruction); int IsOpcode(const char*, Mnemonic*); int IsRegister(const char*, Registers*); void GetMnemonicText(Mnemonic mnemonic, char buffer[12]); -//const Instruction* GetOpcodeDetails(Mnemonic); unsigned char GetInstructionMask(Mnemonic type); #endif \ No newline at end of file diff --git a/src/opcodes.c b/src/opcodes.c index 798b5f1..acd8685 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -37,12 +37,26 @@ Instruction* CreateInstruction(Mnemonic mnemonic) { } instruction->Mnemonic = mnemonic; - instruction->ParameterOneType = NoParameter; - instruction->ParameterTwoType = NoParameter; + // instruction->ParameterOne = CreateParameter(NoParameter); + // instruction->ParameterTwo = CreateParameter(NoParameter); return instruction; } +Parameter* CreateParameter(OpcodeParameter parameterType) { + Parameter* param = calloc(1, sizeof(Parameter)); + + if (!param) { + fprintf(stderr, "Failed to calloc room for a Parameter. %s,\n", strerror(errno)); + + return NULL; + } + + param->ParameterType = parameterType; + + return param; +} + void FreeInstruction(Instruction* instruction) { if (!instruction) return; diff --git a/src/parser.c b/src/parser.c index 73adbea..b094346 100644 --- a/src/parser.c +++ b/src/parser.c @@ -32,7 +32,6 @@ IRState* ParseTokens(List* tokens) { switch(t->Class) { case DirectiveClass: //Maybe these should be ignored, let another process handle that. IgnoreParserLine(); - AdvanceParser(); break; case MnemonicClass: HandleOperation(); @@ -46,7 +45,6 @@ IRState* ParseTokens(List* tokens) { fprintf(stderr, "[Warning] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class); //exit(1); IgnoreParserLine(); - AdvanceParser(); //Consume the new line break; } } @@ -66,22 +64,35 @@ IRState* ParseTokens(List* tokens) { return &MachineState; } -OpcodeParameter GetParameterType(Token** sourceToken) { +Parameter* GetParameterType() { Token* token = PeekToken(); - OpcodeParameter parameterType; + Symbol* symbol = NULL; + Parameter* param = CreateParameter(NoParameter); switch(token->Class) { case RegisterClass: - *sourceToken = token; + param->ParameterType = RegisterParameter; + param->InterpretedAs = RegisterParameter; + + param->Value.Register = token->Value.Register; AdvanceParser(); - return RegisterParameter; + return param; case LabelClass: case IdentifierClass: - *sourceToken = token; + param->ParameterType = AddressParameter; + param->InterpretedAs = AddressParameter; + + symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable); + + if (!symbol) symbol = AddSymbolToTable(token->Lemexe, token->Lemexe, strlen(token->Lemexe), MachineState.SymbolsTable); + + param->Value.Symbol = symbol; + AdvanceParser(); - return AddressParameter; + + return param; case PunctuationClass: if (token->Value.Punctuation != LBracket) { fprintf(stderr, "[Error] Line %d: Expected opening bracket\n", token->LineNumber); @@ -90,7 +101,37 @@ OpcodeParameter GetParameterType(Token** sourceToken) { AdvanceParser(); // [ - parameterType = GetParameterType(sourceToken); + token = PeekToken(); + + if (token->Class == NumberClass) { + param->ParameterType = ConstantParameter; + param->InterpretedAs = AddressParameter; + param->Value.Number = token->Value.Number; + } + else if (token->Class == RegisterClass) { + param->ParameterType = RegisterParameter; + param->InterpretedAs = AddressParameter; + param->Value.Register = token->Value.Register; + } + else if (token->Class & AddressClass) { + param->ParameterType = AddressParameter; + param->ParameterType = AddressParameter; + + symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable); + + if (!symbol) symbol = AddSymbolToTable(token->Lemexe, NULL, strlen(token->Lemexe), MachineState.SymbolsTable); + + param->Value.Symbol = symbol; + } + else { + fprintf(stderr, "[Error] Line %d: Expected identifier, constant number or register.\n", token->LineNumber); + IgnoreParserLine(); + AdvanceParser(); //Consume NewLine + //return NULL; + exit(1); + } + + AdvanceParser(); //Consume the parameter it self. token = PeekToken(); @@ -101,18 +142,21 @@ OpcodeParameter GetParameterType(Token** sourceToken) { AdvanceParser(); // ] - return AddressParameter; + return param; case NumberClass: - *sourceToken = token; + param->ParameterType = ConstantParameter; + param->InterpretedAs = ConstantParameter; + + param->Value.Number = token->Value.Number; AdvanceParser(); - return ConstantParameter; + return param; default: break; } - return NoParameter; + return param; } void HandleOperation() { @@ -130,9 +174,10 @@ void HandleOperation() { goto InsertInstruction; } - ins->ParameterOneType = GetParameterType(&token); + //ins->ParameterOne->ParameterType = GetParameterType(&token); + ins->ParameterOne = GetParameterType(); - if (ins->ParameterOneType == NoParameter) { + if (ins->ParameterOne->ParameterType == NoParameter) { //This would be an error if the next token isn't a line break. if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != NewLine) { fprintf(stderr, "[Error] Line %d: Syntax error, expected line break but got %s.\n", token->LineNumber, token->Lemexe); @@ -143,7 +188,7 @@ void HandleOperation() { } if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) { - goto InsertInstruction; + goto InsertInstruction; } if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != Comma) { @@ -154,7 +199,8 @@ void HandleOperation() { AdvanceParser(); //Consume the comma - ins->ParameterTwoType = GetParameterType(&token); + //ins->ParameterTwo->ParameterType = GetParameterType(&token); + ins->ParameterTwo = GetParameterType(); InsertInstruction: @@ -212,7 +258,10 @@ Token* PeekToken(void) { void IgnoreParserLine(void) { while(!ParserAtEnd()) { - if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) break; + if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) { + AdvanceParser(); + break; + } if (PeekToken()->EndOfFile) break;