namespace Slime { struct Lisp_Object; struct String; struct Environment; enum struct Thread_Type { Main, GarbageCollection }; enum struct Lisp_Object_Type { Nil, T, Symbol, Keyword, Number, String, Pair, Vector, Continuation, Pointer, HashMap, // OwningPointer, Function, }; enum class Lisp_Object_Flags { // bits 1 to 5 (including) will be reserved for the type Already_Garbage_Collected = 1 << 5, Under_Construction = 1 << 6, }; enum struct NasAction { Eval, Step, TM, Pop, If, Define_Var, Pop_Environment }; enum struct Lisp_Function_Type { Lambda, // normal evaluation order Macro // args are not evaluated, a new programm is returned // that will be executed again }; enum struct C_Function_Type { cFunction, // normal evaluation order cSpecial, // args are not evaluated, but result is returned // as you would expect cMacro // No return value, but the current_execution is // modified }; enum struct Log_Level { None, Critical, Warning, Info, Debug, }; struct Continuation { Array_List call_stack; Array_List envi_stack; }; struct String { int length; char data; }; struct Source_Code_Location { String* file; int line; int column; }; struct Pair { Lisp_Object* first; Lisp_Object* rest; }; struct Vector { int length; Lisp_Object* data; }; struct Positional_Arguments { Array_List symbols; }; struct Keyword_Arguments { // Array of Pointers to Lisp_Object Array_List keywords; // NOTE(Felix): values[i] will be nullptr if no defalut value was // declared for key identifiers[i] Array_List values; }; struct Arguments { Positional_Arguments positional; Keyword_Arguments keyword; // NOTE(Felix): rest_argument will be nullptr if no rest argument // is declared otherwise its a symbol Lisp_Object* rest; }; struct Environment { Array_List parents; Hash_Map hm; ~Environment() { hm.~Hash_Map(); } }; struct Function { Arguments args; Environment* parent_environment; bool is_c; union { Lisp_Function_Type lisp_function_type; C_Function_Type c_function_type; } type; union { Lisp_Object* lisp_body; Lisp_Object* (*c_body)(); void (*c_macro_body)(); } body; }; struct Lisp_Object { Source_Code_Location* sourceCodeLocation; u64 flags; Lisp_Object* userType; // keyword String* docstring; union value { String* symbol; // used for symbols and keywords double number; String* string; Pair pair; Vector vector; Function* function; void* pointer; Continuation* continuation; Hash_Map* hashMap; ~value() {} } value; ~Lisp_Object(); }; struct Error { Lisp_Object* position; // type has to be a keyword Lisp_Object* type; String* message; }; }