src/parser.h

changeset 88
5def6ff8b466
parent 87
8f65914e7046
child 89
029a330a9bef
equal deleted inserted replaced
87:8f65914e7046 88:5def6ff8b466
1 /*
2 Copyright 2012-2014 Santeri Piippo
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. The name of the author may not be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef BOTC_PARSER_H
30 #define BOTC_PARSER_H
31
32 #include <stdio.h>
33 #include "main.h"
34 #include "commands.h"
35 #include "lexer_scanner.h"
36 #include "tokens.h"
37
38 #define MAX_SCOPE 32
39 #define MAX_CASE 64
40 #define MAX_MARKS 512 // TODO: get rid of this
41
42 class data_buffer;
43 class lexer;
44 class script_variable;
45
46 struct undefined_label
47 {
48 string name;
49 byte_mark* target;
50 };
51
52 // ============================================================================
53 // Operators
54 //
55 enum operator_e
56 {
57 OPER_ADD,
58 OPER_SUBTRACT,
59 OPER_MULTIPLY,
60 OPER_DIVIDE,
61 OPER_MODULUS,
62 OPER_ASSIGN,
63 OPER_ASSIGNADD,
64 OPER_ASSIGNSUB,
65 OPER_ASSIGNMUL,
66 OPER_ASSIGNDIV,
67 OPER_ASSIGNMOD, // -- 10
68 OPER_EQUALS,
69 OPER_NOTEQUALS,
70 OPER_LESSTHAN,
71 OPER_GREATERTHAN,
72 OPER_LESSTHANEQUALS,
73 OPER_GREATERTHANEQUALS,
74 OPER_LEFTSHIFT,
75 OPER_RIGHTSHIFT,
76 OPER_ASSIGNLEFTSHIFT,
77 OPER_ASSIGNRIGHTSHIFT, // -- 20
78 OPER_OR,
79 OPER_AND,
80 OPER_BITWISEOR,
81 OPER_BITWISEAND,
82 OPER_BITWISEEOR,
83 OPER_TERNARY,
84 OPER_STRLEN,
85 };
86
87 // ============================================================================
88 //
89 struct operator_info
90 {
91 operator_e opercode;
92 e_data_header dataheader;
93 e_token token;
94 };
95
96 // ============================================================================
97 // Mark types
98 //
99 enum marktype_e
100 {
101 e_label_mark,
102 e_if_mark,
103 e_internal_mark, // internal structures
104 };
105
106 // ============================================================================
107 // Scope types
108 //
109 enum scopetype_e
110 {
111 e_unknown_scope,
112 e_if_scope,
113 e_while_scope,
114 e_for_scope,
115 e_do_scope,
116 e_switch_scope,
117 e_else_scope,
118 };
119
120 // ============================================================================
121 // Meta-data about scopes
122 //
123 struct ScopeInfo
124 {
125 byte_mark* mark1;
126 byte_mark* mark2;
127 scopetype_e type;
128 data_buffer* buffer1;
129
130 // switch-related stuff
131 // Which case are we at?
132 int casecursor;
133
134 // Marks to case-blocks
135 byte_mark* casemarks[MAX_CASE];
136
137 // Numbers of the case labels
138 int casenumbers[MAX_CASE];
139
140 // actual case blocks
141 data_buffer* casebuffers[MAX_CASE];
142
143 // What is the current buffer of the block?
144 data_buffer* recordbuffer;
145 };
146
147 // ============================================================================
148 //
149 struct constant_info
150 {
151 string name;
152 type_e type;
153 string val;
154 };
155
156 // ============================================================================
157 //
158 class botscript_parser
159 {
160 public:
161 // ====================================================================
162 // METHODS
163 botscript_parser();
164 ~botscript_parser();
165 void parse_botscript (string file_name);
166 data_buffer* parse_command (command_info* comm);
167 data_buffer* parse_expression (type_e reqtype);
168 data_buffer* parse_assignment (script_variable* var);
169 int parse_operator (bool peek = false);
170 data_buffer* parse_expr_value (type_e reqtype);
171 string parse_float();
172 void push_scope();
173 data_buffer* parse_statement();
174 void add_switch_case (data_buffer* b);
175 void check_toplevel();
176 void check_not_toplevel();
177 bool token_is (e_token a);
178 string token_string();
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 }
191
192 private:
193 // The lexer we're using.
194 lexer* m_lx;
195
196 // The main buffer - the contents of this is what we
197 // write to file after parsing is complete
198 data_buffer* m_main_buffer;
199
200 // onenter buffer - the contents of the onenter{} block
201 // is buffered here and is merged further at the end of state
202 data_buffer* m_on_enter_buffer;
203
204 // Mainloop buffer - the contents of the mainloop{} block
205 // is buffered here and is merged further at the end of state
206 data_buffer* m_main_loop_buffer;
207
208 // Switch buffer - switch case data is recorded to this
209 // buffer initially, instead of into main buffer.
210 data_buffer* m_switch_buffer;
211
212 int m_num_states;
213 int m_num_events;
214 parsermode_e m_current_mode;
215 string m_current_state;
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();
256 };
257
258 constant_info* find_constant (const string& tok);
259
260 #endif // BOTC_PARSER_H

mercurial