From 7004fff6592b93185d5ad4b66eb7dd530c2b39e2 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Thu, 1 Sep 2022 18:46:59 +0000 Subject: [PATCH] This feels like a trainwreck but eh. Changed the way the opcodes are managed. Hopefully this is the right direction when I add support for multiple ASM files. --- includes/opcodes.h | 3 +- includes/parser.h | 31 ++++- includes/token.h | 2 +- misc/test.asm | 6 +- src/main.c | 11 +- src/opcodes.c | 6 +- src/parser.c | 300 ++++++++++++++++++++++++++++----------------- 7 files changed, 230 insertions(+), 129 deletions(-) diff --git a/includes/opcodes.h b/includes/opcodes.h index 366094f..ea3688f 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -6,6 +6,7 @@ #define OPCODECOUNT 13 #define REGISTERCOUNT 8 +//const unsigned char COPYADDRESSMASK = 0x80; typedef struct { char* lexeme; @@ -25,6 +26,6 @@ extern Register registers[REGISTERCOUNT]; int IsOpcode(const char*, TokenType*); int IsRegister(const char*, TokenType*); const Instruction* GetOpcodeDetails(TokenType); -unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType); +unsigned char GetInstructionMask(TokenType type); #endif \ No newline at end of file diff --git a/includes/parser.h b/includes/parser.h index 9dc1178..aa90a1c 100644 --- a/includes/parser.h +++ b/includes/parser.h @@ -1,6 +1,7 @@ #ifndef PARSER_H #define PARSER_H +#include #include #include #include "list.h" @@ -9,6 +10,34 @@ #define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF -unsigned char* ParseTokens(List*); +typedef struct { + Token* token; + //unsigned char terminatingByte; + int address; + int resolved; +} Symbol; + +typedef struct { + TokenType Mnemonic; + TokenClass ParameterOneType; + TokenClass ParameterTwoType; + + union { + uint16_t Constant; + Symbol* Address; + } ParameterOne; + + union { + uint16_t Constant; + Symbol* Address; + } ParameterTwo; +} IROpcode; + +typedef struct { + List* Opcodes; + List* SymbolsTable; +} IRState; + +IRState* ParseTokens(List*); #endif \ No newline at end of file diff --git a/includes/token.h b/includes/token.h index 47f748e..3c05a09 100644 --- a/includes/token.h +++ b/includes/token.h @@ -26,7 +26,7 @@ typedef enum { LineEnd, //Keywords DB, ORG, - //Opcodes + //Mnemonics COPY, ADD, SUB, JZ, INT, YLD, RET, CMP, NOP, JMP, CALL, IN, OUT, //Registers diff --git a/misc/test.asm b/misc/test.asm index 6e50977..b933ba5 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -2,9 +2,9 @@ .db msg "Hello, world!", 0 .db more_stuff "AA", 0 copy r7, msg ; // -cmp r8, msg ;1000 1111 -add r4, 0x42 -sub r1, r8 +;cmp r8, msg ;1000 1111 +;add r4, 0x42 +;sub r1, r8 int 20 jz 45 jmp msg diff --git a/src/main.c b/src/main.c index 32e5a7c..093df12 100644 --- a/src/main.c +++ b/src/main.c @@ -36,14 +36,17 @@ int main(int argc, char* args[]) { // if (t->type == LABEL) printf("* "); // } - unsigned char* image = ParseTokens(list); + IRState* image = ParseTokens(list); //Disassemble(image); + for(int i = 0; i < image->Opcodes->size; i++) { + printf("%d\n", ((IROpcode*) image->Opcodes->content[i])->Mnemonic); + } - FILE* program = fopen("program.bin", "w+b"); + //FILE* program = fopen("program.bin", "w+b"); - fwrite(image, 1, image[2] + image[3], program); + //fwrite(image, 1, image[2] + image[3], program); - fclose(program); + //fclose(program); free(source_code); } \ No newline at end of file diff --git a/src/opcodes.c b/src/opcodes.c index 85c5a76..a5ee8f4 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -18,12 +18,10 @@ Instruction instructions[OPCODECOUNT] = { { "call", CALL, Address, None} }; -unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType) { +unsigned char GetInstructionMask(TokenType type) { switch (type) { case COPY: - if (parameterOneType & Reg) return 0x20; //0b00100000; - - return 0xA0;//0b10100000; + return 0x20; //0b00100000; ORing 0x80 marks the first parameter as an address case ADD: return 0x40;//0b01000000; case SUB: diff --git a/src/parser.c b/src/parser.c index 3e7059a..841b21f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -4,24 +4,20 @@ #include #include -typedef struct { - Token* token; - int address; -} Symbol; - struct intr { TokenType struction; unsigned int parameter1; unsigned int parameter2; }; -Symbol* CreateSymbol(Token* token, int address); +Symbol* CreateSymbol(Token* token, int address, int resolved); const List* TokensList; int CurrentToken = 0; //int HeapStart = 4; // zero indexed, used for declared variables. //int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header) -void AddSymbol(Token*, int); +IROpcode* CreateIROpcode(TokenType mnemonic); +Symbol* AddSymbol(Token* token, int address, int resolved); void PrintSymbols(void); void HandleOperation(void); void HandleAssemblerDirective(void); @@ -30,22 +26,24 @@ Token* PeekToken(void); int ParserAtEnd(void); int Expect(int, ...); int ExpectTokenClass(int, ...); -const Symbol* GetSymbol(char*); -List* SymbolsTable; +Symbol* GetSymbol(char*); +//List* SymbolsTable; unsigned int HeapTop = 4; unsigned int ProgramCounter = 0; -unsigned char Heap[HIGHMEMORY]; -unsigned char Memory[HIGHMEMORY]; +// unsigned char Heap[HIGHMEMORY]; +// unsigned char Memory[HIGHMEMORY]; +IRState MachineState; -unsigned char* ParseTokens(List* tokens) { +IRState* ParseTokens(List* tokens) { if (!tokens) return NULL; - memset(Memory, 0, sizeof(Memory)); - memset(Heap, 0, sizeof(Heap)); + // memset(Memory, 0, sizeof(Memory)); + // memset(Heap, 0, sizeof(Heap)); TokensList = tokens; - SymbolsTable = CreateList(); + MachineState.SymbolsTable = CreateList(); + MachineState.Opcodes = CreateList(); while(!ParserAtEnd()) { Token* t = PeekToken(); @@ -60,7 +58,7 @@ unsigned char* ParseTokens(List* tokens) { case Address: if (t->type == LABEL) { printf("%s: \n", t->lexeme); - AddSymbol(t, ProgramCounter); + AddSymbol(t, ProgramCounter, 1); } break; default: @@ -70,16 +68,16 @@ unsigned char* ParseTokens(List* tokens) { AdvanceParser(); } - if (SymbolsTable->size > 0) PrintSymbols(); + if (MachineState.SymbolsTable->size > 0) PrintSymbols(); - DestroyList(SymbolsTable); + //DestroyList(SymbolsTable); - memcpy(&Heap[HeapTop], Memory, ProgramCounter); + //memcpy(&Heap[HeapTop], Memory, ProgramCounter); int totalSize = HeapTop + ProgramCounter; - Heap[0] = 2 >> HeapTop & 0xFF; - Heap[1] = HeapTop & 0xFF; - Heap[2] = 2 >> totalSize & 0xFF; - Heap[3] = totalSize & 0xFF; + // Heap[0] = 2 >> HeapTop & 0xFF; + // Heap[1] = HeapTop & 0xFF; + // Heap[2] = 2 >> totalSize & 0xFF; + // Heap[3] = totalSize & 0xFF; // for(int i = 0; i < 33; i++) { // if (i != 0 && i % 3 == 0) printf("\n"); @@ -89,7 +87,7 @@ unsigned char* ParseTokens(List* tokens) { // printf("Program Counter: %d\n", ProgramCounter); // printf("Heap Top: %#06X\n", HeapTop); - return Heap; + return &MachineState; } void HandleAssemblerDirective(void) { @@ -104,7 +102,7 @@ void HandleAssemblerDirective(void) { exit(1); } - AddSymbol(identifier, HeapTop); + Symbol* symbol = AddSymbol(identifier, HeapTop, 1); identifier = PeekToken(); @@ -112,10 +110,10 @@ void HandleAssemblerDirective(void) { case STRING: //printf("[INFO] %s = '%s' (%#04X)\n", identifier->lexeme, identifier->lexeme, HeapTop); - for(int i = 0; i < strlen(identifier->lexeme); i++) { - //Memory[ProgramCounter + i] = PeekToken()->lexeme[i]; - Heap[HeapTop + i] = identifier->lexeme[i]; - } + // for(int i = 0; i < strlen(identifier->lexeme); i++) { + // //Memory[ProgramCounter + i] = PeekToken()->lexeme[i]; + // Heap[HeapTop + i] = identifier->lexeme[i]; + // } //ProgramCounter += strlen(PeekToken()->lexeme); HeapTop += strlen(identifier->lexeme); @@ -130,10 +128,11 @@ void HandleAssemblerDirective(void) { exit(1); } else { - //Add the NULL byte. - //Memory[ProgramCounter] = '\0'; - Heap[HeapTop] = '\0'; - //ProgramCounter++; + //Hideous... + int oldLength = strlen(identifier->lexeme); + identifier->lexeme = realloc(identifier->lexeme, oldLength + 2); + identifier->value = identifier->lexeme; + identifier->lexeme[oldLength + 1] = '\0';//*PeekToken()->lexeme & 0x0F; HeapTop++; return; } @@ -147,18 +146,32 @@ void HandleAssemblerDirective(void) { } } -void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) { - Memory[ProgramCounter] = mask; +void HandleRegisterBasedOpcode(unsigned char mask) { + //Memory[ProgramCounter] = mask; ProgramCounter++; - const Token* token = PeekToken(); + Token* token = PeekToken(); + + IROpcode* opcode = CreateIROpcode(token->type); + + AdvanceParser(); + + token = PeekToken(); if (token->token_class == Reg) { - Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07; - + //Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07; + opcode->ParameterOneType = Reg; AdvanceParser(); } + else if (token->token_class == Address && token->type == COPY) { + opcode->ParameterOneType = Address; + + Symbol* symbol = GetSymbol(token->lexeme); + + if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 0, 0); + else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved); + } else { fprintf(stderr, "[Error] Line %d: Expected register operand.\n", token->line); exit(1); @@ -167,39 +180,47 @@ void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) { token = PeekToken(); if (!Expect(1, COMMA)) { - fprintf(stderr, "[Error] Expected command one line %d.\n", token->line); + fprintf(stderr, "[Error] Expected comma on line %d.\n", token->line); exit(1); } token = PeekToken(); if (token->type == IDENTIFIER || token->type == LABEL) { - const Symbol* symbol = GetSymbol(token->lexeme); + opcode->ParameterTwoType = Address; + Symbol* symbol = GetSymbol(token->lexeme); - if (!symbol) { - fprintf(stderr, "[Error] Line %d: %s is undefined.\n", token->line, token->lexeme); - exit(1); - } + // if (!symbol) { + // fprintf(stderr, "[Error] Line %d: %s is undefined.\n", token->line, token->lexeme); + // exit(1); + // } + if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 0, 0);//CreateSymbol(token, 0, 0); + else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved); - Memory[ProgramCounter - 1] |= 0x10;//0b00010000; + // Memory[ProgramCounter - 1] |= 0x10;//0b00010000; - Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; - Memory[ProgramCounter + 1] = symbol->address & 0xFF; + // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; + // Memory[ProgramCounter + 1] = symbol->address & 0xFF; AdvanceParser(); } else if (token->type == NUMBER) { - Memory[ProgramCounter - 1] |= 0x08; //0b00001000; + opcode->ParameterTwoType = Constant; - int* value = PeekToken()->value; + opcode->ParameterTwo.Constant = *(int*)PeekToken()->value; + // Memory[ProgramCounter - 1] |= 0x08; //0b00001000; - Memory[ProgramCounter] = 2 >> *value & 0xFF; - Memory[ProgramCounter + 1] = *value & 0xFF; + // int* value = PeekToken()->value; + + // Memory[ProgramCounter] = 2 >> *value & 0xFF; + // Memory[ProgramCounter + 1] = *value & 0xFF; AdvanceParser(); } else if (token->token_class == Reg) { - Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07; + opcode->ParameterTwoType = Reg; + opcode->ParameterTwo.Constant = (PeekToken()->type - R1) &0x07; + //Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07; AdvanceParser(); @@ -212,49 +233,64 @@ void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) { } ProgramCounter += 2; + + AddListItem(opcode, sizeof(IROpcode), MachineState.Opcodes); } void HandleOperation(void) { - const Instruction* inst = GetOpcodeDetails(PeekToken()->type); + Token* token = PeekToken(); + //const Instruction* inst = GetOpcodeDetails(opcode->type); const unsigned char registerBasedOpcodeMask = 0xE0; - if (!inst) return; + //if (!inst) return; - AdvanceParser(); + // AdvanceParser(); - unsigned char mask = GetInstructionMask(inst->op, inst->parameter_one); + unsigned char mask = GetInstructionMask(token->type); if (mask & registerBasedOpcodeMask) { - HandleRegisterBasedOpcode(Memory[ProgramCounter], mask); + HandleRegisterBasedOpcode(mask); return; } + IROpcode* opcode = CreateIROpcode(token->type); + opcode->ParameterTwoType = None; + + AdvanceParser(); + switch (mask) { case 0: //NOP - Memory[ProgramCounter] = 0x00; + //Memory[ProgramCounter] = 0x00; + opcode->ParameterOneType = None; + ProgramCounter++; return; case 1: //JZ - Memory[ProgramCounter] = 0x01; + //Memory[ProgramCounter] = 0x01; ProgramCounter++; if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { - const Symbol* symbol = GetSymbol(PeekToken()->lexeme); + Symbol* symbol = GetSymbol(PeekToken()->lexeme); + opcode->ParameterOneType = Address; + + if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 0, 0); + else opcode->ParameterOne.Address = symbol; + // if (!symbol) { + // fprintf(stderr, "[Error] %s is undefined.\n", PeekToken()->lexeme); + // exit(1); + // } - if (!symbol) { - fprintf(stderr, "[Error] %s is undefined.\n", PeekToken()->lexeme); - exit(1); - } - - Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; - Memory[ProgramCounter + 1] = symbol->address & 0xFF; + // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; + // Memory[ProgramCounter + 1] = symbol->address & 0xFF; } else if (PeekToken()->type == NUMBER) { - int* value = PeekToken()->value; + opcode->ParameterOneType = Constant; + opcode->ParameterOne.Constant = *(int*)PeekToken()->value; + // int* value = PeekToken()->value; - Memory[ProgramCounter] = 2 >> *value & 0xFF; - Memory[ProgramCounter + 1] = *value & 0xFF; + // Memory[ProgramCounter] = 2 >> *value & 0xFF; + // Memory[ProgramCounter + 1] = *value & 0xFF; } else { fprintf(stderr, "[Error] Line: %d: Expected address after jump if zero (JZ) instruction.\n", ((Token*) TokensList->content[CurrentToken - 1])->line); @@ -265,15 +301,17 @@ void HandleOperation(void) { return; case 2: //INT - Memory[ProgramCounter] = 0x02; + //Memory[ProgramCounter] = 0x02; ProgramCounter++; if (PeekToken()->type == NUMBER) { - int* value = PeekToken()->value; + // int* value = PeekToken()->value; + opcode->ParameterOneType = Constant; + opcode->ParameterOne.Constant = *(int*)PeekToken()->value; - Memory[ProgramCounter] = 2 >> *value & 0xFF; - Memory[ProgramCounter + 1] = *value & 0xFF; + // Memory[ProgramCounter] = 2 >> *value & 0xFF; + // Memory[ProgramCounter + 1] = *value & 0xFF; } else { fprintf(stderr, "[Error] Line %d: Expected Interrupt vector.\n", PeekToken()->line); @@ -284,30 +322,34 @@ void HandleOperation(void) { return; case 3: //YLD - Memory[ProgramCounter] = 0x03; + //Memory[ProgramCounter] = 0x03; + opcode->ParameterOneType = None; ProgramCounter++; break; case 4: //RET - Memory[ProgramCounter] = 0x04; + //Memory[ProgramCounter] = 0x04; + opcode->ParameterOneType = None; ProgramCounter++; break; case 5: //CALL - Memory[ProgramCounter] = 0x05; + //Memory[ProgramCounter] = 0x05; ProgramCounter++; if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { - const Symbol* symbol = GetSymbol(PeekToken()->lexeme); + Symbol* symbol = GetSymbol(PeekToken()->lexeme); + opcode->ParameterOneType = Address; - if (!symbol) { - fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); - exit(1); - } - - Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; - Memory[ProgramCounter + 1] = symbol->address & 0xFF; + // if (!symbol) { + // fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); + // exit(1); + // } + if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 0, 0); + else opcode->ParameterOne.Address = symbol; + //Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; + //Memory[ProgramCounter + 1] = symbol->address & 0xFF; } else { fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line); @@ -317,20 +359,23 @@ void HandleOperation(void) { ProgramCounter += 2; break; case 6: //JMP - Memory[ProgramCounter] = 0x06; + //Memory[ProgramCounter] = 0x06; ProgramCounter++; if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { - const Symbol* symbol = GetSymbol(PeekToken()->lexeme); + Symbol* symbol = GetSymbol(PeekToken()->lexeme); + opcode->ParameterOneType = Address; - if (!symbol) { - fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); - exit(1); - } + // if (!symbol) { + // fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); + // exit(1); + // } + if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 0, 0); + else opcode->ParameterOne.Address = symbol; - Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; - Memory[ProgramCounter + 1] = symbol->address & 0xFF; + // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; + // Memory[ProgramCounter + 1] = symbol->address & 0xFF; } else { fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line); @@ -340,15 +385,17 @@ void HandleOperation(void) { ProgramCounter += 2; break; case 7: //IN - Memory[ProgramCounter] = 0x07; + //Memory[ProgramCounter] = 0x07; ProgramCounter++; if (PeekToken()->type == NUMBER) { - int* value = PeekToken()->value; + opcode->ParameterOneType = Constant; + opcode->ParameterOne.Constant = *(int*)PeekToken()->value; + // int* value = PeekToken()->value; - Memory[ProgramCounter] = 2 >> *value & 0xFF; - Memory[ProgramCounter + 1] = *value & 0xFF; + // Memory[ProgramCounter] = 2 >> *value & 0xFF; + // Memory[ProgramCounter + 1] = *value & 0xFF; } else { fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->line); @@ -358,15 +405,17 @@ void HandleOperation(void) { ProgramCounter += 2; break; case 8: //OUT - Memory[ProgramCounter] = 0x08; + //Memory[ProgramCounter] = 0x08; ProgramCounter++; if (PeekToken()->type == NUMBER) { - int* value = PeekToken()->value; + opcode->ParameterOneType = Constant; + opcode->ParameterOne.Constant = *(int*)PeekToken()->value; + // int* value = PeekToken()->value; - Memory[ProgramCounter] = 2 >> *value & 0xFF; - Memory[ProgramCounter + 1] = *value & 0xFF; + // Memory[ProgramCounter] = 2 >> *value & 0xFF; + // Memory[ProgramCounter + 1] = *value & 0xFF; } else { fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->line); @@ -377,6 +426,8 @@ void HandleOperation(void) { break; } + AddListItem(opcode, sizeof(IROpcode), MachineState.Opcodes); + return; } @@ -420,33 +471,43 @@ int Expect(int count, ...) { void PrintSymbols(void) { printf("-----SYMBOLS-----\n"); - for(int i = 0; i < SymbolsTable->size; i++) { - Symbol* symbol = SymbolsTable->content[i]; + for(int i = 0; i < MachineState.SymbolsTable->size; i++) { + Symbol* symbol = MachineState.SymbolsTable->content[i]; printf("[%#06X] %s\n", symbol->address, symbol->token->lexeme); } printf("-----SYMBOLS-----\n"); } -void AddSymbol(Token* token, int address) { - if (!token) return; - if (token->type != IDENTIFIER && token->type != LABEL) return; +Symbol* AddSymbol(Token* token, int address, int resolved) { + if (!token) return NULL; + if (token->type != IDENTIFIER && token->type != LABEL) return NULL; - for(int i = 0; i < SymbolsTable->size; i++) { - Symbol* s = SymbolsTable->content[i]; + for(int i = 0; i < MachineState.SymbolsTable->size; i++) { + Symbol* s = MachineState.SymbolsTable->content[i]; - if (strcmp(s->token->lexeme, token->lexeme) == 0) return; + if (strcmp(s->token->lexeme, token->lexeme) == 0) { + if (s->resolved) { + fprintf(stderr, "[Error] Line %d: Attempted to redeclare %s.\n", token->line, token->lexeme); + exit(1); + } + s->resolved = resolved; + s->address = address; + return s; + } } - Symbol* symbol = CreateSymbol(token, address); + Symbol* symbol = CreateSymbol(token, address, resolved); - AddListItem(symbol, sizeof(Symbol), SymbolsTable); + AddListItem(symbol, sizeof(Symbol), MachineState.SymbolsTable); + + return symbol; } -const Symbol* GetSymbol(char* name) { +Symbol* GetSymbol(char* name) { if (!name) return NULL; - for(int i = 0; i < SymbolsTable->size; i++) { - const Symbol* s = SymbolsTable->content[i]; + for(int i = 0; i < MachineState.SymbolsTable->size; i++) { + Symbol* s = MachineState.SymbolsTable->content[i]; if (strcmp(s->token->lexeme, name) == 0) return s; } @@ -454,17 +515,26 @@ const Symbol* GetSymbol(char* name) { return NULL; } -Symbol* CreateSymbol(Token* token, int address) { +Symbol* CreateSymbol(Token* token, int address, int resolved) { Symbol* symbol = calloc(1, sizeof(Symbol)); if (!symbol) return NULL; symbol->token = token; symbol->address = address; + symbol->resolved = resolved; return symbol; } +IROpcode* CreateIROpcode(TokenType mnemonic) { + IROpcode* opcode = calloc(1, sizeof(IROpcode)); + + opcode->Mnemonic = mnemonic; + + return opcode; +} + void AdvanceParser(void) { if (ParserAtEnd()) return;