diff --git a/includes/lexer.h b/includes/lexer.h index 06ca791..1257e96 100644 --- a/includes/lexer.h +++ b/includes/lexer.h @@ -9,23 +9,26 @@ #include "tokenizer.h" typedef enum { - TK_Add, - TK_Sub, - TK_Mul, - TK_Div, - TK_Power, - TK_LParam, - TK_RParam, - TK_LBracket, - TK_RBracket, - TK_String, - TK_Number, - TK_Hex, - TK_Opcode, - TK_Register, - TK_Directive, - TK_Symbol, - TK_Comma + PLUS, + MINUS, + STAR, + SLASH, + POWER, + LPARAM, + RPARAM, + LBRACKET, + RBracket, + COMMA, + IDENTIFIER, + NUMBER, + HEX, + //Keywords + DB, ORG, + //Opcodes + COPY, ADD, SUB, JZ, INT, YLD, RET, + CMP, IN, OUT, + //Registers + R1, R2, R3, R4, R5, R6, R7, R8 } TokenType; typedef struct { diff --git a/includes/opcodes.h b/includes/opcodes.h index 667d5ea..2efde03 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -2,14 +2,34 @@ #define OPCODES_H #include +#include "lexer.h" -#define OPCODECOUNT 7 +#define OPCODECOUNT 10 #define REGISTERCOUNT 8 -extern char *opcodes[OPCODECOUNT]; -extern char *registers[REGISTERCOUNT]; +typedef enum { + None = 0, + Reg, + Imm8, + Imm16 +} ParameterType; -int IsOpcode(const char*); -int IsRegister(const char*); +typedef struct { + char* lexeme; + TokenType op; + ParameterType parameter_one; + ParameterType parameter_two; +} OpCode; + +typedef struct { + char* lexeme; + TokenType type; +} Register; + +extern OpCode opcodes[OPCODECOUNT]; +extern Register registers[REGISTERCOUNT]; + +int IsOpcode(const char*, TokenType*); +int IsRegister(const char*, TokenType*); #endif \ No newline at end of file diff --git a/src/lexer.c b/src/lexer.c index 5b2d771..1502533 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -2,6 +2,7 @@ #include "../includes/opcodes.h" #include #include +#include Token* CreateToken(TokenType, char*); Token* GetNextToken(char *); @@ -27,14 +28,17 @@ List* GetTokensFromLine(char* line) { Token* GetNextToken(char *string) { char* string_token = GetToken(string); int base = 0; + TokenType type; while (strlen(string_token) != 0) { - if (string_token[0] == '.') return CreateToken(TK_Directive, string_token); + if (strcmp(string_token, ".db") == 0) { + return CreateToken(DB, string_token); + } if (TokenIsNumeric(string_token, &base)) { - if (base == 10) return CreateToken(TK_Number, string_token); - if (base == 16) return CreateToken(TK_Hex, string_token); + if (base == 10) return CreateToken(NUMBER, string_token); + if (base == 16) return CreateToken(HEX, string_token); } char* next = PeekNextToken(); @@ -43,17 +47,26 @@ Token* GetNextToken(char *string) { if (strcmp(":", next) == 0) { free(next); free(GetToken(NULL)); - return CreateToken(TK_Symbol, string_token); + return CreateToken(IDENTIFIER, string_token); } free(next); } - if (IsOpcode(string_token)) return CreateToken(TK_Opcode, string_token); - if (IsRegister(string_token)) return CreateToken(TK_Register, string_token); - if (strcmp(",", string_token) == 0) return CreateToken(TK_Comma, string_token); + if (IsOpcode(string_token, &type)) { + return CreateToken(type, string_token); + } - return CreateToken(TK_String, string_token); + if (IsRegister(string_token, &type)) { + return CreateToken(type, string_token); + } + + // if (op) return CreateToken(op->op, op->lexeme); + // if (reg) return CreateToken(reg->type, reg->lexeme); + + if (strcmp(",", string_token) == 0) return CreateToken(COMMA, string_token); + + return CreateToken(IDENTIFIER, string_token); } free(string_token); diff --git a/src/main.c b/src/main.c index f688bb2..04148b2 100644 --- a/src/main.c +++ b/src/main.c @@ -48,7 +48,7 @@ int main(int argc, char* args[]) { printf("Token Type: '%d' Value: '%s' (%d)\n", t->type, t->value, line_number); - free(t->value); + if (t->type <= ORG) free(t->value); } DestroyList(tokens); diff --git a/src/opcodes.c b/src/opcodes.c index 1f6d673..9b91ec4 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -1,41 +1,52 @@ #include "../includes/opcodes.h" +#include +#include -char *opcodes[OPCODECOUNT] = { - "copy", - "add", - "sub", - "jz", - "int", - "yld", - "ret" +OpCode opcodes[OPCODECOUNT] = { + { "copy", COPY, Reg, Reg | Imm8 | Imm16 }, + { "add", ADD, Reg, Reg | Imm8 | Imm16 }, + { "sub", SUB, Reg, Reg | Imm8 | Imm16 }, + { "jz", JZ, Imm8 | Imm16, None }, + { "int", INT, Imm8, None }, + { "yld", YLD, None, None }, + { "ret", RET, None, None }, + { "cmp", CMP, Reg | Imm8 | Imm16, Reg | Imm8 | Imm16 }, + { "in", IN, None, None}, + { "out", OUT, None, None} }; -char *registers[REGISTERCOUNT] = { - "r1", - "r2", - "r3", - "r4", - "r5", - "r6", - "r7", - "r8" +Register registers[REGISTERCOUNT] = { + { "r1", R1 }, + { "r2", R2 }, + { "r3", R3 }, + { "r4", R4 }, + { "r5", R5 }, + { "r6", R6 }, + { "r7", R7 }, + { "r8", R8 } }; -int IsOpcode(const char* text) { +int IsOpcode(const char* text, TokenType* opcode) { if (!text) return 0; for(int i = 0; i < OPCODECOUNT; i++) { - if (strcmp(opcodes[i], text) == 0) return 1; + if (strcmp(opcodes[i].lexeme, text) == 0) { + opcode = &opcodes[i].op; + return 1; + } } return 0; } -int IsRegister(const char* text) { +int IsRegister(const char* text, TokenType* reg) { if (!text) return 0; for(int i = 0; i < REGISTERCOUNT; i++) { - if (strcmp(registers[i], text) == 0) return 1; + if (strcmp(registers[i].lexeme, text) == 0) { + reg = ®isters[i].type; + return 1; + } } return 0; diff --git a/src/parser.c b/src/parser.c index 51411ad..a320468 100644 --- a/src/parser.c +++ b/src/parser.c @@ -9,11 +9,11 @@ void ProcessDirective(List*); void ProcessVariableDeclaration(List*); void ParseTokens(List* tokens) { - for(int i = 0; i < tokens->size; i++) { - if (((Token *) tokens->content[i])->type == TK_Directive){ - ProcessDirective(tokens); - } - } + // for(int i = 0; i < tokens->size; i++) { + // if (((Token *) tokens->content[i])->type == TK_Directive){ + // ProcessDirective(tokens); + // } + // } } void ProcessDirective(List* tokens) { @@ -26,11 +26,11 @@ void ProcessDirective(List* tokens) { if (strcmp(".org", directive->value) == 0) { Token* address_start = (Token*) tokens->content[1]; - if (address_start->type == TK_Number) { + if (address_start->type == NUMBER) { long address = strtol(address_start->value, NULL, 10); printf("Address starting at '%ld'\n", address); } - else if (address_start->type == TK_Hex) { + else if (address_start->type == HEX) { long address = strtol(address_start->value, NULL, 16); printf("Setting address to '%ld'\n", address); }