From b532f44d28d4f05a97cdd05c3029d9b6a328146d Mon Sep 17 00:00:00 2001 From: qwertzuiopy Date: Thu, 13 Mar 2025 22:08:53 +0100 Subject: [PATCH] calls! not quit yet~ --- Makefile | 2 +- main.c | 14 ++-- src/lang/ast.c | 199 +++++++++++++++++++++++++++++---------------- src/lang/ast.h | 52 +++++++++--- src/lang/design.md | 22 +++++ src/lang/vstack.c | 50 ++++++++++++ 6 files changed, 252 insertions(+), 87 deletions(-) create mode 100644 src/lang/design.md create mode 100644 src/lang/vstack.c diff --git a/Makefile b/Makefile index 6ed2d19..f944187 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ S+=vulkan.c kitty.c S+=gpu_allocator.c hashmap.c util.c io.c matrix.c dynarray.c image.c types.c allocator.c log.c S+=object.c register.c S+=Wayland/xdg-shell-protocol.c -S+=lang/ast.c +S+=lang/ast.c lang/vstack.c SO=$(addprefix build/,$(S:.c=.o)) SC=$(addprefix src/,$(S)) diff --git a/main.c b/main.c index 6bb5e25..870e41b 100644 --- a/main.c +++ b/main.c @@ -13,15 +13,15 @@ int main() { ast_insert_property(ast, "i", make_pawval_int(ast->mem, 0)); enum PawCtrl *body = make_pawctrl_seq(ast->mem); - pawctrl_append(body, make_pawctrl_call(ast->mem, ping_func)); - pawctrl_append(body, - make_pawctrl_asign( - ast->mem, ast_get_property(ast, "i"), - make_pawval_expr(ast->mem, ast_get_property(ast, "i"), - make_pawval_int(ast->mem, 1), op_add))); + /* pawseq_append(body, make_pawctrl_call(ast->mem, ping_func)); */ + pawseq_append(body, + make_pawctrl_asign( + ast->mem, PSV_P(ast_get_property(ast, "i")), + make_pawval_expr(ast->mem, ast_get_property(ast, "i"), + make_pawval_int(ast->mem, 1), op_add))); meow("add is at %p", op_add); meow("eq is at %p", op_unequals); - pawctrl_append( + pawseq_append( ast->prog, make_pawctrl_while(ast->mem, make_pawval_expr(ast->mem, ast_get_property(ast, "i"), diff --git a/src/lang/ast.c b/src/lang/ast.c index 6fe5278..df98a47 100644 --- a/src/lang/ast.c +++ b/src/lang/ast.c @@ -29,6 +29,11 @@ struct PawStackVal op_equals(struct PawAST *ast, struct PawStackVal lhs, case PAW_VAL_BOOL: return PSV_BOOL(lhs.b == rhs.b); } + case PAW_VAL_CHAR: + switch (rhs.type) { + case PAW_VAL_CHAR: + return PSV_BOOL(lhs.c == rhs.c); + } } meow("trying to compare %s to %s, not suppported", print_valtype(lhs.type), print_valtype(rhs.type)); @@ -43,12 +48,14 @@ const char *print_valtype(enum PawVal type) { return "int"; case PAW_VAL_BOOL: return "bool"; - case PAW_VAL_FUNC: - return "call"; case PAW_VAL_POINT: return "void*"; + case PAW_VAL_SPOINT: + return "stack*"; case PAW_VAL_EXPR: return "expr"; + case PAW_VAL_CHAR: + return "char"; } } @@ -62,6 +69,10 @@ const char *print_ctrltype(enum PawCtrl ctrl) { return "asign"; case PAW_CTRL_CALL: return "call"; + case PAW_CTRL_SPUSH: + return "SPUSH"; + case PAW_CTRL_SPOP: + return "SPOP"; } } @@ -87,6 +98,11 @@ struct PawStackVal try_cast_stack(enum PawVal target, struct PawStackVal val) { case PAW_VAL_BOOL: return PSV_BOOL((bool)val.b); } + case PAW_VAL_CHAR: + switch (val.type) { + case PAW_VAL_CHAR: + return PSV_CHAR((char)val.c); + } } meow("trying to cast %s to %s, returning null", print_valtype(val.type), print_valtype(target)); @@ -113,6 +129,11 @@ struct PawStackVal try_cast(enum PawVal target, enum PawVal *val) { case PAW_VAL_BOOL: return PSV_BOOL((bool)*(bool *)val_get_data(val)); } + case PAW_VAL_CHAR: + switch (*val) { + case PAW_VAL_CHAR: + return PSV_CHAR((char)*(char *)val_get_data(val)); + } } meow("trying to cast %s to %s, returning null", print_valtype(*val), print_valtype(target)); @@ -174,12 +195,28 @@ enum PawVal *make_pawval_bool(struct Mem *mem, bool n) { enum PawVal *make_pawval_point(struct Mem *mem, paw_p n) { enum PawVal *val; - val_make(val, paw_p, PAW_VAL_INT); + val_make(val, paw_p, PAW_VAL_POINT); paw_p *i = val_get_data(val); *i = n; return val; } +enum PawVal *make_pawval_spoint(struct Mem *mem, paw_sp n) { + enum PawVal *val; + val_make(val, paw_sp, PAW_VAL_SPOINT); + paw_sp *i = val_get_data(val); + *i = n; + return val; +} + +enum PawVal *make_pawval_char(struct Mem *mem, char n) { + enum PawVal *val; + val_make(val, paw_p, PAW_VAL_CHAR); + char *i = val_get_data(val); + *i = n; + return val; +} + enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs, enum PawVal *rhs, paw_p op) { enum PawVal *val; @@ -191,24 +228,16 @@ enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs, return val; } -enum PawVal *make_pawval_func(struct Mem *mem) { - enum PawVal *val; - val_make(val, struct PawFunc, PAW_VAL_FUNC); - struct PawFunc *i = val_get_data(val); - return val; -} - void free_pawval(struct Mem *mem, enum PawVal *val) { switch (*val) { case PAW_VAL_FLOAT: case PAW_VAL_INT: case PAW_VAL_BOOL: case PAW_VAL_POINT: + case PAW_VAL_SPOINT: + case PAW_VAL_CHAR: mem_free(mem, val); break; - case PAW_VAL_FUNC: - crash("todo"); - break; case PAW_VAL_EXPR:; struct PawExpr *expr = val_get_data(val); free_pawval(mem, expr->lhs); @@ -226,11 +255,23 @@ enum PawCtrl *make_pawctrl_seq(struct Mem *mem) { return ctrl; } -enum PawCtrl *make_pawctrl_call(struct Mem *mem, paw_p addr) { +enum PawCtrl *make_pawctrl_call(struct Mem *mem, enum PawCtrl *body) { enum PawCtrl *ctrl; ctrl_make(ctrl, struct PawCall, PAW_CTRL_CALL); struct PawCall *i = ctrl_get_data(ctrl); - i->addr = addr; + i->body = body; + return ctrl; +} +enum PawCtrl *make_pawctrl_spush(struct Mem *mem, struct PawStackVal val) { + enum PawCtrl *ctrl; + ctrl_make(ctrl, struct PawCall, PAW_CTRL_SPUSH); + struct PawStackPush *i = ctrl_get_data(ctrl); + i->v = val; + return ctrl; +} +enum PawCtrl *make_pawctrl_spop(struct Mem *mem) { + enum PawCtrl *ctrl; + ctrl_make(ctrl, struct PawCall, PAW_CTRL_SPOP); return ctrl; } @@ -244,7 +285,7 @@ enum PawCtrl *make_pawctrl_while(struct Mem *mem, enum PawVal *cond, return ctrl; } -enum PawCtrl *make_pawctrl_asign(struct Mem *mem, enum PawVal *target, +enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target, enum PawVal *val) { enum PawCtrl *ctrl; ctrl_make(ctrl, struct PawAsign, PAW_CTRL_ASIGN); @@ -254,7 +295,7 @@ enum PawCtrl *make_pawctrl_asign(struct Mem *mem, enum PawVal *target, return ctrl; } -void pawctrl_append(enum PawCtrl *seq, enum PawCtrl *ctrl) { +void pawseq_append(enum PawCtrl *seq, enum PawCtrl *ctrl) { struct PawSeq *seqval = ctrl_get_data(seq); dyn_array_append(&seqval->seq, ctrl); } @@ -331,10 +372,14 @@ void ast_stack_push(struct Stack *stack, enum PawCtrl *ctrl) { stack_push(stack, ctrl); break; case PAW_CTRL_ASIGN: - case PAW_CTRL_CALL: case PAW_CTRL_WHILE: + case PAW_CTRL_SPUSH: + case PAW_CTRL_SPOP: stack_push(stack, ctrl); break; + case PAW_CTRL_CALL: + stack_push(stack, NULL); + stack_push(stack, ctrl); } } @@ -345,28 +390,15 @@ struct PawStackVal ast_eval(struct PawAST *ast, enum PawVal *val) { LS("evaling a %s", print_valtype(*val)); switch (*val) { case PAW_VAL_FLOAT: - return (struct PawStackVal){ - PAW_VAL_FLOAT, - .f = *(float *)val_get_data(val), - }; + return PSV_FLOAT(*(float *)val_get_data(val)); case PAW_VAL_INT: - return (struct PawStackVal){ - PAW_VAL_INT, - .i = *(int *)val_get_data(val), - }; + return PSV_INT(*(int *)val_get_data(val)); case PAW_VAL_BOOL: - return (struct PawStackVal){ - PAW_VAL_BOOL, - .b = *(float *)val_get_data(val), - }; + return PSV_BOOL(*(float *)val_get_data(val)); case PAW_VAL_POINT: - return (struct PawStackVal){ - PAW_VAL_POINT, - .b = *(paw_p *)val_get_data(val), - }; - case PAW_VAL_FUNC: - meow("todo"); - break; + return PSV_P(*(paw_p *)val_get_data(val)); + case PAW_VAL_CHAR: + return PSV_CHAR(*(char *)val_get_data(val)); case PAW_VAL_EXPR:; struct PawExpr *expr = val_get_data(val); LS("calling op at %p", expr->op); @@ -395,6 +427,8 @@ void unwind_stack(struct Stack *stack) { void ast_exec(struct PawAST *ast) { meow("allocing stack"); struct Stack *stack = stack_make(ast->mem, 2048); + struct VStack *vstack = vstack_make(ast->mem, 2048); + int offset = 0; ast_stack_push(stack, ast->prog); meow("starting exec"); while (stack->top < stack->right) { @@ -415,10 +449,14 @@ void ast_exec(struct PawAST *ast) { case PAW_CTRL_CALL:; LS("CALL"); struct PawCall *call = ctrl_get_data(ctrl); - if (call->addr == ast->ping_func) { - ping_func(); + if (stack_poke2(stack) == NULL) { + stack_set2(stack, (void *)(uint64_t)(offset)); + } else { + vstack_reset_to_offset(vstack, offset); + offset = (uint64_t)stack_poke2(stack); + stack_pop(stack); + stack_pop(stack); } - stack_pop(stack); break; case PAW_CTRL_WHILE:; LS("WHILE"); @@ -439,39 +477,64 @@ void ast_exec(struct PawAST *ast) { break; case PAW_CTRL_ASIGN:; LS("ASIGN"); - struct PawAsign *asign = ctrl_get_data(ctrl); - struct PawStackVal val = - try_cast_stack(*asign->lhs, ast_eval(ast, asign->rhs)); - if (val.type != *asign->lhs) { - meow("woopsie wrong type, expected %s but got %s", - print_valtype(*asign->lhs), print_valtype(val.type)); + struct PawAsign *asign = val_get_data(ctrl); + struct PawStackVal val = ast_eval(ast, asign->rhs); + if (asign->lhs.type == PAW_VAL_SPOINT) { + val = try_cast_stack( + vstack_poke_n_after(vstack, asign->lhs.sp, offset).type, val); + } else if (asign->lhs.type == PAW_VAL_POINT) { + val = try_cast_stack(*(enum PawVal *)val.p, val); + } + if (val.type == PAW_VAL_POINT && val.p == NULL) { + meow("woopsie wrong type,,,,"); unwind_stack(stack); } - switch (val.type) { - case PAW_VAL_FLOAT:; - float *ft = val_get_data(asign->lhs); - *ft = val.f; - break; - case PAW_VAL_INT:; - int *it = val_get_data(asign->lhs); - *it = val.i; - break; - case PAW_VAL_BOOL: - bool *bt = val_get_data(asign->lhs); - *bt = val.b; - break; - case PAW_VAL_POINT:; - paw_p *pt = val_get_data(asign->lhs); - *pt = val.p; - break; - case PAW_VAL_EXPR: - case PAW_VAL_FUNC: - meow("whhooopsie not primitive"); - unwind_stack(stack); - break; + if (asign->lhs.type == PAW_VAL_SPOINT) { + vstack_set_n_after(vstack, asign->lhs.sp, offset, val); + } else { + enum PawVal *target = asign->lhs.p; + switch (val.type) { + case PAW_VAL_FLOAT:; + float *ft = val_get_data(target); + *ft = val.f; + break; + case PAW_VAL_INT:; + int *it = val_get_data(target); + *it = val.i; + break; + case PAW_VAL_BOOL: + bool *bt = val_get_data(target); + *bt = val.b; + break; + case PAW_VAL_POINT:; + paw_p *pt = val_get_data(target); + *pt = val.p; + break; + case PAW_VAL_SPOINT: + break; + case PAW_VAL_CHAR:; + char *pc = val_get_data(target); + *pc = val.c; + break; + case PAW_VAL_EXPR: + meow("whhooopsie not primitive"); + unwind_stack(stack); + break; + } } stack_pop(stack); break; + case PAW_CTRL_SPUSH: + LS("SPUSH"); + struct PawStackPush *push = val_get_data(ctrl); + vstack_push(vstack, push->v); + stack_pop(stack); + break; + case PAW_CTRL_SPOP: + LS("SPOP"); + vstack_pop(vstack); + stack_pop(stack); + break; } } meow("ending exec"); diff --git a/src/lang/ast.h b/src/lang/ast.h index 5dd6cee..a9818c7 100644 --- a/src/lang/ast.h +++ b/src/lang/ast.h @@ -1,4 +1,5 @@ +#include #include #include @@ -6,6 +7,7 @@ #include "../dynarray.h" #define paw_p void * +#define paw_sp int #define PSV_NULL \ (struct PawStackVal) { PAW_VAL_POINT, .p = NULL } #define PAW_STACK_SIZE 2048 @@ -17,6 +19,10 @@ (struct PawStackVal) { PAW_VAL_INT, .i = ($v) } #define PSV_P($v) \ (struct PawStackVal) { PAW_VAL_POINT, .p = ($v) } +#define PSV_SP($v) \ + (struct PawStackVal) { PAW_VAL_SPOINT, .sp = ($v) } +#define PSV_CHAR($v) \ + (struct PawStackVal) { PAW_VAL_CHAR, .c = ($v) } #define LS(fmt, ...) \ if (log_stack) { \ @@ -33,8 +39,9 @@ enum PawVal { PAW_VAL_FLOAT, PAW_VAL_INT, PAW_VAL_BOOL, - PAW_VAL_FUNC, + PAW_VAL_CHAR, PAW_VAL_POINT, + PAW_VAL_SPOINT, PAW_VAL_EXPR, }; @@ -42,16 +49,13 @@ enum PawCtrl { PAW_CTRL_SEQ, PAW_CTRL_WHILE, PAW_CTRL_ASIGN, + PAW_CTRL_SPUSH, + PAW_CTRL_SPOP, PAW_CTRL_CALL, }; dyn_array_define(da_paw_ctrl, enum PawCtrl *); dyn_array_define(da_paw_val, enum PawVal *); -struct PawFunc { - enum PawVal *body; - struct da_paw_val val; -}; - struct PawProperty { char *name; enum PawVal *val; @@ -79,7 +83,9 @@ struct PawStackVal { float f; int i; bool b; + char c; paw_p p; + paw_sp sp; }; }; @@ -96,12 +102,16 @@ struct PawWhile { }; struct PawAsign { - enum PawVal *lhs; + struct PawStackVal lhs; enum PawVal *rhs; }; +struct PawStackPush { + struct PawStackVal v; +}; + struct PawCall { - paw_p addr; + enum PawCtrl *body; }; struct PawStackVal op_equals(struct PawAST *ast, struct PawStackVal lhs, @@ -119,12 +129,14 @@ enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs, enum PawVal *rhs, paw_p op); void free_pawval(struct Mem *mem, enum PawVal *val); enum PawCtrl *make_pawctrl_seq(struct Mem *mem); -enum PawCtrl *make_pawctrl_call(struct Mem *mem, paw_p addr); +enum PawCtrl *make_pawctrl_spush(struct Mem *mem, struct PawStackVal val); +enum PawCtrl *make_pawctrl_spop(struct Mem *mem); +enum PawCtrl *make_pawctrl_call(struct Mem *mem, enum PawCtrl *body); enum PawCtrl *make_pawctrl_while(struct Mem *mem, enum PawVal *cond, enum PawCtrl *body); -enum PawCtrl *make_pawctrl_asign(struct Mem *mem, enum PawVal *target, +enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target, enum PawVal *val); -void pawctrl_append(enum PawCtrl *seq, enum PawCtrl *ctrl); +void pawseq_append(enum PawCtrl *seq, enum PawCtrl *ctrl); void ping_func(); struct PawAST *ast_make(); void ast_insert_property(struct PawAST *ast, char *name, enum PawVal *val); @@ -144,3 +156,21 @@ void ast_exec(struct PawAST *ast); $ret = mem_malloc(mem, sizeof(enum PawCtrl) + sizeof($type)); \ *$ret = $TYPE_ENUM; \ } while (0) + +struct VStack { + void *left; + void *right; + void *top; +}; +struct VStack *vstack_make(struct Mem *mem, size_t size); +void vstack_free(struct VStack *stack, struct Mem *mem); +void vstack_pop(struct VStack *stack); +void vstack_push(struct VStack *stack, struct PawStackVal val); +struct PawStackVal vstack_poke(struct VStack *stack); +// 0 being the top of the stack, 1 the element left of that and so on +struct PawStackVal vstack_poke_n(struct VStack *stack, int n); +struct PawStackVal vstack_poke_n_after(struct VStack *stack, int n, int offset); +void vstack_set_n_after(struct VStack *stack, int n, int offset, + struct PawStackVal val); +// make offset the top of the stack +void vstack_reset_to_offset(struct VStack *stack, int offset); diff --git a/src/lang/design.md b/src/lang/design.md new file mode 100644 index 0000000..b58952c --- /dev/null +++ b/src/lang/design.md @@ -0,0 +1,22 @@ + + + +## the vstack +new values can be pushed with PAW_CTRL_SPUSH. +and popped with PAW_CTRL_POP +values will be popped whenn the function returns. +these values can be asigned and read through paw_sp, PawStackVal.sp and PAW_VAL_SPOINT +a paw_sp is essentially just an int used to look up the value +paw_sp starts at 0 and then counts up (but due to 0 being the return value one could argue it actually starts at 1) + +## calls +a call esentially resets the vstack offset, meaning the new function starts at 0 +upon returning the result is pushed to the vstack +the previous vstack offset is pushed to the cstack + +the initial vstack layout of a function looks like this: +prev func | ret | args | func vars + ^ + | top, an asign instruction with an paw_sp of -number of args will set the return value + +after the call all function vars will be popped automatically diff --git a/src/lang/vstack.c b/src/lang/vstack.c new file mode 100644 index 0000000..285bf13 --- /dev/null +++ b/src/lang/vstack.c @@ -0,0 +1,50 @@ +#include "../log.h" +#include "ast.h" + +struct VStack *vstack_make(struct Mem *mem, size_t size) { + struct VStack *stack = mem_malloc(mem, sizeof(struct VStack)); + stack->left = mem_malloc(mem, size); + stack->right = stack->left + size; + stack->top = stack->right; + return stack; +} +void vstack_free(struct VStack *stack, struct Mem *mem) { + mem_free(mem, stack->left); + mem_free(mem, stack); +} + +void vstack_pop(struct VStack *stack) { + stack->top = stack->top + sizeof(struct PawStackVal); + if (stack->top > stack->right) { + meow("pop stack is %p:%p:%p", stack->left, stack->top, stack->right); + crash("uuuh am in cellar"); + } +} + +void vstack_push(struct VStack *stack, struct PawStackVal val) { + stack->top = stack->top - sizeof(void *); + if (stack->top < stack->left) { + crash("uuuh am in space"); + } + *(struct PawStackVal *)stack->top = val; +} + +struct PawStackVal vstack_poke(struct VStack *stack) { + return *(struct PawStackVal *)stack->top; +} + +struct PawStackVal vstack_poke_n(struct VStack *stack, int n) { + return *(((struct PawStackVal *)stack->top) - n); +} + +struct PawStackVal vstack_poke_n_after(struct VStack *stack, int n, + int offset) { + return *(((struct PawStackVal *)stack->right) - offset - n); +} +void vstack_set_n_after(struct VStack *stack, int n, int offset, + struct PawStackVal val) { + *(((struct PawStackVal *)stack->right) - offset - n) = val; +} +void vstack_reset_to_offset(struct VStack *stack, int offset) { + stack->top = (void *)(((struct PawStackVal *)stack->right) - offset); +}