c-scripting/examples/stack_machine.h

111 lines
2.9 KiB
C

#ifndef STACK_MACHINE_H
#define STACK_MACHINE_H
////////////////////////////////
// Stack Machine
typedef struct SM_Ctx SM_Ctx;
//// SM_FRAME ////
typedef struct SM_Frame{
String8 name;
U64 size;
U64 return_size;
} SM_Frame;
#define SYMBOL_SET_DEFINE SM_FRAME
#define SM_FRAME_Type SM_Frame
#define SM_FRAME_elf_section ".sy.frame"
#define SM_FRAME_coff_a_section ".sy$frame_a"
#define SM_FRAME_coff_m_section ".sy$frame_m"
#define SM_FRAME_coff_z_section ".sy$frame_z"
#define SM_FRAME_marker frame
#include "symbol_set.define.h"
#define SM_FRAME_STRUCT(F) typedef struct SM_Frame_##F SM_Frame_##F; \
struct SM_Frame_##F
#define SM_FRAME_TYPE_DEF(F,T) typedef T SM_Frame_##F
#define SM_FRAME_RETURN_STRUCT(F) typedef struct SM_FrameReturn_##F SM_FrameReturn_##F; \
struct SM_FrameReturn_##F
#define SM_FRAME_RETURN_TYPE_DEF(F,T) typedef T SM_FrameReturn_##F
#define SM_FRAME(F) \
SyDefine(SM_FRAME, F) = { str8_const(#F), sizeof(SM_Frame_##F), sizeof(SM_FrameReturn_##F) }
//// SM_STATE ////
typedef void SM_StateFunc(SM_Ctx *ctx, void *frame);
typedef struct SM_State{
String8 name;
SM_StateFunc *func;
SY__UAddr frame_id;
} SM_State;
#define SYMBOL_SET_DEFINE SM_STATE
#define SM_STATE_Type SM_State
#define SM_STATE_elf_section ".sy.state"
#define SM_STATE_coff_a_section ".sy$state_a"
#define SM_STATE_coff_m_section ".sy$state_m"
#define SM_STATE_coff_z_section ".sy$state_z"
#define SM_STATE_marker state
#include "symbol_set.define.h"
#define SM_STATE_DECL(F,N) SyDeclare(SM_STATE, F##_##N)
#define SM_STATE(F,N) \
static void sm_statefunc__##F##_##N(SM_Ctx *ctx, SM_Frame_##F *frame); \
SyDefine(SM_STATE, F##_##N) = { \
.name = str8_const(#F "." #N), \
.func = (SM_StateFunc*)sm_statefunc__##F##_##N, \
.frame_id = SyRaw(SM_FRAME, F) }; \
static void sm_statefunc__##F##_##N(SM_Ctx *ctx, SM_Frame_##F *frame)
#if SY__MAIN
SY_INIT(SM_STATE){
for (SyEach(SM_STATE, state)){
state->frame_id = SyIDFromRaw(SM_FRAME, state->frame_id);
}
}
#endif
//// Context ////
typedef struct SM_StackNode{
struct SM_StackNode *next;
U64 pop_pos;
void *frame;
U32 state_id;
} SM_StackNode;
struct SM_Ctx{
Arena *run_arena;
Arena stack_arena;
SM_StackNode *stack;
void *prev_return;
void *new_return;
B32 diagnostics;
};
static SM_Ctx sm_ctx_new(U32 initial_state_id);
static U32 sm_ctx_get_top_state(SM_Ctx *ctx);
static void* sm_ctx_get_top_frame(SM_Ctx *ctx);
static B32 sm_ctx_stack_empty(SM_Ctx *ctx);
static void* sm_ctx_get_prev_return(SM_Ctx *ctx);
static void sm_state_stationary(SM_Ctx *ctx);
static void sm_state_next(SM_Ctx *ctx, U32 state_id);
static void sm_state_stationary_push(SM_Ctx *ctx, U32 push_state_id);
static void sm_state_next_push(SM_Ctx *ctx, U32 next_state_id, U32 push_state_id);
static void sm_state_pop(SM_Ctx *ctx, void *return_data);
static void sm__stack_push(SM_Ctx *ctx, U32 state_id);
#endif //STACK_MACHINE_H