45 #include "common.h" |
45 #include "common.h" |
46 #include "str.h" |
46 #include "str.h" |
47 #include "objwriter.h" |
47 #include "objwriter.h" |
48 #include "scriptreader.h" |
48 #include "scriptreader.h" |
49 #include "events.h" |
49 #include "events.h" |
|
50 #include "commands.h" |
50 |
51 |
51 #define TOKEN_CHARS token.chars() |
|
52 #define TOKEN_IS(s) !token.compare (s) |
|
53 #define MUST_TOPLEVEL if (g_CurMode != MODE_TOPLEVEL) \ |
52 #define MUST_TOPLEVEL if (g_CurMode != MODE_TOPLEVEL) \ |
54 ParserError ("%ss may only be defined at top level!", token.chars()); |
53 ParserError ("%ss may only be defined at top level!", token.chars()); |
55 |
54 |
56 int g_NumStates = 0; |
55 int g_NumStates = 0; |
57 int g_NumEvents = 0; |
56 int g_NumEvents = 0; |
59 str g_CurState = ""; |
58 str g_CurState = ""; |
60 |
59 |
61 void ScriptReader::BeginParse (ObjWriter* w) { |
60 void ScriptReader::BeginParse (ObjWriter* w) { |
62 while (Next()) { |
61 while (Next()) { |
63 // printf ("got token %s\n", token.chars()); |
62 // printf ("got token %s\n", token.chars()); |
64 if (TOKEN_IS ("#include")) { |
63 if (!token.compare ("#include")) { |
65 MustNext (); |
64 MustNext (); |
66 // First ensure that the file can be opened |
65 // First ensure that the file can be opened |
67 FILE* newfile = fopen (token.chars(), "r"); |
66 FILE* newfile = fopen (token.chars(), "r"); |
68 if (!newfile) |
67 if (!newfile) |
69 ParserError ("couldn't open included file `%s`!", token.chars()); |
68 ParserError ("couldn't open included file `%s`!", token.chars()); |
70 fclose (newfile); |
69 fclose (newfile); |
71 ScriptReader* newreader = new ScriptReader (token.chars()); |
70 ScriptReader* newreader = new ScriptReader (token.chars()); |
72 newreader->BeginParse (w); |
71 newreader->BeginParse (w); |
73 } else if (TOKEN_IS ("state")) { |
72 } else if (!token.compare ("state")) { |
74 MUST_TOPLEVEL |
73 MUST_TOPLEVEL |
75 |
74 |
76 MustNext (); |
75 MustNext (); |
77 |
76 |
78 str statename = token; |
77 str statename = token; |
107 g_CurMode = MODE_EVENT; |
106 g_CurMode = MODE_EVENT; |
108 |
107 |
109 w->Write (DH_EVENT); |
108 w->Write (DH_EVENT); |
110 w->Write<long> (e->number); |
109 w->Write<long> (e->number); |
111 g_NumEvents++; |
110 g_NumEvents++; |
112 } else if (TOKEN_IS ("}")) { |
111 } else if (!token.compare ("}")) { |
113 // Closing brace.. |
112 // Closing brace.. |
114 switch (g_CurMode) { |
113 switch (g_CurMode) { |
115 case MODE_EVENT: |
114 case MODE_EVENT: |
116 // Brace closes event. |
115 // Brace closes event. |
117 w->Write (DH_ENDEVENT); |
116 w->Write (DH_ENDEVENT); |
119 break; |
118 break; |
120 default: |
119 default: |
121 ParserError ("unexpected `}`"); |
120 ParserError ("unexpected `}`"); |
122 } |
121 } |
123 } else { |
122 } else { |
124 ParserError ("unknown keyword `%s`!", TOKEN_CHARS); |
123 // Check if it's a command. |
|
124 CommandDef* comm = GetCommandByName (token); |
|
125 if (comm) { |
|
126 w->Write<long> (DH_COMMAND); |
|
127 w->Write<long> (comm->number); |
|
128 w->Write<long> (comm->numargs); |
|
129 MustNext ("("); |
|
130 int curarg = 0; |
|
131 while (1) { |
|
132 if (curarg >= comm->numargs) { |
|
133 MustNext (")"); |
|
134 break; |
|
135 } |
|
136 |
|
137 if (!Next ()) |
|
138 ParserError ("unexpected end-of-file, unterminated command"); |
|
139 |
|
140 // If we get a ")" now, the user probably gave too few parameters |
|
141 if (!token.compare (")")) |
|
142 ParserError ("unexpected `)`, did you pass too few parameters? (need %d)", comm->numargs); |
|
143 |
|
144 // For now, it takes in just numbers. |
|
145 // Needs to cater for string arguments too... |
|
146 if (!token.isnumber()) |
|
147 ParserError ("argument %d (`%s`) is not a number", curarg, token.chars()); |
|
148 |
|
149 int i = atoi (token.chars ()); |
|
150 w->Write<long> (i); |
|
151 |
|
152 if (curarg != comm->numargs - 1) |
|
153 MustNext (","); |
|
154 |
|
155 curarg++; |
|
156 } |
|
157 MustNext (";"); |
|
158 } else |
|
159 ParserError ("unknown keyword `%s`!", token.chars()); |
125 } |
160 } |
126 } |
161 } |
127 |
162 |
128 if (g_CurMode != MODE_TOPLEVEL) |
163 if (g_CurMode != MODE_TOPLEVEL) |
129 ParserError ("script did not end at top level! did you forget a `}`?\n"); |
164 ParserError ("script did not end at top level! did you forget a `}`?\n"); |