#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