102 e_switch_scope, |
116 e_switch_scope, |
103 e_else_scope, |
117 e_else_scope, |
104 }; |
118 }; |
105 |
119 |
106 // ============================================================================ |
120 // ============================================================================ |
107 // Meta-data about blocks |
121 // Meta-data about scopes |
|
122 // |
108 struct ScopeInfo |
123 struct ScopeInfo |
109 { |
124 { |
110 int mark1; |
125 byte_mark* mark1; |
111 int mark2; |
126 byte_mark* mark2; |
112 scopetype_e type; |
127 scopetype_e type; |
113 data_buffer* buffer1; |
128 data_buffer* buffer1; |
114 |
129 |
115 // switch-related stuff |
130 // switch-related stuff |
116 // Which case are we at? |
131 // Which case are we at? |
117 short casecursor; |
132 int casecursor; |
118 |
133 |
119 // Marks to case-blocks |
134 // Marks to case-blocks |
120 int casemarks[MAX_CASE]; |
135 byte_mark* casemarks[MAX_CASE]; |
121 |
136 |
122 // Numbers of the case labels |
137 // Numbers of the case labels |
123 int casenumbers[MAX_CASE]; |
138 int casenumbers[MAX_CASE]; |
124 |
139 |
125 // actual case blocks |
140 // actual case blocks |
126 data_buffer* casebuffers[MAX_CASE]; |
141 data_buffer* casebuffers[MAX_CASE]; |
127 |
142 |
128 // What is the current buffer of the block? |
143 // What is the current buffer of the block? |
129 data_buffer* recordbuffer; |
144 data_buffer* recordbuffer; |
130 }; |
145 }; |
131 |
146 |
132 // ============================================================================ |
147 // ============================================================================ |
|
148 // |
133 struct constant_info |
149 struct constant_info |
134 { |
150 { |
135 string name; |
151 string name; |
136 type_e type; |
152 type_e type; |
137 string val; |
153 string val; |
138 }; |
154 }; |
139 |
155 |
140 // ============================================================================ |
156 // ============================================================================ |
141 // The script reader reads the script, parses it and tells the object writer |
157 // |
142 // the bytecode it needs to write to file. |
|
143 class botscript_parser |
158 class botscript_parser |
144 { |
159 { |
145 public: |
160 public: |
146 // ==================================================================== |
|
147 // TODO: make private |
|
148 FILE* fp[MAX_FILESTACK]; |
|
149 string filepath[MAX_FILESTACK]; |
|
150 int fc; |
|
151 |
|
152 int pos[MAX_FILESTACK]; |
|
153 int curline[MAX_FILESTACK]; |
|
154 int curchar[MAX_FILESTACK]; |
|
155 ScopeInfo scopestack[MAX_SCOPE]; |
|
156 long savedpos[MAX_FILESTACK]; // filepointer cursor position |
|
157 int commentmode; |
|
158 long prevpos; |
|
159 string prevtoken; |
|
160 |
|
161 // ==================================================================== |
161 // ==================================================================== |
162 // METHODS |
162 // METHODS |
163 botscript_parser(); |
163 botscript_parser(); |
164 ~botscript_parser(); |
164 ~botscript_parser(); |
165 void parse_botscript (string file_name, object_writer* w); |
165 void parse_botscript (string file_name); |
166 data_buffer* ParseCommand (command_info* comm); |
166 data_buffer* parse_command (command_info* comm); |
167 data_buffer* parse_expression (type_e reqtype); |
167 data_buffer* parse_expression (type_e reqtype); |
168 data_buffer* parse_assignment (script_variable* var); |
168 data_buffer* parse_assignment (script_variable* var); |
169 int parse_operator (bool peek = false); |
169 int parse_operator (bool peek = false); |
170 data_buffer* parse_expr_value (type_e reqtype); |
170 data_buffer* parse_expr_value (type_e reqtype); |
171 string parse_float (); |
171 string parse_float(); |
172 void push_scope (); |
172 void push_scope(); |
173 data_buffer* parse_statement (); |
173 data_buffer* parse_statement(); |
174 void add_switch_case (data_buffer* b); |
174 void add_switch_case (data_buffer* b); |
175 void check_toplevel(); |
175 void check_toplevel(); |
176 void check_not_toplevel(); |
176 void check_not_toplevel(); |
177 bool token_is (e_token a); |
177 bool token_is (e_token a); |
178 string token_string(); |
178 string token_string(); |
179 string describe_position() const; |
179 string describe_position() const; |
|
180 void write_to_file (string outfile); |
|
181 |
|
182 inline int get_num_events() const |
|
183 { |
|
184 return m_num_events; |
|
185 } |
|
186 |
|
187 inline int get_num_states() const |
|
188 { |
|
189 return m_num_states; |
|
190 } |
180 |
191 |
181 private: |
192 private: |
182 lexer* m_lx; |
193 // The lexer we're using. |
183 object_writer* m_writer; |
194 lexer* m_lx; |
184 |
195 |
185 void parse_state_block(); |
196 // The main buffer - the contents of this is what we |
186 void parse_event_block(); |
197 // write to file after parsing is complete |
187 void parse_mainloop(); |
198 data_buffer* m_main_buffer; |
188 void parse_on_enter_exit(); |
199 |
189 void parse_variable_declaration(); |
200 // onenter buffer - the contents of the onenter{} block |
190 void parse_goto(); |
201 // is buffered here and is merged further at the end of state |
191 void parse_if(); |
202 data_buffer* m_on_enter_buffer; |
192 void parse_else(); |
203 |
193 void parse_while_block(); |
204 // Mainloop buffer - the contents of the mainloop{} block |
194 void parse_for_block(); |
205 // is buffered here and is merged further at the end of state |
195 void parse_do_block(); |
206 data_buffer* m_main_loop_buffer; |
196 void parse_switch_block(); |
207 |
197 void parse_switch_case(); |
208 // Switch buffer - switch case data is recorded to this |
198 void parse_switch_default(); |
209 // buffer initially, instead of into main buffer. |
199 void parse_break(); |
210 data_buffer* m_switch_buffer; |
200 void parse_continue(); |
211 |
201 void parse_block_end(); |
212 int m_num_states; |
202 void parse_const(); |
213 int m_num_events; |
203 void parse_label(); |
214 parsermode_e m_current_mode; |
204 void parse_eventdef(); |
215 string m_current_state; |
205 void parse_funcdef(); |
216 bool m_state_spawn_defined; |
|
217 bool m_got_main_loop; |
|
218 int m_scope_cursor; |
|
219 data_buffer* m_if_expression; |
|
220 bool m_can_else; |
|
221 list<undefined_label> m_undefined_labels; |
|
222 list<constant_info> m_constants; |
|
223 |
|
224 // How many bytes have we written to file? |
|
225 int m_num_written_bytes; |
|
226 |
|
227 // Scope data |
|
228 // TODO: make a list |
|
229 ScopeInfo m_scope_stack[MAX_SCOPE]; |
|
230 |
|
231 data_buffer* buffer(); |
|
232 constant_info* find_constant (const string& tok); |
|
233 void parse_state_block(); |
|
234 void parse_event_block(); |
|
235 void parse_mainloop(); |
|
236 void parse_on_enter_exit(); |
|
237 void parse_variable_declaration(); |
|
238 void parse_goto(); |
|
239 void parse_if(); |
|
240 void parse_else(); |
|
241 void parse_while_block(); |
|
242 void parse_for_block(); |
|
243 void parse_do_block(); |
|
244 void parse_switch_block(); |
|
245 void parse_switch_case(); |
|
246 void parse_switch_default(); |
|
247 void parse_break(); |
|
248 void parse_continue(); |
|
249 void parse_block_end(); |
|
250 void parse_const(); |
|
251 void parse_label(); |
|
252 void parse_eventdef(); |
|
253 void parse_funcdef(); |
|
254 void write_member_buffers(); |
|
255 void write_string_table(); |
206 }; |
256 }; |
207 |
257 |
208 constant_info* find_constant (const string& tok); |
258 constant_info* find_constant (const string& tok); |
209 |
259 |
210 #endif // BOTC_PARSER_H |
260 #endif // BOTC_PARSER_H |