Compare commits
2 commits
b61c1f9ef2
...
6dcddb4da3
Author | SHA1 | Date | |
---|---|---|---|
|
6dcddb4da3 | ||
|
e30b8f0abc |
43 changed files with 1041 additions and 707 deletions
14
Makefile
14
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+=string.c gpu_allocator.c hashmap.c util.c io.c matrix.c paw_da.c image.c types.c paw_allocator.c paw_log.c
|
||||
S+=paw_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
|
||||
|
|
54
main.c
54
main.c
|
@ -1,5 +1,5 @@
|
|||
#include "src/comp.h"
|
||||
#include "src/object.h"
|
||||
#include "src/paw_object.h"
|
||||
#include "src/register.h"
|
||||
#include "trig.c"
|
||||
|
||||
|
@ -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);
|
||||
|
@ -56,16 +22,16 @@ int main() {
|
|||
struct Register *reg = make_register();
|
||||
reg_attatch_type(reg, "trig", OBJ_MAKE make_trig, OBJ_FREE free_trig,
|
||||
OBJ_TICK trig_tick);
|
||||
struct Scene *scene = make_scene(vk, reg);
|
||||
struct PawScene *scene = paw_scene_make(vk, reg);
|
||||
|
||||
scene_queue_insert(scene, "trig", trig_make_args(scene));
|
||||
paw_scene_queue_insert(scene, "trig", trig_make_args(scene));
|
||||
|
||||
while (!cat_comp_should_close(state)) {
|
||||
scene_tick(scene);
|
||||
paw_scene_tick(scene);
|
||||
cat_comp_draw(state);
|
||||
}
|
||||
|
||||
free_scene(scene);
|
||||
paw_scene_free(scene);
|
||||
free_register(reg);
|
||||
|
||||
cat_comp_uninit(state);
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef INCLUDE_WAYLANDCLIENT_ALLOCATOR_H_
|
||||
#define INCLUDE_WAYLANDCLIENT_ALLOCATOR_H_
|
||||
|
||||
#include "sys/types.h"
|
||||
|
||||
#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_
|
|
@ -1,4 +1,4 @@
|
|||
#include "log.h"
|
||||
#include "paw_log.h"
|
||||
#include "vulkan.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
|
|
@ -146,7 +146,7 @@ void gpu_mem_free(struct Vk *state, struct GpuMem *mem,
|
|||
if (current == NULL || pointer.offset != current->start) {
|
||||
meow("WHOOOPPSIIIEEEE could not find allocated block, potential dobble "
|
||||
"free");
|
||||
print_backtrace();
|
||||
paw_print_backtrace();
|
||||
return;
|
||||
}
|
||||
prev->next = current->next;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "paw_log.h"
|
||||
|
||||
#define HASH_MASK 0b111111
|
||||
#define TYPE uint32_t
|
||||
|
|
2
src/io.c
2
src/io.c
|
@ -1,4 +1,4 @@
|
|||
#include "log.h"
|
||||
#include "paw_log.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
|
48
src/kitty.c
48
src/kitty.c
|
@ -3,30 +3,30 @@
|
|||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "dynarray.h"
|
||||
#include "io.h"
|
||||
#include "kitty.h"
|
||||
#include "paw_allocator.h"
|
||||
#include "paw_da.h"
|
||||
#include "vulkan.h"
|
||||
#include "vulkan_helpers.c"
|
||||
|
||||
struct Kitty *kitty_make(struct Mem *mem) {
|
||||
struct Kitty *kitty_make(struct PawMem *mem) {
|
||||
struct Kitty *kitty;
|
||||
if (mem == NULL) {
|
||||
kitty = malloc(sizeof(struct Kitty));
|
||||
} else {
|
||||
kitty = mem_malloc(mem, sizeof(struct Kitty));
|
||||
kitty = paw_memmalloc(mem, sizeof(struct Kitty));
|
||||
}
|
||||
memset(kitty, 0, sizeof(struct Kitty));
|
||||
kitty->mem = mem;
|
||||
if (kitty->mem == NULL) {
|
||||
dyn_array_create_inplace(&kitty->attatchments);
|
||||
dyn_array_create_inplace(&kitty->vertex_buffer.format);
|
||||
dyn_array_create_inplace(&kitty->instance_buffer.format);
|
||||
paw_da_make_inplace(&kitty->attatchments);
|
||||
paw_da_make_inplace(&kitty->vertex_buffer.format);
|
||||
paw_da_make_inplace(&kitty->instance_buffer.format);
|
||||
} else {
|
||||
dyn_array_create_inplace_mem(&kitty->attatchments, kitty->mem);
|
||||
dyn_array_create_inplace_mem(&kitty->vertex_buffer.format, kitty->mem);
|
||||
dyn_array_create_inplace_mem(&kitty->instance_buffer.format, kitty->mem);
|
||||
paw_da_make_inplace_mem(&kitty->attatchments, kitty->mem);
|
||||
paw_da_make_inplace_mem(&kitty->vertex_buffer.format, kitty->mem);
|
||||
paw_da_make_inplace_mem(&kitty->instance_buffer.format, kitty->mem);
|
||||
}
|
||||
meow("alloced a kitty at %p", kitty);
|
||||
return kitty;
|
||||
|
@ -63,34 +63,34 @@ void kitty_add_instance_buffer(struct Kitty *kitty, void *data, uint32_t count,
|
|||
}
|
||||
void kitty_add_instance_buffer_format(struct Kitty *kitty,
|
||||
enum VkFormat format) {
|
||||
dyn_array_append(&kitty->instance_buffer.format, format);
|
||||
paw_da_append(&kitty->instance_buffer.format, format);
|
||||
}
|
||||
|
||||
void kitty_add_vertex_buffer_format(struct Kitty *kitty, enum VkFormat format) {
|
||||
dyn_array_append(&kitty->vertex_buffer.format, format);
|
||||
paw_da_append(&kitty->vertex_buffer.format, format);
|
||||
}
|
||||
void kitty_attatch_image(struct Kitty *kitty, const char *path) {
|
||||
struct Attatchment attatchment = {0};
|
||||
struct KittyAttatchment attatchment = {0};
|
||||
attatchment.type = CAT_ATTATCH_IMAGE;
|
||||
attatchment.image.path = path;
|
||||
dyn_array_append(&kitty->attatchments, attatchment);
|
||||
paw_da_append(&kitty->attatchments, attatchment);
|
||||
meow("image was attatched");
|
||||
}
|
||||
int kitty_attatch_ubo(struct Kitty *kitty, uint32_t size) {
|
||||
struct Attatchment attatchment = {0};
|
||||
struct KittyAttatchment attatchment = {0};
|
||||
attatchment.type = CAT_ATTATCH_UBO;
|
||||
attatchment.ubo.size = size;
|
||||
dyn_array_append(&kitty->attatchments, attatchment);
|
||||
paw_da_append(&kitty->attatchments, attatchment);
|
||||
meow("ubo of size %d was attatched", size);
|
||||
return kitty->attatchments.count - 1;
|
||||
}
|
||||
int kitty_attatch_ubo_array(struct Kitty *kitty, uint32_t size,
|
||||
uint32_t count) {
|
||||
struct Attatchment attatchment = {0};
|
||||
struct KittyAttatchment attatchment = {0};
|
||||
attatchment.type = CAT_ATTATCH_UBO_ARRAY;
|
||||
attatchment.ubo_array.size = size;
|
||||
attatchment.ubo_array.count = count;
|
||||
dyn_array_append(&kitty->attatchments, attatchment);
|
||||
paw_da_append(&kitty->attatchments, attatchment);
|
||||
return kitty->attatchments.count - 1;
|
||||
}
|
||||
|
||||
|
@ -107,10 +107,10 @@ void kitty_finalise(struct Vk *state, struct Kitty *kitty) {
|
|||
kitty_create_instance_buffer(kitty, state);
|
||||
}
|
||||
|
||||
dyn_array_append(&state->kitties, kitty);
|
||||
paw_da_append(&state->kitties, kitty);
|
||||
}
|
||||
|
||||
void free_kitty(struct Vk *state, struct Kitty *kitty) {
|
||||
void kitty_free(struct Vk *state, struct Kitty *kitty) {
|
||||
vkDeviceWaitIdle(state->device);
|
||||
vkDestroyBuffer(state->device, kitty->vertex_buffer.buffer, NULL);
|
||||
gpu_mem_free(state, state->mem, kitty->vertex_buffer.memory);
|
||||
|
@ -154,14 +154,14 @@ void free_kitty(struct Vk *state, struct Kitty *kitty) {
|
|||
}
|
||||
}
|
||||
|
||||
dyn_array_destroy(&kitty->vertex_buffer.format);
|
||||
dyn_array_destroy(&kitty->attatchments);
|
||||
paw_da_free(&kitty->vertex_buffer.format);
|
||||
paw_da_free(&kitty->attatchments);
|
||||
|
||||
if (kitty->mem == NULL) {
|
||||
memset(kitty, 0, sizeof(struct Kitty));
|
||||
free(kitty);
|
||||
} else {
|
||||
mem_free(kitty->mem, kitty);
|
||||
paw_memfree(kitty->mem, kitty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,7 +537,7 @@ void kitty_create_image_attatchments(struct Kitty *kitty, struct Vk *state) {
|
|||
if (kitty->attatchments.items[index].type != CAT_ATTATCH_IMAGE) {
|
||||
continue;
|
||||
}
|
||||
struct Attatchment *atch = &kitty->attatchments.items[index];
|
||||
struct KittyAttatchment *atch = &kitty->attatchments.items[index];
|
||||
atch->image.pixels = load_image(atch->image.path, &atch->image.dims);
|
||||
atch->image.size = atch->image.dims.x * atch->image.dims.y * 4;
|
||||
|
||||
|
|
14
src/kitty.h
14
src/kitty.h
|
@ -5,14 +5,14 @@
|
|||
#include "vulkan.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
enum AttatchType {
|
||||
enum KittyAttatchType {
|
||||
CAT_ATTATCH_IMAGE,
|
||||
CAT_ATTATCH_UBO,
|
||||
CAT_ATTATCH_UBO_ARRAY,
|
||||
};
|
||||
|
||||
struct Attatchment {
|
||||
enum AttatchType type;
|
||||
struct KittyAttatchment {
|
||||
enum KittyAttatchType type;
|
||||
union {
|
||||
struct {
|
||||
const char *path;
|
||||
|
@ -38,7 +38,7 @@ struct Attatchment {
|
|||
};
|
||||
};
|
||||
|
||||
dyn_array_define(da_Attatchment, struct Attatchment);
|
||||
paw_da_define(da_Attatchment, struct KittyAttatchment);
|
||||
|
||||
struct Kitty {
|
||||
VkPipeline pipeline;
|
||||
|
@ -60,10 +60,10 @@ struct Kitty {
|
|||
VkDescriptorSetLayout descriptor_set_layout;
|
||||
VkDescriptorSet descriptor_sets[MAX_FRAMES_IN_FLIGHT];
|
||||
|
||||
struct Mem *mem;
|
||||
struct PawMem *mem;
|
||||
};
|
||||
|
||||
struct Kitty *kitty_make(struct Mem *mem);
|
||||
struct Kitty *kitty_make(struct PawMem *mem);
|
||||
void kitty_set_vertex_shader(struct Kitty *thingy, const char *path);
|
||||
void kitty_set_fragment_shader(struct Kitty *thingy, const char *path);
|
||||
|
||||
|
@ -105,7 +105,7 @@ void *kitty_get_next_ubo_pointer(struct Vk *state, struct Kitty *kitty,
|
|||
|
||||
void kitty_draw(struct Vk *state, uint32_t image_index, struct Kitty *thingy);
|
||||
|
||||
void free_kitty(struct Vk *state, struct Kitty *kitty);
|
||||
void kitty_free(struct Vk *state, struct Kitty *kitty);
|
||||
|
||||
void kitty_create_layout_bindings(struct Kitty *kitty, struct Vk *state);
|
||||
void kitty_create_pipeline(struct Kitty *kitty, struct Vk *state);
|
||||
|
|
270
src/lang/ast.c
270
src/lang/ast.c
|
@ -1,7 +1,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../log.h"
|
||||
#include "../paw_log.h"
|
||||
#include "ast.h"
|
||||
|
||||
const bool log_stack = false;
|
||||
|
@ -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, paw_b_to_s(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 PawMem *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);
|
||||
|
@ -196,7 +229,7 @@ struct PawStackVal op_add(struct PawStackVal lhs, struct PawStackVal rhs) {
|
|||
return PSV_NULL;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_float(struct Mem *mem, float n) {
|
||||
enum PawVal *make_pawval_float(struct PawMem *mem, float n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, float, PAW_VAL_FLOAT);
|
||||
float *f = val_get_data(val);
|
||||
|
@ -204,7 +237,7 @@ enum PawVal *make_pawval_float(struct Mem *mem, float n) {
|
|||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_int(struct Mem *mem, int n) {
|
||||
enum PawVal *make_pawval_int(struct PawMem *mem, int n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, int, PAW_VAL_INT);
|
||||
int *i = (int *)val_get_data(val);
|
||||
|
@ -212,7 +245,7 @@ enum PawVal *make_pawval_int(struct Mem *mem, int n) {
|
|||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_bool(struct Mem *mem, bool n) {
|
||||
enum PawVal *make_pawval_bool(struct PawMem *mem, bool n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, bool, PAW_VAL_BOOL);
|
||||
bool *i = val_get_data(val);
|
||||
|
@ -220,7 +253,7 @@ enum PawVal *make_pawval_bool(struct Mem *mem, bool n) {
|
|||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_point(struct Mem *mem, paw_p n) {
|
||||
enum PawVal *make_pawval_point(struct PawMem *mem, paw_p n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, paw_p, PAW_VAL_POINT);
|
||||
paw_p *i = val_get_data(val);
|
||||
|
@ -228,7 +261,7 @@ enum PawVal *make_pawval_point(struct Mem *mem, paw_p n) {
|
|||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_spoint(struct Mem *mem, int n) {
|
||||
enum PawVal *make_pawval_spoint(struct PawMem *mem, int n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, paw_p, PAW_VAL_SPOINT);
|
||||
int *i = val_get_data(val);
|
||||
|
@ -236,7 +269,7 @@ enum PawVal *make_pawval_spoint(struct Mem *mem, int n) {
|
|||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_char(struct Mem *mem, char n) {
|
||||
enum PawVal *make_pawval_char(struct PawMem *mem, char n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, paw_p, PAW_VAL_CHAR);
|
||||
char *i = val_get_data(val);
|
||||
|
@ -244,7 +277,7 @@ enum PawVal *make_pawval_char(struct Mem *mem, char n) {
|
|||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs,
|
||||
enum PawVal *make_pawval_expr(struct PawMem *mem, enum PawVal *lhs,
|
||||
enum PawVal *rhs, uint32_t op) {
|
||||
enum PawVal *val;
|
||||
val_make(val, struct PawExpr, PAW_VAL_EXPR);
|
||||
|
@ -255,7 +288,7 @@ enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs,
|
|||
return val;
|
||||
}
|
||||
|
||||
void free_pawval(struct Mem *mem, enum PawVal *val) {
|
||||
void free_pawval(struct PawMem *mem, enum PawVal *val) {
|
||||
switch (*val) {
|
||||
case PAW_VAL_FLOAT:
|
||||
case PAW_VAL_INT:
|
||||
|
@ -263,55 +296,58 @@ void free_pawval(struct Mem *mem, enum PawVal *val) {
|
|||
case PAW_VAL_POINT:
|
||||
case PAW_VAL_SPOINT:
|
||||
case PAW_VAL_CHAR:
|
||||
mem_free(mem, val);
|
||||
paw_memfree(mem, val);
|
||||
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);
|
||||
paw_memfree(mem, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_seq(struct Mem *mem) {
|
||||
enum PawCtrl *make_pawctrl_seq(struct PawMem *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);
|
||||
paw_da_make_inplace_mem(&i->seq, mem);
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_call(struct Mem *mem, enum PawCtrl *body) {
|
||||
enum PawCtrl *make_pawctrl_call(struct PawMem *mem, enum PawCtrl *body) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawCall, PAW_CTRL_CALL);
|
||||
struct PawCall *i = ctrl_get_data(ctrl);
|
||||
i->body = body;
|
||||
return ctrl;
|
||||
}
|
||||
enum PawCtrl *make_pawctrl_spush(struct Mem *mem, struct PawStackVal val) {
|
||||
enum PawCtrl *make_pawctrl_spush(struct PawMem *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 *make_pawctrl_spop(struct PawMem *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 PawMem *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 PawMem *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,
|
||||
enum PawCtrl *make_pawctrl_if(struct PawMem *mem, enum PawVal *cond,
|
||||
enum PawCtrl *truthy, enum PawCtrl *falsy) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawIf, PAW_CTRL_IF);
|
||||
|
@ -322,7 +358,7 @@ enum PawCtrl *make_pawctrl_if(struct Mem *mem, enum PawVal *cond,
|
|||
return ctrl;
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target,
|
||||
enum PawCtrl *make_pawctrl_asign(struct PawMem *mem, struct PawStackVal target,
|
||||
enum PawVal *val) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawAsign, PAW_CTRL_ASIGN);
|
||||
|
@ -332,7 +368,7 @@ enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target,
|
|||
return ctrl;
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_ccall(struct Mem *mem, int index) {
|
||||
enum PawCtrl *make_pawctrl_ccall(struct PawMem *mem, int index) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawCCall, PAW_CTRL_CCALL);
|
||||
struct PawCCall *i = ctrl_get_data(ctrl);
|
||||
|
@ -342,43 +378,32 @@ enum PawCtrl *make_pawctrl_ccall(struct Mem *mem, int index) {
|
|||
|
||||
void pawseq_append(enum PawCtrl *seq, enum PawCtrl *ctrl) {
|
||||
struct PawSeq *seqval = ctrl_get_data(seq);
|
||||
dyn_array_append(&seqval->seq, ctrl);
|
||||
paw_da_append(&seqval->seq, ctrl);
|
||||
}
|
||||
void pawseq_insert(enum PawCtrl *seq, int index, enum PawCtrl *ctrl) {
|
||||
struct PawSeq *seqval = ctrl_get_data(seq);
|
||||
paw_da_insert(&seqval->seq, index, ctrl);
|
||||
}
|
||||
|
||||
struct PawAST *ast_make() {
|
||||
struct Mem *mem = make_mem(8192);
|
||||
struct PawMem *mem = paw_memmake(8192);
|
||||
// ast HAS to be the first thing allocated with mem
|
||||
struct PawAST *ast = mem_malloc(mem, sizeof(struct PawAST));
|
||||
struct PawAST *ast = paw_memmalloc(mem, sizeof(struct PawAST));
|
||||
|
||||
char *t = "meow\n";
|
||||
char *test = mem_malloc(mem, strlen(t) + 1);
|
||||
char *test = paw_memmalloc(mem, strlen(t) + 1);
|
||||
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);
|
||||
paw_da_make_inplace_mem(&ast->properties, ast->mem);
|
||||
paw_da_make_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) {
|
||||
paw_da_append(&ast->methods,
|
||||
((struct PawMethod){.body = body, .name = name}));
|
||||
}
|
||||
|
||||
enum PawVal *ast_get_property(struct PawAST *ast, char *name) {
|
||||
|
@ -392,12 +417,12 @@ enum PawVal *ast_get_property(struct PawAST *ast, char *name) {
|
|||
}
|
||||
|
||||
void ast_insert_property(struct PawAST *ast, char *name, enum PawVal *val) {
|
||||
dyn_array_append(&ast->properties, ((struct PawProperty){name, val}));
|
||||
paw_da_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);
|
||||
struct Stack *stack_make(struct PawMem *mem, size_t size) {
|
||||
struct Stack *stack = paw_memmalloc(mem, sizeof(struct Stack));
|
||||
stack->left = paw_memmalloc(mem, size);
|
||||
stack->right = stack->left + size;
|
||||
stack->top = stack->right;
|
||||
return stack;
|
||||
|
@ -427,13 +452,14 @@ void stack_set2(struct Stack *stack, void *v) {
|
|||
*n = v;
|
||||
}
|
||||
|
||||
void stack_free(struct Stack *stack, struct Mem *mem) {
|
||||
mem_free(mem, stack->left);
|
||||
mem_free(mem, stack);
|
||||
void stack_free(struct Stack *stack, struct PawMem *mem) {
|
||||
paw_memfree(mem, stack->left);
|
||||
paw_memfree(mem, stack);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -442,7 +468,7 @@ void print(struct VStack *stack, int offset) {
|
|||
meow("%i", val.i);
|
||||
break;
|
||||
case PAW_VAL_BOOL:
|
||||
meow("%s", bool_to_string(val.b));
|
||||
meow("%s", paw_b_to_s(val.b));
|
||||
break;
|
||||
case PAW_VAL_CHAR:
|
||||
meow("%c", val.c);
|
||||
|
@ -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 PawScene *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;
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../allocator.h"
|
||||
#include "../dynarray.h"
|
||||
#include "../paw_allocator.h"
|
||||
#include "../paw_da.h"
|
||||
#include "../paw_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,
|
||||
|
@ -65,25 +67,21 @@ enum PawCtrl {
|
|||
PAW_CTRL_CALL,
|
||||
PAW_CTRL_CCALL,
|
||||
};
|
||||
dyn_array_define(da_paw_ctrl, enum PawCtrl *);
|
||||
dyn_array_define(da_paw_val, enum PawVal *);
|
||||
paw_da_define(da_paw_ctrl, enum PawCtrl *);
|
||||
paw_da_define(da_paw_val, enum PawVal *);
|
||||
|
||||
struct PawProperty {
|
||||
char *name;
|
||||
enum PawVal *val;
|
||||
};
|
||||
|
||||
dyn_array_define(da_paw_property, struct PawProperty);
|
||||
|
||||
dyn_array_define(da_cfunc, struct CFunc);
|
||||
dyn_array_define(da_func, struct PawFunc);
|
||||
paw_da_define(da_paw_property, struct PawProperty);
|
||||
paw_da_define(da_method, struct PawMethod);
|
||||
|
||||
struct PawAST {
|
||||
struct Mem *mem;
|
||||
enum PawCtrl *prog;
|
||||
struct PawMem *mem;
|
||||
struct da_paw_property properties;
|
||||
struct da_cfunc cfuncs;
|
||||
struct da_func funcs;
|
||||
struct da_method methods;
|
||||
};
|
||||
|
||||
struct PawExpr {
|
||||
|
@ -107,13 +105,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 +132,7 @@ struct PawStackPush {
|
|||
struct PawStackVal v;
|
||||
};
|
||||
|
||||
struct PawFunc {
|
||||
struct PawMethod {
|
||||
enum PawCtrl *body;
|
||||
char *name;
|
||||
};
|
||||
|
@ -144,6 +145,7 @@ struct PawCCall {
|
|||
};
|
||||
|
||||
struct VStack {
|
||||
struct PawScene *scene;
|
||||
void *left;
|
||||
void *right;
|
||||
void *top;
|
||||
|
@ -151,8 +153,8 @@ struct VStack {
|
|||
|
||||
void print(struct VStack *stack, int offset);
|
||||
|
||||
struct VStack *vstack_make(struct Mem *mem, size_t size);
|
||||
void vstack_free(struct VStack *stack, struct Mem *mem);
|
||||
struct VStack *vstack_make(struct PawMem *mem, size_t size);
|
||||
void vstack_free(struct VStack *stack, struct PawMem *mem);
|
||||
void vstack_pop(struct VStack *stack);
|
||||
void vstack_push(struct VStack *stack, struct PawStackVal val);
|
||||
struct PawStackVal vstack_poke(struct VStack *stack);
|
||||
|
@ -172,45 +174,47 @@ 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_spoint(struct Mem *mem, int n);
|
||||
enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs,
|
||||
enum PawVal *make_pawval_float(struct PawMem *mem, float n);
|
||||
enum PawVal *make_pawval_int(struct PawMem *mem, int n);
|
||||
enum PawVal *make_pawval_bool(struct PawMem *mem, bool n);
|
||||
enum PawVal *make_pawval_point(struct PawMem *mem, paw_p n);
|
||||
enum PawVal *make_pawval_spoint(struct PawMem *mem, int n);
|
||||
enum PawVal *make_pawval_expr(struct PawMem *mem, enum PawVal *lhs,
|
||||
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);
|
||||
enum PawCtrl *make_pawctrl_spop(struct Mem *mem);
|
||||
enum PawCtrl *make_pawctrl_call(struct Mem *mem, enum PawCtrl *body);
|
||||
enum PawCtrl *make_pawctrl_ccall(struct Mem *mem, int index);
|
||||
enum PawCtrl *make_pawctrl_while(struct Mem *mem, enum PawVal *cond,
|
||||
enum PawCtrl *body);
|
||||
enum PawCtrl *make_pawctrl_if(struct Mem *mem, enum PawVal *cond,
|
||||
void free_pawval(struct PawMem *mem, enum PawVal *val);
|
||||
enum PawCtrl *make_pawctrl_seq(struct PawMem *mem);
|
||||
enum PawCtrl *make_pawctrl_spush(struct PawMem *mem, struct PawStackVal val);
|
||||
enum PawCtrl *make_pawctrl_spop(struct PawMem *mem);
|
||||
enum PawCtrl *make_pawctrl_call(struct PawMem *mem, enum PawCtrl *body);
|
||||
enum PawCtrl *make_pawctrl_ccall(struct PawMem *mem, int index);
|
||||
enum PawCtrl *make_pawctrl_loop(struct PawMem *mem, enum PawCtrl *body);
|
||||
enum PawCtrl *make_pawctrl_break(struct PawMem *mem);
|
||||
enum PawCtrl *make_pawctrl_if(struct PawMem *mem, enum PawVal *cond,
|
||||
enum PawCtrl *truthy, enum PawCtrl *falsy);
|
||||
enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target,
|
||||
enum PawCtrl *make_pawctrl_asign(struct PawMem *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 PawMem *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 PawScene *scene);
|
||||
|
||||
#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 = paw_memmalloc(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 = paw_memmalloc(mem, sizeof(enum PawCtrl) + sizeof($type)); \
|
||||
*$ret = $TYPE_ENUM; \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "ast_disc.h"
|
||||
|
||||
#include "../io.h"
|
||||
#include "../log.h"
|
||||
#include "../paw_log.h"
|
||||
#include "ast.h"
|
||||
|
||||
#define AO1($p) \
|
||||
|
@ -23,11 +23,10 @@ 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);
|
||||
int size = ast->mem->mem_size + sizeof(struct PawMem);
|
||||
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);
|
||||
region_end = ast->mem + ast->mem->mem_size + sizeof(struct PawMem);
|
||||
offset = -(long)region_start;
|
||||
apply_before = false;
|
||||
AO2(ast->mem->alloc);
|
||||
|
@ -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,12 +66,9 @@ 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);
|
||||
struct PawMem *mem = (struct PawMem *)data;
|
||||
|
||||
apply_before = true;
|
||||
for (int i = 0; i < MAX_ALLOCS; i++) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#include "../log.h"
|
||||
#include "../paw_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
12
src/lang/glue.c
Normal 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) {
|
||||
kitty_free(stack->scene->vk, vstack_poke_n(stack, offset).p);
|
||||
}
|
9
src/lang/glue.h
Normal file
9
src/lang/glue.h
Normal 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_
|
|
@ -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;
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#include "../log.h"
|
||||
#include "../paw_log.h"
|
||||
#include "ast.h"
|
||||
|
||||
struct VStack *vstack_make(struct Mem *mem, size_t size) {
|
||||
struct VStack *stack = mem_malloc(mem, sizeof(struct VStack));
|
||||
stack->left = mem_malloc(mem, size);
|
||||
struct VStack *vstack_make(struct PawMem *mem, size_t size) {
|
||||
struct VStack *stack = paw_memmalloc(mem, sizeof(struct VStack));
|
||||
stack->left = paw_memmalloc(mem, size);
|
||||
stack->right = stack->left + size;
|
||||
stack->top = stack->right;
|
||||
return stack;
|
||||
}
|
||||
void vstack_free(struct VStack *stack, struct Mem *mem) {
|
||||
mem_free(mem, stack->left);
|
||||
mem_free(mem, stack);
|
||||
void vstack_free(struct VStack *stack, struct PawMem *mem) {
|
||||
paw_memfree(mem, stack->left);
|
||||
paw_memfree(mem, stack);
|
||||
}
|
||||
|
||||
void vstack_pop(struct VStack *stack) {
|
||||
|
|
127
src/object.c
127
src/object.c
|
@ -1,127 +0,0 @@
|
|||
#include "object.h"
|
||||
#include "allocator.h"
|
||||
#include "dynarray.h"
|
||||
#include "log.h"
|
||||
#include "register.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define DT_TARGET 0.016
|
||||
|
||||
struct Scene *make_scene(struct Vk *vk, struct Register *reg) {
|
||||
struct Scene *scene = malloc(sizeof(struct Scene));
|
||||
memset(scene, 0, sizeof(struct Scene));
|
||||
scene->vk = vk;
|
||||
scene->mem = make_mem(100000);
|
||||
if (reg == NULL) {
|
||||
scene->reg = make_register();
|
||||
} else {
|
||||
scene->reg = reg;
|
||||
}
|
||||
|
||||
dyn_array_create_inplace_mem(&scene->objects, scene->mem);
|
||||
dyn_array_create_inplace_mem(&scene->insert_queue, scene->mem);
|
||||
dyn_array_create_inplace_mem(&scene->named, scene->mem);
|
||||
|
||||
struct timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
scene->msecs = time.tv_sec * 1000000 + time.tv_nsec / 1000;
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
void free_scene(struct Scene *scene) {
|
||||
for (int i = 0; i < scene->objects.count; i++) {
|
||||
scene->objects.items[i]->type->free(scene, scene->objects.items[i]->data);
|
||||
mem_free(scene->mem, scene->objects.items[i]);
|
||||
}
|
||||
dyn_array_destroy(&scene->objects);
|
||||
for (int i = 0; i < scene->insert_queue.count; i++) {
|
||||
scene->insert_queue.items[i]->type->free(
|
||||
scene, scene->insert_queue.items[i]->data);
|
||||
mem_free(scene->mem, scene->insert_queue.items[i]);
|
||||
}
|
||||
dyn_array_destroy(&scene->insert_queue);
|
||||
dyn_array_destroy(&scene->named);
|
||||
uninit_mem(scene->mem);
|
||||
|
||||
memset(scene, 0, sizeof(struct Scene));
|
||||
free(scene);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (scene->insert_queue.count > 0) {
|
||||
for (int i = 0; i < scene->insert_queue.count; i++) {
|
||||
dyn_array_append(&scene->objects, scene->insert_queue.items[i]);
|
||||
}
|
||||
scene->insert_queue.count = 0;
|
||||
}
|
||||
for (int i = 0; i < scene->objects.count; i++) {
|
||||
scene->objects.items[i]->type->tick(scene, scene->objects.items[i]->data);
|
||||
}
|
||||
if (scene->insert_queue.count > 0) {
|
||||
for (int i = 0; i < scene->insert_queue.count; i++) {
|
||||
dyn_array_append(&scene->objects, scene->insert_queue.items[i]);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
void scene_queue_insert(struct Scene *scene, char *name, void *object_data) {
|
||||
struct Type *type = reg_get_type(scene->reg, name);
|
||||
struct Object *object = mem_malloc(scene->mem, sizeof(struct Object));
|
||||
object->type = type;
|
||||
object->data = object_data;
|
||||
dyn_array_append(&scene->insert_queue, object);
|
||||
}
|
||||
void scene_queue_insert_from_data(struct Scene *scene, char *name, char *data,
|
||||
int len) {
|
||||
struct Type *type = reg_get_type(scene->reg, name);
|
||||
struct Object *object = mem_malloc(scene->mem, sizeof(struct Object));
|
||||
object->type = type;
|
||||
object->data = type->make(scene, data, len);
|
||||
dyn_array_append(&scene->insert_queue, object);
|
||||
}
|
||||
|
||||
void scene_register_named(struct Scene *scene, const char *id,
|
||||
struct Object *object) {
|
||||
dyn_array_append(&scene->named, ((struct Named){id, object}));
|
||||
}
|
||||
|
||||
void scene_unregister_named(struct Scene *scene, const char *id) {
|
||||
for (int i = 0; i < scene->named.count; i++) {
|
||||
if (strcmp(scene->named.items[i].id, id) == 0) {
|
||||
dyn_array_remove(&scene->named, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
meow("object with name %s was not found", id);
|
||||
}
|
||||
|
||||
struct Object *scene_get_named(struct Scene *scene, const char *id) {
|
||||
for (int i = 0; i < scene->named.count; i++) {
|
||||
if (strcmp(scene->named.items[i].id, id) == 0) {
|
||||
return scene->named.items[i].object;
|
||||
}
|
||||
}
|
||||
meow("object with name %s was not found", id);
|
||||
return NULL;
|
||||
}
|
42
src/object.h
42
src/object.h
|
@ -1,42 +0,0 @@
|
|||
#ifndef INCLUDE_WAYLANDCLIENT_OBJECT_H_
|
||||
#define INCLUDE_WAYLANDCLIENT_OBJECT_H_
|
||||
|
||||
#include "dynarray.h"
|
||||
// #include "vulkan_internal.h"
|
||||
|
||||
dyn_array_define(da_Object, struct Object *);
|
||||
dyn_array_define(da_Named, struct Named);
|
||||
|
||||
struct Scene {
|
||||
struct Vk *vk;
|
||||
struct Mem *mem;
|
||||
struct da_Object objects;
|
||||
struct da_Object insert_queue;
|
||||
struct da_Named named;
|
||||
struct Register *reg;
|
||||
|
||||
float delta_secs;
|
||||
long msecs;
|
||||
};
|
||||
|
||||
struct Object {
|
||||
struct Type *type;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct Named {
|
||||
const char *id;
|
||||
struct Object *object;
|
||||
};
|
||||
|
||||
struct Scene *make_scene(struct Vk *vk, struct Register *reg);
|
||||
void free_scene(struct Scene *scene);
|
||||
void scene_tick(struct Scene *scene);
|
||||
void scene_queue_insert(struct Scene *scene, char *name, void *object_data);
|
||||
|
||||
void scene_register_named(struct Scene *scene, const char *id,
|
||||
struct Object *object);
|
||||
void scene_unregister_named(struct Scene *scene, const char *id);
|
||||
struct Object *scene_get_named(struct Scene *scene, const char *id);
|
||||
|
||||
#endif // INCLUDE_WAYLANDCLIENT_OBJECT_H_
|
|
@ -1,5 +1,5 @@
|
|||
#include "allocator.h"
|
||||
#include "log.h"
|
||||
#include "paw_allocator.h"
|
||||
#include "paw_log.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
@ -7,21 +7,27 @@
|
|||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
struct Mem *make_mem(size_t size) {
|
||||
struct Mem *mem = malloc(sizeof(struct Mem) + size);
|
||||
struct PawMem *paw_memmake(size_t size) {
|
||||
struct PawMem *mem = malloc(sizeof(struct PawMem) + size);
|
||||
mem->mem_size = size;
|
||||
mem->mem = mem + 1;
|
||||
memset(mem->mem, 0, mem->mem_size);
|
||||
mem->count = 0;
|
||||
memset(&mem->allocs, 0, sizeof(struct Alloc) * MAX_ALLOCS);
|
||||
mem->allocs[0] = (struct Alloc){mem->mem + mem->mem_size, 0, NULL};
|
||||
mem->allocs[1] = (struct Alloc){mem->mem, 0, &mem->allocs[0]};
|
||||
memset(&mem->allocs, 0, sizeof(struct PawAlloc) * MAX_ALLOCS);
|
||||
mem->allocs[0] = (struct PawAlloc){mem->mem + mem->mem_size, 0, NULL};
|
||||
mem->allocs[1] = (struct PawAlloc){mem->mem, 0, &mem->allocs[0]};
|
||||
mem->alloc = &mem->allocs[1];
|
||||
return mem;
|
||||
}
|
||||
void uninit_mem(struct Mem *mem) { free(mem); }
|
||||
void paw_memunmake(struct PawMem *mem) {
|
||||
if (mem != NULL) {
|
||||
free(mem);
|
||||
} else {
|
||||
meow("tried to free a null mem");
|
||||
}
|
||||
}
|
||||
|
||||
static struct Alloc *get_next_alloc(struct Mem *mem) {
|
||||
static struct PawAlloc *get_next_alloc(struct PawMem *mem) {
|
||||
while (mem->allocs[mem->count].start != NULL ||
|
||||
mem->allocs[mem->count].size != 0 ||
|
||||
mem->allocs[mem->count].next != NULL) {
|
||||
|
@ -33,31 +39,31 @@ 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) {
|
||||
void *paw_malloc_memmalloc(struct PawMem *mem, size_t size) {
|
||||
if (mem == NULL) {
|
||||
return malloc(size);
|
||||
} else {
|
||||
return mem_malloc(mem, size);
|
||||
return paw_memmalloc(mem, size);
|
||||
}
|
||||
}
|
||||
void free_or_mem_free(struct Mem *mem, void *ptr) {
|
||||
void paw_free_memfree(struct PawMem *mem, void *ptr) {
|
||||
if (mem == NULL) {
|
||||
free(ptr);
|
||||
} else {
|
||||
mem_free(mem, ptr);
|
||||
paw_memfree(mem, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void *mem_malloc(struct Mem *mem, size_t size) {
|
||||
void *paw_memmalloc(struct PawMem *mem, size_t size) {
|
||||
if (size <= 0) {
|
||||
size = 1;
|
||||
}
|
||||
struct Alloc *prev = mem->alloc;
|
||||
struct PawAlloc *prev = mem->alloc;
|
||||
while (prev->next != NULL) {
|
||||
struct Alloc *next = prev->next;
|
||||
struct PawAlloc *next = prev->next;
|
||||
if (next->start - (prev->start + prev->size) > size && next != prev) {
|
||||
struct Alloc *new = get_next_alloc(mem);
|
||||
*new = (struct Alloc){
|
||||
struct PawAlloc *new = get_next_alloc(mem);
|
||||
*new = (struct PawAlloc){
|
||||
prev->start + prev->size,
|
||||
size,
|
||||
next,
|
||||
|
@ -76,16 +82,16 @@ void *mem_malloc(struct Mem *mem, size_t size) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void mem_free(struct Mem *mem, void *p) {
|
||||
struct Alloc *current = mem->alloc;
|
||||
struct Alloc *prev = mem->alloc;
|
||||
void paw_memfree(struct PawMem *mem, void *p) {
|
||||
struct PawAlloc *current = mem->alloc;
|
||||
struct PawAlloc *prev = mem->alloc;
|
||||
while (current != NULL && (p > current->start || current->size <= 0)) {
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
if (current == NULL || p != current->start) {
|
||||
meow("OOPSIE DAISY double free");
|
||||
print_backtrace();
|
||||
paw_print_backtrace();
|
||||
return;
|
||||
}
|
||||
prev->next = current->next;
|
||||
|
@ -95,5 +101,5 @@ void mem_free(struct Mem *mem, void *p) {
|
|||
}
|
||||
/*meow("FREE at %d : %p", index, current->start);
|
||||
print_backtrace(); */
|
||||
memset(&mem->allocs[index], 0, sizeof(struct Alloc));
|
||||
memset(&mem->allocs[index], 0, sizeof(struct PawAlloc));
|
||||
}
|
28
src/paw_allocator.h
Normal file
28
src/paw_allocator.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef INCLUDE_WAYLANDCLIENT_ALLOCATOR_H_
|
||||
#define INCLUDE_WAYLANDCLIENT_ALLOCATOR_H_
|
||||
|
||||
#include "sys/types.h"
|
||||
|
||||
#define MAX_ALLOCS 256
|
||||
struct PawAlloc {
|
||||
void *start;
|
||||
uint size;
|
||||
struct PawAlloc *next;
|
||||
};
|
||||
struct PawMem {
|
||||
void *mem;
|
||||
size_t mem_size;
|
||||
uint count;
|
||||
struct PawAlloc *alloc;
|
||||
struct PawAlloc allocs[MAX_ALLOCS];
|
||||
};
|
||||
|
||||
struct PawMem *paw_memmake(size_t size);
|
||||
void paw_memunmake(struct PawMem *mem);
|
||||
|
||||
void *paw_memmalloc(struct PawMem *mem, size_t size);
|
||||
void *paw_malloc_memmalloc(struct PawMem *mem, size_t size);
|
||||
void paw_memfree(struct PawMem *mem, void *p);
|
||||
void paw_free_memfree(struct PawMem *mem, void *ptr);
|
||||
|
||||
#endif // INCLUDE_WAYLANDCLIENT_ALLOCATOR_H_
|
|
@ -1,4 +1,4 @@
|
|||
#include "allocator.h"
|
||||
#include "paw_da.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -6,12 +6,12 @@ struct da_template {
|
|||
int count;
|
||||
int capacity;
|
||||
void *items;
|
||||
struct Mem *mem;
|
||||
struct PawMem *mem;
|
||||
};
|
||||
|
||||
// the array struct has to be freed manually, all internal data is freedd by
|
||||
// dyn_array_destroy
|
||||
void *dyn_array_create() {
|
||||
void *paw_da_make() {
|
||||
struct da_template *da = malloc(sizeof(struct da_template));
|
||||
da->items = malloc(0);
|
||||
da->capacity = 0;
|
||||
|
@ -21,24 +21,24 @@ void *dyn_array_create() {
|
|||
}
|
||||
// the array struct has to be freed manually, all internal data is freedd by
|
||||
// dyn_array_destroy
|
||||
void *dyn_array_create_mem(struct Mem *mem) {
|
||||
struct da_template *da = mem_malloc(mem, sizeof(struct da_template));
|
||||
da->items = mem_malloc(mem, 0);
|
||||
void *paw_da_make_mem(struct PawMem *mem) {
|
||||
struct da_template *da = paw_memmalloc(mem, sizeof(struct da_template));
|
||||
da->items = paw_memmalloc(mem, 0);
|
||||
da->capacity = 0;
|
||||
da->count = 0;
|
||||
da->mem = mem;
|
||||
return da;
|
||||
}
|
||||
void dyn_array_create_inplace(void *array) {
|
||||
void paw_da_make_inplace(void *array) {
|
||||
struct da_template *da = array;
|
||||
da->items = malloc(0);
|
||||
da->count = 0;
|
||||
da->capacity = 0;
|
||||
da->mem = NULL;
|
||||
}
|
||||
void dyn_array_create_inplace_mem(void *array, struct Mem *mem) {
|
||||
void paw_da_make_inplace_mem(void *array, struct PawMem *mem) {
|
||||
struct da_template *da = array;
|
||||
da->items = mem_malloc(mem, 0);
|
||||
da->items = paw_memmalloc(mem, 0);
|
||||
da->count = 0;
|
||||
da->capacity = 0;
|
||||
da->mem = mem;
|
|
@ -1,13 +1,13 @@
|
|||
#ifndef INCLUDE_WAYLANDCLIENT_DYNARRAY_H_
|
||||
#define INCLUDE_WAYLANDCLIENT_DYNARRAY_H_
|
||||
|
||||
#include "allocator.h"
|
||||
#include "paw_allocator.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define dyn_array_append(array, item) \
|
||||
#define paw_da_append(array, item) \
|
||||
do { \
|
||||
if ((array)->count >= (array)->capacity) { \
|
||||
(array)->capacity += 10; \
|
||||
|
@ -16,31 +16,39 @@
|
|||
(array)->capacity * sizeof(*(array)->items)); \
|
||||
} else { \
|
||||
void *temp = (array)->items; \
|
||||
(array)->items = mem_malloc( \
|
||||
(array)->items = paw_memmalloc( \
|
||||
(array)->mem, (array)->capacity * sizeof(*(array)->items)); \
|
||||
memcpy((array)->items, temp, \
|
||||
((array)->count) * sizeof(*(array)->items)); \
|
||||
mem_free((array)->mem, temp); \
|
||||
paw_memfree((array)->mem, temp); \
|
||||
} \
|
||||
} \
|
||||
(array)->items[(array)->count++] = (item); \
|
||||
} while (0)
|
||||
|
||||
#define dyn_array_remove(array, index) \
|
||||
#define paw_da_insert(array, index, item) \
|
||||
do { \
|
||||
paw_da_append(array, item); \
|
||||
memcpy(&(array)->items[(index) + 1], &(array)->items[(index)], \
|
||||
sizeof(*(array)->items) * ((array)->count - index)); \
|
||||
(array)->items[(index)] = (item); \
|
||||
} while (0)
|
||||
|
||||
#define paw_da_remove(array, index) \
|
||||
do { \
|
||||
(array)->items[(index)] = (array)->items[(array)->count - 1]; \
|
||||
memset(&(array)->items[(array)->count], 0, sizeof((array)->items[0])); \
|
||||
(array)->count--; \
|
||||
} while (0)
|
||||
|
||||
#define dyn_array_destroy(array) \
|
||||
#define paw_da_free(array) \
|
||||
if ((array)->mem == NULL) { \
|
||||
free((array)->items); \
|
||||
} else { \
|
||||
mem_free((array)->mem, (array)->items); \
|
||||
paw_memfree((array)->mem, (array)->items); \
|
||||
}
|
||||
|
||||
#define dyn_array_reset(array) \
|
||||
#define paw_da_reset(array) \
|
||||
do { \
|
||||
(array)->capacity = 10; \
|
||||
(array)->count = 0; \
|
||||
|
@ -48,26 +56,26 @@
|
|||
(array)->items = realloc((array)->items, \
|
||||
(array)->capacity * sizeof(*(array)->items)); \
|
||||
} else { \
|
||||
mem_free((array)->mem, (array)->items); \
|
||||
(array)->items = mem_malloc((array)->mem, (array)->capacity * \
|
||||
sizeof(*(array)->items)); \
|
||||
paw_memfree((array)->mem, (array)->items); \
|
||||
(array)->items = paw_memmalloc( \
|
||||
(array)->mem, (array)->capacity * sizeof(*(array)->items)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define dyn_array_define($name, $type) \
|
||||
#define paw_da_define($name, $type) \
|
||||
struct $name { \
|
||||
int count; \
|
||||
int capacity; \
|
||||
$type *items; \
|
||||
struct Mem *mem; \
|
||||
struct PawMem *mem; \
|
||||
}
|
||||
|
||||
dyn_array_define(da_uint32_t, uint32_t);
|
||||
dyn_array_define(da_string, char *);
|
||||
paw_da_define(da_uint32_t, uint32_t);
|
||||
paw_da_define(da_string, char *);
|
||||
|
||||
void *dyn_array_create();
|
||||
void *dyn_array_create_mem(struct Mem *mem);
|
||||
void dyn_array_create_inplace(void *array);
|
||||
void dyn_array_create_inplace_mem(void *array, struct Mem *mem);
|
||||
void *paw_da_make();
|
||||
void *paw_da_make_mem(struct PawMem *mem);
|
||||
void paw_da_make_inplace(void *array);
|
||||
void paw_da_make_inplace_mem(void *array, struct PawMem *mem);
|
||||
|
||||
#endif // INCLUDE_WAYLANDCLIENT_DYNARRAY_H_
|
|
@ -1,4 +1,4 @@
|
|||
#include "log.h"
|
||||
#include "paw_log.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <execinfo.h>
|
||||
|
@ -17,7 +17,7 @@ static void full_write(int fd, const char *buf, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
void print_backtrace() {
|
||||
void paw_print_backtrace() {
|
||||
static const char start[] = "BACKTRACE ------------\n";
|
||||
static const char end[] = "----------------------\n";
|
||||
|
||||
|
@ -38,7 +38,7 @@ void print_backtrace() {
|
|||
free(bt_syms);
|
||||
}
|
||||
|
||||
char *bool_to_string(bool b) {
|
||||
const char *paw_b_to_s(bool b) {
|
||||
if (b) {
|
||||
return "true";
|
||||
} else {
|
|
@ -11,7 +11,7 @@
|
|||
fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
*(int *)0 = 0;
|
||||
|
||||
void print_backtrace();
|
||||
char *bool_to_string(bool b);
|
||||
void paw_print_backtrace();
|
||||
const char *paw_b_to_s(bool b);
|
||||
|
||||
#endif // INCLUDE_WAYLANDCLIENT_LOG_H_
|
135
src/paw_object.c
Normal file
135
src/paw_object.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
#include "paw_object.h"
|
||||
#include "paw_allocator.h"
|
||||
#include "paw_log.h"
|
||||
#include "register.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define DT_TARGET 0.016
|
||||
|
||||
struct PawScene *paw_scene_make(struct Vk *vk, struct Register *reg) {
|
||||
struct PawScene *scene = malloc(sizeof(struct PawScene));
|
||||
memset(scene, 0, sizeof(struct PawScene));
|
||||
scene->vk = vk;
|
||||
scene->mem = paw_memmake(100000);
|
||||
if (reg == NULL) {
|
||||
scene->reg = make_register();
|
||||
} else {
|
||||
scene->reg = reg;
|
||||
}
|
||||
|
||||
paw_da_make_inplace_mem(&scene->objects, scene->mem);
|
||||
paw_da_make_inplace_mem(&scene->insert_queue, scene->mem);
|
||||
paw_da_make_inplace_mem(&scene->named, scene->mem);
|
||||
|
||||
struct timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
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;
|
||||
}
|
||||
|
||||
void paw_scene_free(struct PawScene *scene) {
|
||||
for (int i = 0; i < scene->objects.count; i++) {
|
||||
scene->objects.items[i]->type->free(scene, scene->objects.items[i]->data);
|
||||
paw_memfree(scene->mem, scene->objects.items[i]);
|
||||
}
|
||||
paw_da_free(&scene->objects);
|
||||
for (int i = 0; i < scene->insert_queue.count; i++) {
|
||||
scene->insert_queue.items[i]->type->free(
|
||||
scene, scene->insert_queue.items[i]->data);
|
||||
paw_memfree(scene->mem, scene->insert_queue.items[i]);
|
||||
}
|
||||
paw_da_free(&scene->insert_queue);
|
||||
paw_da_free(&scene->named);
|
||||
paw_memunmake(scene->mem);
|
||||
|
||||
memset(scene, 0, sizeof(struct PawScene));
|
||||
free(scene);
|
||||
}
|
||||
|
||||
void paw_scene_tick(struct PawScene *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->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++) {
|
||||
paw_da_append(&scene->objects, scene->insert_queue.items[i]);
|
||||
}
|
||||
scene->insert_queue.count = 0;
|
||||
}
|
||||
for (int i = 0; i < scene->objects.count; i++) {
|
||||
scene->objects.items[i]->type->tick(scene, scene->objects.items[i]->data);
|
||||
}
|
||||
if (scene->insert_queue.count > 0) {
|
||||
for (int i = 0; i < scene->insert_queue.count; i++) {
|
||||
paw_da_append(&scene->objects, scene->insert_queue.items[i]);
|
||||
}
|
||||
scene->insert_queue.count = 0;
|
||||
}
|
||||
|
||||
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 paw_scene_queue_insert(struct PawScene *scene, char *name,
|
||||
void *object_data) {
|
||||
struct Type *type = reg_get_type(scene->reg, name);
|
||||
struct PawObject *object =
|
||||
paw_memmalloc(scene->mem, sizeof(struct PawObject));
|
||||
object->type = type;
|
||||
object->data = object_data;
|
||||
paw_da_append(&scene->insert_queue, object);
|
||||
}
|
||||
void paw_scene_queue_insert_from_data(struct PawScene *scene, char *name,
|
||||
char *data, int len) {
|
||||
struct Type *type = reg_get_type(scene->reg, name);
|
||||
struct PawObject *object =
|
||||
paw_memmalloc(scene->mem, sizeof(struct PawObject));
|
||||
object->type = type;
|
||||
object->data = type->make(scene, data, len);
|
||||
paw_da_append(&scene->insert_queue, object);
|
||||
}
|
||||
|
||||
void paw_scene_reg_named(struct PawScene *scene, const char *id,
|
||||
struct PawObject *object) {
|
||||
paw_da_append(&scene->named, ((struct PawNamed){id, object}));
|
||||
}
|
||||
|
||||
void paw_scene_unreg_named(struct PawScene *scene, const char *id) {
|
||||
for (int i = 0; i < scene->named.count; i++) {
|
||||
if (strcmp(scene->named.items[i].id, id) == 0) {
|
||||
paw_da_remove(&scene->named, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
meow("object with name %s was not found", id);
|
||||
}
|
||||
|
||||
struct PawObject *paw_scene_get_named(struct PawScene *scene, const char *id) {
|
||||
for (int i = 0; i < scene->named.count; i++) {
|
||||
if (strcmp(scene->named.items[i].id, id) == 0) {
|
||||
return scene->named.items[i].object;
|
||||
}
|
||||
}
|
||||
meow("object with name %s was not found", id);
|
||||
return NULL;
|
||||
}
|
46
src/paw_object.h
Normal file
46
src/paw_object.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef INCLUDE_WAYLANDCLIENT_OBJECT_H_
|
||||
#define INCLUDE_WAYLANDCLIENT_OBJECT_H_
|
||||
|
||||
#include "paw_da.h"
|
||||
// #include "vulkan_internal.h"
|
||||
|
||||
paw_da_define(da_Object, struct PawObject *);
|
||||
paw_da_define(da_Named, struct PawNamed);
|
||||
|
||||
struct PawScene {
|
||||
struct Vk *vk;
|
||||
struct PawMem *mem;
|
||||
struct da_Object objects;
|
||||
struct da_Object insert_queue;
|
||||
struct da_Named named;
|
||||
struct Register *reg;
|
||||
|
||||
float delta_secs;
|
||||
long avg_delta;
|
||||
long sleep;
|
||||
long target_delta;
|
||||
long last_start_time;
|
||||
};
|
||||
|
||||
struct PawObject {
|
||||
struct Type *type;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct PawNamed {
|
||||
const char *id;
|
||||
struct PawObject *object;
|
||||
};
|
||||
|
||||
struct PawScene *paw_scene_make(struct Vk *vk, struct Register *reg);
|
||||
void paw_scene_free(struct PawScene *scene);
|
||||
void paw_scene_tick(struct PawScene *scene);
|
||||
void paw_scene_queue_insert(struct PawScene *scene, char *name,
|
||||
void *object_data);
|
||||
|
||||
void paw_scene_reg_named(struct PawScene *scene, const char *id,
|
||||
struct PawObject *object);
|
||||
void paw_scene_unreg_named(struct PawScene *scene, const char *id);
|
||||
struct PawObject *paw_scene_get_named(struct PawScene *scene, const char *id);
|
||||
|
||||
#endif // INCLUDE_WAYLANDCLIENT_OBJECT_H_
|
1
src/physics.c
Normal file
1
src/physics.c
Normal file
|
@ -0,0 +1 @@
|
|||
#include "physics.h"
|
25
src/physics.h
Normal file
25
src/physics.h
Normal 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_
|
|
@ -1,28 +1,27 @@
|
|||
#include "register.h"
|
||||
#include "dynarray.h"
|
||||
#include "log.h"
|
||||
#include "object.h"
|
||||
#include "paw_log.h"
|
||||
#include "paw_object.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct Register *make_register() {
|
||||
struct Register *reg = malloc(sizeof(struct Register));
|
||||
dyn_array_create_inplace(®->reg);
|
||||
paw_da_make_inplace(®->reg);
|
||||
return reg;
|
||||
}
|
||||
|
||||
void free_register(struct Register *reg) {
|
||||
dyn_array_destroy(®->reg);
|
||||
paw_da_free(®->reg);
|
||||
free(reg);
|
||||
}
|
||||
|
||||
void reg_attatch_type(struct Register *reg, char *name,
|
||||
void *(*make)(struct Scene *, char *, int len),
|
||||
void (*free)(struct Scene *, void *),
|
||||
void (*tick)(struct Scene *, void *)) {
|
||||
void *(*make)(struct PawScene *, char *, int len),
|
||||
void (*free)(struct PawScene *, void *),
|
||||
void (*tick)(struct PawScene *, void *)) {
|
||||
struct Type type = {name, make, free, tick};
|
||||
dyn_array_append(®->reg, type);
|
||||
paw_da_append(®->reg, type);
|
||||
}
|
||||
|
||||
struct Type *reg_get_type(struct Register *reg, char *name) {
|
||||
|
|
|
@ -1,33 +1,32 @@
|
|||
#ifndef INCLUDE_WAYLANDCLIENT_REGISTER_H_
|
||||
#define INCLUDE_WAYLANDCLIENT_REGISTER_H_
|
||||
|
||||
#include "dynarray.h"
|
||||
#include "object.h"
|
||||
#include "paw_object.h"
|
||||
|
||||
dyn_array_define(da_Type, struct Type);
|
||||
paw_da_define(da_Type, struct Type);
|
||||
|
||||
struct Type {
|
||||
char *name;
|
||||
|
||||
void *(*make)(struct Scene *, char *, int len);
|
||||
void (*free)(struct Scene *, void *);
|
||||
void (*tick)(struct Scene *, void *);
|
||||
void *(*make)(struct PawScene *, char *, int len);
|
||||
void (*free)(struct PawScene *, void *);
|
||||
void (*tick)(struct PawScene *, void *);
|
||||
};
|
||||
|
||||
struct Register {
|
||||
struct da_Type reg;
|
||||
};
|
||||
|
||||
#define OBJ_FREE (void (*)(struct Scene *, void *))
|
||||
#define OBJ_TICK (void (*)(struct Scene *, void *))
|
||||
#define OBJ_MAKE (void *(*)(struct Scene *, char *, int len))
|
||||
#define OBJ_FREE (void (*)(struct PawScene *, void *))
|
||||
#define OBJ_TICK (void (*)(struct PawScene *, void *))
|
||||
#define OBJ_MAKE (void *(*)(struct PawScene *, char *, int len))
|
||||
|
||||
struct Register *make_register();
|
||||
void free_register(struct Register *reg);
|
||||
struct Type *reg_get_type(struct Register *reg, char *name);
|
||||
void reg_attatch_type(struct Register *reg, char *name,
|
||||
void *(*make)(struct Scene *, char *, int len),
|
||||
void (*free)(struct Scene *, void *),
|
||||
void (*tick)(struct Scene *, void *));
|
||||
void *(*make)(struct PawScene *, char *, int len),
|
||||
void (*free)(struct PawScene *, void *),
|
||||
void (*tick)(struct PawScene *, void *));
|
||||
|
||||
#endif // INCLUDE_WAYLANDCLIENT_REGISTER_H_
|
||||
|
|
59
src/string.c
59
src/string.c
|
@ -1,27 +1,31 @@
|
|||
#include "string.h"
|
||||
#include "allocator.h"
|
||||
#include "log.h"
|
||||
#include "paw_allocator.h"
|
||||
#include "paw_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 split(struct PawMem *mem, char *string, char needle) {
|
||||
struct da_string items;
|
||||
dyn_array_create_inplace_mem(&items, mem);
|
||||
paw_da_make_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);
|
||||
char *tmp = paw_memmalloc(mem, i - last + 1);
|
||||
memcpy(tmp, &string[last], i - last);
|
||||
tmp[last - i + 1] = 0x0;
|
||||
dyn_array_append(&items, tmp);
|
||||
tmp[i - last + 1] = 0x0;
|
||||
paw_da_append(&items, tmp);
|
||||
last = i;
|
||||
}
|
||||
}
|
||||
char *tmp = paw_memmalloc(mem, strlen(string) - last + 1);
|
||||
memcpy(tmp, &string[last], strlen(string) - last);
|
||||
tmp[strlen(string) - last + 1] = 0x0;
|
||||
paw_da_append(&items, tmp);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
@ -30,7 +34,7 @@ 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 *extract_brackets(struct PawMem *mem, char *start, char open, char close) {
|
||||
char *end = skip_brackets(start, open, close);
|
||||
// { ... }
|
||||
// ^ end
|
||||
|
@ -43,13 +47,17 @@ char *extract_brackets(struct Mem *mem, char *start, char open, char close) {
|
|||
// { ... }
|
||||
// start ^ ^ end
|
||||
start++;
|
||||
char *res = mem_malloc(mem, end - start + 1);
|
||||
char *res = paw_memmalloc(mem, end - start + 1);
|
||||
memcpy(res, start, end - start);
|
||||
res[end - start] = 0x0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// before: asddasasd(aslfaddf)
|
||||
// ^
|
||||
// after: asddasasd(aslfaddf)
|
||||
// ^
|
||||
char *skip_brackets(char *start, char open, char close) {
|
||||
char *end = start;
|
||||
while (end[0] != open) {
|
||||
|
@ -82,14 +90,14 @@ int index_of_char(char *string, char key) {
|
|||
}
|
||||
}
|
||||
|
||||
char *extract(struct Mem *mem, char *string, int start, int size) {
|
||||
char *new = mem_malloc(mem, size + 1);
|
||||
char *extract(struct PawMem *mem, char *string, int start, int size) {
|
||||
char *new = paw_memmalloc(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 *extract_inbetween_chars(struct PawMem *mem, char *string, char one,
|
||||
char two) {
|
||||
int start = index_of_char(string, one) + 1;
|
||||
int end = index_of_char(string, two);
|
||||
|
@ -100,13 +108,13 @@ char *extract_inbetween_chars(struct Mem *mem, char *string, char one,
|
|||
return extract(mem, string, start, end - start);
|
||||
}
|
||||
|
||||
char *tmp_format(struct Mem *mem, char *format, ...) {
|
||||
char *tmp_format(struct PawMem *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));
|
||||
char *new = paw_memmalloc(mem, (strlen(res) + 1) * sizeof(char));
|
||||
memcpy(new, res, (strlen(res) + 1) * sizeof(char));
|
||||
|
||||
free(res);
|
||||
|
@ -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) {
|
||||
|
@ -156,16 +165,24 @@ bool includes_between(char *start, char *end, char n) {
|
|||
}
|
||||
}
|
||||
|
||||
char *mem_strdup(char *string, struct Mem *mem) {
|
||||
char *new = mem_malloc(mem, (strlen(string) + 1) * sizeof(char));
|
||||
char *mem_strdup(char *string, struct PawMem *mem) {
|
||||
char *new = paw_memmalloc(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;
|
||||
// inclusive!!!
|
||||
char *mem_strdup_reg(char *start, char *end, struct PawMem *mem) {
|
||||
char *new = paw_memmalloc(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;
|
||||
}
|
||||
|
||||
|
|
19
src/string.h
19
src/string.h
|
@ -1,27 +1,28 @@
|
|||
#ifndef INCLUDE_SRC_STRING_H_
|
||||
#define INCLUDE_SRC_STRING_H_
|
||||
|
||||
#include "allocator.h"
|
||||
#include "dynarray.h"
|
||||
#include "paw_allocator.h"
|
||||
#include "paw_da.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct da_string split(struct Mem *mem, char *string, char needle, int *count);
|
||||
struct da_string split(struct PawMem *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 *extract_brackets(struct PawMem *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 *extract(struct PawMem *mem, char *string, int start, int size);
|
||||
char *extract_inbetween_chars(struct PawMem *mem, char *string, char one,
|
||||
char two);
|
||||
char *tmp_format(struct Mem *mem, char *format, ...);
|
||||
char *tmp_format(struct PawMem *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 *mem_strdup(char *string, struct PawMem *mem);
|
||||
char *mem_strdup_reg(char *start, char *end, struct PawMem *mem);
|
||||
char *strdup_reg(char *start, char *end);
|
||||
char *skip_to_char(char *string, char n);
|
||||
char *skip_after_char(char *string, char n);
|
||||
|
||||
|
|
45
src/types.h
45
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_
|
||||
|
|
33
src/util.c
33
src/util.c
|
@ -1,8 +1,10 @@
|
|||
#include "allocator.h"
|
||||
#include "dynarray.h"
|
||||
#include "paw_allocator.h"
|
||||
#include "paw_da.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
float randf() { return (float)rand() / (float)RAND_MAX; }
|
||||
|
||||
struct ST_key {
|
||||
|
@ -10,29 +12,29 @@ struct ST_key {
|
|||
void *value;
|
||||
};
|
||||
|
||||
dyn_array_define(da_ST_key, struct ST_key);
|
||||
paw_da_define(da_ST_key, struct ST_key);
|
||||
|
||||
struct StringTable {
|
||||
struct da_ST_key keys;
|
||||
};
|
||||
|
||||
struct StringTable *st_make(struct Mem *mem) {
|
||||
struct StringTable *st_make(struct PawMem *mem) {
|
||||
struct StringTable *st =
|
||||
malloc_or_mem_malloc(mem, sizeof(struct StringTable));
|
||||
paw_malloc_memmalloc(mem, sizeof(struct StringTable));
|
||||
if (mem == NULL) {
|
||||
dyn_array_create_inplace(&st->keys);
|
||||
paw_da_make_inplace(&st->keys);
|
||||
} else {
|
||||
dyn_array_create_inplace_mem(&st->keys, mem);
|
||||
paw_da_make_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));
|
||||
paw_malloc_memmalloc(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.items = paw_malloc_memmalloc(new->keys.mem, sizeof(struct ST_key) *
|
||||
new->keys.capacity);
|
||||
memcpy(new->keys.items, st->keys.items,
|
||||
st->keys.capacity * sizeof(struct ST_key));
|
||||
|
@ -40,7 +42,7 @@ struct StringTable *st_dup(struct StringTable *st) {
|
|||
return new;
|
||||
}
|
||||
void st_insert(struct StringTable *st, char *key, void *value) {
|
||||
dyn_array_append(&st->keys, ((struct ST_key){.key = key, .value = value}));
|
||||
paw_da_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++) {
|
||||
|
@ -79,18 +81,13 @@ int st_get_index(struct StringTable *st, char *key) {
|
|||
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);
|
||||
paw_da_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);
|
||||
}
|
||||
paw_da_free(&st->keys);
|
||||
paw_free_memfree(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) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#define UINT32_NULL 42424242
|
||||
|
||||
#include "allocator.h"
|
||||
#include "paw_allocator.h"
|
||||
|
||||
float randf();
|
||||
|
||||
|
@ -16,7 +16,7 @@ float randf();
|
|||
} while (0)
|
||||
|
||||
struct StringTable;
|
||||
struct StringTable *st_make(struct Mem *mem);
|
||||
struct StringTable *st_make(struct PawMem *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);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "vulkan.h"
|
||||
#include "kitty.h"
|
||||
#include "log.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "image.h"
|
||||
|
@ -62,7 +61,7 @@ handle_vulkan_error(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
|||
}
|
||||
printf("%s\n", callbackData->pMessage);
|
||||
if (backtrace) {
|
||||
print_backtrace();
|
||||
paw_print_backtrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -737,7 +736,7 @@ struct Vk *init_vk(void *data, int width, int heigh,
|
|||
setup_command_buffers(state);
|
||||
setup_sync_objects(state);
|
||||
|
||||
dyn_array_create_inplace(&state->kitties);
|
||||
paw_da_make_inplace(&state->kitties);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
@ -745,7 +744,7 @@ struct Vk *init_vk(void *data, int width, int heigh,
|
|||
void uninit_vk(struct Vk *state) {
|
||||
CHECK_VK_RESULT(vkDeviceWaitIdle(state->device));
|
||||
|
||||
dyn_array_destroy(&state->kitties);
|
||||
paw_da_free(&state->kitties);
|
||||
|
||||
destroy_swapchain(state);
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#include <stdbool.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "dynarray.h"
|
||||
#include "log.h"
|
||||
#include "paw_da.h"
|
||||
#include "paw_log.h"
|
||||
#include "types.h"
|
||||
|
||||
struct GpuMem;
|
||||
|
@ -28,8 +28,8 @@ struct GpuPointer {
|
|||
|
||||
#define MAX_FRAMES_IN_FLIGHT 2
|
||||
|
||||
dyn_array_define(da_VK_FORMAT, enum VkFormat);
|
||||
dyn_array_define(da_Kitty, struct Kitty *);
|
||||
paw_da_define(da_VK_FORMAT, enum VkFormat);
|
||||
paw_da_define(da_Kitty, struct Kitty *);
|
||||
|
||||
struct VertexBuffer {
|
||||
void *data;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "log.h"
|
||||
#include "paw_log.h"
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include "dynarray.h"
|
||||
#include "hashmap.h"
|
||||
#include "log.h"
|
||||
#include "paw_da.h"
|
||||
#include "paw_log.h"
|
||||
|
||||
#include "vulkan.h"
|
||||
#include <vulkan/vulkan_wayland.h>
|
||||
|
@ -116,10 +116,10 @@ static void keyboard_event_key(void *data, struct wl_keyboard *wl_keyboard,
|
|||
xkb_state_key_get_utf8(state->xkb_state, key, buffer, sizeof(buffer));
|
||||
if (key_state == 1) {
|
||||
insert_hashmap_ui32(state->keys, sym);
|
||||
dyn_array_append(&state->pressed, sym);
|
||||
paw_da_append(&state->pressed, sym);
|
||||
} else if (key_state == 0) {
|
||||
remove_hashmap_ui32(state->keys, sym);
|
||||
dyn_array_append(&state->released, sym);
|
||||
paw_da_append(&state->released, sym);
|
||||
} else {
|
||||
meow("bad wayland, a key can either go up or down, not %d", key_state);
|
||||
}
|
||||
|
@ -243,8 +243,8 @@ struct cat_Wl *cat_init_wl(const char *name, int width, int heigh,
|
|||
struct cat_Wl *state = malloc(sizeof(struct cat_Wl));
|
||||
memset(state, 0, sizeof(struct cat_Wl));
|
||||
state->keys = create_hashmap_ui32();
|
||||
dyn_array_create_inplace(&state->pressed);
|
||||
dyn_array_create_inplace(&state->released);
|
||||
paw_da_make_inplace(&state->pressed);
|
||||
paw_da_make_inplace(&state->released);
|
||||
|
||||
state->should_close = state->resize_ready = state->resize_coming = false;
|
||||
|
||||
|
@ -279,8 +279,8 @@ struct cat_Wl *cat_init_wl(const char *name, int width, int heigh,
|
|||
}
|
||||
|
||||
void cat_wl_draw(struct cat_Wl *state) {
|
||||
dyn_array_reset(&state->pressed);
|
||||
dyn_array_reset(&state->released);
|
||||
paw_da_reset(&state->pressed);
|
||||
paw_da_reset(&state->released);
|
||||
|
||||
if (state->resize_ready && state->resize_coming) {
|
||||
meow("resizing to %d x %d", state->new_width, state->new_heigh);
|
||||
|
@ -306,8 +306,8 @@ void cat_uninit_wl(struct cat_Wl *state) {
|
|||
uninit_vk(state->vk);
|
||||
|
||||
destroy_hashmap_ui32(state->keys);
|
||||
dyn_array_destroy(&state->pressed);
|
||||
dyn_array_destroy(&state->released);
|
||||
paw_da_free(&state->pressed);
|
||||
paw_da_free(&state->released);
|
||||
|
||||
if (state->xkb_state != NULL) {
|
||||
xkb_state_unref(state->xkb_state);
|
||||
|
|
20
trig.c
20
trig.c
|
@ -1,8 +1,8 @@
|
|||
#include "src/allocator.h"
|
||||
#include "src/kitty.h"
|
||||
#include "src/log.h"
|
||||
#include "src/matrix.h"
|
||||
#include "src/object.h"
|
||||
#include "src/paw_allocator.h"
|
||||
#include "src/paw_log.h"
|
||||
#include "src/paw_object.h"
|
||||
#include "src/types.h"
|
||||
#include "src/util.h"
|
||||
|
||||
|
@ -34,8 +34,8 @@ struct TrigUBO {
|
|||
struct mat3x3 view;
|
||||
struct mat3x3 proj;
|
||||
};
|
||||
struct Trig *trig_make_args(struct Scene *scene) {
|
||||
struct Trig *trig = mem_malloc(scene->mem, sizeof(struct Trig));
|
||||
struct Trig *trig_make_args(struct PawScene *scene) {
|
||||
struct Trig *trig = paw_memmalloc(scene->mem, sizeof(struct Trig));
|
||||
|
||||
trig->kitty = kitty_make(scene->mem);
|
||||
kitty_set_vertex_shader(trig->kitty, "./Shaders/vert.spv");
|
||||
|
@ -67,16 +67,16 @@ struct Trig *trig_make_args(struct Scene *scene) {
|
|||
return trig;
|
||||
}
|
||||
|
||||
struct Trig *make_trig(struct Scene *scene, char *_data, int _len) {
|
||||
struct Trig *make_trig(struct PawScene *scene, char *_data, int _len) {
|
||||
return trig_make_args(scene);
|
||||
}
|
||||
|
||||
void free_trig(struct Scene *scene, struct Trig *trig) {
|
||||
free_kitty(scene->vk, trig->kitty);
|
||||
mem_free(scene->mem, trig);
|
||||
void free_trig(struct PawScene *scene, struct Trig *trig) {
|
||||
kitty_free(scene->vk, trig->kitty);
|
||||
paw_memfree(scene->mem, trig);
|
||||
}
|
||||
|
||||
void trig_tick(struct Scene *scene, struct Trig *trig) {
|
||||
void trig_tick(struct PawScene *scene, struct Trig *trig) {
|
||||
struct TrigUBO ubo = {0};
|
||||
ubo.view = multiply3x3(translate3x3((struct Vec2){-1.5f, -0.5f}),
|
||||
scale3x3((struct Vec2){1.0f, 1.0f}));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue