2016-03-27 11:49:47 +02:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
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
|
|
|
|
|
2023-10-01 22:47:25 +02:00
|
|
|
#pragma once
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-06-17 01:24:20 +02:00
|
|
|
#include "../script/scriptopcodes.h"
|
|
|
|
#include "../fgame/gamescript.h"
|
|
|
|
#include "../parser/parsetree.h"
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-04-29 21:56:38 +02:00
|
|
|
class ScriptVariable;
|
|
|
|
|
2023-08-13 03:33:50 +02:00
|
|
|
typedef void (*ScriptDisplayTokenFunc)(const char *type, const char *name);
|
2023-08-12 19:59:40 +02:00
|
|
|
|
2016-03-27 11:49:47 +02:00
|
|
|
typedef struct scriptmacro {
|
2023-07-05 21:23:39 +02:00
|
|
|
str name;
|
|
|
|
str parameters;
|
2016-03-27 11:49:47 +02:00
|
|
|
} scriptmacro_t;
|
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
#define BREAK_JUMP_LOCATION_COUNT 100
|
|
|
|
#define CONTINUE_JUMP_LOCATION_COUNT 100
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
class ScriptCompiler
|
|
|
|
{
|
|
|
|
public:
|
2023-07-05 21:23:39 +02:00
|
|
|
unsigned char *code_pos;
|
|
|
|
unsigned char *code_ptr;
|
|
|
|
unsigned char *prog_ptr;
|
|
|
|
unsigned char *prog_end_ptr;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
GameScript *script;
|
|
|
|
StateScript *stateScript;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
bool bCanBreak;
|
|
|
|
bool bCanContinue;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
opcode_info_t prev_opcodes[100];
|
|
|
|
unsigned int prev_opcode_pos;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
int m_iVarStackOffset;
|
|
|
|
int m_iInternalMaxVarStackOffset;
|
|
|
|
int m_iMaxExternalVarStackOffset;
|
|
|
|
int m_iMaxCallStackOffset;
|
|
|
|
int m_iHasExternal;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
unsigned char *apucBreakJumpLocations[BREAK_JUMP_LOCATION_COUNT];
|
|
|
|
int iBreakJumpLocCount;
|
|
|
|
unsigned char *apucContinueJumpLocations[CONTINUE_JUMP_LOCATION_COUNT];
|
|
|
|
int iContinueJumpLocCount;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
bool compileSuccess;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
static int current_label;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
public:
|
2023-07-05 21:23:39 +02:00
|
|
|
ScriptCompiler();
|
|
|
|
void Reset();
|
|
|
|
|
|
|
|
unsigned char PrevOpcode();
|
|
|
|
char PrevVarStackOffset();
|
|
|
|
void AbsorbPrevOpcode();
|
|
|
|
void ClearPrevOpcode();
|
2023-08-13 17:59:49 +02:00
|
|
|
void AccumulatePrevOpcode(int opcode, int iVarStackOffset);
|
2023-07-05 21:23:39 +02:00
|
|
|
|
|
|
|
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);
|
2023-08-12 19:59:40 +02:00
|
|
|
//void EmitFunction(int iParamCount, sval_t val, unsigned int sourcePos);
|
2023-07-05 21:23:39 +02:00
|
|
|
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);
|
2023-10-01 22:47:25 +02:00
|
|
|
void EmitLabel(const char *name, unsigned int sourcePos);
|
2023-08-13 21:55:22 +02:00
|
|
|
void EmitLabel(int name, unsigned int sourcePos);
|
2023-07-05 21:23:39 +02:00
|
|
|
void EmitLabelParameterList(sval_t parameter_list, unsigned int sourcePos);
|
2023-10-01 22:47:25 +02:00
|
|
|
void EmitLabelPrivate(const char *name, unsigned int sourcePos);
|
2023-08-13 17:59:49 +02:00
|
|
|
void EmitAndJump(sval_t logic_stmt, unsigned int sourcePos);
|
|
|
|
void EmitOrJump(sval_t logic_stmt, unsigned int sourcePos);
|
2023-07-05 21:23:39 +02:00
|
|
|
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);
|
2024-04-08 21:00:48 +02:00
|
|
|
bool Parse(GameScript *m_GameScript, char *sourceBuffer, const char *type, size_t& outLength);
|
|
|
|
bool Compile(GameScript *m_GameScript, unsigned char *progBuffer, size_t& outLength);
|
2023-07-05 21:23:39 +02:00
|
|
|
|
|
|
|
static str GetLine(str content, int line);
|
2023-02-02 23:48:51 +01:00
|
|
|
|
|
|
|
private:
|
2023-07-05 21:23:39 +02:00
|
|
|
template<typename Value>
|
|
|
|
void EmitOpcodeValue(const Value& value, size_t size);
|
2023-02-02 23:48:51 +01:00
|
|
|
|
2024-06-08 14:40:35 +02:00
|
|
|
template<typename Value>
|
|
|
|
void EmitOpcodeValue(const Value& value);
|
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
template<typename Value>
|
|
|
|
void EmitAt(unsigned char *location, const Value& value, size_t size);
|
2023-02-02 23:48:51 +01:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
template<typename Value>
|
|
|
|
void SetOpcodeValue(const Value& value);
|
2023-02-02 23:48:51 +01:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
template<typename Value>
|
|
|
|
Value GetOpcodeValue(size_t size) const;
|
2023-02-02 23:48:51 +01:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
template<typename Value>
|
|
|
|
Value GetOpcodeValue(size_t offset, size_t size) const;
|
2016-03-27 11:49:47 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
extern ScriptCompiler Compiler;
|
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
void CompileAssemble(const char *filename, const char *outputfile);
|
|
|
|
bool GetCompiledScript(GameScript *scr);
|