part of operations, migration to 1.30

This commit is contained in:
ProgramSnail 2024-11-02 01:19:54 +03:00
parent 2c03654cca
commit e17f1f70ed
8 changed files with 166 additions and 137 deletions

View file

@ -1,7 +1,7 @@
FLAGS=-m32 -g2 -fstack-protector-all
all: src/cli.c src/parser.c src/interpreter.c src/utils.c src/types.c src/virt_stack.c
$(CC) $(FLAGS) -o byterun -Iinclude/ src/utils.c src/parser.c src/virt_stack.c src/interpreter.c src/cli.c ../runtime/runtime.a
all: src/cli.c src/parser.c src/interpreter.c src/utils.c src/types.c src/stack.c
$(CC) $(FLAGS) -o byterun -Iinclude/ src/cli.c src/parser.c src/interpreter.c src/utils.c src/types.c src/stack.c ../runtime/runtime.a
clean:
$(RM) *.a *.o *~ byterun

View file

@ -1,9 +1,11 @@
(rule
(target byterun.exe)
(deps
(:main byterun.c)
(:main src/cli.c src/interpreter.c)
(:parser src/parser.c)
(:utils src/utils.c src/types.c src/stack.c)
(:runtime ../runtime/runtime.a))
(mode
(promote (until-clean)))
(action
(run gcc -g %{main} %{runtime} -o %{target})))
(run gcc -g -Iinclude/ %{main} %{runtime} -o %{target})))

View file

@ -1,3 +1,5 @@
#pragma once
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@ -16,126 +18,123 @@
// ---
void *Bsexp(int n, ...);
int LtagHash(char *);
void Lassert(void *f, char *s, ...);
// Gets a raw data_header
int LkindOf(void *p);
aint LkindOf(void *p);
// Compare s-exprs tags
int LcompareTags(void *p, void *q);
aint LcompareTags(void *p, void *q);
// Functional synonym for built-in operator ":";
void *Ls__Infix_58(void *p, void *q);
// Functional synonym for built-in operator "!!";
int Ls__Infix_3333(void *p, void *q);
aint Ls__Infix_3333(void *p, void *q);
// Functional synonym for built-in operator "&&";
int Ls__Infix_3838(void *p, void *q);
aint Ls__Infix_3838(void *p, void *q);
// Functional synonym for built-in operator "==";
int Ls__Infix_6161(void *p, void *q);
aint Ls__Infix_6161(void *p, void *q);
// Functional synonym for built-in operator "!=";
int Ls__Infix_3361(void *p, void *q);
aint Ls__Infix_3361(void *p, void *q);
// Functional synonym for built-in operator "<=";
int Ls__Infix_6061(void *p, void *q);
aint Ls__Infix_6061(void *p, void *q);
// Functional synonym for built-in operator "<";
int Ls__Infix_60(void *p, void *q);
aint Ls__Infix_60(void *p, void *q);
// Functional synonym for built-in operator ">=";
int Ls__Infix_6261(void *p, void *q);
aint Ls__Infix_6261(void *p, void *q);
// Functional synonym for built-in operator ">";
int Ls__Infix_62(void *p, void *q);
aint Ls__Infix_62(void *p, void *q);
// Functional synonym for built-in operator "+";
int Ls__Infix_43(void *p, void *q);
aint Ls__Infix_43(void *p, void *q);
// Functional synonym for built-in operator "-";
int Ls__Infix_45(void *p, void *q);
aint Ls__Infix_45(void *p, void *q);
// Functional synonym for built-in operator "*";
int Ls__Infix_42(void *p, void *q);
aint Ls__Infix_42(void *p, void *q);
// Functional synonym for built-in operator "/";
int Ls__Infix_47(void *p, void *q);
aint Ls__Infix_47(void *p, void *q);
// Functional synonym for built-in operator "%";
int Ls__Infix_37(void *p, void *q);
aint Ls__Infix_37(void *p, void *q);
int Llength(void *p);
aint Llength(void *p);
int LtagHash(char *s);
char *de_hash(int n);
aint LtagHash(char *s);
char *de_hash(aint n);
int Luppercase(void *v);
aint Luppercase(void *v);
int Llowercase(void *v);
aint Llowercase(void *v);
int LmatchSubString(char *subj, char *patt, int pos);
aint LmatchSubString(char *subj, char *patt, aint pos);
void *Lsubstring(void *subj, int p, int l);
void *Lsubstring(aint *args /*void *subj, aint p, aint l*/);
struct re_pattern_buffer *Lregexp(char *regexp);
regex_t *Lregexp(char *regexp);
int LregexpMatch(struct re_pattern_buffer *b, char *s, int pos);
void *Bstring(void *p);
aint LregexpMatch(struct re_pattern_buffer *b, char *s, aint pos);
void *Lclone(void *p);
int inner_hash(int depth, unsigned acc, void *p);
aint inner_hash(aint depth, auint acc, void *p);
void *LstringInt(char *b);
int Lhash(void *p);
aint Lhash(void *p);
int LflatCompare(void *p, void *q);
int Lcompare(void *p, void *q);
aint LflatCompare(void *p, void *q);
aint Lcompare(void *p, void *q);
void *Belem(void *p, int i);
void *Belem(void *p, aint i);
void *LmakeArray(int length);
void *LmakeString(int length);
void *LmakeArray(aint length);
void *LmakeString(aint length);
void *Bstring(void *p);
void *Lstringcat(void *p);
void *Lstring(void *p);
void *Bstring(aint *args /*void *p*/);
void *Lstringcat(aint *args /* void* p */);
void *Lstring(aint *args /* void *p */);
void *Bclosure(int bn, void *entry, ...);
void *Barray(int bn, ...);
void *Bsexp(int bn, ...);
int Btag(void *d, int t, int n);
void *Bclosure(aint *args, aint bn);
void *Barray(aint *args, aint bn);
void *Bsexp(aint *args, aint bn);
aint Btag(void *d, aint t, aint n);
int get_tag(data *d);
int get_len(data *d);
aint get_tag(data *d);
aint get_len(data *d);
int Barray_patt(void *d, int n);
int Bstring_patt(void *x, void *y);
int Bclosure_tag_patt(void *x);
int Bboxed_patt(void *x);
int Bunboxed_patt(void *x);
int Barray_tag_patt(void *x);
int Bstring_tag_patt(void *x);
int Bsexp_tag_patt(void *x);
aint Barray_patt(void *d, aint n);
aint Bstring_patt(void *x, void *y);
aint Bclosure_tag_patt(void *x);
aint Bboxed_patt(void *x);
aint Bunboxed_patt(void *x);
aint Barray_tag_patt(void *x);
aint Bstring_tag_patt(void *x);
aint Bsexp_tag_patt(void *x);
void *Bsta(void *v, int i, void *x);
void *Bsta(void *v, aint i, void *x);
void Lfailure(char *s, ...);
void LprintfPerror(char *s, ...);
void Bmatch_failure(void *v, char *fname, int line, int col);
void Bmatch_failure(void *v, char *fname, aint line, aint col);
void * /*Lstrcat*/ Li__Infix_4343(void *a, void *b);
void *Lsprintf(char *fmt, ...);
void *LgetEnv(char *var);
int Lsystem(char *cmd);
aint Lsystem(char *cmd);
void Lfprintf(FILE *f, char *s, ...);
void Lprintf(char *s, ...);
@ -152,17 +151,17 @@ void *Lhd(void *v);
void *Ltl(void *v);
/* Lread is an implementation of the "read" construct */
int Lread();
aint Lread();
int Lbinoperror(void);
aint Lbinoperror(void);
int Lbinoperror2(void);
aint Lbinoperror2(void);
/* Lwrite is an implementation of the "write" construct */
int Lwrite(int n);
aint Lwrite(aint n);
int Lrandom(int n);
aint Lrandom(aint n);
int Ltime();
aint Ltime();
void set_args(int argc, char *argv[]);
void set_args(aint argc, char *argv[]);

View file

@ -8,13 +8,12 @@
#include "stdlib.h"
void s_push(struct State *s, void *val);
void s_push_i(struct State *s, aint val);
void s_push_nil(struct State *s);
void s_pushn_nil(struct State *s, size_t n);
void *s_pop(struct State *s);
aint s_pop_i(struct State *s);
void s_popn(struct State *s, size_t n);
// ------ functions ------
@ -25,13 +24,9 @@ void s_popn(struct State *s, size_t n);
//
// where |> defines corresponding frame pointer, | is stack pointer
// location before / after new frame added
void s_enter_f(struct State *s, char *func_ip, size_t params_sz,
size_t locals_sz);
void s_enter_f(struct State *s, char *func_ip, auint params_sz,
auint locals_sz);
void s_exit_f(struct State *s);
void **var_by_category(struct State *s, enum VarCategory category, int id);
// --- changed runtime operations ---
void *s_Bsexp(struct State *state, int bn, int tag);

View file

@ -16,23 +16,21 @@ enum Type {
static const size_t MAX_ARRAY_SIZE = 0x11111110;
static inline union VarT *to_var(struct NilT *var) { return (union VarT *)var; }
// ------ Frame ------
struct Frame {
void *ret; // store returned value [gc pointer]
char *rp; // ret instruction pointer [not gc pointer]
size_t to_prev_fp_box; // ret function frame pointer [boxed value, not gc
aint to_prev_fp_box; // ret function frame pointer [boxed value, not gc
// pointer]
size_t args_sz_box; // store arguments [boxed value, not gc pointer]
size_t locals_sz_box; // store locals [boxed value, not gc pointer]
aint args_sz_box; // store arguments [boxed value, not gc pointer]
aint locals_sz_box; // store locals [boxed value, not gc pointer]
};
size_t frame_sz();
auint frame_sz();
void **f_prev_fp(struct Frame *fp);
uint64_t f_locals_sz(struct Frame *fp);
uint64_t f_args_sz(struct Frame *fp);
auint f_locals_sz(struct Frame *fp);
auint f_args_sz(struct Frame *fp);
void **f_locals(struct Frame *fp);
void **f_args(struct Frame *fp);

View file

@ -8,6 +8,8 @@
#include "stack.h"
#include "runtime_externs.h"
extern size_t STACK_SIZE;
int ip_read_int(char** ip) {
*ip += sizeof(int);
return *(int*)((*ip) - sizeof(int));
@ -28,7 +30,7 @@ void run(bytefile *bf) {
const size_t OPS_SIZE = 13;
const char *ops [] = {"+", "-", "*", "/", "%", "<", "<=", ">", ">=", "==", "!=", "&&", "!!"};
int(*ops_func[])(void*, void*) = {
aint(*ops_func[])(void*, void*) = {
&Ls__Infix_43, // +
&Ls__Infix_45, // -
&Ls__Infix_42, // *
@ -75,16 +77,19 @@ void run(bytefile *bf) {
case 1:
switch (l) {
case 0: // CONST %d
s_push(&s, (void*)BOX(ip_read_int(&s.ip)));
s_push_i(&s, BOX(ip_read_int(&s.ip)));
break;
case 1: // STRING %s
s_push(&s, Bstring((void*)ip_read_string(&s.ip, bf)));
case 1: { // STRING %s
void* str = ip_read_string(&s.ip, bf);
s_push(&s, Bstring((aint*)&str));
break;
}
case 2: // SEXP %s %d // create sexpr with tag=%s and %d elements from stack
// params read from stack
s_put_sexp(&s, ip_read_string(&s.ip, bf), ip_read_int(&s.ip));
s_push_i(&s, LtagHash(ip_read_string(&s.ip, bf)));
Bsexp((aint*)s.sp, ip_read_int(&s.ip)); // TODO: check order
break;
case 3: // STI
@ -108,12 +113,12 @@ void run(bytefile *bf) {
break;
case 8: // DROP
s_drop_var(&s);
s_pop(&s);
break;
case 9: // DUP
{ // guess
if (s.sp == s.stack || (s.fp != NULL && s.sp == s.fp->end)) {
{
if (s.sp == s.stack + STACK_SIZE || (s.fp != NULL && s.sp == f_locals(s.fp))) {
failure("can't DUP: no value on stack");
}
*s.sp = *(s.sp - 1);
@ -123,32 +128,22 @@ void run(bytefile *bf) {
case 10: // SWAP
{ // guess
struct NilT* v = *s.sp;
*s.sp = *(s.sp - 1);
*(s.sp - 1) = v;
if (s.sp + 1 >= s.stack + STACK_SIZE || (s.fp != NULL && s.sp + 1 >= f_locals(s.fp))) {
failure("can't SWAP: < 2 values on stack");
}
void* v = *s.sp;
push_extra_root(v);
*s.sp = *(s.sp + 1);
*(s.sp + 1) = v;
pop_extra_root(v);
}
break;
case 11: // ELEM
{
union VarT* array = s_take_var(&s);
union VarT* index = s_take_var(&s);
if (dh_type(array->nil.data_header) != ARRAY_T) {
failure("ELEM: elem, previous element is not array");
}
if (dh_type(index->nil.data_header) != INT_T) {
failure("ELEM: elem, last element is not int");
}
if (index->int_t.value < 0) {
failure("ELEM: can't access by index < 0");
}
if (index->int_t.value >= dh_param(array->array.data_header)) {
failure("ELEM: array index is out of range");
}
s_put_var(&s, array->array.values[index->int_t.value]);
free_var_ptr(array);
free_var_ptr(index);
void* array = s_pop(&s);
aint index = s_pop_i(&s);
s_push(&s, Belem(array, index));
}
break;
@ -159,34 +154,34 @@ void run(bytefile *bf) {
case 2: { // LD %d
int8_t category = ip_read_byte(&s.ip);
union VarT** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
s_put_var(&s, (struct NilT*)*var_ptr); // TODO: check
void** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
s_push(&s, *var_ptr);
break;
}
case 3: { // LDA %d
int8_t category = ip_read_byte(&s.ip);
union VarT** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
void** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
// TODO
break;
}
case 4: { // ST %d
int8_t category = ip_read_byte(&s.ip);
union VarT** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
*var_ptr = s_take_var(&s); // TODO: check
void** var_ptr = var_by_category(&s, to_var_category(category), ip_read_int(&s.ip));
*var_ptr = s_pop(&s);
break;
}
case 5:
switch (l) {
case 0: { // CJMPz 0x%.8x
char* new_ip = (char*)(long)ip_read_int(&s.ip); // TODO: check
if (s_take_i(&s) != 0) {
if (s_pop_i(&s) != UNBOX(0)) {
s.ip = new_ip;
}
break;
}
case 1: { // CJMPnz 0x%.8x
char* new_ip = (char*)(long)ip_read_int(&s.ip); // TODO: check
if (s_take_i(&s) == 0) {
if (s_pop_i(&s) == UNBOX(0)) {
s.ip = new_ip;
}
break;
@ -200,6 +195,7 @@ void run(bytefile *bf) {
break;
case 4: // CLOSURE 0x%.8x
// TODO
{
int n = ip_read_int(&s.ip);
for (int i = 0; i < n; i++) {
@ -226,14 +222,14 @@ void run(bytefile *bf) {
break;
case 7: // TAG %s
// TODO: ??
s_push_i(&s, LtagHash(ip_read_string(&s.ip, bf))); // TODO: check
break;
case 8: // ARRAY %d
s_put_array(&s, ip_read_int(&s.ip));
Barray((aint*)s.sp, ip_read_int(&s.ip));
break;
case 9: // FAIL %d %d
case 9: // FAIL %d %d // TODO
failure("[FAIL]: %d-%d\n", ip_read_int(&s.ip), ip_read_int(&s.ip));
break;
@ -247,30 +243,62 @@ void run(bytefile *bf) {
break;
case 6: // PATT pats[l]
// TODO: JMP if same to pattern ??
// {"=str", "#string", "#array", "#sexp", "#ref", "#val", "#fun"}
switch (l) {
case 0: // =str
s_push_i(&s, Bstring_patt(s_pop(&s), s_pop(&s))); // TODO: order
break;
case 1: // #string
s_push_i(&s, Bstring_tag_patt(s_pop(&s)));
break;
case 2: // #array
s_push_i(&s, Barray_tag_patt(s_pop(&s)));
break;
case 3: // #sexp
s_push_i(&s, Bsexp_tag_patt(s_pop(&s)));
break;
case 4: // #ref
// TODO
break;
case 5: // #val
// TODO
break;
case 6: // #fun
s_push_i(&s, Bclosure_tag_patt(s_pop(&s)));
break;
default:
failure("invalid opcode %d-%d\n", h, l);
}
break;
case 7: {
switch (l) {
case 0: // CALL Lread
f_read(&s);
s_push_i(&s, Lread());
break;
case 1: // CALL Lwrite
f_write(&s);
Lwrite(s_pop_i(&s));
break;
case 2: // CALL Llength
f_length(&s);
s_push_i(&s, Llength(s_pop(&s)));
break;
case 3: // CALL Lstring
f_string(&s);
case 3: { // CALL Lstring
void* str = Lstring((aint*)s.sp);
s_pop(&s);
s_push(&s, str);
break;
}
case 4: // CALL Barray %d
f_array(&s, ip_read_int(&s.ip));
case 4: { // CALL Barray %d
size_t n = ip_read_int(&s.ip);
void* array = Barray((aint*)s.sp, n); // TODO: are elems added (?)
s_popn(&s, n);
s_push(&s, array);
break;
}
default:
failure("invalid opcode %d-%d\n", h, l);

View file

@ -11,6 +11,7 @@ extern size_t __gc_stack_top, __gc_stack_bottom;
flag = __gc_stack_top == 0; \
if (flag) { __gc_stack_top = (size_t)__builtin_frame_address(0); } \
assert(__gc_stack_top != 0); \
assert((__gc_stack_top & 0xF) == 0); \
assert(__builtin_frame_address(0) <= (void *)__gc_stack_top);
#define POST_GC() \
@ -27,6 +28,10 @@ void s_push(struct State *s, void *val) {
*s->sp = val;
}
void s_push_i(struct State *s, aint val) {
s_push(s, (void*)val);
}
void s_push_nil(struct State *s) {
s_push(s, NULL);
}
@ -48,6 +53,10 @@ void* s_pop(struct State *s) {
return value;
}
aint s_pop_i(struct State *s) {
return (aint)s_pop(s);
}
void s_popn(struct State *s, size_t n) {
for (size_t i = 0; i < n; ++i) {
s_pop(s);
@ -56,10 +65,10 @@ void s_popn(struct State *s, size_t n) {
// ------ functions ------
void s_enter_f(struct State *s, char *func_ip, size_t args_sz,
size_t locals_sz) {
void s_enter_f(struct State *s, char *func_ip, auint args_sz,
auint locals_sz) {
// check that params count is valid
if (args_sz > s->sp + STACK_SIZE - s->stack ||
if (s->sp + (aint)args_sz - 1 >= s->stack + STACK_SIZE ||
(s->fp != NULL && args_sz > s->sp + STACK_SIZE - f_locals(s->fp))) {
failure("not enough parameters in stack");
}
@ -147,5 +156,3 @@ void **var_by_category(struct State *s, enum VarCategory category,
return var;
}
// --- changed runtime operations ---

View file

@ -17,8 +17,8 @@ size_t frame_sz() {
void **f_prev_fp(struct Frame *fp) {
return (void **)fp + UNBOX(fp->to_prev_fp_box);
}
uint64_t f_locals_sz(struct Frame *fp) { return UNBOX(fp->locals_sz_box); }
uint64_t f_args_sz(struct Frame *fp) { return UNBOX(fp->args_sz_box); }
auint f_locals_sz(struct Frame *fp) { return UNBOX(fp->locals_sz_box); }
auint f_args_sz(struct Frame *fp) { return UNBOX(fp->args_sz_box); }
void **f_locals(struct Frame *fp) { return (void **)fp - f_locals_sz(fp) - frame_sz(); }
void **f_args(struct Frame *fp) { return (void **)fp + 1; }