File: scriptcompiler.h

package info (click to toggle)
openmohaa 0.81.1%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: trixie
  • size: 29,124 kB
  • sloc: ansic: 270,865; cpp: 250,173; sh: 234; asm: 141; xml: 64; makefile: 7
file content (182 lines) | stat: -rw-r--r-- 6,712 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
===========================================================================
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

#pragma once

#include "../script/scriptopcodes.h"
#include "../fgame/gamescript.h"
#include "../parser/parsetree.h"

class ScriptVariable;

typedef void (*ScriptDisplayTokenFunc)(const char *type, const char *name);

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();
    signed char   PrevVarStackOffset();
    void          AbsorbPrevOpcode();
    void          ClearPrevOpcode();
    void          AccumulatePrevOpcode(int opcode, int iVarStackOffset);

    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(const char *name, unsigned int sourcePos);
    void EmitLabel(int name, unsigned int sourcePos);
    void EmitLabelParameterList(sval_t parameter_list, unsigned int sourcePos);
    void EmitLabelPrivate(const char *name, unsigned int sourcePos);
    void EmitAndJump(sval_t logic_stmt, unsigned int sourcePos);
    void EmitOrJump(sval_t logic_stmt, 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);
    bool Parse(GameScript *m_GameScript, char *sourceBuffer, const char *type, size_t& outLength);
    bool Compile(GameScript *m_GameScript, unsigned char *progBuffer, size_t& outLength);

    static str GetLine(str content, int line);

private:
    template<typename Value>
    void EmitOpcodeValue(const Value& value, size_t size);

    template<typename Value>
    void EmitOpcodeValue(const Value& value);

    template<typename Value>
    void EmitAt(unsigned char *location, const Value& value, size_t size);

    template<typename Value>
    void SetOpcodeValue(const Value& value);

    template<typename Value>
    Value GetOpcodeValue(size_t size) const;

    template<typename Value>
    Value GetOpcodeValue(size_t offset, size_t size) const;
};

extern ScriptCompiler Compiler;

void CompileAssemble(const char *filename, const char *outputfile);
bool GetCompiledScript(GameScript *scr);