calls! not quit yet~
This commit is contained in:
parent
5f36739c9c
commit
b532f44d28
6 changed files with 252 additions and 87 deletions
2
Makefile
2
Makefile
|
@ -13,7 +13,7 @@ S+=vulkan.c kitty.c
|
|||
S+=gpu_allocator.c hashmap.c util.c io.c matrix.c dynarray.c image.c types.c allocator.c log.c
|
||||
S+=object.c register.c
|
||||
S+=Wayland/xdg-shell-protocol.c
|
||||
S+=lang/ast.c
|
||||
S+=lang/ast.c lang/vstack.c
|
||||
SO=$(addprefix build/,$(S:.c=.o))
|
||||
SC=$(addprefix src/,$(S))
|
||||
|
||||
|
|
14
main.c
14
main.c
|
@ -13,15 +13,15 @@ int main() {
|
|||
ast_insert_property(ast, "i", make_pawval_int(ast->mem, 0));
|
||||
|
||||
enum PawCtrl *body = make_pawctrl_seq(ast->mem);
|
||||
pawctrl_append(body, make_pawctrl_call(ast->mem, ping_func));
|
||||
pawctrl_append(body,
|
||||
make_pawctrl_asign(
|
||||
ast->mem, ast_get_property(ast, "i"),
|
||||
make_pawval_expr(ast->mem, ast_get_property(ast, "i"),
|
||||
make_pawval_int(ast->mem, 1), op_add)));
|
||||
/* pawseq_append(body, make_pawctrl_call(ast->mem, ping_func)); */
|
||||
pawseq_append(body,
|
||||
make_pawctrl_asign(
|
||||
ast->mem, PSV_P(ast_get_property(ast, "i")),
|
||||
make_pawval_expr(ast->mem, ast_get_property(ast, "i"),
|
||||
make_pawval_int(ast->mem, 1), op_add)));
|
||||
meow("add is at %p", op_add);
|
||||
meow("eq is at %p", op_unequals);
|
||||
pawctrl_append(
|
||||
pawseq_append(
|
||||
ast->prog,
|
||||
make_pawctrl_while(ast->mem,
|
||||
make_pawval_expr(ast->mem, ast_get_property(ast, "i"),
|
||||
|
|
199
src/lang/ast.c
199
src/lang/ast.c
|
@ -29,6 +29,11 @@ struct PawStackVal op_equals(struct PawAST *ast, struct PawStackVal lhs,
|
|||
case PAW_VAL_BOOL:
|
||||
return PSV_BOOL(lhs.b == rhs.b);
|
||||
}
|
||||
case PAW_VAL_CHAR:
|
||||
switch (rhs.type) {
|
||||
case PAW_VAL_CHAR:
|
||||
return PSV_BOOL(lhs.c == rhs.c);
|
||||
}
|
||||
}
|
||||
meow("trying to compare %s to %s, not suppported", print_valtype(lhs.type),
|
||||
print_valtype(rhs.type));
|
||||
|
@ -43,12 +48,14 @@ const char *print_valtype(enum PawVal type) {
|
|||
return "int";
|
||||
case PAW_VAL_BOOL:
|
||||
return "bool";
|
||||
case PAW_VAL_FUNC:
|
||||
return "call";
|
||||
case PAW_VAL_POINT:
|
||||
return "void*";
|
||||
case PAW_VAL_SPOINT:
|
||||
return "stack*";
|
||||
case PAW_VAL_EXPR:
|
||||
return "expr";
|
||||
case PAW_VAL_CHAR:
|
||||
return "char";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,6 +69,10 @@ const char *print_ctrltype(enum PawCtrl ctrl) {
|
|||
return "asign";
|
||||
case PAW_CTRL_CALL:
|
||||
return "call";
|
||||
case PAW_CTRL_SPUSH:
|
||||
return "SPUSH";
|
||||
case PAW_CTRL_SPOP:
|
||||
return "SPOP";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,6 +98,11 @@ struct PawStackVal try_cast_stack(enum PawVal target, struct PawStackVal val) {
|
|||
case PAW_VAL_BOOL:
|
||||
return PSV_BOOL((bool)val.b);
|
||||
}
|
||||
case PAW_VAL_CHAR:
|
||||
switch (val.type) {
|
||||
case PAW_VAL_CHAR:
|
||||
return PSV_CHAR((char)val.c);
|
||||
}
|
||||
}
|
||||
meow("trying to cast %s to %s, returning null", print_valtype(val.type),
|
||||
print_valtype(target));
|
||||
|
@ -113,6 +129,11 @@ struct PawStackVal try_cast(enum PawVal target, enum PawVal *val) {
|
|||
case PAW_VAL_BOOL:
|
||||
return PSV_BOOL((bool)*(bool *)val_get_data(val));
|
||||
}
|
||||
case PAW_VAL_CHAR:
|
||||
switch (*val) {
|
||||
case PAW_VAL_CHAR:
|
||||
return PSV_CHAR((char)*(char *)val_get_data(val));
|
||||
}
|
||||
}
|
||||
meow("trying to cast %s to %s, returning null", print_valtype(*val),
|
||||
print_valtype(target));
|
||||
|
@ -174,12 +195,28 @@ enum PawVal *make_pawval_bool(struct Mem *mem, bool n) {
|
|||
|
||||
enum PawVal *make_pawval_point(struct Mem *mem, paw_p n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, paw_p, PAW_VAL_INT);
|
||||
val_make(val, paw_p, PAW_VAL_POINT);
|
||||
paw_p *i = val_get_data(val);
|
||||
*i = n;
|
||||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_spoint(struct Mem *mem, paw_sp n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, paw_sp, PAW_VAL_SPOINT);
|
||||
paw_sp *i = val_get_data(val);
|
||||
*i = n;
|
||||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_char(struct Mem *mem, char n) {
|
||||
enum PawVal *val;
|
||||
val_make(val, paw_p, PAW_VAL_CHAR);
|
||||
char *i = val_get_data(val);
|
||||
*i = n;
|
||||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs,
|
||||
enum PawVal *rhs, paw_p op) {
|
||||
enum PawVal *val;
|
||||
|
@ -191,24 +228,16 @@ enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs,
|
|||
return val;
|
||||
}
|
||||
|
||||
enum PawVal *make_pawval_func(struct Mem *mem) {
|
||||
enum PawVal *val;
|
||||
val_make(val, struct PawFunc, PAW_VAL_FUNC);
|
||||
struct PawFunc *i = val_get_data(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
void free_pawval(struct Mem *mem, enum PawVal *val) {
|
||||
switch (*val) {
|
||||
case PAW_VAL_FLOAT:
|
||||
case PAW_VAL_INT:
|
||||
case PAW_VAL_BOOL:
|
||||
case PAW_VAL_POINT:
|
||||
case PAW_VAL_SPOINT:
|
||||
case PAW_VAL_CHAR:
|
||||
mem_free(mem, val);
|
||||
break;
|
||||
case PAW_VAL_FUNC:
|
||||
crash("todo");
|
||||
break;
|
||||
case PAW_VAL_EXPR:;
|
||||
struct PawExpr *expr = val_get_data(val);
|
||||
free_pawval(mem, expr->lhs);
|
||||
|
@ -226,11 +255,23 @@ enum PawCtrl *make_pawctrl_seq(struct Mem *mem) {
|
|||
return ctrl;
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_call(struct Mem *mem, paw_p addr) {
|
||||
enum PawCtrl *make_pawctrl_call(struct Mem *mem, enum PawCtrl *body) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawCall, PAW_CTRL_CALL);
|
||||
struct PawCall *i = ctrl_get_data(ctrl);
|
||||
i->addr = addr;
|
||||
i->body = body;
|
||||
return ctrl;
|
||||
}
|
||||
enum PawCtrl *make_pawctrl_spush(struct Mem *mem, struct PawStackVal val) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawCall, PAW_CTRL_SPUSH);
|
||||
struct PawStackPush *i = ctrl_get_data(ctrl);
|
||||
i->v = val;
|
||||
return ctrl;
|
||||
}
|
||||
enum PawCtrl *make_pawctrl_spop(struct Mem *mem) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawCall, PAW_CTRL_SPOP);
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
|
@ -244,7 +285,7 @@ enum PawCtrl *make_pawctrl_while(struct Mem *mem, enum PawVal *cond,
|
|||
return ctrl;
|
||||
}
|
||||
|
||||
enum PawCtrl *make_pawctrl_asign(struct Mem *mem, enum PawVal *target,
|
||||
enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target,
|
||||
enum PawVal *val) {
|
||||
enum PawCtrl *ctrl;
|
||||
ctrl_make(ctrl, struct PawAsign, PAW_CTRL_ASIGN);
|
||||
|
@ -254,7 +295,7 @@ enum PawCtrl *make_pawctrl_asign(struct Mem *mem, enum PawVal *target,
|
|||
return ctrl;
|
||||
}
|
||||
|
||||
void pawctrl_append(enum PawCtrl *seq, enum PawCtrl *ctrl) {
|
||||
void pawseq_append(enum PawCtrl *seq, enum PawCtrl *ctrl) {
|
||||
struct PawSeq *seqval = ctrl_get_data(seq);
|
||||
dyn_array_append(&seqval->seq, ctrl);
|
||||
}
|
||||
|
@ -331,10 +372,14 @@ void ast_stack_push(struct Stack *stack, enum PawCtrl *ctrl) {
|
|||
stack_push(stack, ctrl);
|
||||
break;
|
||||
case PAW_CTRL_ASIGN:
|
||||
case PAW_CTRL_CALL:
|
||||
case PAW_CTRL_WHILE:
|
||||
case PAW_CTRL_SPUSH:
|
||||
case PAW_CTRL_SPOP:
|
||||
stack_push(stack, ctrl);
|
||||
break;
|
||||
case PAW_CTRL_CALL:
|
||||
stack_push(stack, NULL);
|
||||
stack_push(stack, ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,28 +390,15 @@ struct PawStackVal ast_eval(struct PawAST *ast, enum PawVal *val) {
|
|||
LS("evaling a %s", print_valtype(*val));
|
||||
switch (*val) {
|
||||
case PAW_VAL_FLOAT:
|
||||
return (struct PawStackVal){
|
||||
PAW_VAL_FLOAT,
|
||||
.f = *(float *)val_get_data(val),
|
||||
};
|
||||
return PSV_FLOAT(*(float *)val_get_data(val));
|
||||
case PAW_VAL_INT:
|
||||
return (struct PawStackVal){
|
||||
PAW_VAL_INT,
|
||||
.i = *(int *)val_get_data(val),
|
||||
};
|
||||
return PSV_INT(*(int *)val_get_data(val));
|
||||
case PAW_VAL_BOOL:
|
||||
return (struct PawStackVal){
|
||||
PAW_VAL_BOOL,
|
||||
.b = *(float *)val_get_data(val),
|
||||
};
|
||||
return PSV_BOOL(*(float *)val_get_data(val));
|
||||
case PAW_VAL_POINT:
|
||||
return (struct PawStackVal){
|
||||
PAW_VAL_POINT,
|
||||
.b = *(paw_p *)val_get_data(val),
|
||||
};
|
||||
case PAW_VAL_FUNC:
|
||||
meow("todo");
|
||||
break;
|
||||
return PSV_P(*(paw_p *)val_get_data(val));
|
||||
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 %p", expr->op);
|
||||
|
@ -395,6 +427,8 @@ void unwind_stack(struct Stack *stack) {
|
|||
void ast_exec(struct PawAST *ast) {
|
||||
meow("allocing stack");
|
||||
struct Stack *stack = stack_make(ast->mem, 2048);
|
||||
struct VStack *vstack = vstack_make(ast->mem, 2048);
|
||||
int offset = 0;
|
||||
ast_stack_push(stack, ast->prog);
|
||||
meow("starting exec");
|
||||
while (stack->top < stack->right) {
|
||||
|
@ -415,10 +449,14 @@ void ast_exec(struct PawAST *ast) {
|
|||
case PAW_CTRL_CALL:;
|
||||
LS("CALL");
|
||||
struct PawCall *call = ctrl_get_data(ctrl);
|
||||
if (call->addr == ast->ping_func) {
|
||||
ping_func();
|
||||
if (stack_poke2(stack) == NULL) {
|
||||
stack_set2(stack, (void *)(uint64_t)(offset));
|
||||
} else {
|
||||
vstack_reset_to_offset(vstack, offset);
|
||||
offset = (uint64_t)stack_poke2(stack);
|
||||
stack_pop(stack);
|
||||
stack_pop(stack);
|
||||
}
|
||||
stack_pop(stack);
|
||||
break;
|
||||
case PAW_CTRL_WHILE:;
|
||||
LS("WHILE");
|
||||
|
@ -439,39 +477,64 @@ void ast_exec(struct PawAST *ast) {
|
|||
break;
|
||||
case PAW_CTRL_ASIGN:;
|
||||
LS("ASIGN");
|
||||
struct PawAsign *asign = ctrl_get_data(ctrl);
|
||||
struct PawStackVal val =
|
||||
try_cast_stack(*asign->lhs, ast_eval(ast, asign->rhs));
|
||||
if (val.type != *asign->lhs) {
|
||||
meow("woopsie wrong type, expected %s but got %s",
|
||||
print_valtype(*asign->lhs), print_valtype(val.type));
|
||||
struct PawAsign *asign = val_get_data(ctrl);
|
||||
struct PawStackVal val = ast_eval(ast, asign->rhs);
|
||||
if (asign->lhs.type == PAW_VAL_SPOINT) {
|
||||
val = try_cast_stack(
|
||||
vstack_poke_n_after(vstack, asign->lhs.sp, offset).type, val);
|
||||
} else if (asign->lhs.type == PAW_VAL_POINT) {
|
||||
val = try_cast_stack(*(enum PawVal *)val.p, val);
|
||||
}
|
||||
if (val.type == PAW_VAL_POINT && val.p == NULL) {
|
||||
meow("woopsie wrong type,,,,");
|
||||
unwind_stack(stack);
|
||||
}
|
||||
switch (val.type) {
|
||||
case PAW_VAL_FLOAT:;
|
||||
float *ft = val_get_data(asign->lhs);
|
||||
*ft = val.f;
|
||||
break;
|
||||
case PAW_VAL_INT:;
|
||||
int *it = val_get_data(asign->lhs);
|
||||
*it = val.i;
|
||||
break;
|
||||
case PAW_VAL_BOOL:
|
||||
bool *bt = val_get_data(asign->lhs);
|
||||
*bt = val.b;
|
||||
break;
|
||||
case PAW_VAL_POINT:;
|
||||
paw_p *pt = val_get_data(asign->lhs);
|
||||
*pt = val.p;
|
||||
break;
|
||||
case PAW_VAL_EXPR:
|
||||
case PAW_VAL_FUNC:
|
||||
meow("whhooopsie not primitive");
|
||||
unwind_stack(stack);
|
||||
break;
|
||||
if (asign->lhs.type == PAW_VAL_SPOINT) {
|
||||
vstack_set_n_after(vstack, asign->lhs.sp, offset, val);
|
||||
} else {
|
||||
enum PawVal *target = asign->lhs.p;
|
||||
switch (val.type) {
|
||||
case PAW_VAL_FLOAT:;
|
||||
float *ft = val_get_data(target);
|
||||
*ft = val.f;
|
||||
break;
|
||||
case PAW_VAL_INT:;
|
||||
int *it = val_get_data(target);
|
||||
*it = val.i;
|
||||
break;
|
||||
case PAW_VAL_BOOL:
|
||||
bool *bt = val_get_data(target);
|
||||
*bt = val.b;
|
||||
break;
|
||||
case PAW_VAL_POINT:;
|
||||
paw_p *pt = val_get_data(target);
|
||||
*pt = val.p;
|
||||
break;
|
||||
case PAW_VAL_SPOINT:
|
||||
break;
|
||||
case PAW_VAL_CHAR:;
|
||||
char *pc = val_get_data(target);
|
||||
*pc = val.c;
|
||||
break;
|
||||
case PAW_VAL_EXPR:
|
||||
meow("whhooopsie not primitive");
|
||||
unwind_stack(stack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
stack_pop(stack);
|
||||
break;
|
||||
case PAW_CTRL_SPUSH:
|
||||
LS("SPUSH");
|
||||
struct PawStackPush *push = val_get_data(ctrl);
|
||||
vstack_push(vstack, push->v);
|
||||
stack_pop(stack);
|
||||
break;
|
||||
case PAW_CTRL_SPOP:
|
||||
LS("SPOP");
|
||||
vstack_pop(vstack);
|
||||
stack_pop(stack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
meow("ending exec");
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -6,6 +7,7 @@
|
|||
#include "../dynarray.h"
|
||||
|
||||
#define paw_p void *
|
||||
#define paw_sp int
|
||||
#define PSV_NULL \
|
||||
(struct PawStackVal) { PAW_VAL_POINT, .p = NULL }
|
||||
#define PAW_STACK_SIZE 2048
|
||||
|
@ -17,6 +19,10 @@
|
|||
(struct PawStackVal) { PAW_VAL_INT, .i = ($v) }
|
||||
#define PSV_P($v) \
|
||||
(struct PawStackVal) { PAW_VAL_POINT, .p = ($v) }
|
||||
#define PSV_SP($v) \
|
||||
(struct PawStackVal) { PAW_VAL_SPOINT, .sp = ($v) }
|
||||
#define PSV_CHAR($v) \
|
||||
(struct PawStackVal) { PAW_VAL_CHAR, .c = ($v) }
|
||||
|
||||
#define LS(fmt, ...) \
|
||||
if (log_stack) { \
|
||||
|
@ -33,8 +39,9 @@ enum PawVal {
|
|||
PAW_VAL_FLOAT,
|
||||
PAW_VAL_INT,
|
||||
PAW_VAL_BOOL,
|
||||
PAW_VAL_FUNC,
|
||||
PAW_VAL_CHAR,
|
||||
PAW_VAL_POINT,
|
||||
PAW_VAL_SPOINT,
|
||||
PAW_VAL_EXPR,
|
||||
};
|
||||
|
||||
|
@ -42,16 +49,13 @@ enum PawCtrl {
|
|||
PAW_CTRL_SEQ,
|
||||
PAW_CTRL_WHILE,
|
||||
PAW_CTRL_ASIGN,
|
||||
PAW_CTRL_SPUSH,
|
||||
PAW_CTRL_SPOP,
|
||||
PAW_CTRL_CALL,
|
||||
};
|
||||
dyn_array_define(da_paw_ctrl, enum PawCtrl *);
|
||||
dyn_array_define(da_paw_val, enum PawVal *);
|
||||
|
||||
struct PawFunc {
|
||||
enum PawVal *body;
|
||||
struct da_paw_val val;
|
||||
};
|
||||
|
||||
struct PawProperty {
|
||||
char *name;
|
||||
enum PawVal *val;
|
||||
|
@ -79,7 +83,9 @@ struct PawStackVal {
|
|||
float f;
|
||||
int i;
|
||||
bool b;
|
||||
char c;
|
||||
paw_p p;
|
||||
paw_sp sp;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -96,12 +102,16 @@ struct PawWhile {
|
|||
};
|
||||
|
||||
struct PawAsign {
|
||||
enum PawVal *lhs;
|
||||
struct PawStackVal lhs;
|
||||
enum PawVal *rhs;
|
||||
};
|
||||
|
||||
struct PawStackPush {
|
||||
struct PawStackVal v;
|
||||
};
|
||||
|
||||
struct PawCall {
|
||||
paw_p addr;
|
||||
enum PawCtrl *body;
|
||||
};
|
||||
|
||||
struct PawStackVal op_equals(struct PawAST *ast, struct PawStackVal lhs,
|
||||
|
@ -119,12 +129,14 @@ enum PawVal *make_pawval_expr(struct Mem *mem, enum PawVal *lhs,
|
|||
enum PawVal *rhs, paw_p op);
|
||||
void free_pawval(struct Mem *mem, enum PawVal *val);
|
||||
enum PawCtrl *make_pawctrl_seq(struct Mem *mem);
|
||||
enum PawCtrl *make_pawctrl_call(struct Mem *mem, paw_p addr);
|
||||
enum PawCtrl *make_pawctrl_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_while(struct Mem *mem, enum PawVal *cond,
|
||||
enum PawCtrl *body);
|
||||
enum PawCtrl *make_pawctrl_asign(struct Mem *mem, enum PawVal *target,
|
||||
enum PawCtrl *make_pawctrl_asign(struct Mem *mem, struct PawStackVal target,
|
||||
enum PawVal *val);
|
||||
void pawctrl_append(enum PawCtrl *seq, enum PawCtrl *ctrl);
|
||||
void pawseq_append(enum PawCtrl *seq, enum PawCtrl *ctrl);
|
||||
void ping_func();
|
||||
struct PawAST *ast_make();
|
||||
void ast_insert_property(struct PawAST *ast, char *name, enum PawVal *val);
|
||||
|
@ -144,3 +156,21 @@ void ast_exec(struct PawAST *ast);
|
|||
$ret = mem_malloc(mem, sizeof(enum PawCtrl) + sizeof($type)); \
|
||||
*$ret = $TYPE_ENUM; \
|
||||
} while (0)
|
||||
|
||||
struct VStack {
|
||||
void *left;
|
||||
void *right;
|
||||
void *top;
|
||||
};
|
||||
struct VStack *vstack_make(struct Mem *mem, size_t size);
|
||||
void vstack_free(struct VStack *stack, struct Mem *mem);
|
||||
void vstack_pop(struct VStack *stack);
|
||||
void vstack_push(struct VStack *stack, struct PawStackVal val);
|
||||
struct PawStackVal vstack_poke(struct VStack *stack);
|
||||
// 0 being the top of the stack, 1 the element left of that and so on
|
||||
struct PawStackVal vstack_poke_n(struct VStack *stack, int n);
|
||||
struct PawStackVal vstack_poke_n_after(struct VStack *stack, int n, int offset);
|
||||
void vstack_set_n_after(struct VStack *stack, int n, int offset,
|
||||
struct PawStackVal val);
|
||||
// make offset the top of the stack
|
||||
void vstack_reset_to_offset(struct VStack *stack, int offset);
|
||||
|
|
22
src/lang/design.md
Normal file
22
src/lang/design.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
|
||||
|
||||
## the vstack
|
||||
new values can be pushed with PAW_CTRL_SPUSH.
|
||||
and popped with PAW_CTRL_POP
|
||||
values will be popped whenn the function returns.
|
||||
these values can be asigned and read through paw_sp, PawStackVal.sp and PAW_VAL_SPOINT
|
||||
a paw_sp is essentially just an int used to look up the value
|
||||
paw_sp starts at 0 and then counts up (but due to 0 being the return value one could argue it actually starts at 1)
|
||||
|
||||
## calls
|
||||
a call esentially resets the vstack offset, meaning the new function starts at 0
|
||||
upon returning the result is pushed to the vstack
|
||||
the previous vstack offset is pushed to the cstack
|
||||
|
||||
the initial vstack layout of a function looks like this:
|
||||
prev func | ret | args | func vars
|
||||
^
|
||||
| top, an asign instruction with an paw_sp of -number of args will set the return value
|
||||
|
||||
after the call all function vars will be popped automatically
|
50
src/lang/vstack.c
Normal file
50
src/lang/vstack.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include "../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);
|
||||
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_pop(struct VStack *stack) {
|
||||
stack->top = stack->top + sizeof(struct PawStackVal);
|
||||
if (stack->top > stack->right) {
|
||||
meow("pop stack is %p:%p:%p", stack->left, stack->top, stack->right);
|
||||
crash("uuuh am in cellar");
|
||||
}
|
||||
}
|
||||
|
||||
void vstack_push(struct VStack *stack, struct PawStackVal val) {
|
||||
stack->top = stack->top - sizeof(void *);
|
||||
if (stack->top < stack->left) {
|
||||
crash("uuuh am in space");
|
||||
}
|
||||
*(struct PawStackVal *)stack->top = val;
|
||||
}
|
||||
|
||||
struct PawStackVal vstack_poke(struct VStack *stack) {
|
||||
return *(struct PawStackVal *)stack->top;
|
||||
}
|
||||
|
||||
struct PawStackVal vstack_poke_n(struct VStack *stack, int n) {
|
||||
return *(((struct PawStackVal *)stack->top) - n);
|
||||
}
|
||||
|
||||
struct PawStackVal vstack_poke_n_after(struct VStack *stack, int n,
|
||||
int offset) {
|
||||
return *(((struct PawStackVal *)stack->right) - offset - n);
|
||||
}
|
||||
void vstack_set_n_after(struct VStack *stack, int n, int offset,
|
||||
struct PawStackVal val) {
|
||||
*(((struct PawStackVal *)stack->right) - offset - n) = val;
|
||||
}
|
||||
void vstack_reset_to_offset(struct VStack *stack, int offset) {
|
||||
stack->top = (void *)(((struct PawStackVal *)stack->right) - offset);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue