36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 * POSSIBILITY OF SUCH DAMAGE. |
38 * POSSIBILITY OF SUCH DAMAGE. |
39 */ |
39 */ |
40 |
40 |
|
41 #define __MAIN_CXX__ |
|
42 |
41 #include <stdio.h> |
43 #include <stdio.h> |
42 #include <stdlib.h> |
44 #include <stdlib.h> |
43 #include <string.h> |
45 #include <string.h> |
44 #include "common.h" |
46 #include "common.h" |
45 |
47 |
52 #include "variables.h" |
54 #include "variables.h" |
53 |
55 |
54 #include "bots.h" |
56 #include "bots.h" |
55 #include "botcommands.h" |
57 #include "botcommands.h" |
56 |
58 |
57 bool fexists (char* path) { |
59 const char* g_Keywords[NUM_KEYWORDS] = { |
58 if (FILE* test = fopen (path, "r")) { |
60 "state", |
59 fclose (test); |
61 "event", |
60 return true; |
62 "mainloop", |
61 } |
63 "onenter", |
62 return false; |
64 "onexit", |
63 } |
65 "var", |
|
66 |
|
67 // These ones aren't implemented yet but I plan to do so, thus they are |
|
68 // reserved. Also serves as a to-do list of sorts for me. >:F |
|
69 "break", |
|
70 "case", |
|
71 "continue", |
|
72 "default", |
|
73 "do", |
|
74 "else", |
|
75 "enum", // Would enum actually be useful? I think so. |
|
76 "for", |
|
77 "func", // Would function support need external support from zandronum? |
|
78 "goto", // Labels and goto must be done before if or any loops... |
|
79 "if", |
|
80 "return", |
|
81 "switch", |
|
82 "while" |
|
83 }; |
64 |
84 |
65 int main (int argc, char** argv) { |
85 int main (int argc, char** argv) { |
66 // Intepret command-line parameters: |
86 // Intepret command-line parameters: |
67 // -l: list commands |
87 // -l: list commands |
68 if (argc == 2 && !strcmp (argv[1], "-l")) { |
88 if (argc == 2 && !strcmp (argv[1], "-l")) { |
86 headerline.repeat ((header.len()/2)-1); |
106 headerline.repeat ((header.len()/2)-1); |
87 headerline += '-'; |
107 headerline += '-'; |
88 printf ("%s\n%s\n", header.chars(), headerline.chars()); |
108 printf ("%s\n%s\n", header.chars(), headerline.chars()); |
89 |
109 |
90 if (argc < 2) { |
110 if (argc < 2) { |
91 fprintf (stderr, "usage: %s: <infile> [outfile]\n", argv[0]); |
111 fprintf (stderr, "usage: %s <infile> [outfile]\n", argv[0]); |
|
112 fprintf (stderr, " %s -l # lists commands\n", argv[0]); |
92 exit (1); |
113 exit (1); |
93 } |
114 } |
|
115 |
|
116 // A word should always be exactly 4 bytes. The above list command |
|
117 // doesn't need it, but the rest of the program does. |
|
118 if (sizeof (word) != 4) |
|
119 error ("%s expects a word (unsigned long int) to be 4 bytes in size, is %d\n", |
|
120 APPNAME, sizeof (word)); |
94 |
121 |
95 str outfile; |
122 str outfile; |
96 if (argc < 3) |
123 if (argc < 3) |
97 outfile = ObjectFileName (argv[1]); |
124 outfile = ObjectFileName (argv[1]); |
98 else |
125 else |
140 printf ("Parsing script..\n"); |
167 printf ("Parsing script..\n"); |
141 r->BeginParse (w); |
168 r->BeginParse (w); |
142 |
169 |
143 // Parse done, print statistics and write to file |
170 // Parse done, print statistics and write to file |
144 unsigned int globalcount = CountGlobalVars (); |
171 unsigned int globalcount = CountGlobalVars (); |
145 printf ("%u global variable%s\n", globalcount, PLURAL (globalcount)); |
172 printf ("%u/%u global variable%s\n", globalcount, MAX_SCRIPT_VARIABLES, PLURAL (globalcount)); |
146 printf ("%d state%s written\n", g_NumStates, PLURAL (g_NumStates)); |
173 printf ("%d state%s written\n", g_NumStates, PLURAL (g_NumStates)); |
147 printf ("%d event%s written\n", g_NumEvents, PLURAL (g_NumEvents)); |
174 printf ("%d event%s written\n", g_NumEvents, PLURAL (g_NumEvents)); |
148 w->WriteToFile (); |
175 w->WriteToFile (); |
149 |
176 |
150 // Clear out the junk |
177 // Clear out the junk |
153 printf ("clear w\n"); |
180 printf ("clear w\n"); |
154 delete w; |
181 delete w; |
155 printf ("done!\n"); |
182 printf ("done!\n"); |
156 } |
183 } |
157 |
184 |
|
185 // ============================================================================ |
|
186 // Utility functions |
|
187 |
|
188 // ============================================================================ |
|
189 // Does the given file exist? |
|
190 bool fexists (char* path) { |
|
191 if (FILE* test = fopen (path, "r")) { |
|
192 fclose (test); |
|
193 return true; |
|
194 } |
|
195 return false; |
|
196 } |
|
197 |
|
198 // ============================================================================ |
|
199 // Generic error |
158 void error (const char* text, ...) { |
200 void error (const char* text, ...) { |
159 PERFORM_FORMAT (text, c); |
201 PERFORM_FORMAT (text, c); |
160 fprintf (stderr, "error: %s", c); |
202 fprintf (stderr, "error: %s", c); |
161 exit (1); |
203 exit (1); |
162 } |
204 } |
163 |
205 |
|
206 // ============================================================================ |
|
207 // Mutates given filename to an object filename |
164 char* ObjectFileName (str s) { |
208 char* ObjectFileName (str s) { |
165 // Locate the extension and chop it out |
209 // Locate the extension and chop it out |
166 unsigned int extdot = s.last ("."); |
210 unsigned int extdot = s.last ("."); |
167 if (extdot >= s.len()-4) |
211 if (extdot >= s.len()-4) |
168 s.trim (s.len() - extdot); |
212 s.trim (s.len() - extdot); |
169 |
213 |
170 s += ".o"; |
214 s += ".o"; |
171 return s.chars(); |
215 return s.chars(); |
172 } |
216 } |
|
217 |
|
218 // ============================================================================ |
|
219 // Is the given argument a reserved keyword? |
|
220 bool IsKeyword (str s) { |
|
221 for (unsigned int u = 0; u < NUM_KEYWORDS; u++) |
|
222 if (!s.icompare (g_Keywords[u])) |
|
223 return true; |
|
224 return false; |
|
225 } |