1
0
Fork 0

increase number of locals to 255, fix real to string, update reals implementation

This commit is contained in:
zongor 2026-02-12 23:13:46 -08:00
parent d482c8d814
commit 5e73aa2cba
9 changed files with 99 additions and 104 deletions

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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; }

View File

@ -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

View File

@ -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 {

View File

@ -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;
}

View File

@ -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) {