parser.cxx

changeset 16
393359908179
parent 15
284c2fc6c1cd
child 17
b4fcc69e426a
equal deleted inserted replaced
15:284c2fc6c1cd 16:393359908179
54 54
55 int g_NumStates = 0; 55 int g_NumStates = 0;
56 int g_NumEvents = 0; 56 int g_NumEvents = 0;
57 int g_CurMode = MODE_TOPLEVEL; 57 int g_CurMode = MODE_TOPLEVEL;
58 str g_CurState = ""; 58 str g_CurState = "";
59 bool g_stateSpawnDefined = false;
59 60
60 void ScriptReader::BeginParse (ObjWriter* w) { 61 void ScriptReader::BeginParse (ObjWriter* w) {
62 bool gotMainLoop = false;
61 while (Next()) { 63 while (Next()) {
62 // printf ("got token %s\n", token.chars()); 64 // printf ("got token %s\n", token.chars());
63 if (!token.compare ("#include")) { 65 if (!token.compare ("#include")) {
64 MustString (); 66 MustString ();
65 67
76 MustString (); 78 MustString ();
77 79
78 // State name must be a word. 80 // State name must be a word.
79 if (token.first (" ") != token.len()) 81 if (token.first (" ") != token.len())
80 ParserError ("state name must be a single word! got `%s`", token.chars()); 82 ParserError ("state name must be a single word! got `%s`", token.chars());
83 str statename = token;
84
85 // stateSpawn is special - it *must* be defined. If we
86 // encountered it, then mark down that we have it.
87 if (!token.icompare ("stateSpawn"))
88 g_stateSpawnDefined = true;
81 89
82 // Must end in a colon 90 // Must end in a colon
83 MustNext (":"); 91 MustNext (":");
84 92
93 // If the previous state did not define a mainloop,
94 // define a dummy one now, since one has to be present.
95 if (g_CurState.compare ("") != 0 && !gotMainLoop) {
96 w->Write (DH_MAINLOOP);
97 w->Write (DH_ENDMAINLOOP);
98 }
99
85 w->Write (DH_STATENAME); 100 w->Write (DH_STATENAME);
86 w->Write (token.len()); 101 w->Write (statename.len());
87 w->WriteString (token); 102 w->WriteString (statename);
88 w->Write (DH_STATEIDX); 103 w->Write (DH_STATEIDX);
89 w->Write (g_NumStates); 104 w->Write (g_NumStates);
90 105
91 g_NumStates++; 106 g_NumStates++;
92 g_CurState = token; 107 g_CurState = token;
108 gotMainLoop = false;
93 } else if (!token.compare ("event")) { 109 } else if (!token.compare ("event")) {
94 MUST_TOPLEVEL 110 MUST_TOPLEVEL
95 111
96 // Event definition 112 // Event definition
97 MustString (); 113 MustString ();
105 g_CurMode = MODE_EVENT; 121 g_CurMode = MODE_EVENT;
106 122
107 w->Write (DH_EVENT); 123 w->Write (DH_EVENT);
108 w->Write<long> (e->number); 124 w->Write<long> (e->number);
109 g_NumEvents++; 125 g_NumEvents++;
126 } else if (!token.compare ("mainloop")) {
127 MUST_TOPLEVEL
128 MustNext ("{");
129 g_CurMode = MODE_MAINLOOP;
130 w->Write (DH_MAINLOOP);
131 gotMainLoop = true;
132 } else if (!token.compare ("onenter") || !token.compare ("onexit")) {
133 MUST_TOPLEVEL
134 bool onenter = !token.compare ("onenter");
135
136 MustNext ("{");
137 g_CurMode = onenter ? MODE_ONENTER : MODE_ONEXIT;
138 w->Write (onenter ? DH_ONENTER : DH_ONEXIT);
110 } else if (!token.compare ("}")) { 139 } else if (!token.compare ("}")) {
140 // Closing brace
141 int dataheader = (g_CurMode == MODE_EVENT) ? DH_ENDEVENT :
142 (g_CurMode == MODE_MAINLOOP) ? DH_ENDMAINLOOP :
143 (g_CurMode == MODE_ONENTER) ? DH_ENDONENTER :
144 (g_CurMode == MODE_ONEXIT) ? DH_ENDONEXIT : -1;
145
146 if (dataheader == -1)
147 ParserError ("unexpected `}`");
148
111 // Closing brace.. 149 // Closing brace..
112 switch (g_CurMode) { 150 w->Write (dataheader);
113 case MODE_EVENT: 151 g_CurMode = MODE_TOPLEVEL;
114 // Brace closes event.
115 w->Write (DH_ENDEVENT);
116 g_CurMode = MODE_TOPLEVEL;
117 break;
118 default:
119 ParserError ("unexpected `}`");
120 }
121 } else { 152 } else {
122 // Check if it's a command. 153 // Check if it's a command.
123 CommandDef* comm = GetCommandByName (token); 154 CommandDef* comm = GetCommandByName (token);
124 if (comm) 155 if (comm)
125 ParseCommand (comm, w); 156 ParseCommand (comm, w);
127 ParserError ("unknown keyword `%s`!", token.chars()); 158 ParserError ("unknown keyword `%s`!", token.chars());
128 } 159 }
129 } 160 }
130 161
131 if (g_CurMode != MODE_TOPLEVEL) 162 if (g_CurMode != MODE_TOPLEVEL)
132 ParserError ("script did not end at top level! did you forget a `}`?\n"); 163 ParserError ("script did not end at top level! did you forget a `}`?");
164
165 // stateSpawn must be defined!
166 if (!g_stateSpawnDefined)
167 ParserError ("script must have a state named `stateSpawn`!");
133 168
134 /* 169 /*
135 // State 170 // State
136 w->WriteState ("stateSpawn"); 171 w->WriteState ("stateSpawn");
137 172
149 w->Write (DH_ENDEVENT); 184 w->Write (DH_ENDEVENT);
150 */ 185 */
151 } 186 }
152 187
153 void ScriptReader::ParseCommand (CommandDef* comm, ObjWriter* w) { 188 void ScriptReader::ParseCommand (CommandDef* comm, ObjWriter* w) {
189 // If this was defined at top-level, we stop right at square one!
190 if (g_CurMode == MODE_TOPLEVEL)
191 ParserError ("no commands allowed at top level!");
192
154 w->Write<long> (DH_COMMAND); 193 w->Write<long> (DH_COMMAND);
155 w->Write<long> (comm->number); 194 w->Write<long> (comm->number);
156 w->Write<long> (comm->maxargs); 195 w->Write<long> (comm->maxargs);
157 MustNext ("("); 196 MustNext ("(");
158 int curarg = 0; 197 int curarg = 0;

mercurial