enum scene2_opcode
{
S2_Op_None,                                        // does nothing (effectivly a nop)
S2_Op_Call,                                        // stages runtime hook
S2_Op_Wait,                                        // executes staged actions and waits for user input
S2_Op_Pop,                                         // pops object from stack
S2_Op_PushBool,                                    // pushes a boolean onto the stack
S2_Op_PushNumber,                                  // pushes a number onto the stack
S2_Op_PushString,                                  // pushes a string onto the stack
S2_Op_PushNil,                                     // pushes `nil` onto the stack
S2_Op_PushVariable,                                // pushes a variable onto the stack
S2_Op_DuplicateStack,                              // duplicates the top N-most elements of the stack (specified in Arg as u64)
S2_Op_SetVariable,                                 // pops the stack and stores the value in a variable
S2_Op_SetLocal,                                    // defines a locally scoped variable
S2_Op_BeginBlock,                                  // increases the variable stack depth
S2_Op_EndBlock,                                    // decreases the variable stack depth
S2_Op_Jump,                                        // performs a relative jump (specified in Arg as s64)
S2_Op_CondJump,                                    // performs a relative jump (specified in Arg as s64) if the topmost element on the stack is non-zero
S2_Op_Add,                                         // adds the two topmost elements of the stack
S2_Op_Subtract,                                    // subtracts the topmost element of the stack by the second topmost element
S2_Op_Multiply,                                    // multiplies the two topmost elements of the stack
S2_Op_Divide,                                      // divides the topmost element of the stack by the second topmost element
S2_Op_Equals,                                      // 
S2_Op_Greater,                                     // 
S2_Op_Less,                                        // 
S2_Op_Not,                                         // performs a not operation on the topmost element of the stack
S2_Op_Negate,                                      // negates the topmost element of the stack
S2_Op_COUNT,
};

global read_only string S2_InstructionInfoLookup[] =
{
StrComp("None"),
StrComp("Call"),
StrComp("Wait"),
StrComp("Pop"),
StrComp("PushBool"),
StrComp("PushNumber"),
StrComp("PushString"),
StrComp("PushNil"),
StrComp("PushVariable"),
StrComp("DuplicateStack"),
StrComp("SetVariable"),
StrComp("SetLocal"),
StrComp("BeginBlock"),
StrComp("EndBlock"),
StrComp("Jump"),
StrComp("CondJump"),
StrComp("Add"),
StrComp("Subtract"),
StrComp("Multiply"),
StrComp("Divide"),
StrComp("Equals"),
StrComp("Greater"),
StrComp("Less"),
StrComp("Not"),
StrComp("Negate"),
};

global read_only string S2_InstructionNameLookup[] =
{
StrComp("does nothing (effectivly a nop)"),
StrComp("stages runtime hook"),
StrComp("executes staged actions and waits for user input"),
StrComp("pops object from stack"),
StrComp("pushes a boolean onto the stack"),
StrComp("pushes a number onto the stack"),
StrComp("pushes a string onto the stack"),
StrComp("pushes `nil` onto the stack"),
StrComp("pushes a variable onto the stack"),
StrComp("duplicates the top N-most elements of the stack (specified in Arg as u64)"),
StrComp("pops the stack and stores the value in a variable"),
StrComp("defines a locally scoped variable"),
StrComp("increases the variable stack depth"),
StrComp("decreases the variable stack depth"),
StrComp("performs a relative jump (specified in Arg as s64)"),
StrComp("performs a relative jump (specified in Arg as s64) if the topmost element on the stack is non-zero"),
StrComp("adds the two topmost elements of the stack"),
StrComp("subtracts the topmost element of the stack by the second topmost element"),
StrComp("multiplies the two topmost elements of the stack"),
StrComp("divides the topmost element of the stack by the second topmost element"),
StrComp(""),
StrComp(""),
StrComp(""),
StrComp("performs a not operation on the topmost element of the stack"),
StrComp("negates the topmost element of the stack"),
};

enum scene2_operator
{
S2_Operator_Invalid,
S2_Operator_Not,
S2_Operator_Equal,
S2_Operator_Equals,
S2_Operator_NotEquals,
S2_Operator_GreaterThanOrEquals,
S2_Operator_LessThanOrEquals,
S2_Operator_Greater,
S2_Operator_Less,
S2_Operator_Add,
S2_Operator_Minus,
S2_Operator_Multiply,
S2_Operator_Divide,
};

inline scene2_operator S2_OperatorFromString(string String)
{
scene2_operator Result = S2_Operator_Invalid;
if(0) {}
else if(AreEqual(String, StrLit("###"))) { Result = S2_Operator_Invalid; }
else if(AreEqual(String, StrLit("!")))   { Result = S2_Operator_Not; }
else if(AreEqual(String, StrLit("=")))   { Result = S2_Operator_Equal; }
else if(AreEqual(String, StrLit("==")))  { Result = S2_Operator_Equals; }
else if(AreEqual(String, StrLit("!=")))  { Result = S2_Operator_NotEquals; }
else if(AreEqual(String, StrLit(">=")))  { Result = S2_Operator_GreaterThanOrEquals; }
else if(AreEqual(String, StrLit("<=")))  { Result = S2_Operator_LessThanOrEquals; }
else if(AreEqual(String, StrLit(">")))   { Result = S2_Operator_Greater; }
else if(AreEqual(String, StrLit("<")))   { Result = S2_Operator_Less; }
else if(AreEqual(String, StrLit("+")))   { Result = S2_Operator_Add; }
else if(AreEqual(String, StrLit("-")))   { Result = S2_Operator_Minus; }
else if(AreEqual(String, StrLit("*")))   { Result = S2_Operator_Multiply; }
else if(AreEqual(String, StrLit("/")))   { Result = S2_Operator_Divide; }
return(Result);
}

static S2_CALL_FUNCTION(S2_Call_Stub);             // does nothing
static S2_CALL_FUNCTION(S2_Call_StackSanity);      // does checks that the stack is at a certain depth
static S2_CALL_FUNCTION(S2_Call_TextAppend);       // pops a value and appends it to the textbox
static S2_CALL_FUNCTION(S2_Call_NewLine);          // appends a newline to the textbox
static S2_CALL_FUNCTION(S2_Call_TextClear);        // clears the textbox
static S2_CALL_FUNCTION(S2_Call_ProcSet);          // sets the current proc
static S2_CALL_FUNCTION(S2_Call_CharacterSet);     // sets the state of a character
static S2_CALL_FUNCTION(S2_Call_CharacterRemove);  // removes a character
static S2_CALL_FUNCTION(S2_Call_CharacterSetTalking);  // makes a character talking
static S2_CALL_FUNCTION(S2_Call_CharacterUnsetAllTalking);  // makes no characters talking
static S2_CALL_FUNCTION(S2_Call_NavLoad);          // loads a nav scene
static S2_CALL_FUNCTION(S2_Call_Puzzle15);         // plays the 15-puzzle

global read_only scene2_call_function *S2_CallBindingLookup[] =
{
S2_Call_Stub, 
S2_Call_StackSanity, 
S2_Call_TextAppend, 
S2_Call_NewLine, 
S2_Call_TextClear, 
S2_Call_ProcSet, 
S2_Call_CharacterSet, 
S2_Call_CharacterRemove, 
S2_Call_CharacterSetTalking, 
S2_Call_CharacterUnsetAllTalking, 
S2_Call_NavLoad, 
S2_Call_Puzzle15, 
};

global read_only string S2_CallNameLookup[] =
{
StrComp("none"), 
StrComp("stack_sanity"), 
StrComp("text_append"), 
StrComp("text_newline"), 
StrComp("text_clear"), 
StrComp("proc_set"), 
StrComp("ctr_set"), 
StrComp("ctr_remove"), 
StrComp("ctr_set_talking"), 
StrComp("ctr_unset_all_talking"), 
StrComp("nav_load"), 
StrComp("puzzle_15"), 
};

