calls! not quit yet~

This commit is contained in:
qwertzuiopy 2025-03-13 22:08:53 +01:00
parent 5f36739c9c
commit b532f44d28
6 changed files with 252 additions and 87 deletions

View file

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

14
main.c
View file

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

View file

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

View file

@ -1,4 +1,5 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@ -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);

22
src/lang/design.md Normal file
View file

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

50
src/lang/vstack.c Normal file
View file

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