undar-lang/src/tools/test.c

166 lines
4.5 KiB
C

#include "test.h"
#include "../vm/opcodes.h"
#include "../vm/vm.h"
#include "string.h"
#include <stdint.h>
u32 real_alloc(VM *vm, float v) {
i32 fixed = TO_FIXED(v);
u32 addr = vm->mp;
write_u32(vm, memory, vm->mp, fixed);
vm->mp += 4;
vm->frames[vm->fp].end += 4;
return addr;
}
u32 nat_alloc(VM *vm, u32 v) {
u32 addr = vm->mp;
write_u32(vm, memory, vm->mp, v);
vm->mp += 4;
vm->frames[vm->fp].end += 4;
return addr;
}
u32 int_alloc(VM *vm, i32 v) {
u32 addr = vm->mp;
write_u32(vm, memory, vm->mp, v);
vm->mp += 4;
vm->frames[vm->fp].end += 4;
return addr;
}
/* Array of test mappings */
struct TestMapping internal_tests[] = {
{"simple.ul", test_simple_compile},
{"window.ul", test_window_click_compile},
{NULL, NULL} /* Sentinel to mark end of array */
};
bool compile_internal_test(const char *filename, VM *vm) {
i32 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_simple_compile(VM *vm) {
u32 ptr;
u32 newline_addr = str_alloc(vm, &vm->frames[vm->fp], "\n", 2);
u32 terminal_path_addr =
str_alloc(vm, &vm->frames[vm->fp], "/dev/term/0", 12);
vm->code[vm->cp++] = OP_LOAD;
vm->code[vm->cp++] = 0;
ptr = real_alloc(vm, 1.0f);
write_u32(vm, code, vm->cp, ptr);
vm->cp += 4;
vm->code[vm->cp++] = OP_LOAD;
vm->code[vm->cp++] = 1;
ptr = real_alloc(vm, 2.0f);
write_u32(vm, code, vm->cp, ptr);
vm->cp += 4;
vm->code[vm->cp++] = OP_ADD_REAL;
vm->code[vm->cp++] = 2;
vm->code[vm->cp++] = 1;
vm->code[vm->cp++] = 0; /* let sum = 1 + 2; */
vm->code[vm->cp++] = OP_REAL_TO_STRING;
vm->code[vm->cp++] = 3;
vm->code[vm->cp++] = 2;
vm->code[vm->cp++] = OP_STRLEN;
vm->code[vm->cp++] = 4;
vm->code[vm->cp++] = 3;
vm->code[vm->cp++] = OP_LOAD_IMM;
vm->code[vm->cp++] = 5;
write_u32(vm, code, vm->cp, terminal_path_addr);
vm->cp += 4;
vm->code[vm->cp++] = OP_SYSCALL;
write_u32(vm, code, vm->cp, AS_UINT(SYSCALL_DEVICE_WRITE));
vm->cp += 4;
vm->code[vm->cp++] = 5;
vm->code[vm->cp++] = 3;
vm->code[vm->cp++] = 4;
vm->code[vm->cp++] = OP_LOAD_IMM;
vm->code[vm->cp++] = 6;
write_u32(vm, code, vm->cp, newline_addr);
vm->cp += 4;
vm->code[vm->cp++] = OP_STRLEN;
vm->code[vm->cp++] = 7;
vm->code[vm->cp++] = 6;
vm->code[vm->cp++] = OP_SYSCALL;
write_u32(vm, code, vm->cp, AS_UINT(SYSCALL_DEVICE_WRITE));
vm->cp += 4;
vm->code[vm->cp++] = 5;
vm->code[vm->cp++] = 6;
vm->code[vm->cp++] = 7;
/* syscall_id=WRITE, device-str-ptr=5, ptr, length ; print(sum.toS()); */
vm->code[vm->cp++] = OP_HALT; /* explicit halt */
return true;
}
bool test_window_click_compile(VM *vm) {
u32 test_pixel_addr, loop_start,
screen_path_addr =
str_alloc(vm, &vm->frames[vm->fp], "/dev/screen/0", 14);
vm->code[vm->cp++] = OP_LOAD; /* R0 = screen path */
vm->code[vm->cp++] = 0;
vm->code[vm->cp++] = nat_alloc(vm, screen_path_addr);
vm->code[vm->cp++] = OP_LOAD; /* R1 = mode (0) */
vm->code[vm->cp++] = 1;
vm->code[vm->cp++] = int_alloc(vm, 0);
vm->code[vm->cp++] = OP_SYSCALL;
vm->code[vm->cp++] = SYSCALL_DEVICE_OPEN;
vm->code[vm->cp++] = 0;
vm->code[vm->cp++] = 1;
test_pixel_addr = vm->mp;
vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64);
vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64);
vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64);
vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64);
vm->frames[vm->fp].end += 4;
vm->code[vm->cp++] = OP_LOAD;
vm->code[vm->cp++] = 0;
vm->code[vm->cp++] = nat_alloc(vm, screen_path_addr);
vm->code[vm->cp++] = OP_LOAD;
vm->code[vm->cp++] = 1;
vm->code[vm->cp++] = nat_alloc(vm, test_pixel_addr);
vm->code[vm->cp++] = OP_LOAD;
vm->code[vm->cp++] = 2;
vm->code[vm->cp++] = int_alloc(vm, 1);
vm->code[vm->cp++] = OP_LOAD;
vm->code[vm->cp++] = 3;
loop_start = vm->cp + 2; /* here + after alloc */
vm->code[vm->cp++] = nat_alloc(vm, loop_start);
vm->code[vm->cp++] = OP_SYSCALL;
vm->code[vm->cp++] = SYSCALL_DEVICE_WRITE;
vm->code[vm->cp++] = 0;
vm->code[vm->cp++] = 1;
vm->code[vm->cp++] = 2;
vm->code[vm->cp++] = OP_JMP;
vm->code[vm->cp++] = 3;
vm->code[vm->cp++] = OP_HALT;
return true;
}