/* =========================================================================== Copyright (C) 2008 the OpenMoHAA team This file is part of OpenMoHAA source code. OpenMoHAA source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. OpenMoHAA source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMoHAA source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // compiler.h: Script Compiler #ifndef __COMPILER_H__ #define __COMPILER_H__ #include "../script/scriptopcodes.h" #include "../fgame/gamescript.h" #include "../parser/parsetree.h" class ScriptVariable; enum { method_game, method_level, method_local, method_parm, method_self, method_group, method_owner, method_field, method_array, }; typedef struct scriptmacro { str name; str parameters; } scriptmacro_t; #define BREAK_JUMP_LOCATION_COUNT 100 #define CONTINUE_JUMP_LOCATION_COUNT 100 class ScriptCompiler { public: unsigned char *code_pos; unsigned char *code_ptr; unsigned char *prog_ptr; unsigned char *prog_end_ptr; GameScript *script; StateScript *stateScript; bool bCanBreak; bool bCanContinue; opcode_info_t prev_opcodes[100]; unsigned int prev_opcode_pos; int m_iVarStackOffset; int m_iInternalMaxVarStackOffset; int m_iMaxExternalVarStackOffset; int m_iMaxCallStackOffset; int m_iHasExternal; unsigned char *apucBreakJumpLocations[BREAK_JUMP_LOCATION_COUNT]; int iBreakJumpLocCount; unsigned char *apucContinueJumpLocations[CONTINUE_JUMP_LOCATION_COUNT]; int iContinueJumpLocCount; bool compileSuccess; static int current_label; public: ScriptCompiler(); void Reset(); unsigned char PrevOpcode(); char PrevVarStackOffset(); void AbsorbPrevOpcode(); void ClearPrevOpcode(); void AddBreakJumpLocation(unsigned char *pos); void AddContinueJumpLocation(unsigned char *pos); void AddJumpLocation(unsigned char *pos); void AddJumpBackLocation(unsigned char *pos); void AddJumpToLocation(unsigned char *pos); bool BuiltinReadVariable(unsigned int sourcePos, int type, int eventnum); bool BuiltinWriteVariable(unsigned int sourcePos, int type, int eventnum); void EmitAssignmentStatement(sval_t lhs, unsigned int sourcePos); void EmitBoolJumpFalse(unsigned int sourcePos); void EmitBoolJumpTrue(unsigned int sourcePos); void EmitBoolNot(unsigned int sourcePos); void EmitBoolToVar(unsigned int sourcePos); void EmitBreak(unsigned int sourcePos); void EmitCatch(sval_t val, unsigned char *try_begin_code_pos, unsigned int sourcePos); void EmitConstArray(sval_t lhs, sval_t rhs, unsigned int sourcePos); void EmitConstArrayOpcode(int iCount); void EmitContinue(unsigned int sourcePos); void EmitDoWhileJump(sval_t while_stmt, sval_t while_expr, unsigned int sourcePos); void EmitEof(unsigned int sourcePos); void EmitField(sval_t listener_val, sval_t field_val, unsigned int sourcePos); void EmitFloat(float value, unsigned int sourcePos); void EmitFunc1(int opcode, unsigned int sourcePos); void EmitFunction(int iParamCount, sval_t val, unsigned int sourcePos); void EmitIfElseJump(sval_t if_stmt, sval_t else_stmt, unsigned int sourcePos); void EmitIfJump(sval_t if_stmt, unsigned int sourcePos); void EmitInteger(unsigned int value, unsigned int sourcePos); void EmitJump(unsigned char *pos, unsigned int sourcePos); void EmitJumpBack(unsigned char *pos, unsigned int sourcePos); void EmitLabel(str name, unsigned int sourcePos); void EmitLabelParameterList(sval_t parameter_list, unsigned int sourcePos); void EmitLabelPrivate(str name, unsigned int sourcePos); void EmitLogicJump(sval_t logic_stmt, bool isOr, unsigned int sourcePos); void EmitMakeArray(sval_t val); void EmitMethodExpression(int iParamCount, int eventnum, unsigned int sourcePos); void EmitNil(unsigned int sourcePos); void EmitNop(); int EmitNot(unsigned int sourcePos); void EmitOpcode(int opcode, unsigned int sourcePos); void EmitParameter(sval_u lhs, unsigned int sourcePos); int EmitParameterList(sval_t event_parameter_list); void EmitRef(sval_t val, unsigned int sourcePos); void EmitStatementList(sval_t val); void EmitString(str value, unsigned int sourcePos); void EmitSwitch(sval_t val, unsigned int sourcePos); void EmitValue(sval_t val); void EmitValue(ScriptVariable& var, unsigned int sourcePos); void EmitVarToBool(unsigned int sourcePos); void EmitWhileJump(sval_t while_expr, sval_t while_stmt, sval_t inc_stmt, unsigned int sourcePos); bool EvalPrevValue(ScriptVariable& var); void ProcessBreakJumpLocations(int iStartBreakJumpLocCount); void ProcessContinueJumpLocations(int iStartContinueJumpLocCount); unsigned char *GetPosition(); // compile void CompileError(unsigned int sourcePos, const char *format, ...); scriptmacro_t *GetMacro(char *sourceLine); char *Preprocess(char *sourceBuffer); void Preclean(char *processedBuffer); size_t Parse(GameScript *m_GameScript, char *sourceBuffer); size_t Compile(GameScript *m_GameScript, unsigned char *progBuffer); static str GetLine(str content, int line); private: template void EmitOpcodeValue(const Value& value, size_t size); template void EmitAt(unsigned char *location, const Value& value, size_t size); template void SetOpcodeValue(const Value& value); template Value GetOpcodeValue(size_t size) const; template Value GetOpcodeValue(size_t offset, size_t size) const; }; extern ScriptCompiler Compiler; void CompileAssemble(const char *filename, const char *outputfile); bool GetCompiledScript(GameScript *scr); #endif