miauuuw :3

This commit is contained in:
qwertzuiopy 2025-03-23 20:12:34 +01:00
parent d2d432c4ca
commit 0d16b96fc5
19 changed files with 966 additions and 49 deletions

View file

@ -10,10 +10,10 @@ FLAGS=-g $(CFLAGS) $(LDFLAGS) $(LIBS)
S=main.c
S+=comp.c wayland.c glfw.c
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+=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
S+=lang/ast.c lang/vstack.c lang/parser.c lang/ast_disc.c lang/functable.c
SO=$(addprefix build/,$(S:.c=.o))
SC=$(addprefix src/,$(S))

36
main.c
View file

@ -4,41 +4,49 @@
#include "trig.c"
#include "src/lang/ast.h"
#include "src/lang/ast_disc.h"
#include "src/lang/parser.h"
#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), op_add)));
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, 0));
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), op_equals),
truthy, make_pawctrl_seq(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, 1000000),
op_unequals),
make_pawval_int(ast->mem, 100),
paw_get_op_index("!=")),
body));
ast_write(ast, "test");
ast = ast_read("test");
ast_exec(ast);
return 0;

View file

@ -1,3 +1,4 @@
#include "allocator.h"
#include "log.h"
#include <stddef.h>
@ -21,9 +22,9 @@ struct Mem {
};
struct Mem *make_mem(size_t size) {
struct Mem *mem = malloc(sizeof(struct Mem));
struct Mem *mem = malloc(sizeof(struct Mem) + size);
mem->mem_size = size;
mem->mem = malloc(mem->mem_size);
mem->mem = mem + 1;
memset(mem->mem, 0, mem->mem_size);
mem->count = 0;
memset(&mem->allocs, 0, sizeof(struct Alloc) * MAX_ALLOCS);
@ -32,10 +33,7 @@ struct Mem *make_mem(size_t size) {
mem->alloc = &mem->allocs[1];
return mem;
}
void uninit_mem(struct Mem *mem) {
free(mem->mem);
free(mem);
}
void uninit_mem(struct Mem *mem) { free(mem); }
static struct Alloc *get_next_alloc(struct Mem *mem) {
while (mem->allocs[mem->count].start != NULL ||
@ -49,6 +47,21 @@ static struct Alloc *get_next_alloc(struct Mem *mem) {
return &mem->allocs[mem->count];
}
void *malloc_or_mem_malloc(struct Mem *mem, size_t size) {
if (mem == NULL) {
return malloc(size);
} else {
return mem_malloc(mem, size);
}
}
void free_or_mem_free(struct Mem *mem, void *ptr) {
if (mem == NULL) {
free(ptr);
} else {
mem_free(mem, ptr);
}
}
void *mem_malloc(struct Mem *mem, size_t size) {
if (size <= 0) {
size = 1;

View file

@ -3,12 +3,26 @@
#include "sys/types.h"
struct Mem;
#define MAX_ALLOCS 256
struct Alloc {
void *start;
uint size;
struct Alloc *next;
};
struct Mem {
void *mem;
size_t mem_size;
uint count;
struct Alloc *alloc;
struct Alloc allocs[MAX_ALLOCS];
};
struct Mem *make_mem(size_t size);
void uninit_mem(struct Mem *mem);
void *mem_malloc(struct Mem *mem, size_t size);
void mem_free(struct Mem *mem, void *p);
void *malloc_or_mem_malloc(struct Mem *mem, size_t size);
void free_or_mem_free(struct Mem *mem, void *ptr);
#endif // INCLUDE_WAYLANDCLIENT_ALLOCATOR_H_

View file

@ -4,6 +4,7 @@
#include "allocator.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define dyn_array_append(array, item) \

View file

@ -28,7 +28,7 @@ char *read_text_file(char *path) {
uint32_t *read_binary_file(char *path, int *size) {
FILE *file = fopen(path, "r");
if (file == NULL) {
meow("Could not open file %s", path);
meow("could not open file %s", path);
return NULL;
}
fseek(file, 0, SEEK_END);
@ -45,3 +45,13 @@ uint32_t *read_binary_file(char *path, int *size) {
fclose(file);
return (uint32_t *)content;
}
void write_binary_file(char *path, char *data, int size) {
FILE *file = fopen(path, "w");
if (file == NULL) {
meow("could not open file %s", path);
return;
}
fwrite(data, size, sizeof(char), file);
fclose(file);
}

View file

@ -5,5 +5,6 @@
char *read_text_file(char *path);
uint32_t *read_binary_file(char *path, int *size);
void write_binary_file(char *path, char *data, int size);
#endif // INCLUDE_WAYLANDCLIENT_IO_H_

View file

@ -6,8 +6,7 @@
const bool log_stack = false;
struct PawStackVal op_equals(struct PawAST *ast, struct PawStackVal lhs,
struct PawStackVal rhs) {
struct PawStackVal op_equals(struct PawStackVal lhs, struct PawStackVal rhs) {
LS("comparing %s to %s", print_valtype(lhs.type), print_valtype(rhs.type));
switch (lhs.type) {
case PAW_VAL_FLOAT:
@ -22,6 +21,7 @@ struct PawStackVal op_equals(struct PawAST *ast, struct PawStackVal lhs,
case PAW_VAL_FLOAT:
return PSV_BOOL(lhs.i == rhs.f);
case PAW_VAL_INT:
LS("%d == %d", lhs.i, rhs.i);
return PSV_BOOL(lhs.i == rhs.i);
}
case PAW_VAL_BOOL:
@ -145,13 +145,34 @@ struct PawStackVal try_cast(enum PawVal target, enum PawVal *val) {
return PSV_NULL;
}
struct PawStackVal op_unequals(struct PawAST *ast, struct PawStackVal lhs,
struct PawStackVal rhs) {
return PSV_BOOL(!op_equals(ast, lhs, rhs).b);
enum PawVal *ast_stack_to_heap(struct PawAST *ast, struct PawStackVal val) {
switch (val.type) {
case PAW_VAL_FLOAT:
return make_pawval_float(ast->mem, val.f);
case PAW_VAL_INT:
return make_pawval_int(ast->mem, val.i);
case PAW_VAL_BOOL:
return make_pawval_bool(ast->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);
case PAW_VAL_SPOINT:
crash("TODO");
// return make_pawval_spoint(ast->mem, val.sp);
case PAW_VAL_EXPR:
crash("sdfgjhhkjdfgd");
}
meow("unreachable");
return NULL;
}
struct PawStackVal op_add(struct PawAST *ast, struct PawStackVal lhs,
struct PawStackVal rhs) {
struct PawStackVal op_unequals(struct PawStackVal lhs, struct PawStackVal rhs) {
return PSV_BOOL(!op_equals(lhs, rhs).b);
}
struct PawStackVal op_add(struct PawStackVal lhs, struct PawStackVal rhs) {
LS("adding %s to %s", print_valtype(lhs.type), print_valtype(rhs.type));
switch (lhs.type) {
case PAW_VAL_FLOAT:
@ -166,6 +187,7 @@ struct PawStackVal op_add(struct PawAST *ast, struct PawStackVal lhs,
case PAW_VAL_FLOAT:
return PSV_FLOAT(lhs.i + rhs.f);
case PAW_VAL_INT:
LS("%d + %d", lhs.i, rhs.i);
return PSV_INT(lhs.i + rhs.i);
}
}
@ -223,7 +245,7 @@ enum PawVal *make_pawval_char(struct Mem *mem, char n) {
}
enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs,
enum PawVal *rhs, paw_p op) {
enum PawVal *rhs, uint32_t op) {
enum PawVal *val;
val_make(val, struct PawExpr, PAW_VAL_EXPR);
struct PawExpr *i = val_get_data(val);
@ -323,17 +345,20 @@ void pawseq_append(enum PawCtrl *seq, enum PawCtrl *ctrl) {
dyn_array_append(&seqval->seq, ctrl);
}
void ping_func() { meow("ping"); }
struct PawAST *ast_make() {
struct Mem *mem = make_mem(8192);
// ast HAS to be the first thing allocated with mem
struct PawAST *ast = mem_malloc(mem, sizeof(struct PawAST));
char *t = "meow\n";
char *test = mem_malloc(mem, strlen(t) + 1);
memcpy(test, t, strlen(t) + 1);
ast->mem = mem;
ast->ping_func = ping_func;
ast->prog = make_pawctrl_seq(ast->mem);
dyn_array_create_inplace_mem(&ast->properties, ast->mem);
dyn_array_create_inplace_mem(&ast->cfuncs, ast->mem);
dyn_array_create_inplace_mem(&ast->funcs, ast->mem);
return ast;
}
@ -343,6 +368,19 @@ void ast_append_cfunc(struct PawAST *ast,
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);
}
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) {
@ -457,10 +495,12 @@ struct PawStackVal ast_eval(struct PawAST *ast, enum PawVal *val) {
return PSV_CHAR(*(char *)val_get_data(val));
case PAW_VAL_EXPR:;
struct PawExpr *expr = val_get_data(val);
LS("calling op at %p", expr->op);
LS("calling op at %d", 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 = expr->op(ast, lhs, rhs);
struct PawStackVal ret = ((struct PawStackVal(*)(
struct PawStackVal, struct PawStackVal))paw_get_op(expr->op))(lhs, rhs);
return ret;
break;
}
@ -487,7 +527,17 @@ void ast_exec(struct PawAST *ast) {
int offset = 0;
ast_stack_push(stack, ast->prog);
meow("starting exec");
#define NO_LIMIT_ITS
#ifndef NO_LIMIT_ITS
int i = 0;
#endif
while (stack->top < stack->right) {
#ifndef NO_LIMIT_ITS
i++;
if (i > 100) {
break;
}
#endif
enum PawCtrl *ctrl = stack_poke(stack);
switch (*ctrl) {
case PAW_CTRL_SEQ:;

View file

@ -1,3 +1,5 @@
#ifndef INCLUDE_LANG_AST_H_
#define INCLUDE_LANG_AST_H_
#include <stdbool.h>
#include <stdint.h>
@ -44,6 +46,14 @@ enum PawVal {
PAW_VAL_SPOINT,
PAW_VAL_EXPR,
};
enum ArgType {
PAW_ARG_FLOAT,
PAW_ARG_INT,
PAW_ARG_BOOL,
PAW_ARG_CHAR,
PAW_ARG_POINT,
PAW_ARG_ANY,
};
enum PawCtrl {
PAW_CTRL_SEQ,
@ -66,18 +76,18 @@ struct PawProperty {
dyn_array_define(da_paw_property, struct PawProperty);
dyn_array_define(da_cfunc, struct CFunc);
dyn_array_define(da_func, struct PawFunc);
struct PawAST {
struct Mem *mem;
enum PawCtrl *prog;
void *ping_func;
struct da_paw_property properties;
struct da_cfunc cfuncs;
struct da_func funcs;
};
struct PawExpr {
struct PawStackVal (*op)(struct PawAST *ast, struct PawStackVal lhs,
struct PawStackVal rhs);
uint32_t op;
enum PawVal *lhs;
enum PawVal *rhs;
};
@ -121,11 +131,16 @@ struct PawStackPush {
struct PawStackVal v;
};
struct PawFunc {
enum PawCtrl *body;
char *name;
};
struct PawCall {
enum PawCtrl *body;
};
struct PawCCall {
int index;
uint32_t index;
};
struct VStack {
@ -153,19 +168,16 @@ struct CFunc {
void (*func)(struct VStack *stack, int offset);
};
struct PawStackVal op_equals(struct PawAST *ast, struct PawStackVal lhs,
struct PawStackVal rhs);
struct PawStackVal op_unequals(struct PawAST *ast, struct PawStackVal lhs,
struct PawStackVal rhs);
struct PawStackVal op_add(struct PawAST *ast, struct PawStackVal lhs,
struct PawStackVal rhs);
struct PawStackVal op_equals(struct PawStackVal lhs, struct PawStackVal rhs);
struct PawStackVal op_unequals(struct PawStackVal lhs, struct PawStackVal rhs);
struct PawStackVal op_add(struct PawStackVal lhs, struct PawStackVal 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);
enum PawVal *rhs, uint32_t op);
void free_pawval(struct Mem *mem, enum PawVal *val);
enum PawCtrl *make_pawctrl_seq(struct Mem *mem);
enum PawCtrl *make_pawctrl_spush(struct Mem *mem, struct PawStackVal val);
@ -179,7 +191,7 @@ enum PawCtrl *make_pawctrl_if(struct Mem *mem, enum PawVal *cond,
enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target,
enum PawVal *val);
void pawseq_append(enum PawCtrl *seq, enum PawCtrl *ctrl);
void ping_func();
enum PawVal *ast_stack_to_heap(struct PawAST *ast, struct PawStackVal val);
struct PawAST *ast_make();
void ast_insert_property(struct PawAST *ast, char *name, enum PawVal *val);
void ast_append_cfunc(struct PawAST *ast,
@ -200,3 +212,12 @@ void ast_exec(struct PawAST *ast);
$ret = mem_malloc(mem, sizeof(enum PawCtrl) + sizeof($type)); \
*$ret = $TYPE_ENUM; \
} while (0)
uint32_t paw_get_ops_size();
const char *paw_get_op_sym(uint32_t index);
uint32_t paw_get_op_index(char *sym);
void *paw_get_op(uint32_t);
uint32_t paw_get_cfunc_index(char *name);
void *paw_get_cfunc(uint32_t);
#endif // INCLUDE_LANG_AST_H_

227
src/lang/ast_disc.c Normal file
View file

@ -0,0 +1,227 @@
#include "ast_disc.h"
#include "../io.h"
#include "../log.h"
#include "ast.h"
#define AO1($p) \
if (apply_before && \
((void *)($p) >= region_start && (void *)($p) <= region_end)) { \
$p = (void *)((void *)$p + offset); \
}
#define AO2($p) \
if (!apply_before && \
((void *)$p >= region_start && (void *)$p <= region_end)) { \
$p = (void *)((void *)$p + offset); \
}
long offset = 0;
void *region_start = NULL;
void *region_end = NULL;
bool apply_before = false;
// for nyow ast and ast->mem will be garbled afterwards
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;
apply_before = false;
AO2(ast->mem->alloc);
AO2(ast->mem->mem);
for (int i = 0; i < MAX_ALLOCS; i++) {
if (ast->mem->allocs[i].start == NULL && ast->mem->allocs[i].size == 0 &&
ast->mem->allocs[i].next == NULL) {
continue;
} else {
AO2(ast->mem->allocs[i].start);
AO2(ast->mem->allocs[i].next);
}
}
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);
}
AO2(ast->funcs.items);
AO2(ast->funcs.mem);
write_binary_file(path, data, size);
}
// assumes all PawStackVals existent at compile time of type PAW_VAL_POINT point
// to a valid PawVal
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 &&
mem->allocs[i].next == NULL) {
continue;
} else {
AO1(mem->allocs[i].start);
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);
}
return ast;
}
void apply_offset_ctrl(enum PawCtrl *ctrl) {
switch (*ctrl) {
case PAW_CTRL_SEQ:;
struct PawSeq *seq = ctrl_get_data(ctrl);
AO1(seq->seq.mem);
AO1(seq->seq.items);
for (int i = 0; i < seq->seq.count; i++) {
AO1(seq->seq.items[i]);
apply_offset_ctrl(seq->seq.items[i]);
AO2(seq->seq.items[i]);
}
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);
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);
AO1(_if->cond);
apply_offset_val(_if->cond);
AO2(_if->cond);
break;
case PAW_CTRL_ASIGN:;
struct PawAsign *asign = ctrl_get_data(ctrl);
AO1(asign->rhs);
apply_offset_val(asign->rhs);
AO2(asign->rhs);
asign->lhs = apply_offset_stackval(asign->lhs);
break;
case PAW_CTRL_SPUSH:
break;
case PAW_CTRL_SPOP:
break;
case PAW_CTRL_CALL:;
struct PawCall *call = ctrl_get_data(ctrl);
AO1(call->body);
apply_offset_ctrl(call->body);
AO2(call->body);
break;
case PAW_CTRL_CCALL:
break;
}
}
struct PawStackVal apply_offset_stackval(struct PawStackVal val) {
switch (val.type) {
case PAW_VAL_FLOAT:
case PAW_VAL_INT:
case PAW_VAL_BOOL:
case PAW_VAL_CHAR:
case PAW_VAL_SPOINT:
return val;
case PAW_VAL_EXPR:
meow("AGHJKGHJKASZGHJKASGHJKGHJK");
return (struct PawStackVal){.type = PAW_VAL_POINT, .p = NULL};
case PAW_VAL_POINT:
AO1(val.p);
apply_offset_val(val.p);
AO2(val.p);
return val;
}
}
void apply_offset_val(enum PawVal *val) {
switch (*val) {
case PAW_VAL_FLOAT:
break;
case PAW_VAL_INT:
break;
case PAW_VAL_BOOL:
break;
case PAW_VAL_CHAR:
break;
case PAW_VAL_POINT:
meow("uuuh this should not happen i thinky?");
apply_offset_val(*(enum PawVal **)val_get_data(val));
break;
case PAW_VAL_SPOINT:
break;
case PAW_VAL_EXPR:;
struct PawExpr *expr = val_get_data(val);
AO1(expr->lhs);
AO1(expr->rhs);
apply_offset_val(expr->lhs);
apply_offset_val(expr->rhs);
AO2(expr->lhs);
AO2(expr->rhs);
meow("applying offset to an expr");
break;
}
}

12
src/lang/ast_disc.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef INCLUDE_LANG_AST_DISC_H_
#define INCLUDE_LANG_AST_DISC_H_
#include "ast.h"
void ast_write(struct PawAST *ast, char *path);
struct PawAST *ast_read(char *path);
void apply_offset_ctrl(enum PawCtrl *ctrl);
void apply_offset_val(enum PawVal *val);
struct PawStackVal apply_offset_stackval(struct PawStackVal val);
#endif // INCLUDE_LANG_AST_DISC_H_

49
src/lang/functable.c Normal file
View file

@ -0,0 +1,49 @@
#include "../log.h"
#include "../util.h"
#include "ast.h"
struct FuncDef {
void (*func)(struct VStack *, int);
const char *name;
// enum ArgType *args;
};
struct OpDef {
struct PawStackVal (*op)(struct PawStackVal, struct PawStackVal);
const char *sym;
// enum ArgType *args;
};
struct FuncDef PAW_CFUNCS[] = {
{print, "io::print"},
};
// important to unimportant!!!
struct OpDef PAW_OPS[] = {
{op_equals, "=="}, {op_unequals, "!="}, {NULL, "*"},
{NULL, "/"}, {op_add, "+"}, {NULL, "-"},
};
uint32_t paw_get_ops_size() { return sizeof(PAW_OPS); }
const char *paw_get_op_sym(uint32_t index) { return PAW_OPS[index].sym; }
uint32_t paw_get_op_index(char *sym) {
for (int i = 0; i < sizeof(PAW_OPS) / sizeof(PAW_OPS[0]); i++) {
if (strcmp(sym, PAW_OPS[i].sym) == 0) {
return i;
}
}
meow("could not find op %s, returning %d", sym, UINT32_NULL);
return UINT32_NULL;
}
void *paw_get_op(uint32_t index) { return PAW_OPS[index].op; }
uint32_t paw_get_cfunc_index(char *name) {
for (int i = 0; i < sizeof(PAW_CFUNCS) / sizeof(PAW_CFUNCS[0]); i++) {
if (strcmp(name, PAW_CFUNCS[i].name) == 0) {
return i;
}
}
meow("could not find cfunc %s, returning %d", name, UINT32_NULL);
return UINT32_NULL;
}
void *paw_get_cfunc(uint32_t index) { return PAW_CFUNCS[index].func; }

167
src/lang/parser.c Normal file
View file

@ -0,0 +1,167 @@
#include "../allocator.h"
#include "../io.h"
#include "../log.h"
#include "../string.h"
#include "../util.h"
#include "ast.h"
#include <limits.h>
#include "parser.h"
struct PawStackVal parse_stack_val(char *start) {
start = trim_start(start);
if (start_matches(start, "true")) {
return PSV_BOOL(true);
}
if (start_matches(start, "false")) {
return PSV_BOOL(false);
}
if (start_matches(start, "null")) {
return PSV_NULL;
}
char *end = start;
while (is_digid(*end) || *end == '.') {
end++;
}
if (includes_between(start, end, '.')) {
return PSV_FLOAT(strtof(start, NULL));
} else {
return PSV_INT(strtol(start, NULL, 10));
}
}
enum PawVal *parse_val(int stack_offset, struct StringTable *vars,
struct Mem *tmp, struct Mem *pem, char *start,
char *end) {
start = trim_start(start);
end = trim_end(end);
// figure out the most important op
char *opstart = start;
int op_rating = INT_MAX;
char *op = NULL;
// as * before + in functable it will choose to split on + first, meaning
// a+b*c => (a)+(b*c)
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 (i >= op_rating) {
continue;
}
op_rating = i;
op = opstart;
}
}
opstart++;
}
if (op == 0) {
}
enum PawVal *lhs;
// expected: var, brackets or function
if (start_matches(start, "(")) {
char *in_end = skip_brackets(start, '(', ')');
lhs = parse_val(stack_offset, vars, tmp, pem, start + 1, in_end);
start = in_end;
} else {
char *tmp = start;
while (is_char(*tmp)) {
tmp++;
}
tmp = trim_start(tmp);
if (*tmp == '(') {
// TODO, call
} else {
// TODO, var
}
}
start = trim_start(start);
if (start == end) {
return lhs;
}
}
enum PawCtrl *parse_block(struct Mem *tmp, struct Mem *pem,
struct StringTable *vars, char *start) {
enum PawCtrl *body = make_pawctrl_seq(pem);
start = trim_start(start);
while (!start_matches(start, "}")) {
if (start_matches(start, "while")) {
start = skip_after_char(start, ' ');
char *end = skip_to_char(start, '{') - 1;
enum PawVal *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);
start = skip_brackets(start, '{', '}');
start = trim_start(start);
continue;
}
if (start_matches(start, "if")) {
start = skip_after_char(start, ' ');
char *end = skip_to_char(start, '{') - 1;
enum PawVal *cond = parse_val(0, vars, tmp, pem, start, end);
enum PawCtrl *truthy =
parse_block(tmp, pem, vars, skip_after_char(start, '{'));
enum PawCtrl *falsy = NULL;
start = skip_brackets(start, '{', '}');
if (start_matches(start, "else")) {
start = skip_after_char(start, '{');
falsy = parse_block(tmp, pem, vars, start);
start = skip_brackets(start, '{', '}');
}
enum PawCtrl *i = make_pawctrl_if(pem, cond, truthy, falsy);
pawseq_append(body, i);
start = trim_start(start);
continue;
}
}
}
// start has to start with func asdjlasd(dfssdf)->jsd
enum PawCtrl *parse_func(char *start) { skip_to_char(start, ' '); }
struct PawAST *parse(char *path) {
char *contents = read_text_file(path);
struct PawAST *ast = ast_make();
struct Mem *tmp = make_mem(4096); // temporary memory
struct Mem *pem =
ast->mem; // permanent memory, will be present once ast is evaled
struct StringTable *methods = st_make(tmp);
struct StringTable *props = st_make(tmp);
for (int i = 0; i < strlen(contents); i++) {
if (start_matches(&contents[i], "func ")) {
char *name = extract_inbetween_chars(tmp, &contents[i], ' ', '(');
meow("got a method named '%s'", name);
st_insert(methods, name, &contents[i]);
i = skip_brackets(&contents[i], '{', '}') - contents;
} else if (start_matches(&contents[i], "let")) {
char *name = extract_inbetween_chars(tmp, &contents[i], ' ', ':');
meow("got a property named '%s'", name);
st_insert(props, name, NULL);
}
}
for (int i = 0; i < st_get_size(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)))));
}
uninit_mem(tmp);
return ast;
}

8
src/lang/parser.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef INCLUDE_LANG_PARSER_H_
#define INCLUDE_LANG_PARSER_H_
#include "ast.h"
struct PawAST *parse(char *path);
#endif // INCLUDE_LANG_PARSER_H_

17
src/lang/test.paw Normal file
View file

@ -0,0 +1,17 @@
let count: int = 0;
func make() -> void {
let b: int = 5;
while i != self.count {
if i == b {
io::print(i);
}
i = i + 1;
}
}
func tick() -> void {
}
func free() -> void {
}

183
src/string.c Normal file
View file

@ -0,0 +1,183 @@
#include "string.h"
#include "allocator.h"
#include "log.h"
#include "util.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
struct da_string split(struct Mem *mem, char *string, char needle, int *count) {
struct da_string items;
dyn_array_create_inplace_mem(&items, mem);
int last = 0;
for (int i = 0; i < strlen(string); i++) {
if (string[i] == needle) {
char *tmp = mem_malloc(mem, i - last + 1);
memcpy(tmp, &string[last], i - last);
tmp[last - i + 1] = 0x0;
dyn_array_append(&items, tmp);
last = i;
}
}
return items;
}
bool start_matches(char *string, char *match) {
return memcmp(string, match, strlen(match)) == 0;
}
char *extract_brackets(struct Mem *mem, char *start, char open, char close) {
char *end = skip_brackets(start, open, close);
// { ... }
// ^ end
end -= 2;
// { ... }
// ^ end
while (*start != open) {
start++;
}
// { ... }
// start ^ ^ end
start++;
char *res = mem_malloc(mem, end - start + 1);
memcpy(res, start, end - start);
res[end - start] = 0x0;
return res;
}
char *skip_brackets(char *start, char open, char close) {
char *end = start;
while (end[0] != open) {
end++;
}
end++;
int count = 1;
while (count > 0) {
if (end[0] == close) {
count--;
} else if (end[0] == open) {
count++;
}
end++;
}
return end;
}
int index_of_char(char *string, char key) {
int i = 0;
while (i < strlen(string) && string[i] != key) {
i++;
}
if (i == strlen(string)) {
return -1;
} else {
return i;
}
}
char *extract(struct Mem *mem, char *string, int start, int size) {
char *new = mem_malloc(mem, size + 1);
memcpy(new, string + start, size);
new[size + 1] = 0x0;
return new;
}
char *extract_inbetween_chars(struct Mem *mem, char *string, char one,
char two) {
int start = index_of_char(string, one) + 1;
int end = index_of_char(string, two);
if (end < start) {
SWAP(start, end);
}
return extract(mem, string, start, end - start);
}
char *tmp_format(struct Mem *mem, char *format, ...) {
char *res = malloc(1024);
va_list ap;
va_start(ap, NULL);
vsprintf(res, format, ap);
char *new = mem_malloc(mem, (strlen(res) + 1) * sizeof(char));
memcpy(new, res, (strlen(res) + 1) * sizeof(char));
free(res);
return new;
}
char *trim_start(char *string) {
while (*string == ' ' || *string == '\n') {
string++;
}
return string;
}
char *trim_end(char *string) {
while (*string == ' ' || *string == '\n') {
string--;
}
return string;
}
// dont judge :(
bool is_digid(char n) {
if (n == '0' || n == '1' || n == '2' || n == '3' || n == '4' || n == '5' ||
n == '6' || n == '7' || n == '8' || n == '9') {
return true;
} else {
return false;
}
}
bool is_char(char n) {
// 65 A, 90 Z, 97 a, 122 z
if (n >= 65 && n <= 90 || n >= 97 && n <= 122) {
return true;
} else {
return false;
}
}
bool includes_between(char *start, char *end, char n) {
while (*start != n && start <= end) {
start++;
}
if (*start == n) {
return true;
} else {
return false;
}
}
char *mem_strdup(char *string, struct Mem *mem) {
char *new = mem_malloc(mem, (strlen(string) + 1) * sizeof(char));
memcpy(new, string, (strlen(string) + 1) * sizeof(char));
return new;
}
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;
return new;
}
char *skip_to_char(char *string, char n) {
while (*string != n) {
string++;
}
return string;
}
char *skip_after_char(char *string, char n) {
while (*string != n) {
string++;
}
return string + 1;
}

28
src/string.h Normal file
View file

@ -0,0 +1,28 @@
#ifndef INCLUDE_SRC_STRING_H_
#define INCLUDE_SRC_STRING_H_
#include "allocator.h"
#include "dynarray.h"
#include <stdbool.h>
struct da_string split(struct Mem *mem, char *string, char needle, int *count);
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);
int index_of_char(char *string, char key);
char *extract(struct Mem *mem, char *string, int start, int size);
char *extract_inbetween_chars(struct Mem *mem, char *string, char one,
char two);
char *tmp_format(struct Mem *mem, char *format, ...);
char *trim_start(char *string);
char *trim_end(char *string);
bool is_digid(char n);
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 *skip_to_char(char *string, char n);
char *skip_after_char(char *string, char n);
#endif // INCLUDE_SRC_STRING_H_

View file

@ -1,3 +1,89 @@
#include "allocator.h"
#include "dynarray.h"
#include <stdbool.h>
#include <stdlib.h>
float randf() { return (float)rand() / (float)RAND_MAX; }
struct ST_key {
char *key;
void *value;
};
dyn_array_define(da_ST_key, struct ST_key);
struct StringTable {
struct da_ST_key keys;
};
struct StringTable *st_make(struct Mem *mem) {
struct StringTable *st =
malloc_or_mem_malloc(mem, sizeof(struct StringTable));
if (mem == NULL) {
dyn_array_create_inplace(&st->keys);
} else {
dyn_array_create_inplace_mem(&st->keys, mem);
}
return st;
}
struct StringTable *st_dup(struct StringTable *st) {
struct StringTable *new =
malloc_or_mem_malloc(st->keys.mem, sizeof(struct StringTable));
new->keys.mem = st->keys.mem;
new->keys.count = st->keys.count;
new->keys.capacity = st->keys.capacity;
new->keys.items = malloc_or_mem_malloc(new->keys.mem, sizeof(struct ST_key) *
new->keys.capacity);
memcpy(new->keys.items, st->keys.items,
st->keys.capacity * sizeof(struct ST_key));
return new;
}
void st_insert(struct StringTable *st, char *key, void *value) {
dyn_array_append(&st->keys, ((struct ST_key){.key = key, .value = value}));
}
bool st_has_key(struct StringTable *st, char *key) {
for (int i = 0; i < st->keys.count; i++) {
if (strcmp(st->keys.items[i].key, key) == 0) {
return true;
}
}
return false;
}
bool st_has_value(struct StringTable *st, void *value) {
for (int i = 0; i < st->keys.count; i++) {
if (st->keys.items[i].value == value) {
return true;
}
}
return false;
}
void *st_get(struct StringTable *st, char *key) {
for (int i = 0; i < st->keys.count; i++) {
if (strcmp(st->keys.items[i].key, key) == 0) {
return st->keys.items[i].value;
}
}
return NULL;
}
void st_remove(struct StringTable *st, char *key) {
for (int i = 0; i < st->keys.count; i++) {
if (strcmp(st->keys.items[i].key, key) == 0) {
dyn_array_remove(&st->keys, i);
}
}
}
void st_unmake(struct StringTable *st) {
if (st->keys.mem == NULL) {
dyn_array_destroy(&st->keys);
free(st);
} else {
dyn_array_destroy(&st->keys);
mem_free(st->keys.mem, st);
}
}
int st_get_size(struct StringTable *st) { return st->keys.count; }
char *st_get_nth_key(struct StringTable *st, int index) {
return st->keys.items[index].key;
}

View file

@ -1,6 +1,28 @@
#ifndef INCLUDE_ENGINE_UTIL_H_
#define INCLUDE_ENGINE_UTIL_H_
#define UINT32_NULL 42424242
float randf();
#define SWAP($a, $b) \
do { \
void *tmp = alloca(sizeof($a)); \
memcpy(tmp, &$a, sizeof($a)); \
$a = $b; \
memcpy(&$b, tmp, sizeof($b)); \
} while (0)
struct StringTable;
struct StringTable *st_make(struct Mem *mem);
struct StringTable *st_dup(struct StringTable *st);
void st_insert(struct StringTable *st, char *key, void *value);
bool st_has_key(struct StringTable *st, char *key);
void *st_get(struct StringTable *st, char *key);
bool st_has_value(struct StringTable *st, void *value);
void st_remove(struct StringTable *st, char *key);
void st_unmake(struct StringTable *st);
int st_get_size(struct StringTable *st);
char *st_get_nth_key(struct StringTable *st, int index);
#endif // INCLUDE_ENGINE_UTIL_H_