Refactor and rename to align with new IR better

This commit is contained in:
zongor 2025-11-09 13:22:46 -08:00
parent 99e2f2c0c3
commit c90f236ab3
32 changed files with 1541 additions and 1674 deletions

View File

@ -86,12 +86,16 @@ VM_SOURCES := \
ifeq ($(BUILD_MODE), release)
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
$(ARCH_DIR)/devices.c\
$(SRC_DIR)/tools/assembler/parser.c \
$(SRC_DIR)/tools/old_assembler/parser.c \
$(SRC_DIR)/tools/old_assembler/assembler.c \
$(SRC_DIR)/tools/assembler/lexer.c \
$(SRC_DIR)/tools/assembler/assembler.c
else
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
$(ARCH_DIR)/devices.c \
$(SRC_DIR)/tools/assembler/parser.c \
$(SRC_DIR)/tools/old_assembler/parser.c \
$(SRC_DIR)/tools/old_assembler/assembler.c\
$(SRC_DIR)/tools/assembler/lexer.c \
$(SRC_DIR)/tools/assembler/assembler.c
endif

View File

@ -21,7 +21,7 @@ Undâr is a programming language for the purpose of creating 3D games and graphi
It has an internal REPL that allows for quick development as well as the ability to dump the program to a binary rom for preserving that program/game/etc.
It runs on the =Reality Engine=, a VM written in freestanding C89, has a CISC like instruction format of one byte opcode and a variable byte operand. 32 general purpose registers.
It runs on the =Reality Engine=, a VM written in freestanding C89, has a CISC like instruction format of one byte opcode and a variable byte operand. 32 local variables per frame.
* Philosophy
@ -58,7 +58,7 @@ You can view some examples in the =.ul.ir= files in =/test=
function main ()
str hello is $0
load_heap_immediate "nuqneH 'u'?" -> hello
malloc_immediate "nuqneH 'u'?" -> hello
call pln hello
exit 0
@ -69,12 +69,12 @@ function pln (str message is $0)
int nl_length is $4
int mode is $5
load_heap_immediate "/dev/term/0" -> ts # get terminal device
malloc_immediate "/dev/term/0" -> ts # get terminal device
load_immediate 0 -> mode
syscall OPEN ts mode -> ts
strlen message -> msg_length
syscall WRITE ts message msg_length
load_heap_immediate "\n" -> nl
malloc_immediate "\n" -> nl
strlen nl -> nl_length
syscall WRITE ts nl nl_length
return
@ -97,11 +97,11 @@ function main ()
int mode is $11
str term is $10
load_heap_immediate "/dev/term/0" -> term
malloc_immediate "/dev/term/0" -> term
load_immediate 0 -> mode
syscall OPEN term mode -> term # Terminal term = open("/dev/term/0", 0);
load_heap_immediate "Enter a string:" -> $7
malloc_immediate "Enter a string:" -> $7
string_length $7 -> $8
syscall WRITE term $7 $8 # print prompt
@ -120,12 +120,12 @@ function pln (str message is $0)
str nl is $3
int nl_length is $4
load_heap_immediate "/dev/term/0" -> ts
malloc_immediate "/dev/term/0" -> ts
load_immediate 0 -> mode
syscall OPEN ts mode -> ts # get terminal device
strlen message -> msg_length
syscall WRITE ts message msg_length
load_heap_immediate "\n" -> nl
malloc_immediate "\n" -> nl
strlen nl -> nl_length
syscall WRITE ts nl nl_length

View File

@ -10,6 +10,16 @@
* Roadmap
** Fixes for devices
Devices should be moved into the Tunnel concept
Make it so that instead of returning the whole plex from the OPEN syscall we only return the handle
We should remove the "refesh" options and make it so that "stat"
Stat is the one that actually returns the plex with that info
** Example: Hello world (=hello.ul=)
*WIP syntax, not final implementation**

View File

@ -1,5 +1,6 @@
#include "../../tools/old_assembler/assembler.h"
#include "../../tools/old_assembler/parser.h"
#include "../../tools/assembler/assembler.h"
#include "../../tools/assembler/parser.h"
#include "../../vm/vm.h"
#include "devices.h"
#include <SDL2/SDL.h>
@ -52,7 +53,7 @@ bool saveVM(const char *filename, VM *vm) {
return false;
}
// Write VM state (registers and pointers)
// Write VM state (locals and pointers)
if (fwrite(&vm->pc, sizeof(u32), 1, file) != 1 ||
fwrite(&vm->cp, sizeof(u32), 1, file) != 1 ||
fwrite(&vm->fp, sizeof(u32), 1, file) != 1 ||
@ -90,7 +91,7 @@ bool loadVM(const char *filename, VM *vm) {
return false;
}
// Read VM state (registers and pointers)
// Read VM state (locals and pointers)
if (fread(&vm->pc, sizeof(u32), 1, file) != 1 ||
fread(&vm->cp, sizeof(u32), 1, file) != 1 ||
fread(&vm->fp, sizeof(u32), 1, file) != 1 ||
@ -145,7 +146,7 @@ bool compileAndSave(const char *source_file, const char *output_file, VM *vm) {
source[read] = '\0';
fclose(f);
assemble(vm, source);
return true;
}
@ -177,7 +178,7 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
printf("Parse failed.\n");
return false;
} else {
assemble(vm, ast);
old_assemble(vm, ast);
expr_free(ast);
// If output file specified, save the VM
@ -192,216 +193,6 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
}
}
void repl(VM *vm) {
USED(vm);
char buffer[1024 * 10] = {0}; // Larger buffer for multi-line input
char line[1024];
for (;;) {
// Count current parentheses balance
i32 paren_balance = 0;
for (i32 i = 0; buffer[i]; i++) {
if (buffer[i] == '(')
paren_balance++;
else if (buffer[i] == ')')
paren_balance--;
}
// Show appropriate prompt
if (paren_balance > 0) {
printf(".. "); // Continuation prompt when unbalanced
} else {
printf("> "); // Normal prompt when balanced
}
fflush(stdout);
if (!fgets(line, sizeof(line), stdin)) {
printf("\n");
break;
}
// Append the new line to buffer
strncat(buffer, line, sizeof(buffer) - strlen(buffer) - 1);
// Recalculate balance after adding new line
paren_balance = 0;
for (i32 i = 0; buffer[i]; i++) {
if (buffer[i] == '(')
paren_balance++;
else if (buffer[i] == ')')
paren_balance--;
}
// Only parse when parentheses are balanced
if (paren_balance == 0) {
// Check if buffer has actual content (not just whitespace)
i32 has_content = 0;
for (i32 i = 0; buffer[i]; i++) {
if (!isspace(buffer[i])) {
has_content = 1;
break;
}
}
if (has_content) {
ExprNode *ast = expr_parse(buffer, strlen(buffer));
if (!ast) {
printf("Parse failed.\n");
} else {
assemble(vm, ast);
while (step_vm(vm)) {
}
expr_free(ast);
}
}
// Reset buffer for next input
buffer[0] = '\0';
}
// If unbalanced, continue reading more lines
}
exit(vm->flag);
}
#ifdef ASM_DEBUG
const char *opcode_to_string(Opcode op) {
static const char *names[] = {
[OP_HALT] = "halt",
[OP_JMP] = "jump",
[OP_JMPF] = "jmpf",
[OP_FCALL] = "fcall",
[OP_FRETURN] = "return",
/* Immediate loads (only 32-bit variant needed) */
[OP_LOAD_IMM] = "ldi",
/* Register-indirect loads */
[OP_LOAD_IND_8] = "ld8",
[OP_LOAD_IND_16] = "ld16",
[OP_LOAD_IND_32] = "ld32",
/* Absolute address loads */
[OP_LOAD_ABS_8] = "lda8",
[OP_LOAD_ABS_16] = "lda16",
[OP_LOAD_ABS_32] = "lda32",
/* Base+offset loads */
[OP_LOAD_OFF_8] = "ldo8",
[OP_LOAD_OFF_16] = "ldo16",
[OP_LOAD_OFF_32] = "ldo32",
/* Absolute address stores */
[OP_STORE_ABS_8] = "sta8",
[OP_STORE_ABS_16] = "sta16",
[OP_STORE_ABS_32] = "sta32",
/* Register-indirect stores */
[OP_STORE_IND_8] = "sti8",
[OP_STORE_IND_16] = "sti16",
[OP_STORE_IND_32] = "sti32",
/* Base+offset stores */
[OP_STORE_OFF_8] = "sto8",
[OP_STORE_OFF_16] = "sto16",
[OP_STORE_OFF_32] = "sto32",
/* Memory operations */
[OP_MALLOC] = "malloc",
[OP_MEMSET_8] = "set8",
[OP_MEMSET_16] = "set16",
[OP_MEMSET_32] = "set32",
/* Register operations */
[OP_REG_MOV] = "mov",
[OP_SYSCALL] = "syscall",
/* Bit operations */
[OP_BIT_SHIFT_LEFT] = "sll",
[OP_BIT_SHIFT_RIGHT] = "srl",
[OP_BIT_SHIFT_R_EXT] = "sre",
[OP_BAND] = "and",
[OP_BOR] = "or",
[OP_BXOR] = "xor",
/* Integer arithmetic */
[OP_ADD_INT] = "addi",
[OP_SUB_INT] = "subi",
[OP_MUL_INT] = "muli",
[OP_DIV_INT] = "divi",
[OP_ABS_INT] = "absi", // ← NEW
[OP_NEG_INT] = "negi", // ← NEW
/* Natural number arithmetic */
[OP_ADD_NAT] = "addn",
[OP_SUB_NAT] = "subn",
[OP_MUL_NAT] = "muln",
[OP_DIV_NAT] = "divn",
[OP_ABS_NAT] = "absn", // ← NEW
[OP_NEG_NAT] = "negn", // ← NEW
/* Floating point operations */
[OP_ADD_REAL] = "addr",
[OP_SUB_REAL] = "subr",
[OP_MUL_REAL] = "mulr",
[OP_DIV_REAL] = "divr",
[OP_ABS_REAL] = "absr", // ← NEW
[OP_NEG_REAL] = "negr", // ← NEW
/* Type conversions */
[OP_INT_TO_REAL] = "itor",
[OP_NAT_TO_REAL] = "ntor",
[OP_REAL_TO_INT] = "rtoi",
[OP_REAL_TO_NAT] = "rton",
/* Integer comparisons */
[OP_JEQ_INT] = "jeqi",
[OP_JNEQ_INT] = "jneqi",
[OP_JGT_INT] = "jgti",
[OP_JLT_INT] = "jlti",
[OP_JLE_INT] = "jlei",
[OP_JGE_INT] = "jgei",
/* Natural number comparisons */
[OP_JEQ_NAT] = "jeqn",
[OP_JNEQ_NAT] = "jneqn",
[OP_JGT_NAT] = "jgtn",
[OP_JLT_NAT] = "jltn",
[OP_JLE_NAT] = "jlen",
[OP_JGE_NAT] = "jgen",
/* Floating point comparisons */
[OP_JEQ_REAL] = "jeqr",
[OP_JNEQ_REAL] = "jneqr",
[OP_JGE_REAL] = "jger",
[OP_JGT_REAL] = "jgtr",
[OP_JLT_REAL] = "jltr",
[OP_JLE_REAL] = "jler",
/* String operations */
[OP_STRLEN] = "strlen",
[OP_STREQ] = "streq",
[OP_STRCAT] = "strcat",
[OP_STR_GET_CHAR] = "getch",
[OP_STR_FIND_CHAR] = "findch",
[OP_STR_SLICE] = "strcut",
/* String conversions */
[OP_INT_TO_STRING] = "itos",
[OP_NAT_TO_STRING] = "ntos",
[OP_REAL_TO_STRING] = "rtos",
[OP_STRING_TO_INT] = "stoi",
[OP_STRING_TO_NAT] = "ston",
[OP_STRING_TO_REAL] = "stor"};
if (op < 0 || op >= (int)(sizeof(names) / sizeof(names[0]))) {
return "<invalid-opcode>";
}
const char *name = names[op];
return name ? name : "<unknown-opcode>";
}
#endif
i32 main(i32 argc, char *argv[]) {
bool dump_rom = false;
char *input_file = nil;
@ -453,8 +244,7 @@ i32 main(i32 argc, char *argv[]) {
}
}
} else {
// No input file - enter REPL mode
repl(&vm);
printf("usage: undar <src.ul>...");
return 0;
}
@ -567,9 +357,6 @@ i32 main(i32 argc, char *argv[]) {
int cycles_this_frame = 0;
int max_cycles_per_frame = 100; // Adjust this value
while (cycles_this_frame < max_cycles_per_frame) {
#ifdef ASM_DEBUG
printf("| %s %d\n", opcode_to_string(vm.code[vm.pc]), vm.pc);
#endif
if (!step_vm(&vm)) {
running = false;
break;

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,10 @@
#ifndef ASSEMBLER_H
#define ASSEMBLER_H
#ifndef UNDAR_IR_ASSEMBLER_H
#define UNDAR_IR_ASSEMBLER_H
#include "../../vm/common.h"
#include "../../vm/vm.h"
#include "parser.h"
#include "../../vm/opcodes.h"
#include "lexer.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
#define TO_FIXED(f) ((i32)( \
((f) >= 0.0f) ? ((f) * 65536.0f + 0.5f) : ((f) * 65536.0f - 0.5f) \
))
void assemble(VM *vm, ExprNode *program);
void assemble(VM *vm, char *source);
#endif

View File

@ -1,6 +1,6 @@
#include <string.h>
#include "../vm/common.h"
#include "../../vm/common.h"
#include "lexer.h"
typedef struct {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
#ifndef ASSEMBLER_H
#define ASSEMBLER_H
#include "../../vm/common.h"
#include "../../vm/vm.h"
#include "parser.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
#define TO_FIXED(f) ((i32)( \
((f) >= 0.0f) ? ((f) * 65536.0f + 0.5f) : ((f) * 65536.0f - 0.5f) \
))
void old_assemble(VM *vm, ExprNode *program);
#endif

View File

@ -4,99 +4,100 @@
#include "common.h"
typedef enum {
OP_HALT, /* halt : terminate execution with code [src1] */
OP_EXIT, /* exit : terminate execution with code [src1] */
OP_CALL, /* call : creates a new frame */
OP_RETURN, /* return : returns from a frame to the parent frame */
OP_SYSCALL, /* syscall : src1 src2 src3 src4 more? does a system call based on args */
OP_LOAD_IMM, /* load-immediate : registers[dest] = constant */
OP_LOAD_IND_8, /* load-indirect-8 : registers[dest] = memory[registers[src1]] as u8 */
OP_LOAD_IND_16, /* load-indirect-16 : registers[dest] = memory[registers[src1]] as u8 */
OP_LOAD_IND_32, /* load-indirect-32 : registers[dest] = memory[registers[src1]] as u32 */
OP_LOAD_ABS_8, /* load-absolute-8 : registers[dest] = memory[src1 as u32] */
OP_LOAD_ABS_16, /* load-absolute-16 : registers[dest] = memory[src1 as u32] */
OP_LOAD_ABS_32, /* load-absolute-32 : registers[dest] = memory[src1 as u32] */
OP_LOAD_OFF_8, /* load-offset-8 : registers[dest] = memory[registers[src1] + offset] as u8 */
OP_LOAD_OFF_16, /* load-offset-16 : registers[dest] = memory[registers[src1] + offset] as u16 */
OP_LOAD_OFF_32, /* load-offset-32 : registers[dest] = memory[registers[src1] + offset] as u32 */
OP_STORE_ABS_8, /* store-absolute-8 : memory[dest] = src1 && 0xFF */
OP_STORE_ABS_16, /* store-absolute-16 : memory[dest] = src1 && 0xFFFF */
OP_STORE_ABS_32, /* store-absolute-32 : memory[dest] = src1 */
OP_STORE_IND_8, /* store-indirect-8 : memory[dest] = registers[src1] && 0xFF */
OP_STORE_IND_16, /* store-indirect-16 : memory[dest] = registers[src1] && 0xFFFF*/
OP_STORE_IND_32, /* store-indirect-32 : memory[dest] = registers[src1] */
OP_STORE_OFF_8, /* store-offset-8 : memory[registers[dest] + offset] = registers[src1] && 0xFF */
OP_STORE_OFF_16, /* store-offset-16 : memory[registers[dest] + offset] = registers[src1] && 0xFFFF */
OP_STORE_OFF_32, /* store-offset-32 : memory[registers[dest] + offset] = registers[src1] */
OP_LOAD_IMM, /* load_immediate : locals[dest] = constant */
OP_LOAD_IND_8, /* load_indirect_8 : locals[dest] = memory[locals[src1]] as u8 */
OP_LOAD_IND_16, /* load_indirect_16 : locals[dest] = memory[locals[src1]] as u8 */
OP_LOAD_IND_32, /* load_indirect_32 : locals[dest] = memory[locals[src1]] as u32 */
OP_LOAD_ABS_8, /* load_absolute_8 : locals[dest] = memory[src1 as u32] */
OP_LOAD_ABS_16, /* load_absolute_16 : locals[dest] = memory[src1 as u32] */
OP_LOAD_ABS_32, /* load_absolute_32 : locals[dest] = memory[src1 as u32] */
OP_LOAD_OFF_8, /* load_offset_8 : locals[dest] = memory[locals[src1] + offset] as u8 */
OP_LOAD_OFF_16, /* load_offset_16 : locals[dest] = memory[locals[src1] + offset] as u16 */
OP_LOAD_OFF_32, /* load_offset_32 : locals[dest] = memory[locals[src1] + offset] as u32 */
OP_STORE_ABS_8, /* store_absolute_8 : memory[dest] = src1 && 0xFF */
OP_STORE_ABS_16, /* store_absolute_16 : memory[dest] = src1 && 0xFFFF */
OP_STORE_ABS_32, /* store_absolute_32 : memory[dest] = src1 */
OP_STORE_IND_8, /* store_indirect_8 : memory[dest] = locals[src1] && 0xFF */
OP_STORE_IND_16, /* store_indirect_16 : memory[dest] = locals[src1] && 0xFFFF*/
OP_STORE_IND_32, /* store_indirect_32 : memory[dest] = locals[src1] */
OP_STORE_OFF_8, /* store_offset_8 : memory[locals[dest] + offset] = locals[src1] && 0xFF */
OP_STORE_OFF_16, /* store_offset_16 : memory[locals[dest] + offset] = locals[src1] && 0xFFFF */
OP_STORE_OFF_32, /* store_offset_32 : memory[locals[dest] + offset] = locals[src1] */
OP_MALLOC, /* malloc : dest = fat ptr to memory of ((src1 as size) + 4) */
OP_MEMSET_8, /* memset-8 : dest <-> dest+count = src1 as u8 */
OP_MEMSET_16, /* memset-16 : dest <-> dest+count = src1 as u8 */
OP_MEMSET_32, /* memset-32 : dest <-> dest+count = src1 as u32 */
OP_REG_MOV, /* register-move : registers[dest] = registers[src1] */
OP_ADD_INT, /* add-int : registers[dest] = registers[src1] + registers[src2] */
OP_SUB_INT, /* sub-int : registers[dest] = registers[src1] - registers[src2] */
OP_MUL_INT, /* mul-int : registers[dest] = registers[src1] * registers[src2] */
OP_DIV_INT, /* div-int : registers[dest] = registers[src1] / registers[src2] */
OP_ABS_INT, /* abs-int : registers[dest] = | registers[src1] | */
OP_NEG_INT, /* neg-int : registers[dest] = -registers[src1] */
OP_ADD_NAT, /* add-nat : registers[dest] = registers[src1] + registers[src2] */
OP_SUB_NAT, /* sub-nat : registers[dest] = registers[src1] - registers[src2] */
OP_MUL_NAT, /* mul-nat : registers[dest] = registers[src1] * registers[src2] */
OP_DIV_NAT, /* div-nat : registers[dest] = registers[src1] / registers[src2] */
OP_ABS_NAT, /* abs-nat : registers[dest] = | registers[src1] | */
OP_NEG_NAT, /* neg-nat : registers[dest] = -registers[src1] */
OP_ADD_REAL, /* add-real : registers[dest] = registers[src1] + registers[src2] */
OP_SUB_REAL, /* sub-real : registers[dest] = registers[src1] - registers[src2] */
OP_MUL_REAL, /* mul-real : registers[dest] = registers[src1] * registers[src2] */
OP_DIV_REAL, /* div-real : registers[dest] = registers[src1] / registers[src2] */
OP_ABS_REAL, /* abs-real : registers[dest] = | registers[src1] | */
OP_NEG_REAL, /* neg-real : registers[dest] = -registers[src1] */
OP_INT_TO_REAL, /* int-to-real : registers[dest] = registers[src1] as real */
OP_NAT_TO_REAL, /* nat-to-real : registers[dest] = registers[src1] as real */
OP_REAL_TO_INT, /* real-to-int : registers[dest] = registers[src1] as int */
OP_REAL_TO_NAT, /* real-to-nat : registers[dest] = registers[src1] as nat */
OP_BIT_SHIFT_LEFT, /* bit-shift-left : registers[dest] = registers[src1] << registers[src2] */
OP_BIT_SHIFT_RIGHT,/* bit-shift-right : registers[dest] = registers[src1] >> registers[src2] */
OP_BIT_SHIFT_R_EXT,/* bit-shift-r-ext : registers[dest] as i32 = registers[src1] >> registers[src2] */
OP_BAND, /* bit-and : registers[dest] = registers[src1] & registers[src2] */
OP_BOR, /* bit-or : registers[dest] = registers[src1] | registers[src2] */
OP_BXOR, /* bit-xor : registers[dest] = registers[src1] ^ registers[src2] */
OP_MALLOC_IMM, /* malloc_immediate : dest = fat ptr to memory of raw <str or array or plex>*/
OP_MEMSET_8, /* memset_8 : dest <-> dest+count = src1 as u8 */
OP_MEMSET_16, /* memset_16 : dest <-> dest+count = src1 as u8 */
OP_MEMSET_32, /* memset_32 : dest <-> dest+count = src1 as u32 */
OP_REG_MOV, /* register_move : locals[dest] = locals[src1] */
OP_ADD_INT, /* add_int : locals[dest] = locals[src1] + locals[src2] */
OP_SUB_INT, /* sub_int : locals[dest] = locals[src1] _ locals[src2] */
OP_MUL_INT, /* mul_int : locals[dest] = locals[src1] * locals[src2] */
OP_DIV_INT, /* div_int : locals[dest] = locals[src1] / locals[src2] */
OP_ABS_INT, /* abs_int : locals[dest] = | locals[src1] | */
OP_NEG_INT, /* neg_int : locals[dest] = -locals[src1] */
OP_ADD_NAT, /* add_nat : locals[dest] = locals[src1] + locals[src2] */
OP_SUB_NAT, /* sub_nat : locals[dest] = locals[src1] _ locals[src2] */
OP_MUL_NAT, /* mul_nat : locals[dest] = locals[src1] * locals[src2] */
OP_DIV_NAT, /* div_nat : locals[dest] = locals[src1] / locals[src2] */
OP_ABS_NAT, /* abs_nat : locals[dest] = | locals[src1] | */
OP_NEG_NAT, /* neg_nat : locals[dest] = -locals[src1] */
OP_ADD_REAL, /* add_real : locals[dest] = locals[src1] + locals[src2] */
OP_SUB_REAL, /* sub_real : locals[dest] = locals[src1] _ locals[src2] */
OP_MUL_REAL, /* mul_real : locals[dest] = locals[src1] * locals[src2] */
OP_DIV_REAL, /* div_real : locals[dest] = locals[src1] / locals[src2] */
OP_ABS_REAL, /* abs_real : locals[dest] = | locals[src1] | */
OP_NEG_REAL, /* neg_real : locals[dest] = _locals[src1] */
OP_INT_TO_REAL, /* int_to_real : locals[dest] = locals[src1] as real */
OP_NAT_TO_REAL, /* nat_to_real : locals[dest] = locals[src1] as real */
OP_REAL_TO_INT, /* real_to_int : locals[dest] = locals[src1] as int */
OP_REAL_TO_NAT, /* real_to_nat : locals[dest] = locals[src1] as nat */
OP_BIT_SHIFT_LEFT, /* bit_shift_left : locals[dest] = locals[src1] << locals[src2] */
OP_BIT_SHIFT_RIGHT,/* bit_shift_right : locals[dest] = locals[src1] >> locals[src2] */
OP_BIT_SHIFT_R_EXT,/* bit_shift_r_ext : locals[dest] as i32 = locals[src1] >> locals[src2] */
OP_BAND, /* bit_and : locals[dest] = locals[src1] & locals[src2] */
OP_BOR, /* bit_or : locals[dest] = locals[src1] | locals[src2] */
OP_BXOR, /* bit_xor : locals[dest] = locals[src1] ^ locals[src2] */
OP_JMP, /* jump : jump to &dest unconditionally */
OP_JMPF, /* jump-if-flag : jump to &dest if flag != 0 */
OP_JEQ_INT, /* jump-eq-int : jump to &dest if registers[src1] as int == registers[src2] as int */
OP_JNEQ_INT, /* jump-neq-int : jump to &dest if registers[src1] as int != registers[src2] as int */
OP_JGT_INT, /* jump-gt-int : jump to &dest if registers[src1] as int > registers[src2] as int */
OP_JLT_INT, /* jump-lt-int : jump to &dest if registers[src1] as int < registers[src2] as int */
OP_JLE_INT, /* jump-le-int : jump to &dest if registers[src1] as int <= registers[src2] as int */
OP_JGE_INT, /* jump-ge-int : jump to &dest if registers[src1] as int >= registers[src2] as int */
OP_JEQ_NAT, /* jump-eq-nat : jump to &dest if registers[src1] as nat == registers[src2] as nat */
OP_JNEQ_NAT, /* jump-neq-nat : jump to &dest if registers[src1] as nat != registers[src2] as nat */
OP_JGT_NAT, /* jump-gt-nat : jump to &dest if registers[src1] as nat > registers[src2] as nat */
OP_JLT_NAT, /* jump-lt-nat : jump to &dest if registers[src1] as nat < registers[src2] as nat */
OP_JLE_NAT, /* jump-le-nat : jump to &dest if registers[src1] as nat <= registers[src2] as nat */
OP_JGE_NAT, /* jump-ge-nat : jump to &dest if registers[src1] as nat >= registers[src2] as nat */
OP_JEQ_REAL, /* jump-eq-real : jump to &dest if registers[src1] as real == registers[src2] as real */
OP_JNEQ_REAL, /* jump-neq-real : jump to &dest if registers[src1] as real != registers[src2] as real */
OP_JGE_REAL, /* jump-ge-real : jump to &dest if registers[src1] as real >= registers[src2] as real */
OP_JGT_REAL, /* jump-gt-real : jump to &dest if registers[src1] as real > registers[src2] as real */
OP_JLT_REAL, /* jump-lt-real : jump to &dest if registers[src1] as real < registers[src2] as real */
OP_JLE_REAL, /* jump-le-real : jump to &dest if registers[src1] as real <= registers[src2] as real */
OP_STRLEN, /* string-length : registers[dest] = length of str at src1 ptr */
OP_STREQ, /* string-eq : registers[dest] = src1 ptr string == src2 ptr string */
OP_STRCAT, /* string-concat : registers[dest] = ptr of src1 ptr string + src2 ptr string */
OP_STR_GET_CHAR, /* string-get-char : registers[dest] = ptr of src1 ptr str, src2 index of str */
OP_STR_FIND_CHAR, /* string-find-char : registers[dest] = ptr of src1 ptr string, src2 nat8 char */
OP_STR_SLICE, /* string-slice : registers[dest] = ptr of src1 ptr str, src2 start index, src3 end index */
OP_INT_TO_STRING, /* int-to-string : registers[dest] = src1 as str */
OP_NAT_TO_STRING, /* nat-to-string : registers[dest] = src1 as str */
OP_REAL_TO_STRING, /* real-to-string : registers[dest] = src1 as str */
OP_STRING_TO_INT, /* string-to-int : registers[dest] = src1 as int */
OP_STRING_TO_NAT, /* string-to-nat : registers[dest] = src1 as nat */
OP_STRING_TO_REAL /* string-to-real : registers[dest] = src1 as real */
OP_JMPF, /* jump_if_flag : jump to &dest if flag != 0 */
OP_JEQ_INT, /* jump_eq_int : jump to &dest if locals[src1] as int == locals[src2] as int */
OP_JNEQ_INT, /* jump_neq_int : jump to &dest if locals[src1] as int != locals[src2] as int */
OP_JGT_INT, /* jump_gt_int : jump to &dest if locals[src1] as int > locals[src2] as int */
OP_JLT_INT, /* jump_lt_int : jump to &dest if locals[src1] as int < locals[src2] as int */
OP_JLE_INT, /* jump_le_int : jump to &dest if locals[src1] as int <= locals[src2] as int */
OP_JGE_INT, /* jump_ge_int : jump to &dest if locals[src1] as int >= locals[src2] as int */
OP_JEQ_NAT, /* jump_eq_nat : jump to &dest if locals[src1] as nat == locals[src2] as nat */
OP_JNEQ_NAT, /* jump_neq_nat : jump to &dest if locals[src1] as nat != locals[src2] as nat */
OP_JGT_NAT, /* jump_gt_nat : jump to &dest if locals[src1] as nat > locals[src2] as nat */
OP_JLT_NAT, /* jump_lt_nat : jump to &dest if locals[src1] as nat < locals[src2] as nat */
OP_JLE_NAT, /* jump_le_nat : jump to &dest if locals[src1] as nat <= locals[src2] as nat */
OP_JGE_NAT, /* jump_ge_nat : jump to &dest if locals[src1] as nat >= locals[src2] as nat */
OP_JEQ_REAL, /* jump_eq_real : jump to &dest if locals[src1] as real == locals[src2] as real */
OP_JNEQ_REAL, /* jump_neq_real : jump to &dest if locals[src1] as real != locals[src2] as real */
OP_JGE_REAL, /* jump_ge_real : jump to &dest if locals[src1] as real >= locals[src2] as real */
OP_JGT_REAL, /* jump_gt_real : jump to &dest if locals[src1] as real > locals[src2] as real */
OP_JLT_REAL, /* jump_lt_real : jump to &dest if locals[src1] as real < locals[src2] as real */
OP_JLE_REAL, /* jump_le_real : jump to &dest if locals[src1] as real <= locals[src2] as real */
OP_STRLEN, /* string_length : locals[dest] = length of str at src1 ptr */
OP_STREQ, /* string_eq : locals[dest] = src1 ptr string == src2 ptr string */
OP_STRCAT, /* string_concat : locals[dest] = ptr of src1 ptr string + src2 ptr string */
OP_STR_GET_CHAR, /* string_get_char : locals[dest] = ptr of src1 ptr str, src2 index of str */
OP_STR_FIND_CHAR, /* string_find_char : locals[dest] = ptr of src1 ptr string, src2 nat8 char */
OP_STR_SLICE, /* string_slice : locals[dest] = ptr of src1 ptr str, src2 start index, src3 end index */
OP_INT_TO_STRING, /* int_to_string : locals[dest] = src1 as str */
OP_NAT_TO_STRING, /* nat_to_string : locals[dest] = src1 as str */
OP_REAL_TO_STRING, /* real_to_string : locals[dest] = src1 as str */
OP_STRING_TO_INT, /* string_to_int : locals[dest] = src1 as int */
OP_STRING_TO_NAT, /* string_to_nat : locals[dest] = src1 as nat */
OP_STRING_TO_REAL /* string_to_real : locals[dest] = src1 as real */
} Opcode;
#define MAX_REGS 32
typedef struct frame_s {
u32 registers[MAX_REGS]; /* R0-R31 */
u32 locals[MAX_REGS]; /* R0-R31 */
u32 start; /* start of memory block */
u32 end; /* end of memory block */
u32 return_reg; /* register to store return value in parent */
@ -130,7 +131,7 @@ typedef struct device_s {
char type[DEVICE_TYPE_MAX_LENGTH]; /* e.g., "screen", "mouse", "gpio" */
char path[DEVICE_PATH_MAX_LENGTH]; /* "/dev/screen", "/dev/input/mouse/0",
etc. */
void *data; /* device-specific data */
void *data; /* device_specific data */
DeviceOps *ops; /* operations vtable */
u32 flags; /* permissions, status, etc. */
u32 handle; /* id for fast access in VM */

View File

@ -17,8 +17,8 @@
vm->pc++; \
src2 = read_u8(vm, code, vm->pc); \
vm->pc++; \
value = (type)frame->registers[src1]; \
value2 = (type)frame->registers[src2]; \
value = (type)frame->locals[src1]; \
value2 = (type)frame->locals[src2]; \
cond = !!(value op value2); \
mask = -(u32)cond; \
vm->pc = (target & mask) | (vm->pc & ~mask); \
@ -27,7 +27,7 @@
#define MATH_OP(type, op) \
do { \
u32 *regs = frame->registers; \
u32 *regs = frame->locals; \
dest = read_u8(vm, code, vm->pc); \
vm->pc++; \
src1 = read_u8(vm, code, vm->pc); \
@ -40,7 +40,7 @@
#define BIT_OP(op) \
do { \
u32 *regs = frame->registers; \
u32 *regs = frame->locals; \
dest = read_u8(vm, code, vm->pc); \
vm->pc++; \
src1 = read_u8(vm, code, vm->pc); \
@ -93,7 +93,7 @@ bool step_vm(VM *vm) {
frame = &vm->frames[vm->fp];
switch (opcode) {
case OP_HALT: {
case OP_EXIT: {
vm->flag = read_u32(vm, code, vm->pc);
return false;
}
@ -130,7 +130,7 @@ bool step_vm(VM *vm) {
heap_mask = 0;
for (i = 0; i < N; i++) {
src_reg = args[i];
child->registers[i] = frame->registers[src_reg];
child->locals[i] = frame->locals[src_reg];
/* Bitmask operation instead of conditional branch */
heap_mask |= ((frame->heap_mask >> src_reg) & 1) << i;
@ -154,7 +154,7 @@ bool step_vm(VM *vm) {
parent = &vm->frames[vm->fp - 1];
if (child_return_reg != 0xFF && parent->return_reg != 0xFF) {
value = child->registers[child_return_reg];
value = child->locals[child_return_reg];
if (is_heap_value(vm, child_return_reg)) {
ptr = value;
@ -171,7 +171,7 @@ bool step_vm(VM *vm) {
memcopy(vm->memory + new_ptr + 4, vm->memory + ptr + 4, size);
parent->end += size + 4;
parent->registers[parent->return_reg] = new_ptr;
parent->locals[parent->return_reg] = new_ptr;
parent->heap_mask |= (1 << parent->return_reg);
return true;
}
@ -184,10 +184,10 @@ bool step_vm(VM *vm) {
*(u32 *)(vm->memory + new_ptr) = size;
memcopy(vm->memory + new_ptr + 4, vm->memory + ptr + 4, size);
parent->end += size + 4;
parent->registers[parent->return_reg] = new_ptr;
parent->locals[parent->return_reg] = new_ptr;
parent->heap_mask |= (1 << parent->return_reg);
} else {
parent->registers[parent->return_reg] = value;
parent->locals[parent->return_reg] = value;
parent->heap_mask &= ~(1 << parent->return_reg);
}
}
@ -203,8 +203,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] = vm->mp;
size = frame->registers[src1];
frame->locals[dest] = vm->mp;
size = frame->locals[src1];
write_u32(vm, memory, vm->mp, size);
vm->mp += (size + 4);
set_heap_status(vm, dest, true); /* Mark as heap pointer */
@ -216,9 +216,9 @@ bool step_vm(VM *vm) {
u8 value_reg = read_u8(vm, code, vm->pc++);
u8 count_reg = read_u8(vm, code, vm->pc++);
u32 dest = frame->registers[dest_reg];
u32 value = frame->registers[value_reg];
u32 count = frame->registers[count_reg];
u32 dest = frame->locals[dest_reg];
u32 value = frame->locals[value_reg];
u32 count = frame->locals[count_reg];
if (count == 0) {
vm->flag = 1;
@ -237,7 +237,7 @@ bool step_vm(VM *vm) {
write_u32(vm, memory, i, value);
}
frame->registers[0] = dest;
frame->locals[0] = dest;
vm->flag = 1;
return true;
}
@ -247,9 +247,9 @@ bool step_vm(VM *vm) {
u8 value_reg = read_u8(vm, code, vm->pc++);
u8 count_reg = read_u8(vm, code, vm->pc++);
u32 dest = frame->registers[dest_reg];
u16 value = (u16)(frame->registers[value_reg]);
u32 count = frame->registers[count_reg];
u32 dest = frame->locals[dest_reg];
u16 value = (u16)(frame->locals[value_reg]);
u32 count = frame->locals[count_reg];
if (count == 0) {
vm->flag = 1;
@ -268,7 +268,7 @@ bool step_vm(VM *vm) {
write_u16(vm, memory, i, value);
}
frame->registers[0] = dest;
frame->locals[0] = dest;
vm->flag = 1;
return true;
}
@ -278,9 +278,9 @@ bool step_vm(VM *vm) {
u8 value_reg = read_u8(vm, code, vm->pc++);
u8 count_reg = read_u8(vm, code, vm->pc++);
u32 dest = frame->registers[dest_reg];
u8 value = (u8)(frame->registers[value_reg]);
u32 count = frame->registers[count_reg];
u32 dest = frame->locals[dest_reg];
u8 value = (u8)(frame->locals[value_reg]);
u32 count = frame->locals[count_reg];
if (count == 0) {
vm->flag = 1;
@ -299,7 +299,7 @@ bool step_vm(VM *vm) {
write_u8(vm, memory, i, value);
}
frame->registers[0] = dest;
frame->locals[0] = dest;
vm->flag = 1;
return true;
}
@ -308,7 +308,7 @@ bool step_vm(VM *vm) {
vm->pc++;
v = read_u32(vm, code, vm->pc);
vm->pc += 4;
frame->registers[dest] = v;
frame->locals[dest] = v;
return true;
}
case OP_LOAD_ABS_32: {
@ -317,7 +317,7 @@ bool step_vm(VM *vm) {
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
v = read_u32(vm, memory, ptr);
frame->registers[dest] = v;
frame->locals[dest] = v;
return true;
}
case OP_LOAD_ABS_16: {
@ -326,7 +326,7 @@ bool step_vm(VM *vm) {
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
v = read_u16(vm, memory, ptr);
frame->registers[dest] = v;
frame->locals[dest] = v;
return true;
}
case OP_LOAD_ABS_8: {
@ -335,7 +335,7 @@ bool step_vm(VM *vm) {
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
v = read_u8(vm, memory, ptr);
frame->registers[dest] = v;
frame->locals[dest] = v;
return true;
}
case OP_LOAD_IND_32: {
@ -343,9 +343,9 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
v = frame->locals[src1];
ptr = read_u32(vm, memory, v);
frame->registers[dest] = ptr;
frame->locals[dest] = ptr;
return true;
}
case OP_LOAD_IND_16: {
@ -354,9 +354,9 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
v = frame->locals[src1];
v16 = read_u16(vm, memory, v);
frame->registers[dest] = v16;
frame->locals[dest] = v16;
return true;
}
case OP_LOAD_IND_8: {
@ -365,9 +365,9 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
v = frame->locals[src1];
v8 = read_u8(vm, memory, v);
frame->registers[dest] = v8;
frame->locals[dest] = v8;
return true;
}
case OP_LOAD_OFF_8: {
@ -379,9 +379,9 @@ bool step_vm(VM *vm) {
vm->pc++;
offset = read_u32(vm, code, vm->pc);
vm->pc += 4;
v = frame->registers[src1];
v = frame->locals[src1];
v8 = read_u8(vm, memory, (v + offset));
frame->registers[dest] = v8;
frame->locals[dest] = v8;
return true;
}
case OP_LOAD_OFF_16: {
@ -393,9 +393,9 @@ bool step_vm(VM *vm) {
vm->pc++;
offset = read_u32(vm, code, vm->pc);
vm->pc += 4;
v = frame->registers[src1];
v = frame->locals[src1];
v16 = read_u16(vm, memory, (v + offset));
frame->registers[dest] = v16;
frame->locals[dest] = v16;
return true;
}
case OP_LOAD_OFF_32: {
@ -406,9 +406,9 @@ bool step_vm(VM *vm) {
vm->pc++;
offset = read_u32(vm, code, vm->pc);
vm->pc += 4;
v = frame->registers[src1];
v = frame->locals[src1];
ptr = read_u32(vm, memory, (v + offset));
frame->registers[dest] = ptr;
frame->locals[dest] = ptr;
return true;
}
case OP_STORE_ABS_32: {
@ -416,8 +416,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
ptr = frame->registers[dest];
v = frame->locals[src1];
ptr = frame->locals[dest];
write_u32(vm, memory, ptr, v);
return true;
}
@ -426,8 +426,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
ptr = frame->registers[dest];
v = frame->locals[src1];
ptr = frame->locals[dest];
write_u16(vm, memory, ptr, v);
return true;
}
@ -436,8 +436,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
ptr = frame->registers[dest];
v = frame->locals[src1];
ptr = frame->locals[dest];
write_u8(vm, memory, ptr, v);
return true;
}
@ -446,8 +446,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = frame->registers[dest];
v = frame->registers[src1];
ptr = frame->locals[dest];
v = frame->locals[src1];
write_u32(vm, memory, ptr, v);
return true;
}
@ -457,8 +457,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = frame->registers[dest];
v16 = frame->registers[src1];
ptr = frame->locals[dest];
v16 = frame->locals[src1];
write_u16(vm, memory, ptr, v16);
return true;
}
@ -468,8 +468,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = frame->registers[dest];
v8 = frame->registers[src1];
ptr = frame->locals[dest];
v8 = frame->locals[src1];
write_u8(vm, memory, ptr, v8);
return true;
}
@ -482,8 +482,8 @@ bool step_vm(VM *vm) {
vm->pc++;
offset = read_u32(vm, code, vm->pc);
vm->pc += 4;
ptr = frame->registers[dest];
v8 = frame->registers[src1];
ptr = frame->locals[dest];
v8 = frame->locals[src1];
write_u8(vm, memory, (ptr + offset), v8);
return true;
}
@ -496,8 +496,8 @@ bool step_vm(VM *vm) {
vm->pc++;
offset = read_u32(vm, code, vm->pc);
vm->pc += 4;
ptr = frame->registers[dest];
v16 = frame->registers[src1];
ptr = frame->locals[dest];
v16 = frame->locals[src1];
write_u16(vm, memory, (ptr + offset), v16);
return true;
}
@ -509,8 +509,8 @@ bool step_vm(VM *vm) {
vm->pc++;
offset = read_u32(vm, code, vm->pc);
vm->pc += 4;
ptr = frame->registers[dest];
v = frame->registers[src1];
ptr = frame->locals[dest];
v = frame->locals[src1];
write_u32(vm, memory, (ptr + offset), v);
return true;
}
@ -519,7 +519,7 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] = frame->registers[src1];
frame->locals[dest] = frame->locals[src1];
if (is_heap_value(vm, src1)) {
set_heap_status(vm, dest, true);
@ -559,14 +559,14 @@ bool step_vm(VM *vm) {
mode_reg = read_u8(vm, code, vm->pc);
vm->pc++;
path_ptr = frame->registers[path_reg];
mode = frame->registers[mode_reg];
path_ptr = frame->locals[path_reg];
mode = frame->locals[mode_reg];
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
if (dev) {
if (dev->ops->open) {
/* return device plex to user */
device_ptr = vm->mp;
frame->registers[dest_reg] = device_ptr;
frame->locals[dest_reg] = device_ptr;
/* malloc size for device */
write_u32(vm, memory, device_ptr, dev->size);
vm->mp += (dev->size + 4);
@ -594,9 +594,9 @@ bool step_vm(VM *vm) {
size_reg = read_u8(vm, code, vm->pc);
vm->pc++;
device_ptr = frame->registers[device_reg]; /* device pointer */
buffer_ptr = frame->registers[buffer_reg];
size = frame->registers[size_reg]; /* size */
device_ptr = frame->locals[device_reg]; /* device pointer */
buffer_ptr = frame->locals[buffer_reg];
size = frame->locals[size_reg]; /* size */
handle = vm->memory[device_ptr + 4]; /* get device handle */
dev = &vm->devices[handle];
@ -616,7 +616,7 @@ bool step_vm(VM *vm) {
device_reg = read_u8(vm, code, vm->pc);
vm->pc++;
device_ptr = frame->registers[device_reg]; /* device pointer */
device_ptr = frame->locals[device_reg]; /* device pointer */
handle = vm->memory[device_ptr + 4]; /* get device handle */
dev = &vm->devices[handle];
if (dev && dev->ops->refresh) {
@ -639,9 +639,9 @@ bool step_vm(VM *vm) {
size_reg = read_u8(vm, code, vm->pc);
vm->pc++;
device_ptr = frame->registers[device_reg]; /* device pointer */
buffer_ptr = frame->registers[buffer_reg]; /* R1: buffer pointer */
size = frame->registers[size_reg]; /* R2: size */
device_ptr = frame->locals[device_reg]; /* device pointer */
buffer_ptr = frame->locals[buffer_reg]; /* R1: buffer pointer */
size = frame->locals[size_reg]; /* R2: size */
handle = vm->memory[device_ptr + 4]; /* get device handle */
dev = &vm->devices[handle];
@ -662,7 +662,7 @@ bool step_vm(VM *vm) {
device_reg = read_u8(vm, code, vm->pc);
vm->pc++;
device_ptr = frame->registers[device_reg]; /* device pointer */
device_ptr = frame->locals[device_reg]; /* device pointer */
handle = vm->memory[device_ptr + 4]; /* get device handle */
dev = &vm->devices[handle];
@ -687,9 +687,9 @@ bool step_vm(VM *vm) {
args_ptr_reg = read_u8(vm, code, vm->pc);
vm->pc++;
device_ptr = frame->registers[device_reg]; /* device pointer */
cmd = frame->registers[cmd_reg]; /* R1: ioctl command */
args_ptr = frame->registers[args_ptr_reg]; /* R2: args pointer */
device_ptr = frame->locals[device_reg]; /* device pointer */
cmd = frame->locals[cmd_reg]; /* R1: ioctl command */
args_ptr = frame->locals[args_ptr_reg]; /* R2: args pointer */
handle = vm->memory[device_ptr + 4]; /* get device handle */
dev = &vm->devices[handle];
@ -740,12 +740,12 @@ bool step_vm(VM *vm) {
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
value = frame->registers[src1];
value = frame->locals[src1];
if (value < 0) {
value = -value;
}
frame->registers[dest] = value;
frame->locals[dest] = value;
return true;
}
case OP_NEG_INT: {
@ -754,8 +754,8 @@ bool step_vm(VM *vm) {
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
value = frame->registers[src1];
frame->registers[dest] = -value;
value = frame->locals[src1];
frame->locals[dest] = -value;
return true;
}
case OP_ADD_NAT:
@ -773,8 +773,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src2 = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] =
fixed_mul(frame->registers[src1], frame->registers[src2]);
frame->locals[dest] =
fixed_mul(frame->locals[src1], frame->locals[src2]);
return true;
}
@ -785,8 +785,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src2 = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] =
fixed_div(frame->registers[src1], frame->registers[src2]);
frame->locals[dest] =
fixed_div(frame->locals[src1], frame->locals[src2]);
return true;
}
@ -797,8 +797,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src2 = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] =
fixed_add(frame->registers[src1], frame->registers[src2]);
frame->locals[dest] =
fixed_add(frame->locals[src1], frame->locals[src2]);
return true;
}
@ -809,8 +809,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src2 = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] =
fixed_sub(frame->registers[src1], frame->registers[src2]);
frame->locals[dest] =
fixed_sub(frame->locals[src1], frame->locals[src2]);
return true;
}
case OP_REAL_TO_INT: {
@ -818,9 +818,9 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
value = frame->registers[src1];
value = frame->locals[src1];
frame->registers[dest] = fixed_to_int(value);
frame->locals[dest] = fixed_to_int(value);
return true;
}
@ -829,7 +829,7 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] = int_to_fixed(frame->registers[src1]);
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
return true;
}
case OP_REAL_TO_NAT: {
@ -837,8 +837,8 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
value = frame->registers[src1];
frame->registers[dest] = fixed_to_int(value);
value = frame->locals[src1];
frame->locals[dest] = fixed_to_int(value);
return true;
}
case OP_NAT_TO_REAL: {
@ -846,7 +846,7 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
frame->registers[dest] = int_to_fixed(frame->registers[src1]);
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
return true;
}
case OP_JEQ_NAT: {
@ -909,9 +909,9 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
int_to_string(AS_INT(frame->registers[src1]), buffer);
int_to_string(AS_INT(frame->locals[src1]), buffer);
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
frame->registers[dest] = ptr;
frame->locals[dest] = ptr;
set_heap_status(vm, dest, true); /* Mark as heap pointer */
return true;
}
@ -921,9 +921,9 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
nat_to_string(frame->registers[src1], buffer);
nat_to_string(frame->locals[src1], buffer);
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
frame->registers[dest] = ptr;
frame->locals[dest] = ptr;
set_heap_status(vm, dest, true); /* Mark as heap pointer */
return true;
}
@ -933,10 +933,10 @@ bool step_vm(VM *vm) {
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
fixed_to_string(AS_INT(frame->registers[src1]), buffer);
fixed_to_string(AS_INT(frame->locals[src1]), buffer);
ptr = str_alloc(vm, frame, buffer,
strlength(buffer)); /* copy buffer to dest */
frame->registers[dest] = ptr;
frame->locals[dest] = ptr;
set_heap_status(vm, dest, true); /* Mark as heap pointer */
return true;
}
@ -947,9 +947,9 @@ bool step_vm(VM *vm) {
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = frame->registers[src1];
ptr = frame->locals[src1];
length = read_u32(vm, memory, ptr);
frame->registers[dest] = length;
frame->locals[dest] = length;
return true;
}
case OP_STRCAT: {

View File

@ -5,7 +5,7 @@
(call &add ($0 $1) $2)
(int-to-string $3 $2)
(call &pln ($3) nil)
(halt 0))
(exit 0))
(label add
(add-int $2 $1 $0)

View File

@ -26,12 +26,12 @@ function pln (str message is $0)
str nl is $3
int nl_length is $4
load_heap_immediate ts "/dev/term/0" # get terminal device
malloc_immediate "/dev/term/0" -> ts
load_immediate 0 -> mode
syscall OPEN ts mode -> ts
strlen message -> msg_length
syscall WRITE ts message msg_length
load_heap_immediate "\n" -> nl
malloc_immediate "\n" -> nl
strlen nl -> nl_length
syscall WRITE ts nl nl_length
return

View File

@ -4,7 +4,7 @@
(call &fib ($0) $0)
(int-to-string $1 $0)
(call &pln ($1) nil)
(halt 0))
(exit 0))
(label fib
(load-immediate $1 2)
(jump-lt-int &base-case $0 $1)

View File

@ -33,12 +33,12 @@ function pln (str message is $0)
str nl is $3
int nl_length is $4
load_heap_immediate ts "/dev/term/0" # get terminal device
malloc_immediate "/dev/term/0" -> ts
load_immediate 0 -> mode
syscall OPEN ts mode -> ts
strlen message -> msg_length
syscall WRITE ts message msg_length
load_heap_immediate "\n" -> nl
malloc_immediate "\n" -> nl
strlen nl -> nl_length
syscall WRITE ts nl nl_length
return

View File

@ -2,7 +2,7 @@
(label main
(load-immediate $1 &hello-str) ; load hello string ptr
(call &pln ($1) nil)
(halt 0)) ; done
(exit 0)) ; done
(label pln
(load-immediate $1 &terminal-namespace) ; get terminal device
(load-immediate $11 0)

View File

@ -1,7 +1,7 @@
function main ()
str hello is $0
load_heap_immediate "nuqneH 'u'?" -> hello
malloc_immediate "nuqneH 'u'?" -> hello
call pln hello
exit 0
@ -12,12 +12,12 @@ function pln (str message is $0)
int nl_length is $4
int mode is $5
load_heap_immediate "/dev/term/0" -> ts # get terminal device
malloc_immediate "/dev/term/0" -> ts
load_immediate 0 -> mode
syscall OPEN ts mode -> ts
strlen message -> msg_length
syscall WRITE ts message msg_length
load_heap_immediate "\n" -> nl
malloc_immediate "\n" -> nl
strlen nl -> nl_length
syscall WRITE ts nl nl_length
return

View File

@ -27,7 +27,7 @@
(call &pln ($4) nil)
(real-to-string $3 $0)
(call &pln ($3) nil)
(halt 0))
(exit 0))
(label pln
(load-immediate $1 &terminal-namespace) ; get terminal device
(load-immediate $11 0)

View File

@ -14,13 +14,13 @@ function main ()
add_real a $5 -> a
add_int i $3 -> i
jump_ge_int &loop_body i $2
load_heap_immediate "/dev/term/0" -> term
malloc_immediate "/dev/term/0" -> term
load_immediate 0 -> mode
syscall OPEN term mode -> term # Terminal term = open("/dev/term/0", 0);
nat b is $1
real_to_nat a -> b
load_heap_immediate "Enter a string:" -> $7
malloc_immediate "Enter a string:" -> $7
string_length $7 -> $8
syscall WRITE term $7 $8 # print prompt
@ -43,12 +43,12 @@ function pln (str message is $0)
str nl is $3
int nl_length is $4
load_heap_immediate "/dev/term/0" -> ts
malloc_immediate "/dev/term/0" -> ts
load_immediate 0 -> mode
syscall OPEN ts mode -> ts # get terminal device
strlen message -> msg_length
syscall WRITE ts message msg_length
load_heap_immediate "\n" -> nl
malloc_immediate "\n" -> nl
strlen nl -> nl_length
syscall WRITE ts nl nl_length
return

View File

@ -12,7 +12,7 @@
(syscall READ $0 $4 $1) ; read the string
(call &pln ($0 $4) nil) ; print the string
(halt 0))
(exit 0))
(label pln
(load-immediate $3 &new-line)
(string-length $2 $1)

View File

@ -3,11 +3,11 @@ function main ()
int mode is $11
str term is $10
load_heap_immediate "/dev/term/0" -> term
malloc_immediate "/dev/term/0" -> term
load_immediate 0 -> mode
syscall OPEN term mode -> term # Terminal term = open("/dev/term/0", 0);
load_heap_immediate "Enter a string:" -> $7
malloc_immediate "Enter a string:" -> $7
string_length $7 -> $8
syscall WRITE term $7 $8 # print prompt
@ -26,11 +26,11 @@ function pln (str message is $0)
str nl is $3
int nl_length is $4
load_heap_immediate "/dev/term/0" -> ts
malloc_immediate "/dev/term/0" -> ts
load_immediate 0 -> mode
syscall OPEN ts mode -> ts # get terminal device
strlen message -> msg_length
syscall WRITE ts message msg_length
load_heap_immediate "\n" -> nl
malloc_immediate "\n" -> nl
strlen nl -> nl_length
syscall WRITE ts nl nl_length

View File

@ -66,8 +66,8 @@
(jump &draw-loop))
; Flush and halt
(halt 0))
; Flush and exit
(exit 0))
(label set-color-if-clicked
; (click_x, click_y, box_x, box_y, color, box_size)

View File

@ -94,7 +94,7 @@ function main ()
jump &draw_loop
# Flush and halt
# Flush and exit
exit 0
function set_color_if_clicked (int click_x is $0, int click_y is $1,

View File

@ -153,8 +153,8 @@
(jump &draw-loop))
; Flush and halt
(halt 0))
; Flush and exit
(exit 0))
(label set-color-if-clicked
; (click_x, click_y, box_x, box_y, color, box_size)

View File

@ -94,7 +94,7 @@ function main ()
jump &draw_loop
# Flush and halt
# Flush and exit
exit 0
function set_color_if_clicked (int click_x is $0, int click_y is $1,

View File

@ -5,7 +5,7 @@
(add-real $2 $1 $0)
(real-to-string $3 $2)
(call &pln ($3) nil)
(halt 0))
(exit 0))
(label pln
(load-immediate $1 &terminal-namespace) ; get terminal device
(load-immediate $11 0)

View File

@ -20,12 +20,12 @@ function pln (str message is $0)
int nl_length is $4
int mode is $5
load_heap_immediate "/dev/term/0" -> term # get terminal device
malloc_immediate "/dev/term/0" -> term
load_immediate 0 -> mode
syscall OPEN term mode -> term
strlen message -> msg_length
syscall WRITE term message msg_length
load_heap_immediate "\n" -> nl
malloc_immediate "\n" -> nl
strlen nl -> nl_length
syscall WRITE term nl nl_length
return

View File

@ -52,7 +52,7 @@
(syscall WRITE $0 $21 $22) ; redraw
(jump &draw-loop))
(halt 0))
(exit 0))
(label pln
(load-immediate $1 &terminal-namespace) ; get terminal device
(load-immediate $11 0)

View File

@ -40,21 +40,21 @@ function main () {
byte left_down = mouse.left;
if (left_down == 0) continue;
if (left_down == 1) {
nat x = mouse.x;
nat y = mouse.y;
nat x = mouse.x;
nat y = mouse.y;
// Compute start address: y*width + x
nat pixel_pos = y * width; // = y * width
pixel_pos = x + pixel_pos; // += x
pixel_pos = screen_buffer + pixel_pos; // += pixel_offset
nat fat_ptr_size = 4; // need to add offset for fat pointer size
pixel_pos = pixel_pos + fat_ptr_size;
// Compute start address: y*width + x
nat pixel_pos = y * width; // = y * width
pixel_pos = x + pixel_pos; // += x
pixel_pos = screen_buffer + pixel_pos; // += pixel_offset
nat fat_ptr_size = 4; // need to add offset for fat pointer size
pixel_pos = pixel_pos + fat_ptr_size;
byte color = WHITE;
store_absolute_8(pixel_pos, color); // draw color at screen [x,y]
write(screen, screen_buffer, buffer_size); // redraw
byte color = WHITE;
store_absolute_8(pixel_pos, color); // draw color at screen [x,y]
write(screen, screen_buffer, buffer_size); // redraw
}
}
exit(0);
}