diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-10-08 19:58:00 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-10-08 19:58:00 +0330 |
commit | 8e9d0b5e9a4613e9ef980b5c0fd8e53f2c394195 (patch) | |
tree | 5d0dba6505fd0a7aed7cba79558563a323f8092b | |
parent | addd54dc31603dc204773d3108dba4e000cd7657 (diff) |
-rwxr-xr-x | project | 29 | ||||
-rw-r--r-- | src/fasm/lexer/lexer.c | 7 | ||||
-rw-r--r-- | src/fasm/linker/linker.c | 2 | ||||
-rw-r--r-- | src/fasm/runner/runner.c | 322 | ||||
-rw-r--r-- | src/main.c | 20 | ||||
-rw-r--r-- | src/utils/types.h | 13 |
6 files changed, 227 insertions, 166 deletions
@@ -10,7 +10,7 @@ function compile(){ fi fi - gcc -Wall -Wextra -std=gnu23 -I./src/ -g \ + gcc -Wall -Wextra -std=gnu23 -I./src/ -O3 \ ./src/main.c \ ./src/compiler/source_code/source_code.c \ ./src/compiler/error_helper/error_helper.c \ @@ -46,6 +46,10 @@ function clean(){ if [ "$(ls ./test/generated_output/)" ]; then rm -r ./test/generated_output/* fi + + if [ "$(ls ./test/fasm/generated_output/)" ]; then + rm -r ./test/fasm/generated_output/* + fi } function test(){ @@ -71,6 +75,29 @@ function test(){ done } +function fasm_test(){ + clean && compile + if [ $? -ne 0 ]; then + echo "compile error" + exit + fi + local RED='\033[0;31m' + local GREEN='\033[0;32m' + local NC='\033[0m' + + for file_path in ./test/fasm/input/*; do + local file_name=$(basename "$file_path") + local start=`date +%s.%N` + local ret=$(eval "./build/$project_name run-fasm $file_path > ./test/fasm/generated_output/$file_name") + local end=`date +%s.%N` + runtime="$(jq -n $end-$start)" + $ret && \ + cmp --silent "./test/fasm/generated_output/$file_name" "./test/fasm/output/$file_name" && \ + printf "${GREEN}PASSED${NC} %.9fs $file_path\n" $runtime || \ + printf "${RED}FAILED${NC} %.9fs $file_path\n" $runtime + done +} + function val_test(){ clean && compile if [ $? -ne 0 ]; then diff --git a/src/fasm/lexer/lexer.c b/src/fasm/lexer/lexer.c index e3e9610..5a9e38e 100644 --- a/src/fasm/lexer/lexer.c +++ b/src/fasm/lexer/lexer.c @@ -316,12 +316,15 @@ FasmLines fasmLexerCode(Code *code, SourceCode *sourceCode) { } else { UNEXPECTED: fasmLinePrint(line); - printError("Unexpected character", sourceCode, iter, iter + 1); + printError("Unexpected character '%c'", sourceCode, iter, iter + 1, + *iter); goto RETURN_ERROR; } break; case FASM_LINE_LOOKING_FOR_INSTRUCTION: - if (fasmLexerIsWord(c)) { + if (fasmLexerIsLineSeparator(c)) { + continue; + } else if (fasmLexerIsWord(c)) { char *begin = iter; char *end = iter = fasmLexerGetNextWord(iter); line.end = end; diff --git a/src/fasm/linker/linker.c b/src/fasm/linker/linker.c index faa3cd8..fe58065 100644 --- a/src/fasm/linker/linker.c +++ b/src/fasm/linker/linker.c @@ -10,7 +10,7 @@ #include <utils/memory/memory.h> void fasmVariablePrint(FasmVariable variable) { - printf(" {name='%.*s',value=0x%ld}\n", (int)(variable.end - variable.begin), + printf(" {name='%.*s',value=0x%lx}\n", (int)(variable.end - variable.begin), variable.begin, variable.value); } diff --git a/src/fasm/runner/runner.c b/src/fasm/runner/runner.c index c01db18..ac7b768 100644 --- a/src/fasm/runner/runner.c +++ b/src/fasm/runner/runner.c @@ -11,8 +11,7 @@ #define PUSHN(bits) \ pushToStack##bits##Bits(&stack, &stack_size, &stack_filled, \ - getNext##bits##Bits(&ip)); \ - ip += bits / 8 + getNext##bits##Bits(&ip)) #define LOADN(bits) \ pushToStack##bits##Bits(&stack, &stack_size, &stack_filled, \ @@ -49,11 +48,11 @@ #define OPERATION(type, bits, op) \ { \ - const type a = \ + const uint##bits##_t a = \ popFromStack##bits##Bits(&stack, &stack_size, &stack_filled); \ - const type b = \ + const uint##bits##_t b = \ popFromStack##bits##Bits(&stack, &stack_size, &stack_filled); \ - const type result = a op b; \ + const type result = *((type *)&a)op * ((type *)&b); \ pushToStack##bits##Bits(&stack, &stack_size, &stack_filled, \ *(uint##bits##_t *)&result); \ } @@ -101,6 +100,9 @@ int fasmRunner(ByteCode bytecode) { size_t data_size = bytecode.data_size; memcpy(data, bytecode.data, data_size); + uint8_t *code = bytecode.code; + /*size_t code_size = bytecode.code_size;*/ + size_t stack_size = 0; size_t stack_filled = 0; uint8_t *stack = a404m_malloc(stack_size); @@ -109,413 +111,413 @@ int fasmRunner(ByteCode bytecode) { size_t functions_index = -1; FasmFunction *functions = a404m_malloc(functions_size * sizeof(*functions)); - uint8_t *ip = bytecode.code; + uint8_t *ip = code; while (true) { const FasmToken instruction = *ip; ++ip; switch (instruction) { case FASM_TOKEN_NOOP: - break; + continue; case FASM_TOKEN_PUSH8: PUSHN(8); - break; + continue; case FASM_TOKEN_PUSH16: PUSHN(16); - break; + continue; case FASM_TOKEN_PUSH32: PUSHN(32); - break; + continue; case FASM_TOKEN_PUSH64: PUSHN(64); - break; + continue; case FASM_TOKEN_LOAD8: LOADN(8); - break; + continue; case FASM_TOKEN_LOAD16: LOADN(16); - break; + continue; case FASM_TOKEN_LOAD32: LOADN(32); - break; + continue; case FASM_TOKEN_LOAD64: LOADN(64); - break; + continue; case FASM_TOKEN_POP8: POPN(8); - break; + continue; case FASM_TOKEN_POP16: POPN(16); - break; + continue; case FASM_TOKEN_POP32: POPN(32); - break; + continue; case FASM_TOKEN_POP64: POPN(64); - break; + continue; case FASM_TOKEN_DUP8: DUPN(8); - break; + continue; case FASM_TOKEN_DUP16: DUPN(16); - break; + continue; case FASM_TOKEN_DUP32: DUPN(32); - break; + continue; case FASM_TOKEN_DUP64: DUPN(64); - break; + continue; case FASM_TOKEN_SWAP8: SWAPN(8); - break; + continue; case FASM_TOKEN_SWAP16: SWAPN(16); - break; + continue; case FASM_TOKEN_SWAP32: SWAPN(32); - break; + continue; case FASM_TOKEN_SWAP64: SWAPN(64); - break; + continue; case FASM_TOKEN_DROP8: DROPN(8); - break; + continue; case FASM_TOKEN_DROP16: DROPN(16); - break; + continue; case FASM_TOKEN_DROP32: DROPN(32); - break; + continue; case FASM_TOKEN_DROP64: DROPN(64); - break; + continue; case FASM_TOKEN_ADD_I8: ADD(uint8_t, 8); - break; + continue; case FASM_TOKEN_ADD_I16: ADD(uint16_t, 16); - break; + continue; case FASM_TOKEN_ADD_I32: ADD(uint32_t, 32); - break; + continue; case FASM_TOKEN_ADD_I64: ADD(uint64_t, 64); - break; + continue; case FASM_TOKEN_ADD_F32: ADD(float, 32); - break; + continue; case FASM_TOKEN_ADD_F64: ADD(double, 64); - break; + continue; case FASM_TOKEN_SUB_I8: SUB(uint8_t, 8); - break; + continue; case FASM_TOKEN_SUB_I16: SUB(uint16_t, 16); - break; + continue; case FASM_TOKEN_SUB_I32: SUB(uint32_t, 32); - break; + continue; case FASM_TOKEN_SUB_I64: SUB(uint64_t, 64); - break; + continue; case FASM_TOKEN_SUB_F32: SUB(float, 32); - break; + continue; case FASM_TOKEN_SUB_F64: SUB(double, 64); - break; + continue; case FASM_TOKEN_NEG_I8: NEG(int8_t, 8); - break; + continue; case FASM_TOKEN_NEG_I16: NEG(int16_t, 16); - break; + continue; case FASM_TOKEN_NEG_I32: NEG(int32_t, 32); - break; + continue; case FASM_TOKEN_NEG_I64: NEG(int64_t, 64); - break; + continue; case FASM_TOKEN_NEG_F32: NEG(float, 32); - break; + continue; case FASM_TOKEN_NEG_F64: NEG(double, 64); - break; + continue; case FASM_TOKEN_MUL_I8: MUL(int8_t, 8); - break; + continue; case FASM_TOKEN_MUL_I16: MUL(int16_t, 16); - break; + continue; case FASM_TOKEN_MUL_I32: MUL(int32_t, 32); - break; + continue; case FASM_TOKEN_MUL_I64: MUL(int64_t, 64); - break; + continue; case FASM_TOKEN_MUL_U8: MUL(uint8_t, 8); - break; + continue; case FASM_TOKEN_MUL_U16: MUL(uint16_t, 16); - break; + continue; case FASM_TOKEN_MUL_U32: MUL(uint32_t, 32); - break; + continue; case FASM_TOKEN_MUL_U64: MUL(uint64_t, 64); - break; + continue; case FASM_TOKEN_MUL_F32: MUL(float, 32); - break; + continue; case FASM_TOKEN_MUL_F64: MUL(double, 64); - break; + continue; case FASM_TOKEN_DIV_I8: DIV(int8_t, 8); - break; + continue; case FASM_TOKEN_DIV_I16: DIV(int16_t, 16); - break; + continue; case FASM_TOKEN_DIV_I32: DIV(int32_t, 32); - break; + continue; case FASM_TOKEN_DIV_I64: DIV(int64_t, 64); - break; + continue; case FASM_TOKEN_DIV_U8: DIV(uint8_t, 8); - break; + continue; case FASM_TOKEN_DIV_U16: DIV(uint16_t, 16); - break; + continue; case FASM_TOKEN_DIV_U32: DIV(uint32_t, 32); - break; + continue; case FASM_TOKEN_DIV_U64: DIV(uint64_t, 64); - break; + continue; case FASM_TOKEN_DIV_F32: DIV(float, 32); - break; + continue; case FASM_TOKEN_DIV_F64: DIV(double, 64); - break; + continue; case FASM_TOKEN_REM_I8: REM(int8_t, 8); - break; + continue; case FASM_TOKEN_REM_I16: REM(int16_t, 16); - break; + continue; case FASM_TOKEN_REM_I32: REM(int32_t, 32); - break; + continue; case FASM_TOKEN_REM_I64: REM(int64_t, 64); - break; + continue; case FASM_TOKEN_REM_U8: REM(uint8_t, 8); - break; + continue; case FASM_TOKEN_REM_U16: REM(uint16_t, 16); - break; + continue; case FASM_TOKEN_REM_U32: REM(uint32_t, 32); - break; + continue; case FASM_TOKEN_REM_U64: REM(uint64_t, 64); - break; + continue; case FASM_TOKEN_CAST_I8_I64: CAST(int8_t, 8, int64_t, 64); - break; + continue; case FASM_TOKEN_CAST_I16_I64: CAST(int16_t, 16, int64_t, 64); - break; + continue; case FASM_TOKEN_CAST_I32_I64: CAST(int32_t, 32, int64_t, 64); - break; + continue; case FASM_TOKEN_CAST_I64_I8: CAST(int64_t, 64, int8_t, 8); - break; + continue; case FASM_TOKEN_CAST_I64_I16: CAST(int64_t, 64, int16_t, 16); - break; + continue; case FASM_TOKEN_CAST_I64_I32: CAST(int64_t, 64, int32_t, 32); - break; + continue; case FASM_TOKEN_CAST_F64_I64: CAST(double, 64, int64_t, 64); - break; + continue; case FASM_TOKEN_CAST_I64_F64: CAST(int64_t, 64, double, 64); - break; + continue; case FASM_TOKEN_CAST_U8_U64: CAST(uint8_t, 8, uint64_t, 64); - break; + continue; case FASM_TOKEN_CAST_U16_U64: CAST(uint16_t, 16, uint64_t, 64); - break; + continue; case FASM_TOKEN_CAST_U32_U64: CAST(uint32_t, 32, uint64_t, 64); - break; + continue; case FASM_TOKEN_CAST_U64_U8: CAST(uint64_t, 64, uint8_t, 8); - break; + continue; case FASM_TOKEN_CAST_U64_U16: CAST(uint64_t, 64, uint16_t, 16); - break; + continue; case FASM_TOKEN_CAST_U64_U32: CAST(uint64_t, 64, uint32_t, 32); - break; + continue; case FASM_TOKEN_CAST_F64_U64: CAST(double, 64, uint64_t, 64); - break; + continue; case FASM_TOKEN_CAST_U64_F64: CAST(uint64_t, 64, double, 64); - break; + continue; case FASM_TOKEN_CAST_F32_F64: CAST(float, 32, double, 64); - break; + continue; case FASM_TOKEN_CAST_F64_F32: CAST(double, 64, float, 32); - break; + continue; case FASM_TOKEN_JUMP: ip = (uint8_t *)popFromStack64Bits(&stack, &stack_size, &stack_filled); - break; + continue; case FASM_TOKEN_JZ_I8: COND_JUMP(int8_t, 8, ==); - break; + continue; case FASM_TOKEN_JNZ_I8: COND_JUMP(int8_t, 8, !=); - break; + continue; case FASM_TOKEN_JN_I8: COND_JUMP(int8_t, 8, <); - break; + continue; case FASM_TOKEN_JNN_I8: COND_JUMP(int8_t, 8, >=); - break; + continue; case FASM_TOKEN_JP_I8: COND_JUMP(int8_t, 8, >); - break; + continue; case FASM_TOKEN_JNP_I8: COND_JUMP(int8_t, 8, <=); - break; + continue; case FASM_TOKEN_JZ_I16: COND_JUMP(int16_t, 16, ==); - break; + continue; case FASM_TOKEN_JNZ_I16: COND_JUMP(int16_t, 16, !=); - break; + continue; case FASM_TOKEN_JN_I16: COND_JUMP(int16_t, 16, <); - break; + continue; case FASM_TOKEN_JNN_I16: COND_JUMP(int16_t, 16, >=); - break; + continue; case FASM_TOKEN_JP_I16: COND_JUMP(int16_t, 16, >); - break; + continue; case FASM_TOKEN_JNP_I16: COND_JUMP(int16_t, 16, <=); - break; + continue; case FASM_TOKEN_JZ_I32: COND_JUMP(int32_t, 32, ==); - break; + continue; case FASM_TOKEN_JNZ_I32: COND_JUMP(int32_t, 32, !=); - break; + continue; case FASM_TOKEN_JN_I32: COND_JUMP(int32_t, 32, <); - break; + continue; case FASM_TOKEN_JNN_I32: COND_JUMP(int32_t, 32, >=); - break; + continue; case FASM_TOKEN_JP_I32: COND_JUMP(int32_t, 32, >); - break; + continue; case FASM_TOKEN_JNP_I32: COND_JUMP(int32_t, 32, <=); - break; + continue; case FASM_TOKEN_JZ_I64: COND_JUMP(int64_t, 64, ==); - break; + continue; case FASM_TOKEN_JNZ_I64: COND_JUMP(int64_t, 64, !=); - break; + continue; case FASM_TOKEN_JN_I64: COND_JUMP(int64_t, 64, <); - break; + continue; case FASM_TOKEN_JNN_I64: COND_JUMP(int64_t, 64, >=); - break; + continue; case FASM_TOKEN_JP_I64: COND_JUMP(int64_t, 64, >); - break; + continue; case FASM_TOKEN_JNP_I64: COND_JUMP(int64_t, 64, <=); - break; + continue; case FASM_TOKEN_JZ_F32: COND_JUMP(float, 32, ==); - break; + continue; case FASM_TOKEN_JNZ_F32: COND_JUMP(float, 32, !=); - break; + continue; case FASM_TOKEN_JN_F32: COND_JUMP(float, 32, <); - break; + continue; case FASM_TOKEN_JNN_F32: COND_JUMP(float, 32, >=); - break; + continue; case FASM_TOKEN_JP_F32: COND_JUMP(float, 32, >); - break; + continue; case FASM_TOKEN_JNP_F32: COND_JUMP(float, 32, <=); - break; + continue; case FASM_TOKEN_JZ_F64: COND_JUMP(double, 64, ==); - break; + continue; case FASM_TOKEN_JNZ_F64: COND_JUMP(double, 64, !=); - break; + continue; case FASM_TOKEN_JN_F64: COND_JUMP(double, 64, <); - break; + continue; case FASM_TOKEN_JNN_F64: COND_JUMP(double, 64, >=); - break; + continue; case FASM_TOKEN_JP_F64: COND_JUMP(double, 64, >); - break; + continue; case FASM_TOKEN_JNP_F64: COND_JUMP(double, 64, <=); - break; + continue; case FASM_TOKEN_ALLOC_HEAP: pushToStack64Bits(&stack, &stack_size, &stack_filled, (uint64_t)a404m_malloc(popFromStack64Bits( &stack, &stack_size, &stack_filled))); - break; + continue; case FASM_TOKEN_ALLOC_STACK: functions[functions_index].stack_size = popFromStack64Bits(&stack, &stack_size, &stack_filled); functions[functions_index].stack = a404m_malloc(functions[functions_index].stack_size); - break; + continue; case FASM_TOKEN_FREE_HEAP: free((void *)popFromStack64Bits(&stack, &stack_size, &stack_filled)); - break; + continue; case FASM_TOKEN_GET_STACK_ADDRESS: pushToStack64Bits(&stack, &stack_size, &stack_filled, (uint64_t)functions[functions_index].stack); - break; + continue; case FASM_TOKEN_GET_GLOBAL_ADDRESS: pushToStack64Bits(&stack, &stack_size, &stack_filled, (uint64_t)data); - break; + continue; case FASM_TOKEN_CALL: { uint8_t *const newIp = - (uint8_t *)popFromStack64Bits(&stack, &stack_size, &stack_filled); + code + popFromStack64Bits(&stack, &stack_size, &stack_filled); ++functions_index; if (functions_index == functions_size) { functions_size += functions_size / 2 + 1; @@ -529,7 +531,8 @@ int fasmRunner(ByteCode bytecode) { }; functions[functions_index] = function; ip = newIp; - } break; + } + continue; case FASM_TOKEN_RET: { FasmFunction function = functions[functions_index]; free(function.stack); @@ -540,10 +543,12 @@ int fasmRunner(ByteCode bytecode) { functions = a404m_realloc(functions, functions_size * sizeof(*functions)); } - } break; + } + continue; case FASM_TOKEN_SYSCALL: { - switch ((FasmSyscall)popFromStack8Bits(&stack, &stack_size, - &stack_filled)) { + FasmSyscall syscallId = + popFromStack8Bits(&stack, &stack_size, &stack_filled); + switch (syscallId) { case FASM_SYSCALL_READ: { uint32_t fd = popFromStack32Bits(&stack, &stack_size, &stack_filled); @@ -552,7 +557,8 @@ int fasmRunner(ByteCode bytecode) { uint64_t count = popFromStack64Bits(&stack, &stack_size, &stack_filled); syscall(SYS_read, fd, buf, count); - } break; + } + continue; case FASM_SYSCALL_WRITE: { uint32_t fd = popFromStack32Bits(&stack, &stack_size, &stack_filled); @@ -561,7 +567,8 @@ int fasmRunner(ByteCode bytecode) { uint64_t count = popFromStack64Bits(&stack, &stack_size, &stack_filled); syscall(SYS_write, fd, buf, count); - } break; + } + continue; case FASM_SYSCALL_OPEN: { int8_t *filename = (int8_t *)popFromStack64Bits(&stack, &stack_size, &stack_filled); @@ -570,14 +577,16 @@ int fasmRunner(ByteCode bytecode) { uint32_t mode = popFromStack32Bits(&stack, &stack_size, &stack_filled); syscall(SYS_open, filename, flags, mode); - } break; + } + continue; case FASM_SYSCALL_CLOSE: { uint32_t fd = popFromStack32Bits(&stack, &stack_size, &stack_filled); syscall(SYS_close, fd); - } break; + } + continue; case FASM_SYSCALL_EXIT: - for (size_t i = functions_index; i != (size_t)-1; ++i) { + for (size_t i = functions_index; i != (size_t)-1; --i) { free(functions[i].stack); } const uint32_t status = @@ -587,24 +596,25 @@ int fasmRunner(ByteCode bytecode) { free(data); return status; } - } break; + fprintf(stderr, "Bad system call %d", syscallId); + exit(1); + } case FASM_TOKEN_DEFINE_BYTE: case FASM_TOKEN_DEFINE_WORD: case FASM_TOKEN_DEFINE_DWORD: case FASM_TOKEN_DEFINE_QWORD: case FASM_TOKEN_NONE: - default: - fprintf(stderr, "Bad fasm instruction %d", instruction); - exit(1); } + fprintf(stderr, "Bad fasm instruction %d", instruction); + exit(1); } } -#define getNextNBits(bits) \ - uint##bits##_t getNext##bits##Bits(uint8_t **pos) { \ - uint##bits##_t *p = *((uint##bits##_t **)pos); \ - pos += sizeof(*p); \ - return *p; \ +#define getNextNBits(bits) \ + uint##bits##_t getNext##bits##Bits(uint8_t **pos) { \ + uint##bits##_t value = *((uint##bits##_t *)(*pos)); \ + *pos += sizeof(value); \ + return value; \ } getNextNBits(8); @@ -1,4 +1,5 @@ #include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <utils/file.h> @@ -56,17 +57,17 @@ int compileFasm(const char *const filePath) { } pushToSourceCode(&sourceCode, code); - printf("----lexing:\n"); + // printf("----lexing:\n"); FasmLines *lines; if ((lines = fasmLexer(&sourceCode)) == NULL) { goto RETURN_ERROR; } - for (size_t i = 0; i < sourceCode.size; ++i) { - fasmLinesPrint(lines[i]); - } + // for (size_t i = 0; i < sourceCode.size; ++i) { + // fasmLinesPrint(lines[i]); + // } - printf("----linking:\n"); + // printf("----linking:\n"); FasmLinkedLines linkedLines = fasmLinker(lines, &sourceCode); @@ -74,10 +75,17 @@ int compileFasm(const char *const filePath) { goto RETURN_LINKED_ERROR; } - fasmLinkedLinesPrint(linkedLines); + // fasmLinkedLinesPrint(linkedLines); + + // printf("----bytecode:\n"); ByteCode bytecode = fasmCodeGenerator(&linkedLines); + // for (size_t i = 0; i < bytecode.code_size; ++i) { + // printf("0x%.2x ", bytecode.code[i]); + //} + // printf("\n"); + deleteByteCodeInners(bytecode); fasmLinkedLinesDeleteInner(linkedLines); diff --git a/src/utils/types.h b/src/utils/types.h index b75d64d..4994014 100644 --- a/src/utils/types.h +++ b/src/utils/types.h @@ -14,4 +14,17 @@ typedef struct SizedString { size_t size; } SizedString; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef float f32; +typedef double f64; + #define ERROR_SIZE INT64_MAX |