increase number of locals to 255, fix real to string, update reals implementation
This commit is contained in:
parent
d482c8d814
commit
5e73aa2cba
4
Makefile
4
Makefile
|
|
@ -39,8 +39,8 @@ endif
|
|||
|
||||
# --- MODE & PLATFORM SPECIFIC FLAGS ---
|
||||
ifeq ($(BUILD_MODE), release)
|
||||
CORE_CFLAGS += -O2 -DNDEBUG
|
||||
PLATFORM_CFLAGS += -O2 -DNDEBUG
|
||||
CORE_CFLAGS += -Ofast -DNDEBUG
|
||||
PLATFORM_CFLAGS += -Ofast -DNDEBUG
|
||||
LDFLAGS += -s
|
||||
TARGET_SUFFIX := -release
|
||||
else
|
||||
|
|
|
|||
|
|
@ -46,8 +46,4 @@ echo "test input" | time ../build/linux/undar-linux-release -t "../test/$FILENAM
|
|||
|
||||
# Undâr Implementation (binary)
|
||||
print_section "undar ($FILENAME.rom)"
|
||||
echo "test input" | time ../build/linux/undar-linux-release -t "../test/$FILENAME.rom"
|
||||
|
||||
# Undâr RISC Implementation (hardcoded)
|
||||
print_section "undar ($FILENAME)"
|
||||
echo "test input" | time ../../undar-lang-risc/out/linux/tui/undar
|
||||
echo "test input" | time ../build/linux/undar-linux-release -t "../test/$FILENAME.rom"
|
||||
|
|
@ -418,7 +418,7 @@ bool define_global(VM *vm, ScopeTable *st) {
|
|||
break;
|
||||
}
|
||||
case TOKEN_LITERAL_REAL: {
|
||||
fixed_t out = float_to_fixed(atof(value.start));
|
||||
r32 out = float_to_real(atof(value.start));
|
||||
|
||||
u32 addr = vm->mp;
|
||||
write_u32(vm, memory, addr, out);
|
||||
|
|
@ -1183,7 +1183,7 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) {
|
|||
break;
|
||||
}
|
||||
case TOKEN_LITERAL_REAL: {
|
||||
fixed_t out = float_to_fixed(atof(value.start));
|
||||
r32 out = float_to_real(atof(value.start));
|
||||
emit_u32(vm, out);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ bool define_global(VM *vm, ScopeTable *st) {
|
|||
break;
|
||||
}
|
||||
case TOKEN_LITERAL_REAL: {
|
||||
fixed_t out = float_to_fixed(atof(value.start));
|
||||
r32 out = float_to_real(atof(value.start));
|
||||
|
||||
u32 addr = vm->mp;
|
||||
write_u32(vm, memory, addr, out);
|
||||
|
|
@ -1045,7 +1045,7 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) {
|
|||
break;
|
||||
}
|
||||
case TOKEN_LITERAL_REAL: {
|
||||
fixed_t out = float_to_fixed(atof(value.start));
|
||||
r32 out = float_to_real(atof(value.start));
|
||||
emit_u32(vm, out);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
#include "fixed.h"
|
||||
|
||||
fixed_t int_to_fixed(i32 i) { return i << 16; }
|
||||
r32 int_to_real(i32 i) { return i << 16; }
|
||||
|
||||
i32 fixed_to_int(fixed_t f) { return f >> 16; }
|
||||
i32 real_to_int(r32 f) { return f >> 16; }
|
||||
|
||||
fixed_t float_to_fixed(f32 f) { return (fixed_t)(f * 65536.0f); }
|
||||
r32 float_to_real(f32 f) { return (r32)(f * 65536.0f); }
|
||||
|
||||
f32 fixed_to_float(fixed_t f) { return (f32)f / 65536.0f; }
|
||||
f32 real_to_float(r32 f) { return (f32)f / 65536.0f; }
|
||||
|
||||
fixed_t fixed_add(fixed_t a, fixed_t b) { return a + b; }
|
||||
r32 real_add(r32 a, r32 b) { return a + b; }
|
||||
|
||||
fixed_t fixed_sub(fixed_t a, fixed_t b) { return a - b; }
|
||||
r32 real_sub(r32 a, r32 b) { return a - b; }
|
||||
|
||||
fixed_t fixed_mul(fixed_t a, fixed_t b) {
|
||||
r32 real_mul(r32 a, r32 b) {
|
||||
|
||||
i32 src1_whole = (i32)a >> 16;
|
||||
i32 src2_whole = (i32)b >> 16;
|
||||
|
|
@ -29,7 +29,7 @@ fixed_t fixed_mul(fixed_t a, fixed_t b) {
|
|||
return result;
|
||||
}
|
||||
|
||||
fixed_t fixed_div(fixed_t a, fixed_t b) {
|
||||
r32 real_div(r32 a, r32 b) {
|
||||
i32 result;
|
||||
|
||||
i32 src1_val = (i32)a;
|
||||
|
|
@ -44,18 +44,18 @@ fixed_t fixed_div(fixed_t a, fixed_t b) {
|
|||
return result;
|
||||
}
|
||||
|
||||
i32 fixed_eq(fixed_t a, fixed_t b) { return a == b; }
|
||||
i32 real_eq(r32 a, r32 b) { return a == b; }
|
||||
|
||||
i32 fixed_ne(fixed_t a, fixed_t b) { return a != b; }
|
||||
i32 real_ne(r32 a, r32 b) { return a != b; }
|
||||
|
||||
i32 fixed_lt(fixed_t a, fixed_t b) { return a < b; }
|
||||
i32 real_lt(r32 a, r32 b) { return a < b; }
|
||||
|
||||
i32 fixed_le(fixed_t a, fixed_t b) { return a <= b; }
|
||||
i32 real_le(r32 a, r32 b) { return a <= b; }
|
||||
|
||||
i32 fixed_gt(fixed_t a, fixed_t b) { return a > b; }
|
||||
i32 real_gt(r32 a, r32 b) { return a > b; }
|
||||
|
||||
i32 fixed_ge(fixed_t a, fixed_t b) { return a >= b; }
|
||||
i32 real_ge(r32 a, r32 b) { return a >= b; }
|
||||
|
||||
fixed_t fixed_neg(fixed_t f) { return -f; }
|
||||
r32 real_neg(r32 f) { return -f; }
|
||||
|
||||
fixed_t fixed_abs(fixed_t f) { return (f < 0) ? -f : f; }
|
||||
r32 real_abs(r32 f) { return (f < 0) ? -f : f; }
|
||||
|
|
|
|||
|
|
@ -1,36 +1,28 @@
|
|||
#ifndef FIXED_H
|
||||
#define FIXED_H
|
||||
#ifndef REAL_H
|
||||
#define REAL_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
typedef i32 fixed_t;
|
||||
typedef i32 r32;
|
||||
|
||||
#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 /* 2.71828 */
|
||||
#define FIXED_MAX 0x7FFFFFFFL /* Maximum positive value */
|
||||
#define FIXED_MIN 0x80000000L /* Minimum negative value */
|
||||
r32 int_to_real(i32 i);
|
||||
i32 real_to_int(r32 f);
|
||||
r32 float_to_real(f32 f);
|
||||
f32 real_to_float(r32 f);
|
||||
|
||||
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);
|
||||
r32 real_add(r32 a, r32 b);
|
||||
r32 real_sub(r32 a, r32 b);
|
||||
r32 real_mul(r32 a, r32 b);
|
||||
r32 real_div(r32 a, r32 b);
|
||||
|
||||
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);
|
||||
i32 real_eq(r32 a, r32 b);
|
||||
i32 real_ne(r32 a, r32 b);
|
||||
i32 real_lt(r32 a, r32 b);
|
||||
i32 real_le(r32 a, r32 b);
|
||||
i32 real_gt(r32 a, r32 b);
|
||||
i32 real_ge(r32 a, r32 b);
|
||||
|
||||
i32 fixed_eq(fixed_t a, fixed_t b);
|
||||
i32 fixed_ne(fixed_t a, fixed_t b);
|
||||
i32 fixed_lt(fixed_t a, fixed_t b);
|
||||
i32 fixed_le(fixed_t a, fixed_t b);
|
||||
i32 fixed_gt(fixed_t a, fixed_t b);
|
||||
i32 fixed_ge(fixed_t a, fixed_t b);
|
||||
|
||||
fixed_t fixed_neg(fixed_t f);
|
||||
fixed_t fixed_abs(fixed_t f);
|
||||
r32 real_neg(r32 f);
|
||||
r32 real_abs(r32 f);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -97,13 +97,13 @@ typedef enum {
|
|||
OP_MAX_OPCODE /* not really an opcode but used to check max length of ops */
|
||||
} Opcode;
|
||||
|
||||
#define MAX_LOCALS 32
|
||||
#define MAX_LOCALS 256
|
||||
typedef struct frame_s {
|
||||
u32 locals[MAX_LOCALS]; /* $0-$31 */
|
||||
u32 start; /* start of memory block */
|
||||
u32 end; /* end of memory block */
|
||||
u32 return_reg; /* register to store return value in parent */
|
||||
u32 heap_mask; /* bitfield: 1 bit per register (R0=bit0, R1=bit1, etc) */
|
||||
u32 heap_mask[8];
|
||||
u32 locals[MAX_LOCALS]; /* $0-$255 */
|
||||
u32 start; /* start of memory block */
|
||||
u32 end; /* end of memory block */
|
||||
u8 return_reg; /* register to store return value in parent */
|
||||
} Frame;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
|||
94
src/vm/vm.c
94
src/vm/vm.c
|
|
@ -5,6 +5,7 @@
|
|||
#include "libc.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
#define MAX_LEN_REAL32 12
|
||||
#define MAX_LEN_INT32 11
|
||||
const char radix_set[11] = "0123456789";
|
||||
|
||||
|
|
@ -59,16 +60,20 @@ const char radix_set[11] = "0123456789";
|
|||
|
||||
/* Set heap status for a register in current frame */
|
||||
void set_heap_status(VM *vm, u8 reg, bool is_heap) {
|
||||
u32 index = reg / 32;
|
||||
u32 mask = 1 << (reg % 32);
|
||||
|
||||
if (is_heap) {
|
||||
vm->frames[vm->fp].heap_mask |= (1 << reg);
|
||||
vm->frames[vm->fp].heap_mask[index] |= mask;
|
||||
} else {
|
||||
vm->frames[vm->fp].heap_mask &= ~(1 << reg);
|
||||
vm->frames[vm->fp].heap_mask[index] &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if register contains heap pointer */
|
||||
bool is_heap_value(VM *vm, u8 reg) {
|
||||
return (vm->frames[vm->fp].heap_mask >> reg) & 1;
|
||||
u32 index = reg / 32;
|
||||
return (vm->frames[vm->fp].heap_mask[index] >> (reg % 32)) & 1;
|
||||
}
|
||||
|
||||
u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length) {
|
||||
|
|
@ -101,7 +106,7 @@ bool step_vm(VM *vm) {
|
|||
case OP_CALL: {
|
||||
u8 N, return_reg, src_reg, args[MAX_LOCALS];
|
||||
Frame *child;
|
||||
u32 jmp, heap_mask, i;
|
||||
u32 jmp, mask, i;
|
||||
|
||||
jmp = read_u32(vm, code, vm->pc);
|
||||
vm->pc += 4;
|
||||
|
|
@ -126,15 +131,15 @@ bool step_vm(VM *vm) {
|
|||
child->start = vm->mp;
|
||||
child->end = vm->mp;
|
||||
child->return_reg = 0;
|
||||
child->heap_mask = 0;
|
||||
|
||||
heap_mask = 0;
|
||||
for (i = 0; i < N; i++) {
|
||||
src_reg = args[i];
|
||||
child->locals[i] = frame->locals[src_reg];
|
||||
heap_mask |= ((frame->heap_mask >> src_reg) & 1) << i;
|
||||
mask = 1 << (src_reg % 32);
|
||||
if (frame->heap_mask[src_reg / 32] & mask) {
|
||||
child->heap_mask[i / 32] |= 1 << (i % 32);
|
||||
}
|
||||
}
|
||||
child->heap_mask = heap_mask;
|
||||
|
||||
vm->pc = jmp;
|
||||
return true;
|
||||
|
|
@ -166,10 +171,10 @@ bool step_vm(VM *vm) {
|
|||
memcopy(vm->memory + new_ptr + 4, vm->memory + ptr + 4, size);
|
||||
parent->end += size + 4;
|
||||
parent->locals[parent->return_reg] = new_ptr;
|
||||
parent->heap_mask |= (1 << parent->return_reg);
|
||||
parent->heap_mask[parent->return_reg / 32] |= (1 << parent->return_reg);
|
||||
} else {
|
||||
parent->locals[parent->return_reg] = value;
|
||||
parent->heap_mask &= ~(1 << parent->return_reg);
|
||||
parent->heap_mask[parent->return_reg / 32] &= ~(1 << parent->return_reg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -796,7 +801,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = fixed_mul(frame->locals[src1], frame->locals[src2]);
|
||||
frame->locals[dest] = real_mul(frame->locals[src1], frame->locals[src2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -808,7 +813,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = fixed_div(frame->locals[src1], frame->locals[src2]);
|
||||
frame->locals[dest] = real_div(frame->locals[src1], frame->locals[src2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -820,7 +825,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = fixed_add(frame->locals[src1], frame->locals[src2]);
|
||||
frame->locals[dest] = real_add(frame->locals[src1], frame->locals[src2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -832,7 +837,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = fixed_sub(frame->locals[src1], frame->locals[src2]);
|
||||
frame->locals[dest] = real_sub(frame->locals[src1], frame->locals[src2]);
|
||||
return true;
|
||||
}
|
||||
case OP_REAL_TO_INT: {
|
||||
|
|
@ -844,7 +849,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
value = frame->locals[src1];
|
||||
|
||||
frame->locals[dest] = fixed_to_int(value);
|
||||
frame->locals[dest] = real_to_int(value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -854,7 +859,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
||||
frame->locals[dest] = int_to_real(frame->locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_REAL_TO_NAT: {
|
||||
|
|
@ -865,7 +870,7 @@ bool step_vm(VM *vm) {
|
|||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
value = frame->locals[src1];
|
||||
frame->locals[dest] = fixed_to_int(value);
|
||||
frame->locals[dest] = real_to_int(value);
|
||||
return true;
|
||||
}
|
||||
case OP_NAT_TO_REAL: {
|
||||
|
|
@ -874,7 +879,7 @@ bool step_vm(VM *vm) {
|
|||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
||||
frame->locals[dest] = int_to_real(frame->locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_JEQ_NAT: {
|
||||
|
|
@ -989,46 +994,47 @@ bool step_vm(VM *vm) {
|
|||
return true;
|
||||
}
|
||||
case OP_REAL_TO_STRING: {
|
||||
i32 q;
|
||||
u8 dest, src1, int_part, frac_part;
|
||||
u32 i = 0, j = 0;
|
||||
char buffer[12];
|
||||
char buffer[MAX_LEN_REAL32];
|
||||
r32 q;
|
||||
bool neg;
|
||||
u8 dest, src1;
|
||||
i32 int_part;
|
||||
u32 frac_part;
|
||||
u32 i = MAX_LEN_REAL32;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
|
||||
q = (i32)frame->locals[src1];
|
||||
q = (r32)frame->locals[src1];
|
||||
if (q < 0) {
|
||||
buffer[i++] = '-';
|
||||
q = -q;
|
||||
}
|
||||
|
||||
int_part = q >> 16;
|
||||
frac_part = q & 0xFFFF;
|
||||
|
||||
if (int_part == 0) {
|
||||
buffer[i++] = radix_set[0];
|
||||
} else {
|
||||
char tmp[16];
|
||||
i32 tmp_i = 0;
|
||||
while (int_part > 0) {
|
||||
tmp[tmp_i++] = radix_set[int_part % 10];
|
||||
int_part /= 10;
|
||||
}
|
||||
while (tmp_i > 0) {
|
||||
buffer[i++] = tmp[--tmp_i];
|
||||
}
|
||||
}
|
||||
do {
|
||||
buffer[--i] = radix_set[frac_part % 10];
|
||||
frac_part /= 10;
|
||||
} while (frac_part > 0);
|
||||
|
||||
buffer[i++] = '.';
|
||||
for (j = 0; j < 6; j++) {
|
||||
frac_part *= 10;
|
||||
buffer[i++] = radix_set[frac_part >> 16];
|
||||
frac_part &= 0xFFFF;
|
||||
}
|
||||
buffer[--i] = '.';
|
||||
|
||||
frame->locals[dest] = str_alloc(vm, frame, buffer + i, 12 - i);
|
||||
neg = int_part < 0;
|
||||
|
||||
if (neg)
|
||||
int_part = -int_part;
|
||||
|
||||
do {
|
||||
buffer[--i] = radix_set[int_part % 10];
|
||||
int_part /= 10;
|
||||
} while (int_part > 0);
|
||||
|
||||
if (neg)
|
||||
buffer[--i] = '-';
|
||||
|
||||
frame->locals[dest] = str_alloc(vm, frame, buffer + i, MAX_LEN_REAL32 - i);
|
||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ function main () {
|
|||
|
||||
// Flush and exit
|
||||
exit 0;
|
||||
}
|
||||
|
||||
function set_color_if_clicked (int click_x $0, int click_y $1,
|
||||
int box_x $2, int box_y $3, byte check_color $4, int bsize $5) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue