diff --git a/main.c b/main.c index 870e41b..e65bda0 100644 --- a/main.c +++ b/main.c @@ -11,16 +11,27 @@ int main() { struct PawAST *ast = ast_make(); ast_insert_property(ast, "i", make_pawval_int(ast->mem, 0)); + ast_append_cfunc(ast, print); enum PawCtrl *body = make_pawctrl_seq(ast->mem); - /* 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); + + enum PawCtrl *truthy = make_pawctrl_seq(ast->mem); + pawseq_append(truthy, make_pawctrl_spush(ast->mem, PSV_INT(0))); + pawseq_append(truthy, make_pawctrl_asign(ast->mem, PSV_SP(0), + ast_get_property(ast, "i"))); + pawseq_append(truthy, make_pawctrl_ccall(ast->mem, 0)); + pawseq_append(truthy, make_pawctrl_spop(ast->mem)); + pawseq_append(body, + make_pawctrl_if( + ast->mem, + make_pawval_expr(ast->mem, ast_get_property(ast, "i"), + make_pawval_int(ast->mem, 20), op_equals), + truthy, make_pawctrl_seq(ast->mem))); pawseq_append( ast->prog, make_pawctrl_while(ast->mem, diff --git a/src/lang/ast.c b/src/lang/ast.c index df98a47..c3b2136 100644 --- a/src/lang/ast.c +++ b/src/lang/ast.c @@ -56,6 +56,9 @@ const char *print_valtype(enum PawVal type) { return "expr"; case PAW_VAL_CHAR: return "char"; + default: + meow("type %d", type); + return "unknown type"; } } @@ -73,6 +76,8 @@ const char *print_ctrltype(enum PawCtrl ctrl) { return "SPUSH"; case PAW_CTRL_SPOP: return "SPOP"; + case PAW_CTRL_IF: + return "IF"; } } @@ -284,6 +289,16 @@ enum PawCtrl *make_pawctrl_while(struct Mem *mem, enum PawVal *cond, i->cond = cond; return ctrl; } +enum PawCtrl *make_pawctrl_if(struct Mem *mem, enum PawVal *cond, + enum PawCtrl *truthy, enum PawCtrl *falsy) { + enum PawCtrl *ctrl; + ctrl_make(ctrl, struct PawIf, PAW_CTRL_IF); + struct PawIf *i = ctrl_get_data(ctrl); + i->cond = cond; + i->truthy = truthy; + i->falsy = falsy; + return ctrl; +} enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target, enum PawVal *val) { @@ -295,6 +310,14 @@ enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target, return ctrl; } +enum PawCtrl *make_pawctrl_ccall(struct Mem *mem, int index) { + enum PawCtrl *ctrl; + ctrl_make(ctrl, struct PawCCall, PAW_CTRL_CCALL); + struct PawCCall *i = ctrl_get_data(ctrl); + i->index = index; + return ctrl; +} + void pawseq_append(enum PawCtrl *seq, enum PawCtrl *ctrl) { struct PawSeq *seqval = ctrl_get_data(seq); dyn_array_append(&seqval->seq, ctrl); @@ -310,10 +333,16 @@ struct PawAST *ast_make() { ast->ping_func = ping_func; ast->prog = make_pawctrl_seq(ast->mem); dyn_array_create_inplace_mem(&ast->properties, ast->mem); + dyn_array_create_inplace_mem(&ast->cfuncs, ast->mem); return ast; } +void ast_append_cfunc(struct PawAST *ast, + void (*func)(struct VStack *stack, int offset)) { + dyn_array_append(&ast->cfuncs, (struct CFunc){func}); +} + enum PawVal *ast_get_property(struct PawAST *ast, char *name) { for (int i = 0; i < ast->properties.count; i++) { if (strcmp(ast->properties.items[i].name, name) == 0) { @@ -365,9 +394,39 @@ void stack_free(struct Stack *stack, struct Mem *mem) { mem_free(mem, stack); } +void print(struct VStack *stack, int offset) { + struct PawStackVal val = vstack_poke(stack); + switch (val.type) { + case PAW_VAL_FLOAT: + meow("%f", val.f); + break; + case PAW_VAL_INT: + meow("%i", val.i); + break; + case PAW_VAL_BOOL: + meow("%s", bool_to_string(val.b)); + break; + case PAW_VAL_CHAR: + meow("%c", val.c); + break; + case PAW_VAL_POINT: + meow("%p", val.p); + break; + case PAW_VAL_SPOINT: + meow("%d", val.sp); + break; + case PAW_VAL_EXPR: + meow("expr"); + break; + } +} + void ast_stack_push(struct Stack *stack, enum PawCtrl *ctrl) { switch (*ctrl) { case PAW_CTRL_SEQ: + case PAW_CTRL_IF: + case PAW_CTRL_CALL: + case PAW_CTRL_CCALL: stack_push(stack, NULL); stack_push(stack, ctrl); break; @@ -377,9 +436,6 @@ void ast_stack_push(struct Stack *stack, enum PawCtrl *ctrl) { case PAW_CTRL_SPOP: stack_push(stack, ctrl); break; - case PAW_CTRL_CALL: - stack_push(stack, NULL); - stack_push(stack, ctrl); } } @@ -451,6 +507,7 @@ void ast_exec(struct PawAST *ast) { struct PawCall *call = ctrl_get_data(ctrl); if (stack_poke2(stack) == NULL) { stack_set2(stack, (void *)(uint64_t)(offset)); + ast_stack_push(stack, call->body); } else { vstack_reset_to_offset(vstack, offset); offset = (uint64_t)stack_poke2(stack); @@ -458,6 +515,16 @@ void ast_exec(struct PawAST *ast) { stack_pop(stack); } break; + case PAW_CTRL_CCALL:; + LS("CALL"); + struct PawCCall *ccall = ctrl_get_data(ctrl); + stack_set2(stack, (void *)(uint64_t)(offset)); + ast->cfuncs.items[ccall->index].func(vstack, offset); + vstack_reset_to_offset(vstack, offset); + offset = (uint64_t)stack_poke2(stack); + stack_pop(stack); + stack_pop(stack); + break; case PAW_CTRL_WHILE:; LS("WHILE"); struct PawWhile *whle = ctrl_get_data(ctrl); @@ -475,15 +542,45 @@ void ast_exec(struct PawAST *ast) { stack_pop(stack); } break; + case PAW_CTRL_IF:; + LS("IF"); + if (stack_poke2(stack) != NULL) { + stack_pop(stack); + stack_pop(stack); + break; + } else { + stack_set2(stack, (void *)0x1); + } + struct PawIf *_if = ctrl_get_data(ctrl); + struct PawStackVal iret = + try_cast_stack(PAW_VAL_BOOL, ast_eval(ast, _if->cond)); + if (iret.type != PAW_VAL_BOOL) { + meow("unsuported: a %s in an if statement", print_valtype(ret.type)); + break; + } + if (iret.b) { + ast_stack_push(stack, _if->truthy); + } else { + ast_stack_push(stack, _if->falsy); + } + break; case PAW_CTRL_ASIGN:; LS("ASIGN"); struct PawAsign *asign = val_get_data(ctrl); struct PawStackVal val = ast_eval(ast, asign->rhs); if (asign->lhs.type == PAW_VAL_SPOINT) { + LS("lhs points to stack at %d after %d", asign->lhs.sp, offset); + LS("top of stack has type %s", + print_valtype((*(struct PawStackVal *)vstack->top).type)); + LS("right of stack has type %s", + print_valtype((*(struct PawStackVal *)vstack->right).type)); + LS("n of stack has type %s", + print_valtype(vstack_poke_n_after(vstack, 0, 0).type)); 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); + LS("lhs points to heap at %p", asign->lhs.p); + val = try_cast_stack(*(enum PawVal *)asign->lhs.p, val); } if (val.type == PAW_VAL_POINT && val.p == NULL) { meow("woopsie wrong type,,,,"); diff --git a/src/lang/ast.h b/src/lang/ast.h index a9818c7..0160454 100644 --- a/src/lang/ast.h +++ b/src/lang/ast.h @@ -48,10 +48,12 @@ enum PawVal { enum PawCtrl { PAW_CTRL_SEQ, PAW_CTRL_WHILE, + PAW_CTRL_IF, PAW_CTRL_ASIGN, PAW_CTRL_SPUSH, PAW_CTRL_SPOP, PAW_CTRL_CALL, + PAW_CTRL_CCALL, }; dyn_array_define(da_paw_ctrl, enum PawCtrl *); dyn_array_define(da_paw_val, enum PawVal *); @@ -60,13 +62,17 @@ struct PawProperty { char *name; enum PawVal *val; }; + dyn_array_define(da_paw_property, struct PawProperty); +dyn_array_define(da_cfunc, struct CFunc); + struct PawAST { struct Mem *mem; enum PawCtrl *prog; void *ping_func; struct da_paw_property properties; + struct da_cfunc cfuncs; }; struct PawExpr { @@ -100,6 +106,11 @@ struct PawWhile { enum PawVal *cond; enum PawCtrl *body; }; +struct PawIf { + enum PawVal *cond; + enum PawCtrl *truthy; + enum PawCtrl *falsy; +}; struct PawAsign { struct PawStackVal lhs; @@ -113,6 +124,34 @@ struct PawStackPush { struct PawCall { enum PawCtrl *body; }; +struct PawCCall { + int index; +}; + +struct VStack { + void *left; + void *right; + void *top; +}; + +void print(struct VStack *stack, int offset); + +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); + +struct CFunc { + void (*func)(struct VStack *stack, int offset); +}; struct PawStackVal op_equals(struct PawAST *ast, struct PawStackVal lhs, struct PawStackVal rhs); @@ -132,14 +171,19 @@ enum PawCtrl *make_pawctrl_seq(struct Mem *mem); 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_ccall(struct Mem *mem, int index); enum PawCtrl *make_pawctrl_while(struct Mem *mem, enum PawVal *cond, enum PawCtrl *body); +enum PawCtrl *make_pawctrl_if(struct Mem *mem, enum PawVal *cond, + enum PawCtrl *truthy, enum PawCtrl *falsy); enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target, enum PawVal *val); 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); +void ast_append_cfunc(struct PawAST *ast, + void (*func)(struct VStack *stack, int offset)); enum PawVal *ast_get_property(struct PawAST *ast, char *name); void ast_exec(struct PawAST *ast); @@ -156,21 +200,3 @@ 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/vstack.c b/src/lang/vstack.c index 285bf13..8fb54b7 100644 --- a/src/lang/vstack.c +++ b/src/lang/vstack.c @@ -22,9 +22,10 @@ void vstack_pop(struct VStack *stack) { } void vstack_push(struct VStack *stack, struct PawStackVal val) { - stack->top = stack->top - sizeof(void *); + stack->top = stack->top - sizeof(struct PawStackVal); if (stack->top < stack->left) { crash("uuuh am in space"); + meow("push stack is %p:%p:%p", stack->left, stack->top, stack->right); } *(struct PawStackVal *)stack->top = val; } @@ -34,17 +35,19 @@ struct PawStackVal vstack_poke(struct VStack *stack) { } struct PawStackVal vstack_poke_n(struct VStack *stack, int n) { - return *(((struct PawStackVal *)stack->top) - n); + return *(struct PawStackVal *)(stack->top - (n * sizeof(struct PawStackVal))); } struct PawStackVal vstack_poke_n_after(struct VStack *stack, int n, int offset) { - return *(((struct PawStackVal *)stack->right) - offset - n); + return *(struct PawStackVal *)(stack->right - + (offset + n + 1) * sizeof(struct PawStackVal)); } void vstack_set_n_after(struct VStack *stack, int n, int offset, struct PawStackVal val) { - *(((struct PawStackVal *)stack->right) - offset - n) = val; + *(struct PawStackVal *)(stack->right - + (offset + n + 1) * sizeof(struct PawStackVal)) = val; } void vstack_reset_to_offset(struct VStack *stack, int offset) { - stack->top = (void *)(((struct PawStackVal *)stack->right) - offset); + stack->top = stack->right - (offset + 1) * sizeof(struct PawStackVal); } diff --git a/src/log.c b/src/log.c index 99d689e..4531c18 100644 --- a/src/log.c +++ b/src/log.c @@ -1,6 +1,7 @@ +#include "log.h" + #include #include -#include #include #include @@ -36,3 +37,11 @@ void print_backtrace() { full_write(STDERR_FILENO, end, strlen(end)); free(bt_syms); } + +char *bool_to_string(bool b) { + if (b) { + return "true"; + } else { + return "false"; + } +} diff --git a/src/log.h b/src/log.h index 414391e..702aaa7 100644 --- a/src/log.h +++ b/src/log.h @@ -1,8 +1,10 @@ #ifndef INCLUDE_WAYLANDCLIENT_LOG_H_ #define INCLUDE_WAYLANDCLIENT_LOG_H_ +#include #include #include + #define meow(fmt, ...) \ fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define crash(fmt, ...) \ @@ -10,5 +12,6 @@ *(int *)0 = 0; void print_backtrace(); +char *bool_to_string(bool b); #endif // INCLUDE_WAYLANDCLIENT_LOG_H_