yes im insane :3
This commit is contained in:
parent
f0892fd902
commit
ea19c28156
6 changed files with 492 additions and 4 deletions
2
Makefile
2
Makefile
|
@ -13,6 +13,7 @@ S+=vulkan.c kitty.c
|
|||
S+=gpu_allocator.c hashmap.c util.c io.c matrix.c dynarray.c image.c types.c allocator.c log.c
|
||||
S+=object.c register.c
|
||||
S+=Wayland/xdg-shell-protocol.c
|
||||
S+=lang/ast.c
|
||||
SO=$(addprefix build/,$(S:.c=.o))
|
||||
SC=$(addprefix src/,$(S))
|
||||
|
||||
|
@ -20,6 +21,7 @@ clean:
|
|||
rm -rf build/
|
||||
mkdir build
|
||||
mkdir build/Wayland
|
||||
mkdir build/lang
|
||||
|
||||
install:
|
||||
./main
|
||||
|
|
23
main.c
23
main.c
|
@ -3,9 +3,32 @@
|
|||
#include "src/register.h"
|
||||
#include "trig.c"
|
||||
|
||||
#include "src/lang/ast.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
int main() {
|
||||
|
||||
struct PawAST *ast = ast_make();
|
||||
ast_insert_property(ast, "i", make_pawval_int(ast->mem, 0));
|
||||
|
||||
enum PawCtrl *body = make_pawctrl_seq(ast->mem);
|
||||
pawctrl_append(body, make_pawctrl_call(ast->mem, ping_func));
|
||||
pawctrl_append(body,
|
||||
make_pawctrl_asign(
|
||||
ast->mem, ast_get_property(ast, "i"),
|
||||
make_pawval_expr(ast->mem, ast_get_property(ast, "i"),
|
||||
make_pawval_int(ast->mem, 1), op_add)));
|
||||
pawctrl_append(
|
||||
ast->prog,
|
||||
make_pawctrl_while(ast->mem,
|
||||
make_pawval_expr(ast->mem, ast_get_property(ast, "i"),
|
||||
make_pawval_int(ast->mem, 1000000),
|
||||
op_unequals),
|
||||
body));
|
||||
ast_exec(ast);
|
||||
return 0;
|
||||
|
||||
struct Vk *vk;
|
||||
cat_Comp *state = cat_comp_init("meooow", 500, 500, &vk);
|
||||
|
||||
|
|
|
@ -64,10 +64,10 @@ void *mem_malloc(struct Mem *mem, size_t size) {
|
|||
next,
|
||||
};
|
||||
prev->next = new;
|
||||
meow("MALLOC %p:%ld, size %zu, prev is %p:%ld, size %u", new->start,
|
||||
/*meow("MALLOC %p:%ld, size %zu, prev is %p:%ld, size %u", new->start,
|
||||
new - mem->allocs, size, prev->start, prev - mem->allocs,
|
||||
prev->size);
|
||||
/* print_backtrace(); */
|
||||
print_backtrace(); */
|
||||
return new->start;
|
||||
} else {
|
||||
prev = next;
|
||||
|
@ -94,7 +94,7 @@ void mem_free(struct Mem *mem, void *p) {
|
|||
if (index < mem->count) {
|
||||
mem->count = index;
|
||||
}
|
||||
meow("FREE at %d : %p", index, current->start);
|
||||
/* print_backtrace(); */
|
||||
/*meow("FREE at %d : %p", index, current->start);
|
||||
print_backtrace(); */
|
||||
memset(&mem->allocs[index], 0, sizeof(struct Alloc));
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "allocator.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define dyn_array_append(array, item) \
|
||||
do { \
|
||||
|
|
347
src/lang/ast.c
Normal file
347
src/lang/ast.c
Normal file
|
@ -0,0 +1,347 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../log.h"
|
||||
#include "ast.h"
|
||||
|
||||
enum PawVal *op_equals(struct PawAST *ast, enum PawVal *lhs, enum PawVal *rhs) {
|
||||
if (*lhs == PAW_VAL_BOOL && *rhs == PAW_VAL_BOOL) {
|
||||
if (*(bool *)val_get_data(lhs) == *(bool *)val_get_data(rhs)) {
|
||||
return make_pawval_bool(ast->mem, true);
|
||||
} else {
|
||||
return make_pawval_bool(ast->mem, false);
|
||||
}
|
||||
}
|
||||
float l;
|
||||
float r;
|
||||
if (*lhs == PAW_VAL_FLOAT) {
|
||||
l = *(float *)val_get_data(lhs);
|
||||
} else if (*lhs == PAW_VAL_INT) {
|
||||
l = *(int *)val_get_data(lhs);
|
||||
}
|
||||
if (*rhs == PAW_VAL_FLOAT) {
|
||||
r = *(float *)val_get_data(rhs);
|
||||
} else if (*rhs == PAW_VAL_INT) {
|
||||
r = *(int *)val_get_data(rhs);
|
||||
}
|
||||
if (l == r) {
|
||||
return make_pawval_bool(ast->mem, true);
|
||||
} else {
|
||||
return make_pawval_bool(ast->mem, false);
|
||||
}
|
||||
}
|
||||
|
||||
enum PawVal *op_unequals(struct PawAST *ast, enum PawVal *lhs,
|
||||
enum PawVal *rhs) {
|
||||
enum PawVal *res = op_equals(ast, lhs, rhs);
|
||||
*(bool *)val_get_data(res) = !*(bool *)val_get_data(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
enum PawVal *op_add(struct PawAST *ast, enum PawVal *lhs, enum PawVal *rhs) {
|
||||
return make_pawval_int(ast->mem,
|
||||
*(int *)val_get_data(lhs) + *(int *)val_get_data(rhs));
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_float(struct Mem *mem, float n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, float, PAW_VAL_FLOAT);
|
||||
float *f = val_get_data(val);
|
||||
*f = n;
|
||||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_int(struct Mem *mem, int n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, int, PAW_VAL_INT);
|
||||
int *i = (int *)val_get_data(val);
|
||||
*i = n;
|
||||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_bool(struct Mem *mem, bool n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, bool, PAW_VAL_BOOL);
|
||||
bool *i = val_get_data(val);
|
||||
*i = n;
|
||||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_point(struct Mem *mem, paw_p n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, paw_p, PAW_VAL_INT);
|
||||
paw_p *i = val_get_data(val);
|
||||
*i = n;
|
||||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs,
|
||||
enum PawVal *rhs, paw_p op) {
|
||||
enum PawVal *val;
|
||||
val_make(val, struct PawExpr, PAW_VAL_EXPR);
|
||||
struct PawExpr *i = val_get_data(val);
|
||||
i->op = op;
|
||||
i->lhs = lhs;
|
||||
i->rhs = rhs;
|
||||
return val;
|
||||
*i = (struct PawExpr){
|
||||
.op = op,
|
||||
.lhs = lhs,
|
||||
.rhs = rhs,
|
||||
};
|
||||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_func(struct Mem *mem) {
|
||||
enum PawVal *val;
|
||||
val_make(val, struct PawFunc, PAW_VAL_FUNC);
|
||||
struct PawFunc *i = val_get_data(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
void free_pawval(struct Mem *mem, enum PawVal *val) {
|
||||
switch (*val) {
|
||||
case PAW_VAL_FLOAT:
|
||||
case PAW_VAL_INT:
|
||||
case PAW_VAL_BOOL:
|
||||
case PAW_VAL_POINT:
|
||||
mem_free(mem, val);
|
||||
break;
|
||||
case PAW_VAL_FUNC:
|
||||
crash("todo");
|
||||
break;
|
||||
case PAW_VAL_EXPR:;
|
||||
struct PawExpr *expr = val_get_data(val);
|
||||
free_pawval(mem, expr->lhs);
|
||||
free_pawval(mem, expr->rhs);
|
||||
mem_free(mem, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_seq(struct Mem *mem) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawSeq, PAW_CTRL_SEQ);
|
||||
struct PawSeq *i = ctrl_get_data(ctrl);
|
||||
dyn_array_create_inplace_mem(&i->seq, mem);
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_call(struct Mem *mem, paw_p addr) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawCall, PAW_CTRL_CALL);
|
||||
struct PawCall *i = ctrl_get_data(ctrl);
|
||||
i->addr = addr;
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_while(struct Mem *mem, enum PawVal *cond,
|
||||
enum PawCtrl *body) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawWhile, PAW_CTRL_WHILE);
|
||||
struct PawWhile *i = ctrl_get_data(ctrl);
|
||||
i->body = body;
|
||||
i->cond = cond;
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_asign(struct Mem *mem, enum PawVal *target,
|
||||
enum PawVal *val) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawAsign, PAW_CTRL_ASIGN);
|
||||
struct PawAsign *i = ctrl_get_data(ctrl);
|
||||
i->lhs = target;
|
||||
i->rhs = val;
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
void pawctrl_append(enum PawCtrl *seq, enum PawCtrl *ctrl) {
|
||||
struct PawSeq *seqval = ctrl_get_data(seq);
|
||||
dyn_array_append(&seqval->seq, ctrl);
|
||||
}
|
||||
|
||||
void ping_func() { meow("ping"); }
|
||||
|
||||
struct PawAST *ast_make() {
|
||||
struct Mem *mem = make_mem(8192);
|
||||
struct PawAST *ast = mem_malloc(mem, sizeof(struct PawAST));
|
||||
|
||||
ast->mem = mem;
|
||||
ast->ping_func = ping_func;
|
||||
ast->prog = make_pawctrl_seq(ast->mem);
|
||||
dyn_array_create_inplace_mem(&ast->properties, ast->mem);
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
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) {
|
||||
return ast->properties.items[i].val;
|
||||
}
|
||||
}
|
||||
meow("could not find property %s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ast_insert_property(struct PawAST *ast, char *name, enum PawVal *val) {
|
||||
dyn_array_append(&ast->properties, ((struct PawProperty){name, val}));
|
||||
}
|
||||
|
||||
struct Stack *stack_make(struct Mem *mem, size_t size) {
|
||||
struct Stack *stack = mem_malloc(mem, sizeof(struct Stack));
|
||||
stack->left = mem_malloc(mem, size);
|
||||
stack->right = stack->left + size;
|
||||
stack->top = stack->right;
|
||||
return stack;
|
||||
}
|
||||
|
||||
void stack_pop(struct Stack *stack) {
|
||||
stack->top = stack->top + sizeof(void *);
|
||||
if (stack->top > stack->right) {
|
||||
meow("pop stack is %p:%p:%p", stack->left, stack->top, stack->right);
|
||||
crash("uuuh am in cellar");
|
||||
}
|
||||
}
|
||||
void stack_push(struct Stack *stack, void *v) {
|
||||
stack->top = stack->top - sizeof(void *);
|
||||
if (stack->top < stack->left) {
|
||||
crash("uuuh am in space");
|
||||
}
|
||||
*(void **)stack->top = v;
|
||||
}
|
||||
|
||||
void *stack_poke(struct Stack *stack) { return *(void **)stack->top; }
|
||||
void *stack_poke2(struct Stack *stack) {
|
||||
return *(void **)(stack->top + sizeof(void *));
|
||||
}
|
||||
void stack_set2(struct Stack *stack, void *v) {
|
||||
void **n = stack->top + sizeof(void *);
|
||||
*n = v;
|
||||
}
|
||||
|
||||
void stack_free(struct Stack *stack, struct Mem *mem) {
|
||||
mem_free(mem, stack->left);
|
||||
mem_free(mem, stack);
|
||||
}
|
||||
|
||||
void ast_stack_push(struct Stack *stack, enum PawCtrl *ctrl) {
|
||||
switch (*ctrl) {
|
||||
case PAW_CTRL_SEQ:
|
||||
stack_push(stack, NULL);
|
||||
stack_push(stack, ctrl);
|
||||
break;
|
||||
case PAW_CTRL_ASIGN:
|
||||
case PAW_CTRL_CALL:
|
||||
case PAW_CTRL_WHILE:
|
||||
stack_push(stack, ctrl);
|
||||
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
|
||||
enum PawVal *ast_eval(struct PawAST *ast, enum PawVal *val) {
|
||||
switch (*val) {
|
||||
case PAW_VAL_FLOAT:
|
||||
return make_pawval_float(ast->mem, *(float *)val_get_data(val));
|
||||
case PAW_VAL_INT:
|
||||
return make_pawval_int(ast->mem, *(int *)val_get_data(val));
|
||||
case PAW_VAL_BOOL:
|
||||
return make_pawval_bool(ast->mem, *(bool *)val_get_data(val));
|
||||
case PAW_VAL_POINT:
|
||||
return make_pawval_point(ast->mem, *(void **)val_get_data(val));
|
||||
case PAW_VAL_FUNC:
|
||||
meow("todo");
|
||||
break;
|
||||
case PAW_VAL_EXPR:;
|
||||
struct PawExpr *expr = val_get_data(val);
|
||||
enum PawVal *lhs = ast_eval(ast, expr->lhs);
|
||||
enum PawVal *rhs = ast_eval(ast, expr->rhs);
|
||||
enum PawVal *ret = expr->op(ast, lhs, rhs);
|
||||
free_pawval(ast->mem, lhs);
|
||||
free_pawval(ast->mem, rhs);
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
meow("unreachable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ast_exec(struct PawAST *ast) {
|
||||
meow("allocing stack");
|
||||
struct Stack *stack = stack_make(ast->mem, 2048);
|
||||
ast_stack_push(stack, ast->prog);
|
||||
meow("starting exec");
|
||||
while (stack->top < stack->right) {
|
||||
enum PawCtrl *ctrl = stack_poke(stack);
|
||||
switch (*ctrl) {
|
||||
case PAW_CTRL_SEQ:;
|
||||
int i = (int64_t)(stack_poke2(stack));
|
||||
struct PawSeq *seq = ctrl_get_data(ctrl);
|
||||
if (i >= seq->seq.count) {
|
||||
stack_pop(stack);
|
||||
stack_pop(stack);
|
||||
continue;
|
||||
}
|
||||
stack_set2(stack, (void *)(uint64_t)(i + 1));
|
||||
ast_stack_push(stack, seq->seq.items[i]);
|
||||
break;
|
||||
case PAW_CTRL_CALL:;
|
||||
struct PawCall *call = ctrl_get_data(ctrl);
|
||||
if (call->addr == ast->ping_func) {
|
||||
ping_func();
|
||||
}
|
||||
stack_pop(stack);
|
||||
break;
|
||||
case PAW_CTRL_WHILE:;
|
||||
struct PawWhile *whle = ctrl_get_data(ctrl);
|
||||
enum PawVal *ret = ast_eval(ast, whle->cond);
|
||||
if (*ret != PAW_VAL_BOOL) {
|
||||
meow("unsuported");
|
||||
}
|
||||
bool *v = val_get_data(ret);
|
||||
if (*v) {
|
||||
ast_stack_push(stack, whle->body);
|
||||
} else {
|
||||
stack_pop(stack);
|
||||
}
|
||||
free_pawval(ast->mem, ret);
|
||||
break;
|
||||
case PAW_CTRL_ASIGN:;
|
||||
struct PawAsign *asign = ctrl_get_data(ctrl);
|
||||
enum PawVal *val = ast_eval(ast, asign->rhs);
|
||||
if (*val != *asign->lhs) {
|
||||
crash("woopsie wrong type");
|
||||
}
|
||||
switch (*val) {
|
||||
case PAW_VAL_FLOAT:;
|
||||
float *ft = val_get_data(asign->lhs);
|
||||
*ft = *(float *)val_get_data(val);
|
||||
break;
|
||||
case PAW_VAL_INT:;
|
||||
int *it = val_get_data(asign->lhs);
|
||||
*it = *(int *)val_get_data(val);
|
||||
break;
|
||||
case PAW_VAL_BOOL:
|
||||
bool *bt = val_get_data(asign->lhs);
|
||||
*bt = *(bool *)val_get_data(val);
|
||||
break;
|
||||
case PAW_VAL_POINT:;
|
||||
paw_p *pt = val_get_data(asign->lhs);
|
||||
*bt = *(paw_p *)val_get_data(val);
|
||||
break;
|
||||
case PAW_VAL_EXPR:
|
||||
case PAW_VAL_FUNC:
|
||||
meow("whhooopsie not primitive");
|
||||
break;
|
||||
}
|
||||
|
||||
free_pawval(ast->mem, val);
|
||||
stack_pop(stack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
meow("ending exec");
|
||||
}
|
115
src/lang/ast.h
Normal file
115
src/lang/ast.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../allocator.h"
|
||||
#include "../dynarray.h"
|
||||
|
||||
#define paw_p void *
|
||||
#define PAW_STACK_SIZE 2048
|
||||
|
||||
struct Stack {
|
||||
void *right;
|
||||
void *left;
|
||||
void *top;
|
||||
};
|
||||
|
||||
enum PawVal {
|
||||
PAW_VAL_FLOAT,
|
||||
PAW_VAL_INT,
|
||||
PAW_VAL_BOOL,
|
||||
PAW_VAL_FUNC,
|
||||
PAW_VAL_POINT,
|
||||
PAW_VAL_EXPR,
|
||||
};
|
||||
|
||||
enum PawCtrl {
|
||||
PAW_CTRL_SEQ,
|
||||
PAW_CTRL_WHILE,
|
||||
PAW_CTRL_ASIGN,
|
||||
PAW_CTRL_CALL,
|
||||
};
|
||||
|
||||
dyn_array_define(da_paw_ctrl, enum PawCtrl *);
|
||||
dyn_array_define(da_paw_val, enum PawVal *);
|
||||
|
||||
struct PawSeq {
|
||||
struct da_paw_ctrl seq;
|
||||
};
|
||||
|
||||
struct PawFunc {
|
||||
enum PawVal *body;
|
||||
struct da_paw_val val;
|
||||
};
|
||||
|
||||
struct PawWhile {
|
||||
enum PawVal *cond;
|
||||
enum PawCtrl *body;
|
||||
};
|
||||
|
||||
struct PawAsign {
|
||||
enum PawVal *lhs;
|
||||
enum PawVal *rhs;
|
||||
};
|
||||
|
||||
struct PawProperty {
|
||||
char *name;
|
||||
enum PawVal *val;
|
||||
};
|
||||
dyn_array_define(da_paw_property, struct PawProperty);
|
||||
|
||||
struct PawAST {
|
||||
struct Mem *mem;
|
||||
enum PawCtrl *prog;
|
||||
void *ping_func;
|
||||
struct da_paw_property properties;
|
||||
};
|
||||
|
||||
struct PawExpr {
|
||||
enum PawVal *(*op)(struct PawAST *ast, enum PawVal *lhs, enum PawVal *rhs);
|
||||
enum PawVal *lhs;
|
||||
enum PawVal *rhs;
|
||||
};
|
||||
|
||||
struct PawCall {
|
||||
paw_p addr;
|
||||
};
|
||||
|
||||
enum PawVal *op_equals(struct PawAST *ast, enum PawVal *lhs, enum PawVal *rhs);
|
||||
enum PawVal *op_unequals(struct PawAST *ast, enum PawVal *lhs,
|
||||
enum PawVal *rhs);
|
||||
enum PawVal *op_add(struct PawAST *ast, enum PawVal *lhs, enum PawVal *rhs);
|
||||
|
||||
enum PawVal *make_pawval_float(struct Mem *mem, float n);
|
||||
enum PawVal *make_pawval_int(struct Mem *mem, int n);
|
||||
enum PawVal *make_pawval_bool(struct Mem *mem, bool n);
|
||||
enum PawVal *make_pawval_point(struct Mem *mem, paw_p n);
|
||||
enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs,
|
||||
enum PawVal *rhs, paw_p op);
|
||||
void free_pawval(struct Mem *mem, enum PawVal *val);
|
||||
enum PawCtrl *make_pawctrl_seq(struct Mem *mem);
|
||||
enum PawCtrl *make_pawctrl_call(struct Mem *mem, paw_p addr);
|
||||
enum PawCtrl *make_pawctrl_while(struct Mem *mem, enum PawVal *cond,
|
||||
enum PawCtrl *body);
|
||||
enum PawCtrl *make_pawctrl_asign(struct Mem *mem, enum PawVal *target,
|
||||
enum PawVal *val);
|
||||
void pawctrl_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);
|
||||
enum PawVal *ast_get_property(struct PawAST *ast, char *name);
|
||||
void ast_exec(struct PawAST *ast);
|
||||
|
||||
#define val_get_data($val) ((void *)$val + sizeof(enum PawVal))
|
||||
#define val_make($ret, $type, $TYPE_ENUM) \
|
||||
do { \
|
||||
$ret = mem_malloc(mem, sizeof(enum PawVal) + sizeof($type)); \
|
||||
*$ret = $TYPE_ENUM; \
|
||||
} while (0)
|
||||
|
||||
#define ctrl_get_data($ctrl) (void *)$ctrl + sizeof(enum PawCtrl)
|
||||
#define ctrl_make($ret, $type, $TYPE_ENUM) \
|
||||
do { \
|
||||
$ret = mem_malloc(mem, sizeof(enum PawCtrl) + sizeof($type)); \
|
||||
*$ret = $TYPE_ENUM; \
|
||||
} while (0)
|
Loading…
Add table
Add a link
Reference in a new issue