diff --git a/README.md b/README.md index 0764826..c83c8c8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ But uhh that's the name of the VM itself, the name of the programming language I made is Sylt, named after the German island. To compile the VM for Linux: `gcc src/main.c src/vmbl.c src/exception.c src/file_utils.c -o vmbl -O3` -To compile SASM for Linux: `gcc src/asm/sasm.c src/asm/tokenize.c src/file_utils.c src/asm/assembler.c -o sasm -O3` +To compile SASM for Linux: `gcc src/asm/sasm.c src/asm/instructions.c src/file_utils.c src/asm/assembler.c -o sasm -O3` ## Syntax ### Example "Hello, World!" Program diff --git a/fib.sasm b/fib.sasm index e2f3af6..93b43e2 100644 --- a/fib.sasm +++ b/fib.sasm @@ -1,6 +1,5 @@ -push 0 -push 1 -dup 1 -dup 1 +push 10 +push 9 add -jump 2 \ No newline at end of file +halt +add \ No newline at end of file diff --git a/sasm b/sasm index 8a90e9f..6426bcd 100644 Binary files a/sasm and b/sasm differ diff --git a/src/asm/assembler.c b/src/asm/assembler.c index 816b0e1..e6653c8 100644 --- a/src/asm/assembler.c +++ b/src/asm/assembler.c @@ -1,17 +1,22 @@ #include "assembler.h" +#include "instructions.h" #include +#include +#include -void assemble(Tokenizer *tokenizer) { - Token token = getCurrentToken(tokenizer); - while (token.type != TOKEN_EOF) +VMBL_Instruction assembleLine(char *line) { + char *instName = strtok(line, " "); + printf("%s\n", instName); +} + +void assemble(char *sourceCode, VMBL_Instruction program[], size_t programCapacity) { + char *line = strtok(sourceCode, "\n"); + + int i = 0; + while (line != NULL) { - //printf("%s: %s - line %d\n", tokenTypeAsCStr(token.type), token.value, token.line); - - - //free(token.value); - token = getCurrentToken(tokenizer); - - + program[i++] = assembleLine(line); + line = strtok(NULL, "\n"); } - free(token.value); + } \ No newline at end of file diff --git a/src/asm/assembler.h b/src/asm/assembler.h index 8c0b172..9c2e2ae 100644 --- a/src/asm/assembler.h +++ b/src/asm/assembler.h @@ -1,8 +1,12 @@ #ifndef ASSEMBLER_H #define ASSEMBLER_H -#include "tokenize.h" +#include +#include "../vmbl.h" + + +VMBL_Instruction assembleLine(char *line); +void assemble(char *sourceCode, VMBL_Instruction program[], size_t programCapacity); -void assemble(Tokenizer *tokenizer); #endif // !ASSEMBLER_H diff --git a/src/asm/instructions.c b/src/asm/instructions.c new file mode 100644 index 0000000..6e9f708 --- /dev/null +++ b/src/asm/instructions.c @@ -0,0 +1,12 @@ +#include "instructions.h" +#include + +InstructionType instructionNameToType(char* instName) { + for (size_t i = 0; i < sizeof(instruction_table)/sizeof(instruction_table[0]); i++) { + + if (strcmp(instName, instruction_table[i].mnemonic) == 0) { + return (InstructionType)i; + } + + } +} \ No newline at end of file diff --git a/src/asm/instructions.h b/src/asm/instructions.h index b3f3729..4d40d3c 100644 --- a/src/asm/instructions.h +++ b/src/asm/instructions.h @@ -1,18 +1,35 @@ #ifndef INSTRUCTIONS_H #define INSTRUCTIONS_H +#include "../vmbl.h" + #define MAX_ARGS 3 typedef enum { + ARG_TYPE_NONE, ARG_TYPE_INT } ArgType; typedef struct { - char *mnemonic, - uint8_t argCount, - ArgType args[MAX_ARGS] + char *mnemonic; + uint8_t argCount; + ArgType args[MAX_ARGS]; } InstructionInfo; -#endif // !INSTRUCTIONS_H +static const InstructionInfo instruction_table[] = { + [INSTRUCTION_NOP] = { "nop", 0, { ARG_TYPE_NONE } }, + [INSTRUCTION_PUSH] = { "push", 1, { ARG_TYPE_INT } }, + [INSTRUCTION_DROP] = { "drop", 1, { ARG_TYPE_INT } }, + [INSTRUCTION_ADD] = { "add", 0, { ARG_TYPE_NONE } }, + [INSTRUCTION_SUB] = { "sub", 0, { ARG_TYPE_NONE } }, + [INSTRUCTION_MUL] = { "mul", 0, { ARG_TYPE_NONE } }, + [INSTRUCTION_DIV] = { "div", 0, { ARG_TYPE_NONE } }, + [INSTRUCTION_DUPLICATE] = { "dup", 1, { ARG_TYPE_INT } }, + [INSTRUCTION_HALT] = { "halt", 0, { ARG_TYPE_NONE } }, +}; + +InstructionType instructionNameToType(char* instName); + +#endif // !INSTRUCTIONS_H \ No newline at end of file diff --git a/src/asm/sasm.c b/src/asm/sasm.c index 6d72405..acc9d00 100644 --- a/src/asm/sasm.c +++ b/src/asm/sasm.c @@ -1,8 +1,8 @@ #include #include -#include "tokenize.h" #include "../file_utils.h" #include "assembler.h" +#include "../vmbl.h" int main(int argc, char *argv[]) { if (argc < 3) { @@ -13,14 +13,16 @@ int main(int argc, char *argv[]) { char *buffer = readStringFromFile(argv[1]); //printf("%s\n", buffer); - Tokenizer tokenizer = { + /*Tokenizer tokenizer = { .source = buffer, .column = 1, .line = 1, .pos = 0 - }; + };*/ - assemble(&tokenizer); + VMBL_Instruction program[VMBL_PROGRAM_SIZE]; + + assemble(buffer, program, VMBL_PROGRAM_SIZE); free(buffer); return 0; diff --git a/src/asm/tokenize.c b/src/asm/tokenize.c index 27040ce..aff5a13 100644 --- a/src/asm/tokenize.c +++ b/src/asm/tokenize.c @@ -125,6 +125,8 @@ Token getCurrentToken(Tokenizer *tokenizer) { default: if (isalpha(*tokenizer->source)) { + token.columnStart = tokenizer->column; + char *tokenValue = parseName(tokenizer); token.value = tokenValue; @@ -140,6 +142,7 @@ Token getCurrentToken(Tokenizer *tokenizer) { } } else if (isdigit(*tokenizer->source)) { + token.columnStart = token.columnStart; char *tokenValue = parseNumber(tokenizer); token.value = tokenValue; diff --git a/src/asm/tokenize.h b/src/asm/tokenize.h index 1b88c85..9c7063c 100644 --- a/src/asm/tokenize.h +++ b/src/asm/tokenize.h @@ -35,6 +35,7 @@ typedef struct TokenType type; char* value; unsigned int line; + unsigned int columnStart; } Token; typedef struct