/* date = December 30th 2023 8:26 pm */ #ifndef VN_SCENE2_H #define VN_SCENE2_H struct scene2_runtime; struct compiled_scene2; #define S2_CALL_FUNCTION(name) void name(scene2_runtime *Runtime, compiled_scene2 *Compiled) typedef S2_CALL_FUNCTION(scene2_call_function); static S2_CALL_FUNCTION(S2_Call_Stub) {} static u64 S2_CallFunctionIndexFromString(string String); static scene2_call_function *S2_CallFunctionFromString(string String); #include "generated/vn_scene2.meta.h" //////////////////////////////// //~ sixten: Scene Message Types struct scene2_message { scene2_message *Next; string Message; token Token; }; struct scene2_message_list { scene2_message *First; scene2_message *Last; u64 Count; }; //////////////////////////////// //~ sixten: Scene Parsing Types enum scene2_precedence { S2_Precedence_None, S2_Precedence_Assignment, S2_Precedence_Or, S2_Precedence_And, S2_Precedence_Equality, S2_Precedence_Comparison, S2_Precedence_Term, S2_Precedence_Factor, S2_Precedence_Unary, S2_Precedence_Call, S2_Precedence_Primary, }; typedef void scene2_parse_function(struct scene2_compiler *Compiler, b32 CanAssign); struct scene2_parse_rule { scene2_parse_function *PrefixRule; scene2_parse_function *InfixRule; scene2_precedence Precedence; }; struct scene2_instruction { scene2_opcode Opcode; union { struct { u32 Arg1; u32 Arg2; }; struct { u32 Min; u32 Max; }; u64 Arg; r64 Number; }; }; struct scene2_instruction_chunk { scene2_instruction_chunk *Next; u64 InstructionsUsed; scene2_instruction Instructions[1]; }; struct scene2_proc_info { string Name; u64 InstructionBegin; u64 InstructionEnd; }; struct scene2_proc_node { scene2_proc_node *Next; scene2_proc_info Info; }; struct scene2_proc_list { scene2_proc_node *First; scene2_proc_node *Last; u64 Count; }; struct scene2_compiler { arena *Arena; scene2_message_list Messages; b32 InPanicMode; scene2_instruction_chunk *FirstChunk; scene2_instruction_chunk *LastChunk; u64 InstructionPointer; scene2_proc_list ProcList; string Source; token_array Tokens; s64 At; }; struct compiled_scene2 { string Source; scene2_message_list Messages; u64 InstructionCount; scene2_instruction *Instructions; scene2_proc_list ProcList; }; //////////////////////////////// //~ sixten: Scene Message Functions static void S2_PushMessage(arena *Arena, scene2_message_list *List, token Token, string Message); static void S2_PushMessageFV(arena *Arena, scene2_message_list *List, token Token, char *Format, va_list Arguments); static void S2_PushMessageF(arena *Arena, scene2_message_list *List, token Token, char *Format, ...); static scene2_message_list S2_CopyMessageList(arena *Arena, scene2_message_list *Source); static void S2_ConcatMessageList(arena *Arena, scene2_message_list *Dest, scene2_message_list *Source); //////////////////////////////// //~ sixten: Scene Action Types enum scene2_action_kind { S2_ActionKind_None = 0, }; struct scene2_action { scene2_action *Next; scene2_action_kind Kind; }; struct scene2_action_list { scene2_action *First; scene2_action *Last; u64 Count; }; //////////////////////////////// //~ sixten: Scene Action Functions static void S2_SceneActionPush(scene2_action_list *List, scene2_action Action); //////////////////////////////// //~ sixten: Scene Runtime Types enum scene2_object_kind { S2_ObjectKind_Nil, S2_ObjectKind_Bool, S2_ObjectKind_Number, S2_ObjectKind_String, }; global read_only string S2_ObjectKindNameLookup[] = { StrComp("nil"), StrComp("bool"), StrComp("number"), StrComp("string"), }; struct scene2_object { scene2_object_kind Kind; union { b32 Bool; r64 Number; string String; } As; }; struct scene2_variable { scene2_variable *Next; scene2_variable *Prev; string Name; scene2_object Value; }; struct scene2_runtime { scene2_proc_info CurrentProc; u64 InstructionPointer; //- siten: variables arena *VariableArena; scene2_variable *FirstGlobalVariable; scene2_variable *LastGlobalVariable; scene2_variable *FirstFreeVariable; scene2_variable *LastFreeVariable; //- sixten: runtime stack u64 StackPointer; scene2_object Stack[128]; //- sixten: custom callback data void *Data; }; struct scene2_run_result { scene2_message_list Messages; scene2_action_list Actions; }; //////////////////////////////// //~ sixten: Scene Parsing Helpers static token S2_Token(scene2_compiler *Compiler); static token S2_Consume(scene2_compiler *Compiler, token_kind Expected, string Message); static void S2_Advance(scene2_compiler *Compiler); static scene2_parse_rule S2_ParseRuleFromToken(scene2_compiler *Compiler, token Token); static scene2_instruction S2_Instruction(scene2_opcode Opcode); static scene2_instruction S2_Instruction(scene2_opcode Opcode, u64 Arg); static scene2_instruction S2_Instruction(scene2_opcode Opcode, r64 Number); static scene2_instruction S2_Instruction(scene2_opcode Opcode, u32 Arg1, u32 Arg2); static scene2_instruction S2_Instruction(scene2_opcode Opcode, range1_s64 Range); static scene2_instruction *S2_Emit(scene2_compiler *Compiler, scene2_instruction Instruction); //////////////////////////////// //~ sixten: Scene Parsing Functions static void S2_ParseTopLevel(scene2_compiler *Compiler); static void S2_ParseProc(scene2_compiler *Compiler); static void S2_ParseBlock(scene2_compiler *Compiler); static void S2_ParseStatement(scene2_compiler *Compiler); static void S2_ParseWaitStatement(scene2_compiler *Compiler); static void S2_ParseIfStatement(scene2_compiler *Compiler); static void S2_ParseWhileStatement(scene2_compiler *Compiler); static void S2_ParseLetStatement(scene2_compiler *Compiler); static void S2_ParseShorthand(scene2_compiler *Compiler); static void S2_ParseExpression(scene2_compiler *Compiler); static void S2_ParsePrecedence(scene2_compiler *Compiler, scene2_precedence Precedence); static void S2_ParseStatement(scene2_compiler *Compiler); static void S2_ParseGrouping(scene2_compiler *Compiler, b32 CanAssign); static void S2_ParseUnary(scene2_compiler *Compiler, b32 CanAssign); static void S2_ParseBinary(scene2_compiler *Compiler, b32 CanAssign); static void S2_ParseLiteral(scene2_compiler *Compiler, b32 CanAssign); static void S2_ParseNumber(scene2_compiler *Compiler, b32 CanAssign); static void S2_ParseString(scene2_compiler *Compiler, b32 CanAssign); static void S2_ParseVariable(scene2_compiler *Compiler, b32 CanAssign); static void S2_ParseCall(scene2_compiler *Compiler, b32 CanAssign); //////////////////////////////// //~ sixten: Scene Runtime Helper Functions static string S2_StringFromObject(arena *Arena, scene2_object Object); static void S2_StackPush(scene2_runtime *Runtime, scene2_object Object); static scene2_object S2_StackPop(scene2_runtime *Runtime); static scene2_object S2_MakeNil(void); static scene2_object S2_MakeNumber(r64 Number); static scene2_object S2_MakeString(string String); static b32 S2_ObjectIsTrue(scene2_object Object); //////////////////////////////// //~ sixten: Scene Interface Functions static compiled_scene2 S2_CompiledFromString(arena *Arena, string String); static compiled_scene2 S2_CopyCompiledScene(arena *Arena, compiled_scene2 *Source); static void S2_SetCurrentProc(scene2_runtime *Runtime, scene2_proc_info *Info); static scene2_proc_info S2_ProcFromName(compiled_scene2 *Compiled, string Name); #endif //VN_SCENE2_H