This commit is contained in:
qwertzuiopy 2025-04-04 18:52:45 +02:00
parent b61c1f9ef2
commit e30b8f0abc
19 changed files with 595 additions and 263 deletions

View file

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

44
main.c
View file

@ -10,45 +10,11 @@
#include <stdbool.h>
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);

View file

@ -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]; \

View file

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

View file

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

View file

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

View file

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

12
src/lang/glue.c Normal file
View file

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

9
src/lang/glue.h Normal file
View file

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

View file

@ -4,37 +4,101 @@
#include "../string.h"
#include "../util.h"
#include "ast.h"
#include "ast_disc.h"
#include <limits.h>
#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;

View file

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

View file

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

View file

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

View file

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

1
src/physics.c Normal file
View file

@ -0,0 +1 @@
#include "physics.h"

25
src/physics.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef INCLUDE_SRC_PHYSICS_H_
#define INCLUDE_SRC_PHYSICS_H_
#include "allocator.h"
#include "types.h"
#include <stdint.h>
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_

View file

@ -7,21 +7,25 @@
#include <stdio.h>
#include <string.h>
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;
}

View file

@ -6,7 +6,7 @@
#include <stdbool.h>
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);

View file

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