wip compiler stuff
This commit is contained in:
parent
edb00d0a4c
commit
5d2aa1ad22
7
Makefile
7
Makefile
|
|
@ -80,6 +80,7 @@ endif
|
|||
VM_SOURCES := \
|
||||
$(SRC_DIR)/vm/vm.c \
|
||||
$(SRC_DIR)/vm/device.c \
|
||||
$(SRC_DIR)/vm/fixed.c \
|
||||
$(SRC_DIR)/vm/libc.c
|
||||
|
||||
ifeq ($(BUILD_MODE), release)
|
||||
|
|
@ -87,13 +88,15 @@ ifeq ($(BUILD_MODE), release)
|
|||
$(ARCH_DIR)/devices.c\
|
||||
$(SRC_DIR)/tools/parser.c \
|
||||
$(SRC_DIR)/tools/lexer.c \
|
||||
$(SRC_DIR)/tools/assembler.c
|
||||
$(SRC_DIR)/tools/assembler.c\
|
||||
$(SRC_DIR)/tools/compiler.c
|
||||
else
|
||||
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
||||
$(ARCH_DIR)/devices.c \
|
||||
$(SRC_DIR)/tools/parser.c \
|
||||
$(SRC_DIR)/tools/lexer.c \
|
||||
$(SRC_DIR)/tools/assembler.c
|
||||
$(SRC_DIR)/tools/assembler.c\
|
||||
$(SRC_DIR)/tools/compiler.c
|
||||
endif
|
||||
|
||||
# --- OBJECT FILES ---
|
||||
|
|
|
|||
41
README.org
41
README.org
|
|
@ -58,23 +58,16 @@ The Undâr compiler will be written in Sċieppan, as well as core VM tests.
|
|||
#+BEGIN_SRC lisp
|
||||
((code
|
||||
(label main
|
||||
(load-immediate $1 &hello-str) ; load hello string ptr
|
||||
(call &pln ($1) nil)
|
||||
(halt)) ; done
|
||||
(label pln
|
||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
||||
(load-immediate $11 0)
|
||||
(syscall OPEN $1 $1 $11)
|
||||
(load-immediate $3 &new-line)
|
||||
(string-length $2 $0)
|
||||
(syscall WRITE $1 $0 $2)
|
||||
(string-length $4 $3)
|
||||
(syscall WRITE $1 $3 $4)
|
||||
(return nil)))
|
||||
(ldi $0 &terminal-namespace) ; get terminal device
|
||||
(ldi $1 0)
|
||||
(syscall OPEN $0 $0 $1)
|
||||
(ldi $1 &hello-str) ; load hello string ptr
|
||||
(strlen $2 $1)
|
||||
(syscall WRITE $0 $1 $2)
|
||||
(halt 0)))
|
||||
(data
|
||||
(label terminal-namespace "/dev/term/0")
|
||||
(label new-line "\n")
|
||||
(label hello-str "nuqneH 'u'?")))
|
||||
(label hello-str "nuqneH 'u'?\n")))
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
|
|
@ -92,24 +85,24 @@ heap allocations using the internal malloc opcode push pointers within this fram
|
|||
#+BEGIN_SRC lisp
|
||||
((code
|
||||
(label main
|
||||
(load-immediate $0 &terminal-namespace) ; get terminal device
|
||||
(load-immediate $11 0)
|
||||
(ldi $0 &terminal-namespace) ; get terminal device
|
||||
(ldi $11 0)
|
||||
(syscall OPEN $0 $0 $11)
|
||||
|
||||
(load-immediate $1 &help) ; print help message
|
||||
(call &pln ($0 $1) nil)
|
||||
(ldi $1 &help) ; print help message
|
||||
(fcall &pln ($0 $1) nil)
|
||||
|
||||
(load-immediate $1 32) ; read in a string of max 32 char length
|
||||
(ldi $1 32) ; read in a string of max 32 char length
|
||||
(malloc $4 $1) ; allocate memory for the string
|
||||
(syscall READ $0 $4 $1) ; read the string
|
||||
|
||||
(call &pln ($0 $4) nil) ; print the string
|
||||
(fcall &pln ($0 $4) nil) ; print the string
|
||||
(halt))
|
||||
(label pln
|
||||
(load-immediate $3 &new-line)
|
||||
(string-length $2 $1)
|
||||
(ldi $3 &new-line)
|
||||
(strlen $2 $1)
|
||||
(syscall WRITE $0 $1 $2)
|
||||
(string-length $4 $3)
|
||||
(strlen $4 $3)
|
||||
(syscall WRITE $0 $3 $4)
|
||||
(return nil)))
|
||||
(data
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@
|
|||
(return n))
|
||||
(return (+ (fib (- n 2)) (fib (- n 1)))))
|
||||
|
||||
(print (fib 35))
|
||||
(print (fib 36))
|
||||
|
|
@ -3,6 +3,6 @@ function fib(n)
|
|||
return fib(n-1) + fib(n-2)
|
||||
end
|
||||
|
||||
local result = fib(35)
|
||||
local result = fib(36)
|
||||
|
||||
print(result)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ sub fib {
|
|||
return fib($n-1) + fib($n-2);
|
||||
}
|
||||
|
||||
my $result = fib(35);
|
||||
my $result = fib(36);
|
||||
|
||||
print "$result\n";
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@ def fib(n):
|
|||
return n
|
||||
return fib(n-1) + fib(n-2)
|
||||
|
||||
result = fib(35)
|
||||
result = fib(36)
|
||||
print(result)
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@ fn fib(n) {
|
|||
return fib(n - 2) + fib(n - 1);
|
||||
}
|
||||
|
||||
let result = fib(35);
|
||||
let result = fib(36);
|
||||
print result;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
#include "devices.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#include <unistd.h>
|
||||
|
||||
i32 console_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
||||
USED(mode);
|
||||
|
|
@ -141,10 +140,14 @@ i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
|||
}
|
||||
|
||||
i32 mouse_read(void *data, u8 *buffer, u32 size) {
|
||||
MouseDeviceData *mouse_data = (MouseDeviceData *)data;
|
||||
USED(data);
|
||||
USED(buffer);
|
||||
USED(size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (size < 12)
|
||||
return -1;
|
||||
i32 mouse_refresh(void *data, u8 *buffer) {
|
||||
MouseDeviceData *mouse_data = (MouseDeviceData *)data;
|
||||
|
||||
u8 *info = (u8 *)buffer;
|
||||
memcpy(&info[4], &mouse_data->x, sizeof(u32));
|
||||
|
|
|
|||
|
|
@ -26,16 +26,13 @@ typedef struct mouse_device_data_s {
|
|||
u8 btn2;
|
||||
u8 btn3;
|
||||
u8 btn4;
|
||||
u32 size;
|
||||
} MouseDeviceData;
|
||||
|
||||
/* Keyboard device data */
|
||||
typedef struct keyboard_device_data_s {
|
||||
u32 handle;
|
||||
const u8 *keys;
|
||||
i32 key_count;
|
||||
u32 pos;
|
||||
u32 size;
|
||||
const u8 *keys;
|
||||
} KeyboardDeviceData;
|
||||
|
||||
/* Console device data */
|
||||
|
|
@ -52,6 +49,7 @@ i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer);
|
|||
|
||||
i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 mouse_read(void *data, u8 *buffer, u32 size);
|
||||
i32 mouse_refresh(void *data, u8 *buffer);
|
||||
i32 mouse_write(void *data, const u8 *buffer, u32 size);
|
||||
i32 mouse_close(void *data);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ static DeviceOps mouse_ops = {.open = mouse_open,
|
|||
.read = mouse_read,
|
||||
.write = mouse_write,
|
||||
.close = mouse_close,
|
||||
.ioctl = nil};
|
||||
.ioctl = nil,
|
||||
.refresh = mouse_refresh};
|
||||
|
||||
static DeviceOps console_device_ops = {
|
||||
.open = console_open,
|
||||
|
|
@ -177,13 +178,12 @@ int main(int argc, char **argv) {
|
|||
mouse_data.btn2 = 0;
|
||||
mouse_data.btn3 = 0;
|
||||
mouse_data.btn4 = 0;
|
||||
mouse_data.size = 16;
|
||||
|
||||
// Register devices
|
||||
vm_register_device(&vm, "/dev/screen/0", "screen", &screen_data,
|
||||
&screen_ops, 16 + screen_data.buffer_size);
|
||||
vm_register_device(&vm, "/dev/mouse/0", "mouse", &mouse_data, &mouse_ops,
|
||||
mouse_data.size);
|
||||
16);
|
||||
vm_register_device(&vm, "/dev/term/0", "terminal", &console_data,
|
||||
&console_device_ops, 4);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
#include "../../tools/assembler.h"
|
||||
#include "../../tools/lexer.h"
|
||||
#include "../../tools/compiler.h"
|
||||
#include "../../tools/parser.h"
|
||||
#include "../../vm/vm.h"
|
||||
#include "devices.h"
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -280,130 +281,130 @@ const char *opcode_to_string(Opcode op) {
|
|||
static const char *names[] = {
|
||||
[OP_HALT] = "halt",
|
||||
[OP_JMP] = "jump",
|
||||
[OP_JMPF] = "jump-if-flag",
|
||||
[OP_CALL] = "call",
|
||||
[OP_RETURN] = "return",
|
||||
[OP_JMPF] = "jmpf",
|
||||
[OP_FCALL] = "fcall",
|
||||
[OP_FRETURN] = "return",
|
||||
|
||||
/* Immediate loads (only 32-bit variant needed) */
|
||||
[OP_LOAD_IMM] = "load-immediate",
|
||||
[OP_LOAD_IMM] = "ldi",
|
||||
|
||||
/* Register-indirect loads */
|
||||
[OP_LOAD_IND_8] = "load-indirect-8",
|
||||
[OP_LOAD_IND_16] = "load-indirect-16",
|
||||
[OP_LOAD_IND_32] = "load-indirect-32",
|
||||
[OP_LOAD_IND_8] = "ld8",
|
||||
[OP_LOAD_IND_16] = "ld16",
|
||||
[OP_LOAD_IND_32] = "ld32",
|
||||
|
||||
/* Absolute address loads */
|
||||
[OP_LOAD_ABS_8] = "load-absolute-8",
|
||||
[OP_LOAD_ABS_16] = "load-absolute-16",
|
||||
[OP_LOAD_ABS_32] = "load-absolute-32",
|
||||
[OP_LOAD_ABS_8] = "lda8",
|
||||
[OP_LOAD_ABS_16] = "lda16",
|
||||
[OP_LOAD_ABS_32] = "lda32",
|
||||
|
||||
/* Base+offset loads */
|
||||
[OP_LOAD_OFF_8] = "load-offset-8",
|
||||
[OP_LOAD_OFF_16] = "load-offset-16",
|
||||
[OP_LOAD_OFF_32] = "load-offset-32",
|
||||
[OP_LOAD_OFF_8] = "ldo8",
|
||||
[OP_LOAD_OFF_16] = "ldo16",
|
||||
[OP_LOAD_OFF_32] = "ldo32",
|
||||
|
||||
/* Absolute address stores */
|
||||
[OP_STORE_ABS_8] = "store-absolute-8",
|
||||
[OP_STORE_ABS_16] = "store-absolute-16",
|
||||
[OP_STORE_ABS_32] = "store-absolute-32",
|
||||
[OP_STORE_ABS_8] = "sta8",
|
||||
[OP_STORE_ABS_16] = "sta16",
|
||||
[OP_STORE_ABS_32] = "sta32",
|
||||
|
||||
/* Register-indirect stores */
|
||||
[OP_STORE_IND_8] = "store-indirect-8",
|
||||
[OP_STORE_IND_16] = "store-indirect-16",
|
||||
[OP_STORE_IND_32] = "store-indirect-32",
|
||||
[OP_STORE_IND_8] = "sti8",
|
||||
[OP_STORE_IND_16] = "sti16",
|
||||
[OP_STORE_IND_32] = "sti32",
|
||||
|
||||
/* Base+offset stores */
|
||||
[OP_STORE_OFF_8] = "store-offset-8",
|
||||
[OP_STORE_OFF_16] = "store-offset-16",
|
||||
[OP_STORE_OFF_32] = "store-offset-32",
|
||||
[OP_STORE_OFF_8] = "sto8",
|
||||
[OP_STORE_OFF_16] = "sto16",
|
||||
[OP_STORE_OFF_32] = "sto32",
|
||||
|
||||
/* Memory operations */
|
||||
[OP_MALLOC] = "malloc",
|
||||
[OP_MEMSET_8] = "memset-8",
|
||||
[OP_MEMSET_16] = "memset-16",
|
||||
[OP_MEMSET_32] = "memset-32",
|
||||
[OP_MEMSET_8] = "set8",
|
||||
[OP_MEMSET_16] = "set16",
|
||||
[OP_MEMSET_32] = "set32",
|
||||
|
||||
/* Register operations */
|
||||
[OP_REG_MOV] = "register-move",
|
||||
[OP_REG_MOV] = "mov",
|
||||
[OP_SYSCALL] = "syscall",
|
||||
|
||||
/* Bit operations */
|
||||
[OP_BIT_SHIFT_LEFT] = "bit-shift-left",
|
||||
[OP_BIT_SHIFT_RIGHT] = "bit-shift-right",
|
||||
[OP_BIT_SHIFT_R_EXT] = "bit-shift-r-ext",
|
||||
[OP_BAND] = "bit-and",
|
||||
[OP_BOR] = "bit-or",
|
||||
[OP_BXOR] = "bit-xor",
|
||||
[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] = "add-int",
|
||||
[OP_SUB_INT] = "sub-int",
|
||||
[OP_MUL_INT] = "mul-int",
|
||||
[OP_DIV_INT] = "div-int",
|
||||
[OP_ABS_INT] = "abs-int", // ← NEW
|
||||
[OP_NEG_INT] = "neg-int", // ← NEW
|
||||
[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] = "add-nat",
|
||||
[OP_SUB_NAT] = "sub-nat",
|
||||
[OP_MUL_NAT] = "mul-nat",
|
||||
[OP_DIV_NAT] = "div-nat",
|
||||
[OP_ABS_NAT] = "abs-nat", // ← NEW
|
||||
[OP_NEG_NAT] = "neg-nat", // ← NEW
|
||||
[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] = "add-real",
|
||||
[OP_SUB_REAL] = "sub-real",
|
||||
[OP_MUL_REAL] = "mul-real",
|
||||
[OP_DIV_REAL] = "div-real",
|
||||
[OP_ABS_REAL] = "abs-real", // ← NEW
|
||||
[OP_NEG_REAL] = "neg-real", // ← NEW
|
||||
[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] = "int-to-real",
|
||||
[OP_NAT_TO_REAL] = "nat-to-real",
|
||||
[OP_REAL_TO_INT] = "real-to-int",
|
||||
[OP_REAL_TO_NAT] = "real-to-nat",
|
||||
[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] = "jump-eq-int",
|
||||
[OP_JNEQ_INT] = "jump-neq-int",
|
||||
[OP_JGT_INT] = "jump-gt-int",
|
||||
[OP_JLT_INT] = "jump-lt-int",
|
||||
[OP_JLE_INT] = "jump-le-int",
|
||||
[OP_JGE_INT] = "jump-ge-int",
|
||||
[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] = "jump-eq-nat",
|
||||
[OP_JNEQ_NAT] = "jump-neq-nat",
|
||||
[OP_JGT_NAT] = "jump-gt-nat",
|
||||
[OP_JLT_NAT] = "jump-lt-nat",
|
||||
[OP_JLE_NAT] = "jump-le-nat",
|
||||
[OP_JGE_NAT] = "jump-ge-nat",
|
||||
[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] = "jump-eq-real",
|
||||
[OP_JNEQ_REAL] = "jump-neq-real",
|
||||
[OP_JGE_REAL] = "jump-ge-real",
|
||||
[OP_JGT_REAL] = "jump-gt-real",
|
||||
[OP_JLT_REAL] = "jump-lt-real",
|
||||
[OP_JLE_REAL] = "jump-le-real",
|
||||
[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] = "string-length",
|
||||
[OP_STREQ] = "string-eq",
|
||||
[OP_STRCAT] = "string-concat",
|
||||
[OP_STR_GET_CHAR] = "string-get-char",
|
||||
[OP_STR_FIND_CHAR] = "string-find-char",
|
||||
[OP_STR_SLICE] = "string-slice",
|
||||
[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] = "int-to-string",
|
||||
[OP_NAT_TO_STRING] = "nat-to-string",
|
||||
[OP_REAL_TO_STRING] = "real-to-string",
|
||||
[OP_STRING_TO_INT] = "string-to-int",
|
||||
[OP_STRING_TO_NAT] = "string-to-nat",
|
||||
[OP_STRING_TO_REAL] = "string-to-real"};
|
||||
[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>";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
#include "compiler.h"
|
||||
#include "lexer.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//typedef struct {
|
||||
// Token current;
|
||||
// Token previous;
|
||||
// bool hadError;
|
||||
// bool panicMode;
|
||||
//} Parser;
|
||||
//
|
||||
//typedef enum {
|
||||
// PREC_NONE,
|
||||
// PREC_ASSIGNMENT, /* = */
|
||||
// PREC_OR, /* or */
|
||||
// PREC_AND, /* and */
|
||||
// PREC_EQUALITY, /* == != */
|
||||
// PREC_COMPARISON, /* < > <= >= */
|
||||
// PREC_TERM, /* + - */
|
||||
// PREC_FACTOR, /* * / */
|
||||
// PREC_UNARY, /* not */
|
||||
// PREC_CALL, /* . () */
|
||||
// PREC_PRIMARY
|
||||
//} Precedence;
|
||||
//
|
||||
//typedef void (*ParseFn)(char *program);
|
||||
//
|
||||
//typedef struct {
|
||||
// ParseFn prefix;
|
||||
// ParseFn infix;
|
||||
// Precedence precedence;
|
||||
//} ParseRule;
|
||||
//
|
||||
//typedef struct {
|
||||
// i8 rp; // Next free register
|
||||
//} Compiler;
|
||||
//
|
||||
//Parser parser;
|
||||
//
|
||||
//const char *internalErrorMsg =
|
||||
// "FLAGRANT COMPILER ERROR\n\nCompiler over.\nBug = Very Yes.";
|
||||
//
|
||||
//void errorAt(Token *token, const char *message) {
|
||||
// if (parser.panicMode)
|
||||
// return;
|
||||
// parser.panicMode = true;
|
||||
// fprintf(stderr, "[line %d] Error", token->line);
|
||||
//
|
||||
// if (token->type == TOKEN_EOF) {
|
||||
// fprintf(stderr, " at end");
|
||||
// } else if (token->type == TOKEN_ERROR) {
|
||||
// } else {
|
||||
// fprintf(stderr, " at '%.*s'", token->length, token->start);
|
||||
// }
|
||||
//
|
||||
// fprintf(stderr, ": %s\n", message);
|
||||
// parser.hadError = true;
|
||||
//}
|
||||
//
|
||||
//void error(const char *message) { errorAt(&parser.previous, message); }
|
||||
//
|
||||
//void errorAtCurrent(const char *message) { errorAt(&parser.current, message); }
|
||||
//
|
||||
//void advance() {
|
||||
// parser.previous = parser.current;
|
||||
//
|
||||
// for (;;) {
|
||||
// parser.current = nextToken();
|
||||
// if (parser.current.type != TOKEN_ERROR)
|
||||
// break;
|
||||
//
|
||||
// errorAtCurrent(parser.current.start);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void consume(TokenType type, const char *message) {
|
||||
// if (parser.current.type == type) {
|
||||
// advance();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// errorAtCurrent(message);
|
||||
//}
|
||||
//
|
||||
//static int allocateRegister(Compiler *c) {
|
||||
// char buffer[38];
|
||||
// if (c->rp > 28) {
|
||||
// sprintf(buffer, "Out of registers (used %d, max 28)", c->rp);
|
||||
// error(buffer);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// return c->rp++;
|
||||
//}
|
||||
|
||||
//static void freeRegister(Compiler *c, u8 reg) {
|
||||
// if (reg == c->rp - 1) {
|
||||
// c->rp--;
|
||||
// }
|
||||
//}
|
||||
|
||||
//void emit_byte(VM *vm, u8 byte) { vm->code[vm->cp++] = byte; }
|
||||
//
|
||||
//void emit_u32(VM *vm, u32 value) {
|
||||
// write_u32(vm, code, vm->cp, value);
|
||||
// vm->cp += 4;
|
||||
//}
|
||||
//
|
||||
//void emit_opcode(VM *vm, Opcode op) { emit_byte(vm, op); }
|
||||
//
|
||||
//static bool check(TokenType type) { return parser.current.type == type; }
|
||||
//
|
||||
//static bool match(TokenType type) {
|
||||
// if (!check(type))
|
||||
// return false;
|
||||
// advance();
|
||||
// return true;
|
||||
//}
|
||||
//
|
||||
//static void expression(Compiler *c, VM *vm) {
|
||||
// USED(c);
|
||||
// USED(vm);
|
||||
//}
|
||||
//
|
||||
//void number(Compiler *c, VM *vm) {
|
||||
// emit_opcode(vm, OP_LOAD_IMM);
|
||||
// int reg = allocateRegister(c);
|
||||
// if (reg < 0)
|
||||
// return;
|
||||
// emit_byte(vm, reg);
|
||||
//
|
||||
// switch (parser.previous.type) {
|
||||
// case TOKEN_INT_LITERAL: {
|
||||
// char *endptr;
|
||||
// i32 value = (i32)strtol(parser.previous.start, &endptr, 10);
|
||||
// emit_u32(vm, value);
|
||||
// return;
|
||||
// }
|
||||
// case TOKEN_UINT_LITERAL: {
|
||||
// long value = atol(parser.previous.start);
|
||||
// emit_u32(vm, value);
|
||||
// return;
|
||||
// }
|
||||
// case TOKEN_FLOAT_LITERAL: {
|
||||
// float value = atof(parser.previous.start);
|
||||
// fixed_t fvalue = float_to_fixed(value);
|
||||
// emit_u32(vm, fvalue);
|
||||
// return;
|
||||
// }
|
||||
// default:
|
||||
// return; // Unreachable.
|
||||
// }
|
||||
//
|
||||
// errorAtCurrent("Invalid number format");
|
||||
//}
|
||||
//
|
||||
//static void unary(Compiler *c, VM *vm) {
|
||||
// TokenType operatorType = parser.previous.type;
|
||||
//
|
||||
// // Compile the operand.
|
||||
// expression(c, vm);
|
||||
//
|
||||
// // Emit the operator instruction.
|
||||
// switch (operatorType) {
|
||||
// default:
|
||||
// return; // Unreachable.
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//static void emitHalt(Compiler *c, VM *vm) {
|
||||
// emit_opcode(vm, OP_HALT);
|
||||
// advance();
|
||||
// number(c, vm);
|
||||
//}
|
||||
//
|
||||
//static void endCompiler(Compiler *c, VM *vm) { emitHalt(c, vm); }
|
||||
//
|
||||
//static void grouping(Compiler *c, VM *vm) {
|
||||
// expression(c, vm);
|
||||
// consume(TOKEN_RPAREN, "Expect ')' after expression.");
|
||||
//}
|
||||
|
||||
bool compile(const char *source, VM *vm) {
|
||||
USED(source);
|
||||
USED(vm);
|
||||
//initLexer(source);
|
||||
//
|
||||
//parser.hadError = false;
|
||||
//parser.panicMode = false;
|
||||
//
|
||||
//Compiler compiler;
|
||||
//advance();
|
||||
//expression(&compiler, vm);
|
||||
//consume(TOKEN_EOF, "Expect end of expression.");
|
||||
//endCompiler(&compiler, vm);
|
||||
//
|
||||
//return parser.hadError;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef UNDAR_COMPILER_H
|
||||
#define UNDAR_COMPILER_H
|
||||
|
||||
#include "../vm/common.h"
|
||||
#include "../vm/vm.h"
|
||||
#include "../vm/fixed.h"
|
||||
#include "lexer.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
typedef struct field_s {
|
||||
char* name; // "handle"
|
||||
TokenType type; // TOKEN_TYPE_NAT
|
||||
u32 offset; // 4 (for first field in heap object)
|
||||
u32 size; // 4 (bytes for nat)
|
||||
} Field;
|
||||
|
||||
typedef struct plex_def_s {
|
||||
char* name;
|
||||
u32 field_count;
|
||||
u32 logical_size; // Data size (e.g., 12 for Vec3)
|
||||
u32 physical_size; // Total allocation (logical + 4)
|
||||
Field *fields; // All offsets are PHYSICAL
|
||||
} PlexDef;
|
||||
|
||||
typedef struct array_def_s {
|
||||
TokenType type;
|
||||
u32 length;
|
||||
u32 logical_size; // length * element_size
|
||||
u32 physical_size; // logical_size + 4
|
||||
} ArrayDef;
|
||||
|
||||
bool compile(const char *source, VM *vm);
|
||||
|
||||
#endif
|
||||
|
|
@ -10,6 +10,7 @@ typedef uint16_t u16;
|
|||
typedef int16_t i16;
|
||||
typedef uint32_t u32;
|
||||
typedef int32_t i32;
|
||||
typedef float f32;
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,181 @@
|
|||
/* fixed.c - Q16.16 Fixed-Point Math Implementation */
|
||||
|
||||
#include "fixed.h"
|
||||
|
||||
/* Conversion functions */
|
||||
fixed_t int_to_fixed(i32 i) { return i << 16; }
|
||||
|
||||
i32 fixed_to_int(fixed_t f) { return f >> 16; }
|
||||
|
||||
fixed_t float_to_fixed(f32 f) { return (fixed_t)(f * 65536.0f); }
|
||||
|
||||
f32 fixed_to_float(fixed_t f) { return (f32)f / 65536.0f; }
|
||||
|
||||
fixed_t fixed_add(fixed_t a, fixed_t b) { return a + b; }
|
||||
|
||||
fixed_t fixed_sub(fixed_t a, fixed_t b) { return a - b; }
|
||||
|
||||
fixed_t fixed_mul(fixed_t a, fixed_t b) {
|
||||
/* Extract high and low parts */
|
||||
i32 a_hi = a >> 16;
|
||||
u32 a_lo = (u32)a & 0xFFFFU;
|
||||
i32 b_hi = b >> 16;
|
||||
u32 b_lo = (u32)b & 0xFFFFU;
|
||||
|
||||
/* Compute partial products */
|
||||
i32 p0 = (i32)(a_lo * b_lo) >> 16; /* Low * Low */
|
||||
i32 p1 = a_hi * (i32)b_lo; /* High * Low */
|
||||
i32 p2 = (i32)a_lo * b_hi; /* Low * High */
|
||||
i32 p3 = (a_hi * b_hi) << 16; /* High * High */
|
||||
|
||||
/* Combine results */
|
||||
return p0 + p1 + p2 + p3;
|
||||
}
|
||||
|
||||
fixed_t fixed_div(fixed_t a, fixed_t b) {
|
||||
int negative;
|
||||
u32 ua, ub, quotient, remainder;
|
||||
int i;
|
||||
|
||||
if (b == 0)
|
||||
return 0; /* Handle division by zero */
|
||||
|
||||
/* Determine sign */
|
||||
negative = ((a < 0) ^ (b < 0));
|
||||
|
||||
/* Work with absolute values */
|
||||
ua = (a < 0) ? -a : a;
|
||||
ub = (b < 0) ? -b : b;
|
||||
|
||||
/* Perform division using long division in base 2^16 */
|
||||
quotient = 0;
|
||||
remainder = 0;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
remainder <<= 1;
|
||||
if (ua & 0x80000000U) {
|
||||
remainder |= 1;
|
||||
}
|
||||
ua <<= 1;
|
||||
|
||||
if (remainder >= ub) {
|
||||
remainder -= ub;
|
||||
quotient |= 1;
|
||||
}
|
||||
|
||||
if (i < 31) {
|
||||
quotient <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return negative ? -(i32)quotient : (i32)quotient;
|
||||
}
|
||||
|
||||
int fixed_eq(fixed_t a, fixed_t b) { return a == b; }
|
||||
|
||||
int fixed_ne(fixed_t a, fixed_t b) { return a != b; }
|
||||
|
||||
int fixed_lt(fixed_t a, fixed_t b) { return a < b; }
|
||||
|
||||
int fixed_le(fixed_t a, fixed_t b) { return a <= b; }
|
||||
|
||||
int fixed_gt(fixed_t a, fixed_t b) { return a > b; }
|
||||
|
||||
int fixed_ge(fixed_t a, fixed_t b) { return a >= b; }
|
||||
|
||||
/* Unary operations */
|
||||
fixed_t fixed_neg(fixed_t f) { return -f; }
|
||||
|
||||
fixed_t fixed_abs(fixed_t f) { return (f < 0) ? -f : f; }
|
||||
|
||||
/* Square root using Newton-Raphson method */
|
||||
fixed_t fixed_sqrt(fixed_t f) {
|
||||
fixed_t x, prev;
|
||||
|
||||
if (f <= 0)
|
||||
return 0;
|
||||
|
||||
x = f;
|
||||
/* Newton-Raphson iteration: x = (x + f/x) / 2 */
|
||||
do {
|
||||
prev = x;
|
||||
x = fixed_div(fixed_add(x, fixed_div(f, x)), int_to_fixed(2));
|
||||
} while (
|
||||
fixed_gt(fixed_abs(fixed_sub(x, prev)), 1)); /* Precision to 1/65536 */
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Sine function using Taylor series */
|
||||
fixed_t fixed_sin(fixed_t f) {
|
||||
fixed_t result, term, f_squared;
|
||||
int i;
|
||||
/* Normalize angle to [-π, π] */
|
||||
fixed_t pi2 = fixed_mul(FIXED_PI, int_to_fixed(2));
|
||||
while (fixed_gt(f, FIXED_PI))
|
||||
f = fixed_sub(f, pi2);
|
||||
while (fixed_lt(f, fixed_neg(FIXED_PI)))
|
||||
f = fixed_add(f, pi2);
|
||||
|
||||
/* Taylor series: sin(x) = x - x³/3! + x⁵/5! - x⁷/7! + ... */
|
||||
result = f;
|
||||
term = f;
|
||||
f_squared = fixed_mul(f, f);
|
||||
|
||||
/* Calculate first few terms for reasonable precision */
|
||||
for (i = 3; i <= 11; i += 2) {
|
||||
term = fixed_mul(term, f_squared);
|
||||
term = fixed_div(term, int_to_fixed(i * (i - 1)));
|
||||
|
||||
if ((i / 2) % 2 == 0) {
|
||||
result = fixed_add(result, term);
|
||||
} else {
|
||||
result = fixed_sub(result, term);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Cosine function using Taylor series */
|
||||
fixed_t fixed_cos(fixed_t f) {
|
||||
/* cos(x) = 1 - x²/2! + x⁴/4! - x⁶/6! + ... */
|
||||
fixed_t result = FIXED_ONE;
|
||||
fixed_t term = FIXED_ONE;
|
||||
fixed_t f_squared = fixed_mul(f, f);
|
||||
|
||||
int i;
|
||||
for (i = 2; i <= 12; i += 2) {
|
||||
term = fixed_mul(term, f_squared);
|
||||
term = fixed_div(term, int_to_fixed(i * (i - 1)));
|
||||
|
||||
if ((i / 2) % 2 == 0) {
|
||||
result = fixed_add(result, term);
|
||||
} else {
|
||||
result = fixed_sub(result, term);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Tangent function */
|
||||
fixed_t fixed_tan(fixed_t f) {
|
||||
fixed_t cos_val = fixed_cos(f);
|
||||
if (cos_val == 0)
|
||||
return 0; /* Handle undefined case */
|
||||
return fixed_div(fixed_sin(f), cos_val);
|
||||
}
|
||||
|
||||
/* Utility functions */
|
||||
fixed_t fixed_min(fixed_t a, fixed_t b) { return (a < b) ? a : b; }
|
||||
|
||||
fixed_t fixed_max(fixed_t a, fixed_t b) { return (a > b) ? a : b; }
|
||||
|
||||
fixed_t fixed_clamp(fixed_t f, fixed_t min_val, fixed_t max_val) {
|
||||
if (f < min_val)
|
||||
return min_val;
|
||||
if (f > max_val)
|
||||
return max_val;
|
||||
return f;
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef FIXED_H
|
||||
#define FIXED_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* Q16.16 fixed-point type */
|
||||
typedef i32 fixed_t;
|
||||
|
||||
/* Constants */
|
||||
#define FIXED_ONE 0x00010000L /* 1.0 in Q16.16 */
|
||||
#define FIXED_ZERO 0x00000000L /* 0.0 in Q16.16 */
|
||||
#define FIXED_HALF 0x00008000L /* 0.5 in Q16.16 */
|
||||
#define FIXED_PI 0x0003243FL /* π ≈ 3.14159 */
|
||||
#define FIXED_E 0x0002B7E1L /* e ≈ 2.71828 */
|
||||
#define FIXED_MAX 0x7FFFFFFFL /* Maximum positive value */
|
||||
#define FIXED_MIN 0x80000000L /* Minimum negative value */
|
||||
|
||||
/* Conversion functions */
|
||||
fixed_t int_to_fixed(i32 i);
|
||||
i32 fixed_to_int(fixed_t f);
|
||||
fixed_t float_to_fixed(f32 f);
|
||||
f32 fixed_to_float(fixed_t f);
|
||||
|
||||
/* Basic arithmetic operations */
|
||||
fixed_t fixed_add(fixed_t a, fixed_t b);
|
||||
fixed_t fixed_sub(fixed_t a, fixed_t b);
|
||||
fixed_t fixed_mul(fixed_t a, fixed_t b);
|
||||
fixed_t fixed_div(fixed_t a, fixed_t b);
|
||||
|
||||
/* Comparison functions */
|
||||
int fixed_eq(fixed_t a, fixed_t b);
|
||||
int fixed_ne(fixed_t a, fixed_t b);
|
||||
int fixed_lt(fixed_t a, fixed_t b);
|
||||
int fixed_le(fixed_t a, fixed_t b);
|
||||
int fixed_gt(fixed_t a, fixed_t b);
|
||||
int fixed_ge(fixed_t a, fixed_t b);
|
||||
|
||||
/* Unary operations */
|
||||
fixed_t fixed_neg(fixed_t f);
|
||||
fixed_t fixed_abs(fixed_t f);
|
||||
|
||||
/* Advanced math functions */
|
||||
fixed_t fixed_sqrt(fixed_t f);
|
||||
fixed_t fixed_sin(fixed_t f); /* f in radians */
|
||||
fixed_t fixed_cos(fixed_t f); /* f in radians */
|
||||
fixed_t fixed_tan(fixed_t f); /* f in radians */
|
||||
|
||||
/* Utility functions */
|
||||
fixed_t fixed_min(fixed_t a, fixed_t b);
|
||||
fixed_t fixed_max(fixed_t a, fixed_t b);
|
||||
fixed_t fixed_clamp(fixed_t f, fixed_t min, fixed_t max);
|
||||
|
||||
#endif /* FIXED_H */
|
||||
76
src/vm/vm.c
76
src/vm/vm.c
|
|
@ -1,7 +1,8 @@
|
|||
#include "vm.h"
|
||||
#include "device.h"
|
||||
#include "opcodes.h"
|
||||
#include "fixed.h"
|
||||
#include "libc.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
#define COMPARE_AND_JUMP(type, op) \
|
||||
do { \
|
||||
|
|
@ -101,12 +102,10 @@ bool step_vm(VM *vm) {
|
|||
Frame *child;
|
||||
u32 jmp, heap_mask, i;
|
||||
|
||||
/* Read call parameters */
|
||||
jmp = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
N = vm->code[vm->pc++];
|
||||
|
||||
/* Read arguments */
|
||||
for (i = 0; i < N; i++) {
|
||||
args[i] = vm->code[vm->pc++];
|
||||
}
|
||||
|
|
@ -114,7 +113,6 @@ bool step_vm(VM *vm) {
|
|||
return_reg = vm->code[vm->pc++];
|
||||
frame->return_reg = return_reg;
|
||||
|
||||
/* Stack and frame checks */
|
||||
if (vm->sp >= STACK_SIZE)
|
||||
return false;
|
||||
vm->stack[vm->sp++] = vm->pc;
|
||||
|
|
@ -123,14 +121,12 @@ bool step_vm(VM *vm) {
|
|||
return false;
|
||||
vm->fp++;
|
||||
|
||||
/* Setup child frame */
|
||||
child = &vm->frames[vm->fp];
|
||||
child->start = vm->mp;
|
||||
child->end = vm->mp;
|
||||
child->return_reg = 0;
|
||||
child->heap_mask = 0;
|
||||
|
||||
/* Optimized register copy with bitmask for heap status */
|
||||
heap_mask = 0;
|
||||
for (i = 0; i < N; i++) {
|
||||
src_reg = args[i];
|
||||
|
|
@ -185,11 +181,9 @@ bool step_vm(VM *vm) {
|
|||
if (parent->end + size + 4 > MEMORY_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*(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->heap_mask |= (1 << parent->return_reg);
|
||||
} else {
|
||||
|
|
@ -198,7 +192,6 @@ bool step_vm(VM *vm) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Always handle frame cleanup */
|
||||
vm->pc = vm->stack[--vm->sp];
|
||||
vm->mp = child->start;
|
||||
vm->fp--;
|
||||
|
|
@ -603,7 +596,7 @@ bool step_vm(VM *vm) {
|
|||
|
||||
device_ptr = frame->registers[device_reg]; /* device pointer */
|
||||
buffer_ptr = frame->registers[buffer_reg];
|
||||
size = frame->registers[size_reg]; /* size */
|
||||
size = frame->registers[size_reg]; /* size */
|
||||
|
||||
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
||||
dev = &vm->devices[handle];
|
||||
|
|
@ -624,7 +617,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
|
||||
device_ptr = frame->registers[device_reg]; /* device pointer */
|
||||
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
||||
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
||||
dev = &vm->devices[handle];
|
||||
if (dev && dev->ops->refresh) {
|
||||
vm->flag = dev->ops->refresh(dev->data, &vm->memory[device_ptr + 4]);
|
||||
|
|
@ -635,7 +628,6 @@ bool step_vm(VM *vm) {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
case SYSCALL_DEVICE_WRITE: {
|
||||
Device *dev;
|
||||
u32 handle, buffer_ptr, size, device_ptr;
|
||||
|
|
@ -743,28 +735,28 @@ 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++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
|
||||
value = frame->registers[src1];
|
||||
if (value < 0) {
|
||||
value = -value;
|
||||
}
|
||||
value = frame->registers[src1];
|
||||
if (value < 0) {
|
||||
value = -value;
|
||||
}
|
||||
|
||||
frame->registers[dest] = value;
|
||||
return true;
|
||||
frame->registers[dest] = value;
|
||||
return true;
|
||||
}
|
||||
case OP_NEG_INT: {
|
||||
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++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
|
||||
value = frame->registers[src1];
|
||||
frame->registers[dest] = -value;
|
||||
return true;
|
||||
value = frame->registers[src1];
|
||||
frame->registers[dest] = -value;
|
||||
return true;
|
||||
}
|
||||
case OP_ADD_NAT:
|
||||
MATH_OP(u32, +);
|
||||
|
|
@ -782,7 +774,7 @@ bool step_vm(VM *vm) {
|
|||
src2 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->registers[dest] =
|
||||
(frame->registers[src1] * frame->registers[src2]) >> 16;
|
||||
fixed_mul(frame->registers[src1], frame->registers[src2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -794,7 +786,7 @@ bool step_vm(VM *vm) {
|
|||
src2 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->registers[dest] =
|
||||
(frame->registers[src1] << 16) / frame->registers[src2];
|
||||
fixed_div(frame->registers[src1], frame->registers[src2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -805,7 +797,8 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
src2 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->registers[dest] = frame->registers[src1] + frame->registers[src2];
|
||||
frame->registers[dest] =
|
||||
fixed_add(frame->registers[src1], frame->registers[src2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -816,7 +809,8 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
src2 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->registers[dest] = frame->registers[src1] - frame->registers[src2];
|
||||
frame->registers[dest] =
|
||||
fixed_sub(frame->registers[src1], frame->registers[src2]);
|
||||
return true;
|
||||
}
|
||||
case OP_REAL_TO_INT: {
|
||||
|
|
@ -826,11 +820,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
value = frame->registers[src1];
|
||||
|
||||
if (value >= 0) {
|
||||
frame->registers[dest] = value >> 16;
|
||||
} else {
|
||||
frame->registers[dest] = -((-value) >> 16);
|
||||
}
|
||||
frame->registers[dest] = fixed_to_int(value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -839,7 +829,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->registers[dest] = (frame->registers[src1] << 16);
|
||||
frame->registers[dest] = int_to_fixed(frame->registers[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_REAL_TO_NAT: {
|
||||
|
|
@ -848,11 +838,7 @@ bool step_vm(VM *vm) {
|
|||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
value = frame->registers[src1];
|
||||
if (value < 0) {
|
||||
frame->registers[dest] = 0;
|
||||
} else {
|
||||
frame->registers[dest] = AS_NAT(value >> 16);
|
||||
}
|
||||
frame->registers[dest] = fixed_to_int(value);
|
||||
return true;
|
||||
}
|
||||
case OP_NAT_TO_REAL: {
|
||||
|
|
@ -860,7 +846,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->registers[dest] = AS_INT(frame->registers[src1] << 16);
|
||||
frame->registers[dest] = int_to_fixed(frame->registers[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_JEQ_NAT: {
|
||||
|
|
|
|||
BIN
test/add.rom
BIN
test/add.rom
Binary file not shown.
BIN
test/fib.rom
BIN
test/fib.rom
Binary file not shown.
BIN
test/hello.rom
BIN
test/hello.rom
Binary file not shown.
BIN
test/loop.rom
BIN
test/loop.rom
Binary file not shown.
BIN
test/malloc.rom
BIN
test/malloc.rom
Binary file not shown.
Binary file not shown.
BIN
test/paint.rom
BIN
test/paint.rom
Binary file not shown.
BIN
test/simple.rom
BIN
test/simple.rom
Binary file not shown.
BIN
test/window.rom
BIN
test/window.rom
Binary file not shown.
Loading…
Reference in New Issue