diff --git a/Makefile b/Makefile index 89bb4cc..75ad604 100644 --- a/Makefile +++ b/Makefile @@ -7,13 +7,12 @@ LDFLAGS+=-lm -lglfw -rdynamic FLAGS=-g $(CFLAGS) $(LDFLAGS) $(LIBS) -S=main.c -S+=comp.c wayland.c glfw.c +S=comp.c wayland.c glfw.c S+=vulkan.c kitty.c S+=string.c 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 lang/vstack.c lang/parser.c lang/ast_disc.c lang/functable.c +S+=lang/ast.c lang/vstack.c lang/ast_disc.c lang/functable.c lang/glue.c SO=$(addprefix build/,$(S:.c=.o)) SC=$(addprefix src/,$(S)) @@ -34,7 +33,10 @@ build/%.o: src/%.c gcc -c $(FLAGS) -o $@ $< main: $(SO) - gcc $(FLAGS) -o $@ $(SO) + gcc $(FLAGS) -o $@ main.c $(SO) + +parser: $(SO) + gcc $(FLAGS) -o $@ src/lang/parser.c $(SO) .DEFAULT_GOAL=main .PHONY: clean diff --git a/main.c b/main.c index a923d45..def2e65 100644 --- a/main.c +++ b/main.c @@ -10,45 +10,11 @@ #include int main() { - - struct PawAST *t = parse("./src/lang/test.paw"); - return 0; - - 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_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), - paw_get_op_index("+")))); - - 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, paw_get_cfunc_index("io::print"))); - 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), - paw_get_op_index("==")), - truthy, make_pawctrl_seq(ast->mem))); - pawseq_append( - ast->prog, - make_pawctrl_while(ast->mem, - make_pawval_expr(ast->mem, ast_get_property(ast, "i"), - make_pawval_int(ast->mem, 100), - paw_get_op_index("!=")), - body)); - ast_write(ast, "test"); - ast = ast_read("test"); - ast_exec(ast); - return 0; + /* struct PawAST *comp_ast = ast_read("out.paw.bin"); */ + /* ast_call(comp_ast, "ready"); */ + /* ast_call(comp_ast, "tick"); */ + /* ast_call(comp_ast, "free"); */ + /* return 0; */ struct Vk *vk; cat_Comp *state = cat_comp_init("meooow", 500, 500, &vk); diff --git a/src/dynarray.h b/src/dynarray.h index b3c8645..53d8586 100644 --- a/src/dynarray.h +++ b/src/dynarray.h @@ -26,6 +26,14 @@ (array)->items[(array)->count++] = (item); \ } while (0) +#define dyn_array_insert(array, index, item) \ + do { \ + dyn_array_append(array, item); \ + memcpy(&(array)->items[(index) + 1], &(array)->items[(index)], \ + sizeof(*(array)->items) * ((array)->count - index)); \ + (array)->items[(index)] = (item); \ + } while (0) + #define dyn_array_remove(array, index) \ do { \ (array)->items[(index)] = (array)->items[(array)->count - 1]; \ diff --git a/src/lang/ast.c b/src/lang/ast.c index 71ca961..1308241 100644 --- a/src/lang/ast.c +++ b/src/lang/ast.c @@ -62,16 +62,49 @@ const char *print_valtype(enum PawVal type) { } } +// returned string has to be freed +char *print_stackval(struct PawStackVal val) { + char *res = malloc(64); + switch (val.type) { + case PAW_VAL_FLOAT: + sprintf(res, "%f", val.f); + break; + case PAW_VAL_INT: + sprintf(res, "%d", val.i); + break; + case PAW_VAL_BOOL: + strcpy(res, bool_to_string(val.b)); + break; + case PAW_VAL_CHAR: + sprintf(res, "%c", val.c); + break; + case PAW_VAL_POINT: + sprintf(res, "%p", val.p); + break; + case PAW_VAL_SPOINT: + sprintf(res, "stackp %d", val.sp); + break; + case PAW_VAL_EXPR: + crash("unreachable"); + break; + } + return res; +} + const char *print_ctrltype(enum PawCtrl ctrl) { switch (ctrl) { case PAW_CTRL_SEQ: return "seq"; - case PAW_CTRL_WHILE: - return "while"; + case PAW_CTRL_LOOP: + return "loop"; + case PAW_CTRL_BREAK: + return "break"; case PAW_CTRL_ASIGN: return "asign"; case PAW_CTRL_CALL: return "call"; + case PAW_CTRL_CCALL: + return "ccall"; case PAW_CTRL_SPUSH: return "SPUSH"; case PAW_CTRL_SPOP: @@ -145,19 +178,19 @@ struct PawStackVal try_cast(enum PawVal target, enum PawVal *val) { return PSV_NULL; } -enum PawVal *ast_stack_to_heap(struct PawAST *ast, struct PawStackVal val) { +enum PawVal *ast_stack_to_heap(struct Mem *mem, struct PawStackVal val) { switch (val.type) { case PAW_VAL_FLOAT: - return make_pawval_float(ast->mem, val.f); + return make_pawval_float(mem, val.f); case PAW_VAL_INT: - return make_pawval_int(ast->mem, val.i); + return make_pawval_int(mem, val.i); case PAW_VAL_BOOL: - return make_pawval_bool(ast->mem, val.b); + return make_pawval_bool(mem, val.b); case PAW_VAL_CHAR: crash("TODO"); // return make_pawval_char(ast->mem, val.c); case PAW_VAL_POINT: - return make_pawval_point(ast->mem, val.p); + return make_pawval_point(mem, val.p); case PAW_VAL_SPOINT: crash("TODO"); // return make_pawval_spoint(ast->mem, val.sp); @@ -291,24 +324,27 @@ enum PawCtrl *make_pawctrl_call(struct Mem *mem, enum PawCtrl *body) { } enum PawCtrl *make_pawctrl_spush(struct Mem *mem, struct PawStackVal val) { enum PawCtrl *ctrl; - ctrl_make(ctrl, struct PawCall, PAW_CTRL_SPUSH); + ctrl_make(ctrl, struct PawStackPush, 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); + ctrl_make(ctrl, struct PawEmpty, PAW_CTRL_SPOP); + return ctrl; +} +enum PawCtrl *make_pawctrl_break(struct Mem *mem) { + enum PawCtrl *ctrl; + ctrl_make(ctrl, struct PawEmpty, PAW_CTRL_BREAK); return ctrl; } -enum PawCtrl *make_pawctrl_while(struct Mem *mem, enum PawVal *cond, - enum PawCtrl *body) { +enum PawCtrl *make_pawctrl_loop(struct Mem *mem, enum PawCtrl *body) { enum PawCtrl *ctrl; - ctrl_make(ctrl, struct PawWhile, PAW_CTRL_WHILE); - struct PawWhile *i = ctrl_get_data(ctrl); + ctrl_make(ctrl, struct PawLoop, PAW_CTRL_LOOP); + struct PawLoop *i = ctrl_get_data(ctrl); i->body = body; - i->cond = cond; return ctrl; } enum PawCtrl *make_pawctrl_if(struct Mem *mem, enum PawVal *cond, @@ -344,6 +380,10 @@ void pawseq_append(enum PawCtrl *seq, enum PawCtrl *ctrl) { struct PawSeq *seqval = ctrl_get_data(seq); dyn_array_append(&seqval->seq, ctrl); } +void pawseq_insert(enum PawCtrl *seq, int index, enum PawCtrl *ctrl) { + struct PawSeq *seqval = ctrl_get_data(seq); + dyn_array_insert(&seqval->seq, index, ctrl); +} struct PawAST *ast_make() { struct Mem *mem = make_mem(8192); @@ -355,30 +395,15 @@ struct PawAST *ast_make() { memcpy(test, t, strlen(t) + 1); ast->mem = mem; - 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); - dyn_array_create_inplace_mem(&ast->funcs, ast->mem); + dyn_array_create_inplace_mem(&ast->methods, 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}); -} - -void ast_register_func(struct PawAST *ast, char *name) { - dyn_array_append(&ast->funcs, ((struct PawFunc){.body = NULL, .name = name})); -} -void ast_set_func_body(struct PawAST *ast, char *name, enum PawCtrl *body) { - for (int i = 0; i < ast->funcs.count; i++) { - if (strcmp(name, ast->funcs.items[i].name) == 0) { - ast->funcs.items[i].body = body; - return; - } - } - meow("function %s could not be found", name); +void ast_register_method(struct PawAST *ast, char *name, enum PawCtrl *body) { + dyn_array_append(&ast->methods, + ((struct PawMethod){.body = body, .name = name})); } enum PawVal *ast_get_property(struct PawAST *ast, char *name) { @@ -433,7 +458,8 @@ void stack_free(struct Stack *stack, struct Mem *mem) { } void print(struct VStack *stack, int offset) { - struct PawStackVal val = vstack_poke(stack); + /* struct PawStackVal val = vstack_poke(stack); */ + struct PawStackVal val = vstack_poke_n_after(stack, 0, offset); switch (val.type) { case PAW_VAL_FLOAT: meow("%f", val.f); @@ -451,6 +477,7 @@ void print(struct VStack *stack, int offset) { meow("%p", val.p); break; case PAW_VAL_SPOINT: + print(stack, val.sp); meow("%d", val.sp); break; case PAW_VAL_EXPR: @@ -469,37 +496,63 @@ void ast_stack_push(struct Stack *stack, enum PawCtrl *ctrl) { stack_push(stack, ctrl); break; case PAW_CTRL_ASIGN: - case PAW_CTRL_WHILE: + case PAW_CTRL_LOOP: case PAW_CTRL_SPUSH: case PAW_CTRL_SPOP: + case PAW_CTRL_BREAK: stack_push(stack, ctrl); break; } } +void ast_stack_pop(struct Stack *stack) { + enum PawCtrl *ctrl = stack_poke(stack); + switch (*ctrl) { + case PAW_CTRL_SEQ: + case PAW_CTRL_IF: + case PAW_CTRL_CALL: + case PAW_CTRL_CCALL: + stack_pop(stack); + stack_pop(stack); + break; + case PAW_CTRL_ASIGN: + case PAW_CTRL_LOOP: + case PAW_CTRL_SPUSH: + case PAW_CTRL_SPOP: + case PAW_CTRL_BREAK: + stack_pop(stack); + break; + } +} -// will no ownership of val is transferred and val will not be touched, -// the caller takes ownership of the returned value which is always a newly -// allocated value -struct PawStackVal ast_eval(struct PawAST *ast, enum PawVal *val) { +// no ownership of val is transferred and val will not be touched, +struct PawStackVal ast_eval(struct PawAST *ast, struct VStack *vstack, + int offset, enum PawVal *val) { LS("evaling a %s", print_valtype(*val)); switch (*val) { case PAW_VAL_FLOAT: return PSV_FLOAT(*(float *)val_get_data(val)); case PAW_VAL_INT: + LS("to %d", *(int *)val_get_data(val)); return PSV_INT(*(int *)val_get_data(val)); case PAW_VAL_BOOL: return PSV_BOOL(*(float *)val_get_data(val)); case PAW_VAL_POINT: return PSV_P(*(paw_p *)val_get_data(val)); + case PAW_VAL_SPOINT: + LS("to type %s", + print_valtype( + vstack_poke_n_after(vstack, *(int *)val_get_data(val), offset) + .type)); + return vstack_poke_n_after(vstack, *(int *)val_get_data(val), offset); 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 %d", expr->op); + LS("calling op %s", paw_get_op_sym(expr->op)); LS("lhs is %p rhs is %p", expr->lhs, expr->rhs); - struct PawStackVal lhs = ast_eval(ast, expr->lhs); - struct PawStackVal rhs = ast_eval(ast, expr->rhs); - struct PawStackVal ret = ((struct PawStackVal(*)( + struct PawStackVal lhs = ast_eval(ast, vstack, offset, expr->lhs); + struct PawStackVal rhs = ast_eval(ast, vstack, offset, expr->rhs); + struct PawStackVal ret = ((struct PawStackVal (*)( struct PawStackVal, struct PawStackVal))paw_get_op(expr->op))(lhs, rhs); return ret; break; @@ -520,13 +573,21 @@ void unwind_stack(struct Stack *stack) { crash("unwound stack, exiting"); } -void ast_exec(struct PawAST *ast) { - meow("allocing stack"); +void ast_call(struct PawAST *ast, char *method, struct Scene *scene) { + enum PawCtrl *entry; + for (int i = 0; i < ast->methods.count; i++) { + if (strcmp(ast->methods.items[i].name, method) == 0) { + entry = ast->methods.items[i].body; + break; + } + } + struct Stack *stack = stack_make(ast->mem, 2048); struct VStack *vstack = vstack_make(ast->mem, 2048); + vstack->scene = scene; int offset = 0; - ast_stack_push(stack, ast->prog); - meow("starting exec"); + ast_stack_push(stack, entry); + meow("starting exec of %s", method); #define NO_LIMIT_ITS #ifndef NO_LIMIT_ITS int i = 0; @@ -569,30 +630,26 @@ void ast_exec(struct PawAST *ast) { LS("CALL"); struct PawCCall *ccall = ctrl_get_data(ctrl); stack_set2(stack, (void *)(uint64_t)(offset)); - ast->cfuncs.items[ccall->index].func(vstack, offset); + ((void (*)(struct VStack *, int))paw_get_cfunc(ccall->index))(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); - struct PawStackVal ret = - try_cast_stack(PAW_VAL_BOOL, ast_eval(ast, whle->cond)); - if (ret.type != PAW_VAL_BOOL) { - meow("unsuported: a %s in a while loop condition", - print_valtype(ret.type)); - stack_pop(stack); - break; - } - if ((bool)ret.b) { - ast_stack_push(stack, whle->body); - } else { - stack_pop(stack); - } + case PAW_CTRL_LOOP: + LS("LOOP"); + struct PawLoop *loop = ctrl_get_data(ctrl); + ast_stack_push(stack, loop->body); break; - case PAW_CTRL_IF:; + case PAW_CTRL_BREAK: + LS("BREAK"); + while (*(enum PawCtrl *)stack_poke(stack) != PAW_CTRL_LOOP) { + ast_stack_pop(stack); + } + ast_stack_pop(stack); + break; + case PAW_CTRL_IF: LS("IF"); if (stack_poke2(stack) != NULL) { stack_pop(stack); @@ -602,22 +659,26 @@ void ast_exec(struct PawAST *ast) { 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)); + struct PawStackVal iret = try_cast_stack( + PAW_VAL_BOOL, ast_eval(ast, vstack, offset, _if->cond)); if (iret.type != PAW_VAL_BOOL) { - meow("unsuported: a %s in an if statement", print_valtype(ret.type)); + meow("unsuported: a %s in an if statement", print_valtype(iret.type)); break; } if (iret.b) { - ast_stack_push(stack, _if->truthy); + if (_if->truthy != NULL) { + ast_stack_push(stack, _if->truthy); + } } else { - ast_stack_push(stack, _if->falsy); + if (_if->falsy != NULL) { + 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); + struct PawStackVal val = ast_eval(ast, vstack, offset, 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", @@ -674,6 +735,9 @@ void ast_exec(struct PawAST *ast) { case PAW_CTRL_SPUSH: LS("SPUSH"); struct PawStackPush *push = val_get_data(ctrl); + char *s = print_stackval(push->v); + LS("%s", s); + free(s); vstack_push(vstack, push->v); stack_pop(stack); break; diff --git a/src/lang/ast.h b/src/lang/ast.h index 69f1abc..dc4b1a7 100644 --- a/src/lang/ast.h +++ b/src/lang/ast.h @@ -7,6 +7,7 @@ #include "../allocator.h" #include "../dynarray.h" +#include "../object.h" #define paw_p void * #define paw_sp int @@ -57,7 +58,8 @@ enum ArgType { enum PawCtrl { PAW_CTRL_SEQ, - PAW_CTRL_WHILE, + PAW_CTRL_LOOP, + PAW_CTRL_BREAK, PAW_CTRL_IF, PAW_CTRL_ASIGN, PAW_CTRL_SPUSH, @@ -75,15 +77,12 @@ struct PawProperty { dyn_array_define(da_paw_property, struct PawProperty); -dyn_array_define(da_cfunc, struct CFunc); -dyn_array_define(da_func, struct PawFunc); +dyn_array_define(da_method, struct PawMethod); struct PawAST { struct Mem *mem; - enum PawCtrl *prog; struct da_paw_property properties; - struct da_cfunc cfuncs; - struct da_func funcs; + struct da_method methods; }; struct PawExpr { @@ -107,13 +106,16 @@ struct PawStackVal { // the return value does not have to be freed const char *print_valtype(enum PawVal type); +// returned string has to be freed +char *print_stackval(struct PawStackVal val); + +struct PawEmpty {}; struct PawSeq { struct da_paw_ctrl seq; }; -struct PawWhile { - enum PawVal *cond; +struct PawLoop { enum PawCtrl *body; }; struct PawIf { @@ -131,7 +133,7 @@ struct PawStackPush { struct PawStackVal v; }; -struct PawFunc { +struct PawMethod { enum PawCtrl *body; char *name; }; @@ -144,6 +146,7 @@ struct PawCCall { }; struct VStack { + struct Scene *scene; void *left; void *right; void *top; @@ -185,20 +188,22 @@ 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_loop(struct Mem *mem, enum PawCtrl *body); +enum PawCtrl *make_pawctrl_break(struct Mem *mem); 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); -enum PawVal *ast_stack_to_heap(struct PawAST *ast, struct PawStackVal val); +void pawseq_insert(enum PawCtrl *seq, int index, enum PawCtrl *ctrl); +enum PawVal *ast_stack_to_heap(struct Mem *mem, struct PawStackVal val); struct PawAST *ast_make(); void ast_insert_property(struct PawAST *ast, char *name, enum PawVal *val); +void ast_register_method(struct PawAST *ast, char *name, enum PawCtrl *body); 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); +void ast_call(struct PawAST *ast, char *method, struct Scene *scene); #define val_get_data($val) ((void *)$val + sizeof(enum PawVal)) #define val_make($ret, $type, $TYPE_ENUM) \ diff --git a/src/lang/ast_disc.c b/src/lang/ast_disc.c index 21d3a6b..7a0d0a5 100644 --- a/src/lang/ast_disc.c +++ b/src/lang/ast_disc.c @@ -25,7 +25,6 @@ bool apply_before = false; void ast_write(struct PawAST *ast, char *path) { int size = ast->mem->mem_size + sizeof(struct Mem); char *data = (char *)ast->mem; - meow("size is %d data %p", size, data); region_start = ast->mem; region_end = ast->mem + ast->mem->mem_size + sizeof(struct Mem); offset = -(long)region_start; @@ -42,27 +41,21 @@ void ast_write(struct PawAST *ast, char *path) { } } AO2(ast->mem); - apply_offset_ctrl(ast->prog); - AO2(ast->prog); for (int i = 0; i < ast->properties.count; i++) { AO2(ast->properties.items[i].name); apply_offset_val(ast->properties.items[i].val); AO2(ast->properties.items[i].val); - meow("a property is now at %p", ast->properties.items[i].val); } AO2(ast->properties.items); AO2(ast->properties.mem); - AO2(ast->cfuncs.items); - AO2(ast->cfuncs.mem); - - for (int i = 0; i < ast->funcs.count; i++) { - AO2(ast->funcs.items[i].name); - apply_offset_ctrl(ast->funcs.items[i].body); - AO2(ast->funcs.items[i].body); + for (int i = 0; i < ast->methods.count; i++) { + AO2(ast->methods.items[i].name); + apply_offset_ctrl(ast->methods.items[i].body); + AO2(ast->methods.items[i].body); } - AO2(ast->funcs.items); - AO2(ast->funcs.mem); + AO2(ast->methods.items); + AO2(ast->methods.mem); write_binary_file(path, data, size); } @@ -73,13 +66,10 @@ struct PawAST *ast_read(char *path) { region_start = 0x0; int size; char *data = (char *)read_binary_file(path, &size); - meow("size is %d data %p", size, data); offset = (long)data; region_end = (void *)(long)size; struct Mem *mem = (struct Mem *)data; - meow("offset is %ld", offset); - apply_before = true; for (int i = 0; i < MAX_ALLOCS; i++) { if (mem->allocs[i].start == NULL && mem->allocs[i].size == 0 && @@ -90,34 +80,24 @@ struct PawAST *ast_read(char *path) { AO1(mem->allocs[i].next); } } - meow("mem before %p", mem->mem); AO1(mem->mem); - meow("mem after %p", mem->mem); AO1(mem->alloc); struct PawAST *ast = mem->allocs[2].start; AO1(ast->mem); - AO1(ast->prog); - apply_offset_ctrl(ast->prog); - meow("ao1 %p", ast->prog); AO1(ast->properties.items); AO1(ast->properties.mem); for (int i = 0; i < ast->properties.count; i++) { - meow("a property was at %p", ast->properties.items[i].val); AO1(ast->properties.items[i].name); AO1(ast->properties.items[i].val); apply_offset_val(ast->properties.items[i].val); - meow("a property is now at %p", ast->properties.items[i].val); } - AO1(ast->cfuncs.items); - AO1(ast->cfuncs.mem); - - AO1(ast->funcs.items); - AO1(ast->funcs.mem); - for (int i = 0; i < ast->funcs.count; i++) { - AO1(ast->funcs.items[i].name); - AO1(ast->funcs.items[i].body); - apply_offset_ctrl(ast->funcs.items[i].body); + AO1(ast->methods.items); + AO1(ast->methods.mem); + for (int i = 0; i < ast->methods.count; i++) { + AO1(ast->methods.items[i].name); + AO1(ast->methods.items[i].body); + apply_offset_ctrl(ast->methods.items[i].body); } return ast; @@ -137,23 +117,24 @@ void apply_offset_ctrl(enum PawCtrl *ctrl) { AO2(seq->seq.items); AO2(seq->seq.mem); break; - case PAW_CTRL_WHILE:; - struct PawWhile *_while = ctrl_get_data(ctrl); - AO1(_while->body); - apply_offset_ctrl(_while->body); - AO2(_while->body); - AO1(_while->cond); - apply_offset_val(_while->cond); - AO2(_while->cond); + case PAW_CTRL_LOOP:; + struct PawLoop *_loop = ctrl_get_data(ctrl); + AO1(_loop->body); + apply_offset_ctrl(_loop->body); + AO2(_loop->body); break; case PAW_CTRL_IF:; struct PawIf *_if = ctrl_get_data(ctrl); - AO1(_if->truthy); - AO1(_if->falsy); - apply_offset_ctrl(_if->truthy); - apply_offset_ctrl(_if->falsy); - AO2(_if->truthy); - AO2(_if->falsy); + if (_if->truthy != NULL) { + AO1(_if->truthy); + apply_offset_ctrl(_if->truthy); + AO2(_if->truthy); + } + if (_if->falsy != NULL) { + AO1(_if->falsy); + apply_offset_ctrl(_if->falsy); + AO2(_if->falsy); + } AO1(_if->cond); apply_offset_val(_if->cond); AO2(_if->cond); @@ -177,6 +158,8 @@ void apply_offset_ctrl(enum PawCtrl *ctrl) { break; case PAW_CTRL_CCALL: break; + case PAW_CTRL_BREAK: + break; } } struct PawStackVal apply_offset_stackval(struct PawStackVal val) { @@ -221,7 +204,6 @@ void apply_offset_val(enum PawVal *val) { apply_offset_val(expr->rhs); AO2(expr->lhs); AO2(expr->rhs); - meow("applying offset to an expr"); break; } } diff --git a/src/lang/functable.c b/src/lang/functable.c index 82873c9..2b37c32 100644 --- a/src/lang/functable.c +++ b/src/lang/functable.c @@ -1,10 +1,12 @@ #include "../log.h" #include "../util.h" #include "ast.h" +#include "glue.h" struct FuncDef { void (*func)(struct VStack *, int); const char *name; + const char *ret; // enum ArgType *args; }; struct OpDef { @@ -15,7 +17,9 @@ struct OpDef { }; struct FuncDef PAW_CFUNCS[] = { - {print, "io::print"}, + {print, "io::print", NULL}, + {pawlang_kitty_make, "kitty::make", "Kitty"}, + {print, "kitty::free", NULL}, }; // important to unimportant!!! @@ -24,7 +28,7 @@ struct OpDef PAW_OPS[] = { {NULL, "/", 2}, {op_add, "+", 1}, {NULL, "-", 1}, }; -uint32_t paw_get_ops_size() { return sizeof(PAW_OPS); } +uint32_t paw_get_ops_size() { return sizeof(PAW_OPS) / sizeof(PAW_OPS[0]); } const char *paw_get_op_sym(uint32_t index) { return PAW_OPS[index].sym; } int paw_get_op_importance(uint32_t index) { return PAW_OPS[index].importance; } diff --git a/src/lang/glue.c b/src/lang/glue.c new file mode 100644 index 0000000..99a573e --- /dev/null +++ b/src/lang/glue.c @@ -0,0 +1,12 @@ +#include "../kitty.h" +#include "ast.h" + +void pawlang_kitty_make(struct VStack *stack, int offset) { + void *kitty = kitty_make(stack->scene->mem); + vstack_push(stack, PSV_P(kitty)); + return; +} + +void pawlang_kitty_free(struct VStack *stack, int offset) { + free_kitty(stack->scene->vk, vstack_poke_n(stack, offset).p); +} diff --git a/src/lang/glue.h b/src/lang/glue.h new file mode 100644 index 0000000..64e52c0 --- /dev/null +++ b/src/lang/glue.h @@ -0,0 +1,9 @@ +#ifndef INCLUDE_LANG_GLUE_H_ +#define INCLUDE_LANG_GLUE_H_ + +#include "ast.h" + +void pawlang_kitty_make(struct VStack *stack, int offset); +void pawlang_kitty_free(struct VStack *stack, int offset); + +#endif // INCLUDE_LANG_GLUE_H_ diff --git a/src/lang/parser.c b/src/lang/parser.c index 992f251..9ae98b1 100644 --- a/src/lang/parser.c +++ b/src/lang/parser.c @@ -4,37 +4,101 @@ #include "../string.h" #include "../util.h" #include "ast.h" +#include "ast_disc.h" #include #include "parser.h" -struct PawStackVal parse_stack_val(char *start) { +int main(int argc, char *argv[]) { + struct PawAST *ast = parse(argv[1]); + ast_write(ast, argv[2]); + meow("success!"); + return 0; +} + +// val has to be NULL terminated!!! +bool is_stackval(char *val) { + val = trim_start(val); + meow("'%s'", val); + char *tmp = val; + while (*tmp != 0x0) { + if (!is_char(*tmp)) { + break; + } + tmp++; + } + if (*tmp == 0x0) { + return true; + } + tmp = val; + while (*tmp != 0x0) { + if (!is_digid(*tmp) && *tmp != '.') { + break; + } + tmp++; + } + if (*tmp == 0x0) { + return true; + } + return false; +} + +struct PawStackVal parse_stack_val(char *start, struct StringTable *vars, + int offset) { start = trim_start(start); if (start_matches(start, "true")) { + meow("parsed true"); return PSV_BOOL(true); } if (start_matches(start, "false")) { + meow("parsed false"); return PSV_BOOL(false); } if (start_matches(start, "null")) { return PSV_NULL; } - char *end = start; + if (is_digid(*start)) { + char *end = start; + while (is_digid(*end) || *end == '.') { + end++; + } - while (is_digid(*end) || *end == '.') { - end++; - } - - if (includes_between(start, end, '.')) { - return PSV_FLOAT(strtof(start, NULL)); + if (includes_between(start, end, '.')) { + meow("parsed %f", strtof(start, NULL)); + return PSV_FLOAT(strtof(start, NULL)); + } else { + meow("parsed %ld", strtol(start, NULL, 10)); + return PSV_INT(strtol(start, NULL, 10)); + } } else { - return PSV_INT(strtol(start, NULL, 10)); + char *end = start; + while (is_char(*end)) { + end++; + } + char *name = strdup_reg(start, end); + int i = st_get_index(vars, name) + offset; + meow("got stackval %d aka %s", i, name); + free(name); + return PSV_SP(i); } } -enum PawVal *parse_val(int stack_offset, struct StringTable *vars, - struct Mem *tmp, struct Mem *pem, char *start, - char *end) { +struct PawParseVal combine_val_ctrls(struct PawParseVal base, + struct PawParseVal additions) { + for (int i = 0; i < additions.pre.count; i++) { + dyn_array_append(&base.pre, additions.pre.items[i]); + } + base.num_pops += additions.num_pops; + return base; +} + +struct PawParseVal parse_val(int offset, struct StringTable *vars, + struct Mem *tmp, struct Mem *pem, char *start, + char *end) { + struct PawParseVal val = {0}; + dyn_array_create_inplace_mem(&val.pre, tmp); + + meow("parsing a val"); start = trim_start(start); end = trim_end(end); @@ -47,14 +111,14 @@ enum PawVal *parse_val(int stack_offset, struct StringTable *vars, // as * before + in functable it will choose to split on + first, meaning // a+b*c => (a)+(b*c) // also do a + b - c => (a + b) - c - while (opstart < end) { + while (opstart <= end) { if (*opstart == '(') { opstart = skip_brackets(opstart, '(', ')'); continue; } for (int i = 0; i < paw_get_ops_size(); i++) { if (start_matches(opstart, (char *)paw_get_op_sym(i))) { - if (paw_get_op_importance(i) < op_rating) { + if (paw_get_op_importance(i) > op_rating) { continue; } op_rating = paw_get_op_importance(i); @@ -66,22 +130,24 @@ enum PawVal *parse_val(int stack_offset, struct StringTable *vars, } if (op != NULL) { - enum PawVal *lhs = - parse_val(stack_offset, vars, tmp, pem, start, opstart - 1); - enum PawVal *rhs = - parse_val(stack_offset, vars, tmp, pem, - opstart + strlen(paw_get_op_sym(op_index)), end); - return make_pawval_expr(pem, lhs, rhs, op_index); + meow("got an op %s", paw_get_op_sym(op_index)); + struct PawParseVal lhs = parse_val(offset, vars, tmp, pem, start, op - 1); + struct PawParseVal rhs = parse_val( + offset, vars, tmp, pem, op + strlen(paw_get_op_sym(op_index)), end); + val.res = make_pawval_expr(pem, lhs.res, rhs.res, op_index); + val = combine_val_ctrls(val, lhs); + val = combine_val_ctrls(val, rhs); } else { - enum PawVal *res; + meow("no op"); // expected: var, brackets or function if (start_matches(start, "(")) { + meow("brackets"); char *in_end = skip_brackets(start, '(', ')'); - res = parse_val(stack_offset, vars, tmp, pem, start + 1, in_end); + val = parse_val(offset, vars, tmp, pem, start + 1, in_end); start = in_end; } else { char *tmpc = start; - while (tmpc < end && is_char(*tmpc)) { + while (tmpc < end && (is_char(*tmpc) || *tmpc == ':')) { tmpc++; } tmpc = trim_start(tmpc); @@ -89,52 +155,188 @@ enum PawVal *parse_val(int stack_offset, struct StringTable *vars, // TODO, call } else { char *name = mem_strdup_reg(start, end, tmp); - return make_pawval_spoint(pem, stack_offset + st_get_index(vars, name)); + if (st_has_key(vars, name)) { + meow("got var %s at %d", name, st_get_index(vars, name) + offset); + val.res = make_pawval_spoint(pem, offset + st_get_index(vars, name)); + } else { + meow("got stackval"); + val.res = ast_stack_to_heap(pem, parse_stack_val(name, vars, offset)); + } } } - start = trim_start(start); - if (start == end) { - return res; - } + /* start = trim_start(start); */ + /* if (start != end) { */ + /* meow("%s", start); */ + /* meow("%s", end); */ + /* crash("woopsie"); */ + /* } */ } + return val; } -enum PawCtrl *parse_block(struct Mem *tmp, struct Mem *pem, +enum PawCtrl *parse_block(struct Mem *tmp, struct Mem *pem, int offset, struct StringTable *vars, char *start) { + meow("parsing a block"); enum PawCtrl *body = make_pawctrl_seq(pem); + int num_pops = 0; start = trim_start(start); + if (*start == '{') { + start++; + start = trim_start(start); + } while (!start_matches(start, "}")) { + /* meow("----"); */ + /* meow("%s", start); */ + /* meow("----"); */ if (start_matches(start, "while")) { + meow("got a while"); start = skip_after_char(start, ' '); char *end = skip_to_char(start, '{') - 1; - enum PawVal *cond = parse_val(0, vars, tmp, pem, start, end); + struct PawParseVal cond = parse_val(0, vars, tmp, pem, start, end); enum PawCtrl *wbody = - parse_block(tmp, pem, vars, skip_after_char(start, '{')); - enum PawCtrl *w = make_pawctrl_while(pem, cond, wbody); - pawseq_append(body, w); + parse_block(tmp, pem, offset, vars, skip_after_char(start, '{')); + enum PawCtrl *truthy = make_pawctrl_seq(pem); + enum PawCtrl *falsy = make_pawctrl_seq(pem); + for (int i = 0; i < cond.pre.count; i++) { + pawseq_append(wbody, cond.pre.items[i]); + pawseq_append(body, cond.pre.items[i]); + } + for (int i = 0; i < cond.num_pops; i++) { + pawseq_append(truthy, make_pawctrl_spop(pem)); + pawseq_append(falsy, make_pawctrl_spop(pem)); + st_remove(vars, st_get_nth_key(vars, st_get_size(vars) - 1)); + } + pawseq_append(falsy, make_pawctrl_break(pem)); + pawseq_insert(wbody, 0, make_pawctrl_if(pem, cond.res, NULL, wbody)); + pawseq_append(body, make_pawctrl_loop(pem, wbody)); start = skip_brackets(start, '{', '}'); start = trim_start(start); continue; } if (start_matches(start, "if")) { + meow("got an if"); start = skip_after_char(start, ' '); char *end = skip_to_char(start, '{') - 1; - enum PawVal *cond = parse_val(0, vars, tmp, pem, start, end); + struct PawParseVal cond = parse_val(0, vars, tmp, pem, start, end); enum PawCtrl *truthy = - parse_block(tmp, pem, vars, skip_after_char(start, '{')); + parse_block(tmp, pem, offset, vars, skip_after_char(start, '{')); enum PawCtrl *falsy = NULL; start = skip_brackets(start, '{', '}'); + start = trim_start(start); if (start_matches(start, "else")) { start = skip_after_char(start, '{'); - falsy = parse_block(tmp, pem, vars, start); - start = skip_brackets(start, '{', '}'); + falsy = parse_block(tmp, pem, offset, vars, start); + start = skip_brackets(start - 1, '{', '}'); } - enum PawCtrl *i = make_pawctrl_if(pem, cond, truthy, falsy); + for (int i = 0; i < cond.pre.count; i++) { + pawseq_append(body, cond.pre.items[i]); + } + for (int i = 0; i < cond.num_pops; i++) { + if (falsy != NULL) { + pawseq_insert(falsy, 0, make_pawctrl_spop(pem)); + } + pawseq_insert(truthy, 0, make_pawctrl_spop(pem)); + } + enum PawCtrl *i = make_pawctrl_if(pem, cond.res, truthy, falsy); pawseq_append(body, i); start = trim_start(start); continue; } + if (start_matches(start, "let")) { + start = trim_start(skip_after_char(start, ' ')); + char *name_end = trim_end(skip_to_char(start, ':') - 1); + char *ident = mem_strdup_reg(start, name_end, tmp); + if (index_of_char(start, '=') != -1 && + index_of_char(start, '=') < index_of_char(start, ';')) { + struct PawStackVal val = + parse_stack_val(skip_after_char(start, '='), NULL, 0); + char *s = print_stackval(val); + meow("let has val %s", s); + free(s); + pawseq_append(body, make_pawctrl_spush(pem, val)); + num_pops++; + } else { + crash("TODO figure out defaults for types"); + } + st_insert(vars, ident, NULL); + meow("got a let %s at %d", ident, st_get_index(vars, ident) + offset); + start = skip_after_char(start, ';'); + } + char *tmpc = start; + while (is_char(*tmpc) || *tmpc == ':') { + tmpc++; + } + tmpc = trim_start(tmpc); + if (*tmpc == '(') { + meow("got a call"); + // CALL + char *name = mem_strdup_reg(start, trim_end(tmpc - 1), tmp); + uint32_t index = paw_get_cfunc_index(name); + if (index == UINT32_NULL) { + crash("unknown func"); + return NULL; + } + char *start_arglist = trim_start(tmpc) + 1; + /* meow("args start at %s", start_arglist); */ + char *end_arglist = + trim_end(skip_brackets(start_arglist - 1, '(', ')') - 2); + char *arg_s = mem_strdup_reg(start_arglist, end_arglist, tmp); + int pops = 0; + struct da_string args = split(tmp, arg_s, ','); + meow("got %d args", args.count); + for (int i = 0; i < args.count; i++) { + char *start_arg = trim_start(args.items[i]); + char *end_arg = trim_end(args.items[i] + strlen(args.items[i])); + char *s = mem_strdup_reg(start_arg, end_arg, tmp); + meow("%s", s); + if (is_stackval(s)) { + meow("stackval in arg"); + struct PawStackVal v = parse_stack_val(s, vars, offset); + pawseq_append(body, make_pawctrl_spush(pem, v)); + char *blah = print_stackval(v); + meow("got arg %s", blah); + free(blah); + pops++; + } else { + meow("expr in arg"); + struct PawParseVal res = + parse_val(offset, vars, tmp, pem, s, s + strlen(s)); + if (res.pre.count != 0) { + crash("not supported"); + } + pawseq_append(body, make_pawctrl_spush(pem, PSV_NULL)); + pawseq_append( + body, make_pawctrl_asign(pem, PSV_SP(offset + st_get_size(vars)), + res.res)); + pops++; + } + } + pawseq_append(body, make_pawctrl_ccall(pem, index)); + for (int i = 0; i < pops; i++) { + pawseq_append(body, make_pawctrl_spop(pem)); + } + start = skip_after_char(start, ';'); + } else if (*tmpc == '=') { + meow("got an asign"); + // ASIGN + char *name = mem_strdup_reg(start, trim_end(tmpc - 1), tmp); + struct PawStackVal lhs = PSV_SP(offset + st_get_index(vars, name)); + struct PawParseVal rhs = parse_val(offset, vars, tmp, pem, tmpc + 1, + tmpc + index_of_char(tmpc, ';')); + for (int i = 0; i < rhs.pre.count; i++) { + pawseq_append(body, rhs.pre.items[i]); + } + pawseq_append(body, make_pawctrl_asign(pem, lhs, rhs.res)); + for (int i = 0; i < rhs.num_pops; i++) { + pawseq_append(body, make_pawctrl_spop(pem)); + } + start = skip_after_char(start, ';'); + } + start = trim_start(start); } + + meow("body at %p", body); + return body; } // start has to start with func asdjlasd(dfssdf)->jsd @@ -153,7 +355,7 @@ struct PawAST *parse(char *path) { for (int i = 0; i < strlen(contents); i++) { if (start_matches(&contents[i], "func ")) { - char *name = extract_inbetween_chars(tmp, &contents[i], ' ', '('); + char *name = extract_inbetween_chars(pem, &contents[i], ' ', '('); meow("got a method named '%s'", name); st_insert(methods, name, &contents[i]); i = skip_brackets(&contents[i], '{', '}') - contents; @@ -165,12 +367,21 @@ struct PawAST *parse(char *path) { } for (int i = 0; i < st_get_size(props); i++) { + meow("%s", st_get_nth_key(props, i)); ast_insert_property( ast, mem_strdup(st_get_nth_key(props, i), pem), ast_stack_to_heap( - ast, parse_stack_val(st_get(props, st_get_nth_key(props, i))))); + pem, + parse_stack_val(st_get(props, st_get_nth_key(props, i)), NULL, 0))); } + for (int i = 0; i < st_get_size(methods); i++) { + ast_register_method( + ast, st_get_nth_key(methods, i), + parse_block( + tmp, pem, 0, st_make(tmp), + skip_to_char(st_get(methods, st_get_nth_key(methods, i)), '{'))); + } uninit_mem(tmp); return ast; diff --git a/src/lang/parser.h b/src/lang/parser.h index 10338b0..38cd0c6 100644 --- a/src/lang/parser.h +++ b/src/lang/parser.h @@ -3,6 +3,12 @@ #include "ast.h" +struct PawParseVal { + struct da_paw_ctrl pre; + enum PawVal *res; + int num_pops; +}; + struct PawAST *parse(char *path); #endif // INCLUDE_LANG_PARSER_H_ diff --git a/src/lang/test.paw b/src/lang/test.paw index c6c855a..bfe0919 100644 --- a/src/lang/test.paw +++ b/src/lang/test.paw @@ -1,17 +1,24 @@ -let count: int = 0; - -func make() -> void { - let b: int = 5; - while i != self.count { +func ready() -> void { + let i: int = 0; + let b: int = 42; + while i != 100 { if i == b { - io::print(i); + io::print(i * 2); } i = i + 1; } } +func make_kitty() -> void { + let kitty: Kitty = null; + kitty = kitty::make(); + kitty::free(kitty); +} + func tick() -> void { + io::print(4242); } func free() -> void { + io::print(424242); } diff --git a/src/object.c b/src/object.c index ccafead..f4aaa6f 100644 --- a/src/object.c +++ b/src/object.c @@ -27,7 +27,10 @@ struct Scene *make_scene(struct Vk *vk, struct Register *reg) { struct timespec time; clock_gettime(CLOCK_MONOTONIC, &time); - scene->msecs = time.tv_sec * 1000000 + time.tv_nsec / 1000; + scene->target_delta = 1000000 / 60; + scene->avg_delta = scene->target_delta; + scene->sleep = scene->target_delta; + scene->last_start_time = time.tv_sec * 1000000 + time.tv_nsec / 1000; return scene; } @@ -55,7 +58,10 @@ void scene_tick(struct Scene *scene) { struct timespec time; clock_gettime(CLOCK_MONOTONIC, &time); long msecs_start = time.tv_sec * 1000000 + time.tv_nsec / 1000; - scene->delta_secs = (float)(msecs_start - scene->msecs) / 1000000; + scene->delta_secs = (float)(msecs_start - scene->last_start_time) / 1000000; + scene->avg_delta = + (scene->avg_delta * 5 + (msecs_start - scene->last_start_time) * 1) / 6; + scene->sleep += scene->target_delta - scene->avg_delta; if (scene->insert_queue.count > 0) { for (int i = 0; i < scene->insert_queue.count; i++) { @@ -73,16 +79,16 @@ void scene_tick(struct Scene *scene) { scene->insert_queue.count = 0; } - clock_gettime(CLOCK_MONOTONIC, &time); - long msecs_end = time.tv_sec * 1000000 + time.tv_nsec / 1000; - struct timespec t = { - .tv_sec = 0, - .tv_nsec = - (((1.0 / 120.0) * 1000000) - (msecs_end - scene->msecs)) * 1000, - }; - scene->msecs = msecs_start; - nanosleep(&t, NULL); - meow("dt was %f", scene->delta_secs); + if (scene->sleep <= 0) { + scene->sleep = 0; + } else { + struct timespec t = { + .tv_sec = 0, + .tv_nsec = (scene->sleep) * 1000, + }; + nanosleep(&t, NULL); + } + scene->last_start_time = msecs_start; } void scene_queue_insert(struct Scene *scene, char *name, void *object_data) { diff --git a/src/object.h b/src/object.h index 66f2564..4b6bafe 100644 --- a/src/object.h +++ b/src/object.h @@ -16,7 +16,10 @@ struct Scene { struct Register *reg; float delta_secs; - long msecs; + long avg_delta; + long sleep; + long target_delta; + long last_start_time; }; struct Object { diff --git a/src/physics.c b/src/physics.c new file mode 100644 index 0000000..5aaaacb --- /dev/null +++ b/src/physics.c @@ -0,0 +1 @@ +#include "physics.h" diff --git a/src/physics.h b/src/physics.h new file mode 100644 index 0000000..8e5e17f --- /dev/null +++ b/src/physics.h @@ -0,0 +1,25 @@ +#ifndef INCLUDE_SRC_PHYSICS_H_ +#define INCLUDE_SRC_PHYSICS_H_ + +#include "allocator.h" +#include "types.h" +#include + +enum PawPBodyType { + PAW_PBODY_RECT, + PAW_PBODY_CIRCLE, +}; +struct PawPBody { + enum PawPBodyType type; + uint32_t layers; + union { + struct Rect rect; + struct Circle cirle; + }; +}; + +struct PawPServer { + struct Mem *mem; +}; + +#endif // INCLUDE_SRC_PHYSICS_H_ diff --git a/src/string.c b/src/string.c index 5d0a2b8..61b948e 100644 --- a/src/string.c +++ b/src/string.c @@ -7,21 +7,25 @@ #include #include -struct da_string split(struct Mem *mem, char *string, char needle, int *count) { +struct da_string split(struct Mem *mem, char *string, char needle) { struct da_string items; dyn_array_create_inplace_mem(&items, mem); int last = 0; for (int i = 0; i < strlen(string); i++) { - + meow("got match!"); if (string[i] == needle) { char *tmp = mem_malloc(mem, i - last + 1); memcpy(tmp, &string[last], i - last); - tmp[last - i + 1] = 0x0; + tmp[i - last + 1] = 0x0; dyn_array_append(&items, tmp); last = i; } } + char *tmp = mem_malloc(mem, strlen(string) - last + 1); + memcpy(tmp, &string[last], strlen(string) - last); + tmp[strlen(string) - last + 1] = 0x0; + dyn_array_append(&items, tmp); return items; } @@ -50,6 +54,10 @@ char *extract_brackets(struct Mem *mem, char *start, char open, char close) { return res; } +// before: asddasasd(aslfaddf) +// ^ +// after: asddasasd(aslfaddf) +// ^ char *skip_brackets(char *start, char open, char close) { char *end = start; while (end[0] != open) { @@ -136,6 +144,7 @@ bool is_digid(char n) { return false; } } + bool is_char(char n) { // 65 A, 90 Z, 97 a, 122 z if (n >= 65 && n <= 90 || n >= 97 && n <= 122) { @@ -162,10 +171,18 @@ char *mem_strdup(char *string, struct Mem *mem) { return new; } +// inclusive!!! char *mem_strdup_reg(char *start, char *end, struct Mem *mem) { - char *new = mem_malloc(mem, end - start + 1); - memcpy(new, start, end - start); - new[end - start + 1] = 0x0; + char *new = mem_malloc(mem, end - start + 2); + memcpy(new, start, end - start + 1); + new[end - start + 2] = 0x0; + return new; +} +// inclusive +char *strdup_reg(char *start, char *end) { + char *new = malloc(end - start + 2); + memcpy(new, start, end - start + 1); + new[end - start + 2] = 0x0; return new; } diff --git a/src/string.h b/src/string.h index 02de9a3..59dc06d 100644 --- a/src/string.h +++ b/src/string.h @@ -6,7 +6,7 @@ #include -struct da_string split(struct Mem *mem, char *string, char needle, int *count); +struct da_string split(struct Mem *mem, char *string, char needle); bool start_matches(char *string, char *match); char *extract_brackets(struct Mem *mem, char *start, char open, char close); char *skip_brackets(char *start, char open, char close); @@ -22,6 +22,7 @@ bool is_char(char n); bool includes_between(char *start, char *end, char n); char *mem_strdup(char *string, struct Mem *mem); char *mem_strdup_reg(char *start, char *end, struct Mem *mem); +char *strdup_reg(char *start, char *end); char *skip_to_char(char *string, char n); char *skip_after_char(char *string, char n); diff --git a/src/types.h b/src/types.h index 8111028..3fc00b2 100644 --- a/src/types.h +++ b/src/types.h @@ -3,16 +3,13 @@ #define PI 3.141592653589793238462643f -// struct vec2 { -// union { -// struct { -// float x, y; -// }; -// float arr[2]; -// }; -// }; struct Vec2 { - float x, y; + union { + struct { + float x, y; + }; + float arr[2]; + }; }; #define vec2_mul(v, n) \ (struct Vec2) { (v).x *(n), (v).y *(n) } @@ -25,19 +22,16 @@ struct IVec2 { int x, y; }; -// struct vec3 { -// union { -// struct { -// float x, y, z; -// }; -// struct { -// float r, g, b; -// }; -// float arr[3]; -// }; -// }; struct Vec3 { - float x, y, z; + union { + struct { + float x, y, z; + }; + struct { + float r, g, b; + }; + float arr[3]; + }; }; struct Vec4 { float x, y, z, w; @@ -48,4 +42,13 @@ struct Vertex { struct Vec3 col; }; +struct Rect { + struct Vec2 pos; + struct Vec2 ext; +}; +struct Circle { + struct Vec2 pos; + float r; +}; + #endif // INCLUDE_WAYLANDCLIENT_TYPES_H_