WIP Code generation, 'simple' works
This commit is contained in:
parent
2e5eb03227
commit
f901dafa2b
|
|
@ -1,4 +0,0 @@
|
|||
(lambda add-two (a b)
|
||||
(return (+ a b)))
|
||||
|
||||
(print (to-string (add-two 1 1)))
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
(lambda fib (n)
|
||||
(if (n < 2)
|
||||
(return n))
|
||||
(return (+ (fib (- n 2)) (fib (- n 1)))))
|
||||
|
||||
(print (fib 36))
|
||||
|
|
@ -1 +0,0 @@
|
|||
(print "nuqneH 'u'?")
|
||||
|
|
@ -1 +0,0 @@
|
|||
(print (+ 1.0 2.0))
|
||||
|
|
@ -163,25 +163,6 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool init_vm(VM *vm) {
|
||||
vm->memory = (u8 *)malloc(MEMORY_SIZE * sizeof(u8));
|
||||
vm->memory_size = MEMORY_SIZE;
|
||||
|
||||
vm->code = (u8 *)malloc(CODE_SIZE * sizeof(u8));
|
||||
vm->code_size = CODE_SIZE;
|
||||
|
||||
vm->frames = (Frame *)malloc(FRAMES_SIZE * sizeof(Frame));
|
||||
vm->frames_size = FRAMES_SIZE;
|
||||
|
||||
vm->stack = (u32 *)malloc(STACK_SIZE * sizeof(u32));
|
||||
vm->stack_size = STACK_SIZE;
|
||||
|
||||
vm->devices = (Device *)malloc(DEVICES_SIZE * sizeof(Device));
|
||||
vm->device_size = DEVICES_SIZE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
i32 main(i32 argc, char *argv[]) {
|
||||
bool dump_rom = false;
|
||||
char *input_file = nil;
|
||||
|
|
@ -212,11 +193,6 @@ i32 main(i32 argc, char *argv[]) {
|
|||
}
|
||||
|
||||
VM vm = {0};
|
||||
if (!init_vm(&vm)) {
|
||||
printf("vm did not initialize for some reason.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool compilation_success = true;
|
||||
if (input_file) {
|
||||
if (is_rom) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -30,6 +30,7 @@ typedef struct symbol_tab_s SymbolTable;
|
|||
#define MAX_SYMBOL_NAME_LENGTH 64
|
||||
struct symbol_s {
|
||||
char name[MAX_SYMBOL_NAME_LENGTH];
|
||||
u8 name_length;
|
||||
SymbolType type;
|
||||
ScopeType scope;
|
||||
u32 ref; // vm->mp if global, vm->pc local, register if var
|
||||
|
|
|
|||
|
|
@ -276,6 +276,16 @@ static TokenType identifierType() {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
if (lexer.current - lexer.start > 1) {
|
||||
switch (lexer.start[1]) {
|
||||
case 'y':
|
||||
return check_keyword(2, 2, "te", TOKEN_TYPE_U8);
|
||||
case 'o':
|
||||
return check_keyword(2, 2, "ol", TOKEN_TYPE_U8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
return check_keyword(1, 5, "lobal", TOKEN_KEYWORD_GLOBAL);
|
||||
case 'l':
|
||||
|
|
|
|||
|
|
@ -150,16 +150,11 @@ typedef struct vm_s {
|
|||
u32 mp; /* memory pointer (last allocated value) */
|
||||
u32 dc; /* device count */
|
||||
i32 flag; /* flag (temporary results like SYSCALL status) */
|
||||
Frame *frames; /* function call frames */
|
||||
u32 frames_size; /* max frames */
|
||||
u32 *stack; /* main stack */
|
||||
u32 stack_size; /* max stack */
|
||||
Device *devices; /* device definitions */
|
||||
u32 device_size; /* max devices */
|
||||
u8 *code; /* code block */
|
||||
u32 code_size; /* max code size */
|
||||
u8 *memory; /* memory block */
|
||||
u32 memory_size; /* max memory size */
|
||||
Frame frames[FRAMES_SIZE]; /* function call frames */
|
||||
u32 stack[STACK_SIZE]; /* main stack */
|
||||
Device devices[DEVICES_SIZE]; /* device definitions */
|
||||
u8 code[CODE_SIZE]; /* code block */
|
||||
u8 memory[MEMORY_SIZE]; /* memory block */
|
||||
} VM;
|
||||
|
||||
/**
|
||||
|
|
|
|||
576
src/vm/vm.c
576
src/vm/vm.c
|
|
@ -27,26 +27,28 @@
|
|||
|
||||
#define MATH_OP(type, op) \
|
||||
do { \
|
||||
u8 src1, src2, dest; \
|
||||
u32 *regs = frame->locals; \
|
||||
dest = read_u8(vm, code, vm->pc); \
|
||||
vm->pc++; \
|
||||
src1 = read_u8(vm, code, vm->pc); \
|
||||
vm->pc++; \
|
||||
src2 = read_u8(vm, code, vm->pc); \
|
||||
vm->pc++; \
|
||||
dest = read_u8(vm, code, vm->pc); \
|
||||
vm->pc++; \
|
||||
regs[dest] = (type)regs[src1] op(type) regs[src2]; \
|
||||
return true; \
|
||||
} while (0)
|
||||
|
||||
#define BIT_OP(op) \
|
||||
do { \
|
||||
u8 src1, src2, dest; \
|
||||
u32 *regs = frame->locals; \
|
||||
dest = read_u8(vm, code, vm->pc); \
|
||||
vm->pc++; \
|
||||
src1 = read_u8(vm, code, vm->pc); \
|
||||
vm->pc++; \
|
||||
src2 = read_u8(vm, code, vm->pc); \
|
||||
vm->pc++; \
|
||||
dest = read_u8(vm, code, vm->pc); \
|
||||
vm->pc++; \
|
||||
regs[dest] = regs[src1] op regs[src2]; \
|
||||
return true; \
|
||||
} while (0)
|
||||
|
|
@ -83,14 +85,9 @@ u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length) {
|
|||
* Step to the next opcode in the vm.
|
||||
*/
|
||||
bool step_vm(VM *vm) {
|
||||
u16 opcode, dest, src1, src2;
|
||||
u32 v, ptr;
|
||||
i32 value;
|
||||
Frame *frame;
|
||||
|
||||
/* Get current instruction & Advance to next instruction */
|
||||
opcode = vm->code[vm->pc++];
|
||||
frame = &vm->frames[vm->fp];
|
||||
u8 opcode = vm->code[vm->pc++];
|
||||
Frame *frame = &vm->frames[vm->fp];
|
||||
|
||||
switch (opcode) {
|
||||
case OP_EXIT: {
|
||||
|
|
@ -177,12 +174,23 @@ bool step_vm(VM *vm) {
|
|||
vm->fp--;
|
||||
return true;
|
||||
}
|
||||
case OP_MALLOC: {
|
||||
u32 size;
|
||||
case OP_LOAD_IMM: {
|
||||
u32 v;
|
||||
u8 dest;
|
||||
v = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = v;
|
||||
return true;
|
||||
}
|
||||
case OP_MALLOC: {
|
||||
u8 src1, dest;
|
||||
u32 size;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = vm->mp;
|
||||
size = frame->locals[src1];
|
||||
write_u32(vm, memory, vm->mp, size);
|
||||
|
|
@ -192,9 +200,9 @@ bool step_vm(VM *vm) {
|
|||
}
|
||||
case OP_MEMSET_32: {
|
||||
u32 i, start, end;
|
||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||
|
||||
u32 dest = frame->locals[dest_reg];
|
||||
u32 value = frame->locals[value_reg];
|
||||
|
|
@ -221,11 +229,250 @@ bool step_vm(VM *vm) {
|
|||
vm->flag = 1;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_ABS_32: {
|
||||
u32 v, ptr;
|
||||
u8 dest;
|
||||
ptr = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
v = read_u32(vm, memory, ptr);
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = v;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_ABS_16: {
|
||||
u32 v, ptr;
|
||||
u8 dest;
|
||||
ptr = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
v = read_u16(vm, memory, ptr);
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = v;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_ABS_8: {
|
||||
u32 v, ptr;
|
||||
u8 dest;
|
||||
ptr = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
v = read_u8(vm, memory, ptr);
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = v;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_IND_32: {
|
||||
u32 v, ptr;
|
||||
u8 dest, src1;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
ptr = read_u32(vm, memory, v);
|
||||
frame->locals[dest] = ptr;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_IND_16: {
|
||||
u32 v;
|
||||
u8 dest, src1;
|
||||
u16 v16;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
v16 = read_u16(vm, memory, v);
|
||||
frame->locals[dest] = v16;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_IND_8: {
|
||||
u32 v;
|
||||
u8 dest, src1;
|
||||
u8 v8;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
v8 = read_u8(vm, memory, v);
|
||||
frame->locals[dest] = v8;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_OFF_8: {
|
||||
u32 v;
|
||||
u8 dest, src1;
|
||||
u32 offset;
|
||||
u8 v8;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
v8 = read_u8(vm, memory, (v + offset));
|
||||
frame->locals[dest] = v8;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_OFF_16: {
|
||||
u32 v;
|
||||
u8 dest, src1;
|
||||
u32 offset;
|
||||
u16 v16;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
v16 = read_u16(vm, memory, (v + offset));
|
||||
frame->locals[dest] = v16;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_OFF_32: {
|
||||
u32 v, ptr;
|
||||
u8 dest, src1;
|
||||
u32 offset;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
ptr = read_u32(vm, memory, (v + offset));
|
||||
frame->locals[dest] = ptr;
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_ABS_32: {
|
||||
u32 v, ptr;
|
||||
u8 dest, src1;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
ptr = frame->locals[dest];
|
||||
write_u32(vm, memory, ptr, v);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_ABS_16: {
|
||||
u32 v, ptr;
|
||||
u8 dest, src1;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
ptr = frame->locals[dest];
|
||||
write_u16(vm, memory, ptr, v);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_ABS_8: {
|
||||
u32 v, ptr;
|
||||
u8 dest, src1;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
ptr = frame->locals[dest];
|
||||
write_u8(vm, memory, ptr, v);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_IND_32: {
|
||||
u32 v, ptr;
|
||||
u8 dest, src1;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = frame->locals[dest];
|
||||
v = frame->locals[src1];
|
||||
write_u32(vm, memory, ptr, v);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_IND_16: {
|
||||
u32 ptr;
|
||||
u8 dest, src1;
|
||||
u16 v16;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = frame->locals[dest];
|
||||
v16 = frame->locals[src1];
|
||||
write_u16(vm, memory, ptr, v16);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_IND_8: {
|
||||
u32 ptr;
|
||||
u8 dest, src1;
|
||||
u8 v8;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = frame->locals[dest];
|
||||
v8 = frame->locals[src1];
|
||||
write_u8(vm, memory, ptr, v8);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_OFF_8: {
|
||||
u32 ptr;
|
||||
u8 dest, src1;
|
||||
u32 offset;
|
||||
u8 v8;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = frame->locals[dest];
|
||||
v8 = frame->locals[src1];
|
||||
write_u8(vm, memory, (ptr + offset), v8);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_OFF_16: {
|
||||
u32 ptr;
|
||||
u8 dest, src1;
|
||||
u32 offset;
|
||||
u16 v16;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = frame->locals[dest];
|
||||
v16 = frame->locals[src1];
|
||||
write_u16(vm, memory, (ptr + offset), v16);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_OFF_32: {
|
||||
u32 v, ptr;
|
||||
u8 dest, src1;
|
||||
u32 offset;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = frame->locals[dest];
|
||||
v = frame->locals[src1];
|
||||
write_u32(vm, memory, (ptr + offset), v);
|
||||
return true;
|
||||
}
|
||||
case OP_MEMSET_16: {
|
||||
u32 i, start, end;
|
||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||
|
||||
u32 dest = frame->locals[dest_reg];
|
||||
u16 value = (u16)(frame->locals[value_reg]);
|
||||
|
|
@ -254,9 +501,9 @@ bool step_vm(VM *vm) {
|
|||
}
|
||||
case OP_MEMSET_8: {
|
||||
u32 i, start, end;
|
||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||
|
||||
u32 dest = frame->locals[dest_reg];
|
||||
u8 value = (u8)(frame->locals[value_reg]);
|
||||
|
|
@ -283,222 +530,12 @@ bool step_vm(VM *vm) {
|
|||
vm->flag = 1;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_IMM: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
frame->locals[dest] = v;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_ABS_32: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
v = read_u32(vm, memory, ptr);
|
||||
frame->locals[dest] = v;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_ABS_16: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
v = read_u16(vm, memory, ptr);
|
||||
frame->locals[dest] = v;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_ABS_8: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
v = read_u8(vm, memory, ptr);
|
||||
frame->locals[dest] = v;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_IND_32: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
ptr = read_u32(vm, memory, v);
|
||||
frame->locals[dest] = ptr;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_IND_16: {
|
||||
u16 v16;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
v16 = read_u16(vm, memory, v);
|
||||
frame->locals[dest] = v16;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_IND_8: {
|
||||
u8 v8;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
v8 = read_u8(vm, memory, v);
|
||||
frame->locals[dest] = v8;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_OFF_8: {
|
||||
u32 offset;
|
||||
u8 v8;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
v = frame->locals[src1];
|
||||
v8 = read_u8(vm, memory, (v + offset));
|
||||
frame->locals[dest] = v8;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_OFF_16: {
|
||||
u32 offset;
|
||||
u16 v16;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
v = frame->locals[src1];
|
||||
v16 = read_u16(vm, memory, (v + offset));
|
||||
frame->locals[dest] = v16;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_OFF_32: {
|
||||
u32 offset;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
v = frame->locals[src1];
|
||||
ptr = read_u32(vm, memory, (v + offset));
|
||||
frame->locals[dest] = ptr;
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_ABS_32: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
ptr = frame->locals[dest];
|
||||
write_u32(vm, memory, ptr, v);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_ABS_16: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
ptr = frame->locals[dest];
|
||||
write_u16(vm, memory, ptr, v);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_ABS_8: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
v = frame->locals[src1];
|
||||
ptr = frame->locals[dest];
|
||||
write_u8(vm, memory, ptr, v);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_IND_32: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = frame->locals[dest];
|
||||
v = frame->locals[src1];
|
||||
write_u32(vm, memory, ptr, v);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_IND_16: {
|
||||
u16 v16;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = frame->locals[dest];
|
||||
v16 = frame->locals[src1];
|
||||
write_u16(vm, memory, ptr, v16);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_IND_8: {
|
||||
u8 v8;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
ptr = frame->locals[dest];
|
||||
v8 = frame->locals[src1];
|
||||
write_u8(vm, memory, ptr, v8);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_OFF_8: {
|
||||
u32 offset;
|
||||
u8 v8;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
ptr = frame->locals[dest];
|
||||
v8 = frame->locals[src1];
|
||||
write_u8(vm, memory, (ptr + offset), v8);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_OFF_16: {
|
||||
u32 offset;
|
||||
u16 v16;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
ptr = frame->locals[dest];
|
||||
v16 = frame->locals[src1];
|
||||
write_u16(vm, memory, (ptr + offset), v16);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_OFF_32: {
|
||||
u32 offset;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
offset = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
ptr = frame->locals[dest];
|
||||
v = frame->locals[src1];
|
||||
write_u32(vm, memory, (ptr + offset), v);
|
||||
return true;
|
||||
}
|
||||
case OP_REG_MOV: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = frame->locals[src1];
|
||||
|
||||
if (is_heap_value(vm, src1)) {
|
||||
|
|
@ -532,12 +569,12 @@ bool step_vm(VM *vm) {
|
|||
Device *dev;
|
||||
u32 path_ptr, mode, device_ptr;
|
||||
u8 path_reg, mode_reg, dest_reg;
|
||||
dest_reg = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
path_reg = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
mode_reg = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest_reg = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
|
||||
path_ptr = frame->locals[path_reg];
|
||||
mode = frame->locals[mode_reg];
|
||||
|
|
@ -715,10 +752,12 @@ bool step_vm(VM *vm) {
|
|||
case OP_DIV_INT:
|
||||
MATH_OP(i32, /);
|
||||
case OP_ABS_INT: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1;
|
||||
i32 value;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
|
||||
value = frame->locals[src1];
|
||||
if (value < 0) {
|
||||
|
|
@ -729,10 +768,12 @@ bool step_vm(VM *vm) {
|
|||
return true;
|
||||
}
|
||||
case OP_NEG_INT: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1;
|
||||
i32 value;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
|
||||
value = frame->locals[src1];
|
||||
frame->locals[dest] = -value;
|
||||
|
|
@ -747,53 +788,59 @@ bool step_vm(VM *vm) {
|
|||
case OP_DIV_NAT:
|
||||
MATH_OP(u32, /);
|
||||
case OP_MUL_REAL: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1, src2;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src2 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = fixed_mul(frame->locals[src1], frame->locals[src2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
case OP_DIV_REAL: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1, src2;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src2 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = fixed_div(frame->locals[src1], frame->locals[src2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
case OP_ADD_REAL: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1, src2;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src2 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = fixed_add(frame->locals[src1], frame->locals[src2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
case OP_SUB_REAL: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1, src2;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src2 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = fixed_sub(frame->locals[src1], frame->locals[src2]);
|
||||
return true;
|
||||
}
|
||||
case OP_REAL_TO_INT: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1;
|
||||
i32 value;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
value = frame->locals[src1];
|
||||
|
||||
frame->locals[dest] = fixed_to_int(value);
|
||||
|
|
@ -801,27 +848,31 @@ bool step_vm(VM *vm) {
|
|||
return true;
|
||||
}
|
||||
case OP_INT_TO_REAL: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_REAL_TO_NAT: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1;
|
||||
u32 value;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
value = frame->locals[src1];
|
||||
frame->locals[dest] = fixed_to_int(value);
|
||||
return true;
|
||||
}
|
||||
case OP_NAT_TO_REAL: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u8 dest, src1;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -880,11 +931,13 @@ bool step_vm(VM *vm) {
|
|||
COMPARE_AND_JUMP(i32, <=);
|
||||
}
|
||||
case OP_INT_TO_STRING: {
|
||||
u32 ptr;
|
||||
u8 dest, src1;
|
||||
char buffer[32];
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
int_to_string(AS_INT(frame->locals[src1]), buffer);
|
||||
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||
frame->locals[dest] = ptr;
|
||||
|
|
@ -892,11 +945,13 @@ bool step_vm(VM *vm) {
|
|||
return true;
|
||||
}
|
||||
case OP_NAT_TO_STRING: {
|
||||
u32 ptr;
|
||||
u8 dest, src1;
|
||||
char buffer[32];
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
nat_to_string(frame->locals[src1], buffer);
|
||||
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||
frame->locals[dest] = ptr;
|
||||
|
|
@ -904,11 +959,13 @@ bool step_vm(VM *vm) {
|
|||
return true;
|
||||
}
|
||||
case OP_REAL_TO_STRING: {
|
||||
u32 ptr;
|
||||
u8 dest, src1;
|
||||
char buffer[32];
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
fixed_to_string(AS_INT(frame->locals[src1]), buffer);
|
||||
ptr = str_alloc(vm, frame, buffer,
|
||||
strlength(buffer)); /* copy buffer to dest */
|
||||
|
|
@ -917,11 +974,12 @@ bool step_vm(VM *vm) {
|
|||
return true;
|
||||
}
|
||||
case OP_STRLEN: {
|
||||
u8 dest, src1;
|
||||
u32 ptr, length;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
|
||||
ptr = frame->locals[src1];
|
||||
length = read_u32(vm, memory, ptr);
|
||||
|
|
|
|||
|
|
@ -4,14 +4,11 @@ global int x = 1;
|
|||
global int y = 1;
|
||||
|
||||
function main ()
|
||||
int ans $2;
|
||||
str ans_string $3;
|
||||
|
||||
load_absolute_32 x -> $0;
|
||||
load_absolute_32 y -> $1;
|
||||
call add $0 $1 -> ans;
|
||||
int_to_string ans -> ans_string;
|
||||
call pln ans_string -> void;
|
||||
call add $0 $1 -> $2;
|
||||
int_to_string $2 -> $3;
|
||||
call pln $3;
|
||||
exit 0;
|
||||
|
||||
function add (int a $0, int b $1)
|
||||
|
|
@ -20,16 +17,19 @@ function add (int a $0, int b $1)
|
|||
return result;
|
||||
|
||||
function pln (str message $0)
|
||||
str term $1;
|
||||
plex term $1;
|
||||
int msg_length $2;
|
||||
str nl $3;
|
||||
int nl_length $4;
|
||||
int mode $5;
|
||||
str term_ns $6;
|
||||
|
||||
load_immediate 0 -> mode;
|
||||
syscall OPEN terminal_namespace mode -> term;
|
||||
load_address terminal_namespace -> term_ns;
|
||||
syscall OPEN term_ns mode -> term;
|
||||
string_length message -> msg_length;
|
||||
syscall WRITE term message msg_length;
|
||||
string_length new_line -> nl_length;
|
||||
load_address new_line -> nl;
|
||||
string_length nl -> nl_length;
|
||||
syscall WRITE term nl nl_length;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -31,19 +31,20 @@ function fib (int n $0)
|
|||
return n;
|
||||
|
||||
function pln (str message $0)
|
||||
str ts $1;
|
||||
int mode $5;
|
||||
plex term $1;
|
||||
int msg_length $2;
|
||||
str nl $3;
|
||||
int nl_length $4;
|
||||
int mode $5;
|
||||
str term_ns $6;
|
||||
|
||||
load_immediate terminal_namespace -> ts;
|
||||
load_immediate 0 -> mode;
|
||||
syscall OPEN ts mode -> ts;
|
||||
load_address terminal_namespace -> term_ns;
|
||||
syscall OPEN term_ns mode -> term;
|
||||
string_length message -> msg_length;
|
||||
syscall WRITE ts message msg_length;
|
||||
load_immediate new_line -> nl;
|
||||
syscall WRITE term message msg_length;
|
||||
load_address new_line -> nl;
|
||||
string_length nl -> nl_length;
|
||||
syscall WRITE ts nl nl_length;
|
||||
syscall WRITE term nl nl_length;
|
||||
return;
|
||||
|
||||
|
|
@ -1,27 +1,28 @@
|
|||
global str terminal_namespace = "/dev/term/0"
|
||||
global str new_line = "\n"
|
||||
global str message = "nuqneH 'u'?"
|
||||
global str terminal_namespace = "/dev/term/0";
|
||||
global str new_line = "\n";
|
||||
global str message = "nuqneH 'u'?";
|
||||
|
||||
function main ()
|
||||
str hello $0;
|
||||
|
||||
load_immediate message -> hello;
|
||||
call pln hello -> void;
|
||||
load_address message -> hello;
|
||||
call pln hello;
|
||||
exit 0;
|
||||
|
||||
function pln (str message $0)
|
||||
str ts $1;
|
||||
int mode $5;
|
||||
plex term $1;
|
||||
int msg_length $2;
|
||||
str nl $3;
|
||||
int nl_length $4;
|
||||
int mode $5;
|
||||
str term_ns $6;
|
||||
|
||||
load_immediate terminal_namespace -> ts;
|
||||
load_immediate 0 -> mode;
|
||||
syscall OPEN ts mode -> ts;
|
||||
load_address terminal_namespace -> term_ns;
|
||||
syscall OPEN term_ns mode -> term;
|
||||
string_length message -> msg_length;
|
||||
syscall WRITE ts message msg_length;
|
||||
load_immediate new_line -> nl;
|
||||
syscall WRITE term message msg_length;
|
||||
load_address new_line -> nl;
|
||||
string_length nl -> nl_length;
|
||||
syscall WRITE ts nl nl_length;
|
||||
syscall WRITE term nl nl_length;
|
||||
return;
|
||||
|
|
@ -18,41 +18,41 @@ function main ()
|
|||
add_int i $3 -> i;
|
||||
jump_ge_int loop_body i $2;
|
||||
|
||||
load_immediate terminal_namespace -> term;
|
||||
load_address terminal_namespace -> term;
|
||||
load_immediate 0 -> mode;
|
||||
syscall OPEN term mode -> term; // Terminal term = open("/dev/term/0", 0);
|
||||
|
||||
nat b $1;
|
||||
real_to_nat a -> b;
|
||||
load_immediate prompt -> $7;
|
||||
load_address prompt -> $7;
|
||||
string_length $7 -> $8;
|
||||
syscall WRITE term $7 $8; // print prompt
|
||||
|
||||
str user_string $9;
|
||||
load_immediate 32 -> $8;
|
||||
malloc $8 -> user_string;
|
||||
syscall READ term user_string; $8 // read in max 32 byte string
|
||||
syscall READ term user_string $8; // read in max 32 byte string
|
||||
|
||||
call pln user_string -> void;
|
||||
call pln user_string;
|
||||
nat_to_string b -> $4;
|
||||
call pln $4 -> void;
|
||||
call pln $4;
|
||||
real_to_string a -> $3;
|
||||
call pln $3 -> void;
|
||||
call pln $3;
|
||||
exit 0;
|
||||
|
||||
function pln (str message $0);
|
||||
str ts $1;
|
||||
int mode $5;
|
||||
function pln (str message $0)
|
||||
plex term $1;
|
||||
int msg_length $2;
|
||||
str nl $3;
|
||||
int nl_length $4;
|
||||
int mode $5;
|
||||
|
||||
load_immediate terminal_namespace -> ts;
|
||||
load_address terminal_namespace -> term;
|
||||
load_immediate 0 -> mode;
|
||||
syscall OPEN ts mode -> ts;
|
||||
syscall OPEN term mode -> term; // Terminal term = open("/dev/term/0", 0);
|
||||
string_length message -> msg_length;
|
||||
syscall WRITE ts message msg_length ;
|
||||
load_immediate new_line -> nl;
|
||||
syscall WRITE term message msg_length;
|
||||
load_address new_line -> nl;
|
||||
string_length nl -> nl_length;
|
||||
syscall WRITE ts nl nl_length;
|
||||
syscall WRITE term nl nl_length;
|
||||
return;
|
||||
|
|
@ -23,18 +23,19 @@ function main ()
|
|||
exit 0;
|
||||
|
||||
function pln (str message $0)
|
||||
str ts $1;
|
||||
int mode $5;
|
||||
plex term $1;
|
||||
int msg_length $2;
|
||||
str nl $3;
|
||||
int nl_length $4;
|
||||
int mode $5;
|
||||
str term_ns $6;
|
||||
|
||||
load_immediate terminal_namespace -> ts;
|
||||
load_immediate 0 -> mode;
|
||||
syscall OPEN ts mode -> ts;
|
||||
load_address terminal_namespace -> term_ns;
|
||||
syscall OPEN term_ns mode -> term;
|
||||
string_length message -> msg_length;
|
||||
syscall WRITE ts message msg_length;
|
||||
load_immediate new_line -> nl;
|
||||
syscall WRITE term message msg_length;
|
||||
load_address new_line -> nl;
|
||||
string_length nl -> nl_length;
|
||||
syscall WRITE ts nl nl_length;
|
||||
syscall WRITE term nl nl_length;
|
||||
return;
|
||||
|
|
@ -2,8 +2,6 @@
|
|||
* Constants
|
||||
*/
|
||||
const str nl = "\n";
|
||||
const real x = 1.0;
|
||||
const real y = 1.0;
|
||||
|
||||
plex Terminal {
|
||||
nat handle;
|
||||
|
|
@ -13,7 +11,8 @@ plex Terminal {
|
|||
* Main function
|
||||
*/
|
||||
function main() {
|
||||
pln((x + y).str);
|
||||
pln((1.0 + 1.0) as str);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,28 +1,25 @@
|
|||
global str terminal_namespace = "/dev/term/0";
|
||||
global real x = 1.0;
|
||||
global real y = 1.0;
|
||||
global str new_line = "\n";
|
||||
|
||||
function main ()
|
||||
real a $0;
|
||||
load_absolute_32 x -> a;
|
||||
real b $1;
|
||||
load_absolute_32 y -> b;
|
||||
real result $2;
|
||||
add_real a b -> result;
|
||||
str result_str $3;
|
||||
real_to_string result -> result_str;
|
||||
call pln result_str -> void;
|
||||
load_immediate 1.0 -> $0;
|
||||
load_immediate 1.0 -> $1;
|
||||
add_real $0 $1 -> $0;
|
||||
real_to_string $0 -> $0;
|
||||
call pln $0;
|
||||
exit 0;
|
||||
|
||||
function pln (str message $0)
|
||||
str term $1;
|
||||
plex term $1;
|
||||
int msg_length $2;
|
||||
str nl $3;
|
||||
int nl_length $4;
|
||||
int mode $5;
|
||||
str term_ns $6;
|
||||
|
||||
load_immediate 0 -> mode;
|
||||
syscall OPEN terminal_namespace mode -> term;
|
||||
load_address terminal_namespace -> term_ns;
|
||||
syscall OPEN term_ns mode -> term;
|
||||
string_length message -> msg_length;
|
||||
syscall WRITE term message msg_length;
|
||||
load_address new_line -> nl;
|
||||
|
|
|
|||
|
|
@ -72,18 +72,19 @@ function main ()
|
|||
exit 0;
|
||||
|
||||
function pln (str message $0)
|
||||
str ts $1;
|
||||
int mode $5;
|
||||
plex term $1;
|
||||
int msg_length $2;
|
||||
str nl $3;
|
||||
int nl_length $4;
|
||||
int mode $5;
|
||||
str term_ns $6;
|
||||
|
||||
load_immediate terminal_namespace -> ts;
|
||||
load_immediate 0 -> mode;
|
||||
syscall OPEN ts mode -> ts;
|
||||
load_address terminal_namespace -> term_ns;
|
||||
syscall OPEN term_ns mode -> term;
|
||||
string_length message -> msg_length;
|
||||
syscall WRITE ts message msg_length ;
|
||||
load_immediate new_line -> nl;
|
||||
syscall WRITE term message msg_length;
|
||||
load_address new_line -> nl;
|
||||
string_length nl -> nl_length;
|
||||
syscall WRITE ts nl nl_length;
|
||||
syscall WRITE term nl nl_length;
|
||||
return;
|
||||
Loading…
Reference in New Issue