add better testing, flags, fix fib.zrl
This commit is contained in:
parent
f1edd4267f
commit
0dedf5a2ad
|
@ -1,6 +1,9 @@
|
|||
#include "../../compiler.h"
|
||||
#include "../../vm.h"
|
||||
#include "../../debug.h"
|
||||
#include "../../test.h"
|
||||
#include "../../vm.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_SRC_SIZE 16384
|
||||
|
||||
|
@ -43,27 +46,99 @@ static void repl(VM *vm) {
|
|||
vm->mp = 0;
|
||||
|
||||
compile(line, vm);
|
||||
while (step_vm(vm));
|
||||
while (step_vm(vm))
|
||||
;
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
enum FlagType {
|
||||
FLAG_NONE = 0,
|
||||
FLAG_DEV_MODE = 1,
|
||||
FLAG_TEST_MODE = 2,
|
||||
FLAG_DUMP_ROM = 4
|
||||
/* Easy to extend with bitwise OR */
|
||||
};
|
||||
|
||||
#define MAX_INPUT_FILES 16 /* Adjust based on your system's constraints */
|
||||
|
||||
struct CompilerConfig {
|
||||
int flags;
|
||||
char *input_files[MAX_INPUT_FILES];
|
||||
int input_file_count;
|
||||
};
|
||||
|
||||
int parse_arguments(int argc, char *argv[], struct CompilerConfig *config) {
|
||||
int i;
|
||||
|
||||
/* Initialize config */
|
||||
config->flags = 0;
|
||||
config->input_file_count = 0;
|
||||
|
||||
/* Zero out input files array for safety */
|
||||
for (i = 0; i < MAX_INPUT_FILES; i++) {
|
||||
config->input_files[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
/* Long and short flag handling */
|
||||
if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--dev") == 0) {
|
||||
config->flags |= FLAG_DEV_MODE;
|
||||
} else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--test") == 0) {
|
||||
config->flags |= FLAG_TEST_MODE;
|
||||
} else if (strcmp(argv[i], "-o") == 0 ||
|
||||
strcmp(argv[i], "--dump-rom") == 0) {
|
||||
config->flags |= FLAG_DUMP_ROM;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown flag: %s\n", argv[i]);
|
||||
return -1;
|
||||
}
|
||||
} else if (strstr(argv[i], ".zrl") != NULL) {
|
||||
/* Collect input files */
|
||||
if (config->input_file_count >= MAX_INPUT_FILES) {
|
||||
fprintf(stderr, "Too many input files. Maximum is %d\n",
|
||||
MAX_INPUT_FILES);
|
||||
return -1;
|
||||
}
|
||||
config->input_files[config->input_file_count++] = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct CompilerConfig config = {0};
|
||||
|
||||
if (parse_arguments(argc, argv, &config) != 0) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-d] [-t] [-r] [-o] <file1.zrl> [file2.zrl] ...\n",
|
||||
argv[0]);
|
||||
return 64;
|
||||
}
|
||||
|
||||
VM vm = {0};
|
||||
vm.frames_size = FRAMES_SIZE;
|
||||
vm.return_stack_size = STACK_SIZE;
|
||||
vm.stack_size = STACK_SIZE;
|
||||
vm.memory_size = MEMORY_SIZE;
|
||||
|
||||
if (argc == 1) {
|
||||
test_add_compile(&vm);
|
||||
/* repl(&vm); */
|
||||
} else if (argc == 2) {
|
||||
compileFile(argv[1], &vm);
|
||||
} else {
|
||||
fprintf(stderr, "Usage: %s <file.zrl>\n", argv[0]);
|
||||
return 64;
|
||||
if (config.input_file_count == 0) {
|
||||
repl(&vm);
|
||||
} else {
|
||||
if (config.flags & FLAG_TEST_MODE) {
|
||||
compile_internal_test(config.input_files[0], &vm);
|
||||
} else {
|
||||
int j;
|
||||
for (j = 0; j < config.input_file_count; j++) {
|
||||
compileFile(config.input_files[j], &vm);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.flags & FLAG_DUMP_ROM) {
|
||||
core_dump(&vm);
|
||||
}
|
||||
}
|
||||
|
||||
bool running = true;
|
||||
|
|
64
src/test.c
64
src/test.c
|
@ -1,13 +1,32 @@
|
|||
#include "test.h"
|
||||
#include "vm.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Array of test mappings */
|
||||
struct TestMapping internal_tests[] = {
|
||||
{"simple.zrl", test_add_compile},
|
||||
{"loop.zrl", test_loop_compile},
|
||||
{"add.zrl", test_add_function_compile},
|
||||
{"fib.zrl", test_recursive_function_compile},
|
||||
/* Add more test mappings here */
|
||||
{NULL, NULL} /* Sentinel to mark end of array */
|
||||
};
|
||||
|
||||
bool compile_internal_test(const char* filename, VM* vm) {
|
||||
int i;
|
||||
for (i = 0; internal_tests[i].filename != NULL; i++) {
|
||||
if (strcmp(internal_tests[i].filename, filename) == 0) {
|
||||
return internal_tests[i].test_func(vm);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool test_add_compile(VM *vm) {
|
||||
vm->code[vm->cp++].u = OP(OP_LOADU, 0, 0, 0);
|
||||
vm->code[vm->cp++].u = 0;
|
||||
nat_alloc(vm, 1);
|
||||
vm->code[vm->cp++].u = nat_alloc(vm, 1);
|
||||
vm->code[vm->cp++].u = OP(OP_LOADU, 1, 1, 0);
|
||||
vm->code[vm->cp++].u = 1;
|
||||
nat_alloc(vm, 2);
|
||||
vm->code[vm->cp++].u = nat_alloc(vm, 2);
|
||||
vm->code[vm->cp++].u = OP(OP_ADD_UINT, 2, 1, 0); /* let sum = 1 + 2; */
|
||||
vm->code[vm->cp++].u = OP(OP_UINT_TO_STRING, 3, 2, 0);
|
||||
vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(sum.toS()); */
|
||||
|
@ -17,30 +36,24 @@ bool test_add_compile(VM *vm) {
|
|||
|
||||
bool test_loop_compile(VM *vm) {
|
||||
vm->code[vm->cp++].u = OP(OP_LOADF, 0, 0, 0); /* let a = 5.0 */
|
||||
uint32_t addr = real_alloc(vm, 5.0f);
|
||||
vm->code[vm->cp++].u = addr;
|
||||
vm->code[vm->cp++].u = real_alloc(vm, 5.0f);
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 1, 0, 0); /* do (i = 50000, 0, -1) { */
|
||||
addr = int_alloc(vm, 50000);
|
||||
vm->code[vm->cp++].u = addr;
|
||||
vm->code[vm->cp++].u = int_alloc(vm, 50000);
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* loop check value */
|
||||
addr = int_alloc(vm, 0);
|
||||
vm->code[vm->cp++].u = addr;
|
||||
vm->code[vm->cp++].u = int_alloc(vm, 0);
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* loop incriment value */
|
||||
addr = int_alloc(vm, -1);
|
||||
vm->code[vm->cp++].u = addr;
|
||||
vm->code[vm->cp++].u = int_alloc(vm, -1);
|
||||
vm->code[vm->cp++].u = OP(OP_LOADU, 4, 0, 0); /* loop start */
|
||||
addr = int_alloc(vm, vm->cp + 1);
|
||||
vm->code[vm->cp++].u = addr;
|
||||
uint32_t addr = vm->cp + 1;
|
||||
vm->code[vm->cp++].u = int_alloc(vm, addr);
|
||||
vm->code[vm->cp++].u = OP(OP_LOADF, 5, 0, 0);
|
||||
addr = real_alloc(vm, 5.0f);
|
||||
vm->code[vm->cp++].u = addr;
|
||||
vm->code[vm->cp++].u = real_alloc(vm, 5.0f);
|
||||
vm->code[vm->cp++].u = OP(OP_ADD_REAL, 0, 0, 5); /* a += 5.0; */
|
||||
vm->code[vm->cp++].u = OP(OP_ADD_INT, 1, 1, 3); /* (implied by loop) i = i + (-1) */
|
||||
vm->code[vm->cp++].u = OP(OP_JGE_INT, 4, 1, 2); /* } */
|
||||
vm->code[vm->cp++].u = OP(OP_REAL_TO_UINT, 1, 0, 0); /* let b = a as nat; */
|
||||
vm->code[vm->cp++].u = OP(OP_LOADP, 6, 0, 0);
|
||||
addr = str_alloc(vm, "Enter a string:", 0);
|
||||
vm->code[vm->cp++].u = addr;
|
||||
vm->code[vm->cp++].u = str_alloc(vm, "Enter a string:", 0);
|
||||
vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 6, 0); /* print("Enter a string: "); */
|
||||
vm->code[vm->cp++].u = OP(OP_READ_STRING, 2, 0, 0); /* let user_string = gets(); */
|
||||
vm->code[vm->cp++].u = OP(OP_UINT_TO_STRING, 3, 1, 0);
|
||||
|
@ -55,10 +68,11 @@ bool test_loop_compile(VM *vm) {
|
|||
bool test_add_function_compile(VM *vm) {
|
||||
/* fn main() */
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */
|
||||
vm->code[vm->cp++].i = 1;
|
||||
uint32_t addr = int_alloc(vm, 1);
|
||||
vm->code[vm->cp++].u = addr;
|
||||
vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0);
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */
|
||||
vm->code[vm->cp++].i = 1;
|
||||
vm->code[vm->cp++].u = addr;
|
||||
vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0);
|
||||
vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* ); */
|
||||
vm->code[vm->cp++].u = 12;
|
||||
|
@ -78,7 +92,7 @@ bool test_add_function_compile(VM *vm) {
|
|||
bool test_recursive_function_compile(VM *vm) {
|
||||
/* fn main() */
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 0, 0, 0); /* 35 */
|
||||
vm->code[vm->cp++].i = 35;
|
||||
vm->code[vm->cp++].u = int_alloc(vm, 35);
|
||||
vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0);
|
||||
vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* ); */
|
||||
vm->code[vm->cp++].u = 9;
|
||||
|
@ -89,18 +103,18 @@ bool test_recursive_function_compile(VM *vm) {
|
|||
/* fn fib() */
|
||||
vm->code[vm->cp++].u = OP(OP_POPI, 0, 0, 0); /* n int */
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 1, 0, 0); /* 2 */
|
||||
vm->code[vm->cp++].i = 2;
|
||||
vm->code[vm->cp++].u = int_alloc(vm, 2);
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* &fib */
|
||||
vm->code[vm->cp++].i = 32;
|
||||
vm->code[vm->cp++].u = int_alloc(vm, 32);
|
||||
vm->code[vm->cp++].u = OP(OP_JLT_INT, 2, 0, 1);
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* 2 */
|
||||
vm->code[vm->cp++].i = 2;
|
||||
vm->code[vm->cp++].u = int_alloc(vm, 2);
|
||||
vm->code[vm->cp++].u = OP(OP_SUB_INT, 4, 0, 3);
|
||||
vm->code[vm->cp++].u = OP(OP_PUSHI, 4, 0, 0);
|
||||
vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 2) */
|
||||
vm->code[vm->cp++].u = 9;
|
||||
vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* 1 */
|
||||
vm->code[vm->cp++].i = 1;
|
||||
vm->code[vm->cp++].u = int_alloc(vm, 1);
|
||||
vm->code[vm->cp++].u = OP(OP_SUB_INT, 4, 0, 3);
|
||||
vm->code[vm->cp++].u = OP(OP_PUSHI, 4, 0, 0);
|
||||
vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 1) */
|
||||
|
|
10
src/test.h
10
src/test.h
|
@ -3,6 +3,16 @@
|
|||
|
||||
#include "opcodes.h"
|
||||
|
||||
/* Test function type definition */
|
||||
typedef bool (*TestFunction)(VM *vm);
|
||||
|
||||
/* Test mapping structure */
|
||||
struct TestMapping {
|
||||
const char* filename;
|
||||
TestFunction test_func;
|
||||
};
|
||||
|
||||
bool compile_internal_test(const char* filename, VM* vm);
|
||||
bool test_add_compile (VM *vm);
|
||||
bool test_loop_compile (VM *vm);
|
||||
bool test_add_function_compile(VM *vm);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
fn add(int a, int b) int {
|
||||
function add(int a, int b) int {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
fn fib(int n) int {
|
||||
function fib(int n) int {
|
||||
if (n < 2) return n;
|
||||
return fib(n - 2) + fib(n - 1);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ for (let i = 50000; i > 0; i = i - 1) {
|
|||
}
|
||||
let b = a;
|
||||
print "Enter a string:";
|
||||
let user_string = read();
|
||||
//let user_string = read();
|
||||
print(a);
|
||||
print(b);
|
||||
print(user_string);
|
||||
//print(user_string);
|
||||
|
|
|
@ -37,5 +37,5 @@ print_section "zlc ($FILENAME.zl)"
|
|||
echo "test input" | time zlc "$FILENAME.zl"
|
||||
|
||||
# ZRE Implementation
|
||||
print_section "zre ($FILENAME.zre)"
|
||||
echo "test input" | time ../src/zre "$FILENAME.zre"
|
||||
print_section "zre ($FILENAME.zrl)"
|
||||
echo "test input" | time ../src/zre -t "$FILENAME.zrl"
|
||||
|
|
Loading…
Reference in New Issue