parser.cxx

changeset 26
54eaea6dc27c
parent 25
2a600af97c6b
child 28
fb46d3d40064
equal deleted inserted replaced
25:2a600af97c6b 26:54eaea6dc27c
57 int g_NumStates = 0; 57 int g_NumStates = 0;
58 int g_NumEvents = 0; 58 int g_NumEvents = 0;
59 int g_CurMode = MODE_TOPLEVEL; 59 int g_CurMode = MODE_TOPLEVEL;
60 str g_CurState = ""; 60 str g_CurState = "";
61 bool g_stateSpawnDefined = false; 61 bool g_stateSpawnDefined = false;
62 bool g_GotMainLoop = false;
62 63
63 void ScriptReader::BeginParse (ObjWriter* w) { 64 void ScriptReader::BeginParse (ObjWriter* w) {
64 bool gotMainLoop = false;
65 while (Next()) { 65 while (Next()) {
66 // printf ("got token %s\n", token.chars()); 66 // printf ("got token %s\n", token.chars());
67 if (!token.icompare ("#include")) { 67 if (!token.icompare ("#include")) {
68 MustString (); 68 MustString ();
69 69
93 g_stateSpawnDefined = true; 93 g_stateSpawnDefined = true;
94 94
95 // Must end in a colon 95 // Must end in a colon
96 MustNext (":"); 96 MustNext (":");
97 97
98 // If the previous state did not define a mainloop, 98 // Write the previous state's onenter and
99 // define a dummy one now, since one has to be present. 99 // mainloop buffers to file now
100 if (g_CurState.len() && !gotMainLoop) { 100 if (g_CurState.len())
101 w->Write (DH_MAINLOOP); 101 w->WriteBuffers();
102 w->Write (DH_ENDMAINLOOP);
103 }
104 102
105 w->Write (DH_STATENAME); 103 w->Write (DH_STATENAME);
106 w->WriteString (statename); 104 w->WriteString (statename);
107 w->Write (DH_STATEIDX); 105 w->Write (DH_STATEIDX);
108 w->Write (g_NumStates); 106 w->Write (g_NumStates);
109 107
110 g_NumStates++; 108 g_NumStates++;
111 g_CurState = token; 109 g_CurState = token;
112 gotMainLoop = false; 110 g_GotMainLoop = false;
113 continue; 111 continue;
114 } 112 }
115 113
116 if (!token.icompare ("event")) { 114 if (!token.icompare ("event")) {
117 MUST_TOPLEVEL 115 MUST_TOPLEVEL
134 } 132 }
135 133
136 if (!token.icompare ("mainloop")) { 134 if (!token.icompare ("mainloop")) {
137 MUST_TOPLEVEL 135 MUST_TOPLEVEL
138 MustNext ("{"); 136 MustNext ("{");
137
138 // Mode must be set before dataheader is written here!
139 g_CurMode = MODE_MAINLOOP; 139 g_CurMode = MODE_MAINLOOP;
140 w->Write (DH_MAINLOOP); 140 w->Write (DH_MAINLOOP);
141 gotMainLoop = true;
142 continue; 141 continue;
143 } 142 }
144 143
145 if (!token.icompare ("onenter") || !token.icompare ("onexit")) { 144 if (!token.icompare ("onenter") || !token.icompare ("onexit")) {
146 MUST_TOPLEVEL 145 MUST_TOPLEVEL
147 bool onenter = !token.compare ("onenter"); 146 bool onenter = !token.compare ("onenter");
148
149 MustNext ("{"); 147 MustNext ("{");
148
149 // Mode must be set before dataheader is written here,
150 // because onenter goes to a separate buffer.
150 g_CurMode = onenter ? MODE_ONENTER : MODE_ONEXIT; 151 g_CurMode = onenter ? MODE_ONENTER : MODE_ONEXIT;
151 w->Write (onenter ? DH_ONENTER : DH_ONEXIT); 152 w->Write (onenter ? DH_ONENTER : DH_ONEXIT);
152 continue; 153 continue;
153 } 154 }
154 155
182 (g_CurMode == MODE_ONEXIT) ? DH_ENDONEXIT : -1; 183 (g_CurMode == MODE_ONEXIT) ? DH_ENDONEXIT : -1;
183 184
184 if (dataheader == -1) 185 if (dataheader == -1)
185 ParserError ("unexpected `}`"); 186 ParserError ("unexpected `}`");
186 187
187 // Closing brace.. 188 // Data header must be written before mode is changed because
189 // onenter and mainloop go into buffers, and we want the closing
190 // data headers into said buffers too.
188 w->Write (dataheader); 191 w->Write (dataheader);
189 g_CurMode = MODE_TOPLEVEL; 192 g_CurMode = MODE_TOPLEVEL;
190 193
191 MustNext (";"); 194 MustNext (";");
192 continue; 195 continue;
196 if (g) { 199 if (g) {
197 // Not in top level, unfortunately.. 200 // Not in top level, unfortunately..
198 if (g_CurMode == MODE_TOPLEVEL) 201 if (g_CurMode == MODE_TOPLEVEL)
199 ParserError ("can't alter variables at top level"); 202 ParserError ("can't alter variables at top level");
200 203
201 // Only addition for now..
202 MustNext ();
203
204 // Build operator string. Only '=' is one 204 // Build operator string. Only '=' is one
205 // character, others are two. 205 // character, others are two.
206 MustNext ();
206 str oper = token; 207 str oper = token;
207 if (token.compare ("=") != 0) { 208 if (token.compare ("=") != 0) {
208 MustNext (); 209 MustNext ();
209 oper += token; 210 oper += token;
210 } 211 }
259 260
260 // stateSpawn must be defined! 261 // stateSpawn must be defined!
261 if (!g_stateSpawnDefined) 262 if (!g_stateSpawnDefined)
262 ParserError ("script must have a state named `stateSpawn`!"); 263 ParserError ("script must have a state named `stateSpawn`!");
263 264
264 // If the last state did not have a main loop, define a dummy one now. 265
265 if (!gotMainLoop) { 266
266 w->Write (DH_MAINLOOP); 267 // Dump the last state's onenter and mainloop
267 w->Write (DH_ENDMAINLOOP); 268 w->WriteBuffers();
268 }
269 269
270 // If we added strings here, we need to write a list of them. 270 // If we added strings here, we need to write a list of them.
271 unsigned int stringcount = CountStringTable (); 271 unsigned int stringcount = CountStringTable ();
272 if (stringcount) { 272 if (stringcount) {
273 w->Write<long> (DH_STRINGLIST); 273 w->Write<long> (DH_STRINGLIST);

mercurial