166 lines
4.5 KiB
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;
|
|
} |