src/main.cxx

changeset 72
03e4d9db3fd9
parent 71
11f23fabf8a6
child 73
1ee9b312dc18
equal deleted inserted replaced
71:11f23fabf8a6 72:03e4d9db3fd9
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
43 #include <stdio.h> 42 #include <stdio.h>
44 #include <stdlib.h> 43 #include <stdlib.h>
45 #include <string.h> 44 #include <string.h>
46 #include "common.h" 45 #include "main.h"
47 46
48 #include "str.h" 47 #include "str.h"
49 #include "scriptreader.h" 48 #include "scriptreader.h"
50 #include "objwriter.h" 49 #include "objwriter.h"
51 #include "events.h" 50 #include "events.h"
52 #include "commands.h" 51 #include "commands.h"
53 #include "stringtable.h" 52 #include "stringtable.h"
54 #include "variables.h" 53 #include "variables.h"
55 #include "array.h" 54 #include "containers.h"
56 #include "databuffer.h" 55 #include "databuffer.h"
57 56
58 #include "bots.h" 57 #include "bots.h"
59 #include "botcommands.h" 58 #include "botcommands.h"
60 59
61 // List of keywords 60 // List of keywords
62 const char* g_Keywords[] = { 61 const string_list g_Keywords = {
63 "bool", 62 "bool",
64 "break", 63 "break",
65 "case", 64 "case",
66 "continue", 65 "continue",
67 "const", 66 "const",
101 printf ("Begin list of commands:\n"); 100 printf ("Begin list of commands:\n");
102 printf ("------------------------------------------------------\n"); 101 printf ("------------------------------------------------------\n");
103 102
104 CommandDef* comm; 103 CommandDef* comm;
105 ITERATE_COMMANDS (comm) 104 ITERATE_COMMANDS (comm)
106 printf ("%s\n", GetCommandPrototype (comm).chars()); 105 print ("%1\n", GetCommandPrototype (comm));
107 106
108 printf ("------------------------------------------------------\n"); 107 printf ("------------------------------------------------------\n");
109 printf ("End of command list\n"); 108 printf ("End of command list\n");
110 exit (0); 109 exit (0);
111 } 110 }
112 111
113 // Print header 112 // Print header
114 str header; 113 string header;
115 str headerline = "-="; 114 string headerline;
116 header.appendformat ("%s version %d.%d", APPNAME, VERSION_MAJOR, VERSION_MINOR); 115 header = format ("%1 version %2.%3", APPNAME, VERSION_MAJOR, VERSION_MINOR);
117 116
118 headerline *= (header.len() / 2) - 1; 117 for (int i = 0; i < (header.len() / 2) - 1; ++i)
118 headerline += "-=";
119
119 headerline += '-'; 120 headerline += '-';
120 printf ("%s\n%s\n", header.chars(), headerline.chars()); 121 print ("%1\n%2\n", header, headerline);
121 122
122 if (argc < 2) { 123 if (argc < 2) {
123 fprintf (stderr, "usage: %s <infile> [outfile] # compiles botscript\n", argv[0]); 124 fprintf (stderr, "usage: %s <infile> [outfile] # compiles botscript\n", argv[0]);
124 fprintf (stderr, " %s -l # lists commands\n", argv[0]); 125 fprintf (stderr, " %s -l # lists commands\n", argv[0]);
125 exit (1); 126 exit (1);
129 // doesn't need it, but the rest of the program does. 130 // doesn't need it, but the rest of the program does.
130 if (sizeof (word) != 4) 131 if (sizeof (word) != 4)
131 error ("%s expects a word (uint32_t) to be 4 bytes in size, is %d\n", 132 error ("%s expects a word (uint32_t) to be 4 bytes in size, is %d\n",
132 APPNAME, sizeof (word)); 133 APPNAME, sizeof (word));
133 134
134 str outfile; 135 string outfile;
135 if (argc < 3) 136 if (argc < 3)
136 outfile = ObjectFileName (argv[1]); 137 outfile = ObjectFileName (argv[1]);
137 else 138 else
138 outfile = argv[2]; 139 outfile = argv[2];
139 140
140 // If we'd end up writing into an existing file, 141 // If we'd end up writing into an existing file,
141 // ask the user if we want to overwrite it 142 // ask the user if we want to overwrite it
142 if (fexists (outfile)) { 143 if (fexists (outfile)) {
143 // Additional warning if the paths are the same 144 // Additional warning if the paths are the same
144 str warning; 145 string warning;
145 #ifdef FILE_CASEINSENSITIVE 146 #ifdef FILE_CASEINSENSITIVE
146 if (!outfile.icompare (argv[1])) 147 if (!outfile.icompare (argv[1]))
147 #else 148 #else
148 if (!outfile.compare (argv[1])) 149 if (!outfile.compare (argv[1]))
149 #endif 150 #endif
165 // Read definitions 166 // Read definitions
166 printf ("Reading definitions...\n"); 167 printf ("Reading definitions...\n");
167 ReadEvents (); 168 ReadEvents ();
168 ReadCommands (); 169 ReadCommands ();
169 170
170 // Init stuff
171 InitStringTable ();
172
173 // Prepare reader and writer 171 // Prepare reader and writer
174 ScriptReader* r = new ScriptReader (argv[1]); 172 ScriptReader* r = new ScriptReader (argv[1]);
175 ObjWriter* w = new ObjWriter (outfile); 173 ObjWriter* w = new ObjWriter (outfile);
176 174
177 // We're set, begin parsing :) 175 // We're set, begin parsing :)
179 r->ParseBotScript (w); 177 r->ParseBotScript (w);
180 printf ("Script parsed successfully.\n"); 178 printf ("Script parsed successfully.\n");
181 179
182 // Parse done, print statistics and write to file 180 // Parse done, print statistics and write to file
183 unsigned int globalcount = g_GlobalVariables.size(); 181 unsigned int globalcount = g_GlobalVariables.size();
184 unsigned int stringcount = CountStringTable (); 182 unsigned int stringcount = num_strings_in_table ();
185 int NumMarks = w->MainBuffer->CountMarks (); 183 int NumMarks = w->MainBuffer->CountMarks ();
186 int NumRefs = w->MainBuffer->CountReferences (); 184 int NumRefs = w->MainBuffer->CountReferences ();
187 printf ("%u / %u strings written\n", stringcount, MAX_LIST_STRINGS); 185 printf ("%u / %u strings written\n", stringcount, MAX_LIST_STRINGS);
188 printf ("%u / %u global variables\n", globalcount, MAX_SCRIPT_VARIABLES); 186 printf ("%u / %u global variables\n", globalcount, MAX_SCRIPT_VARIABLES);
189 printf ("%d / %d bytecode marks\n", NumMarks, MAX_MARKS); 187 printf ("%d / %d bytecode marks\n", NumMarks, MAX_MARKS);
204 // ============================================================================ 202 // ============================================================================
205 // Utility functions 203 // Utility functions
206 204
207 // ============================================================================ 205 // ============================================================================
208 // Does the given file exist? 206 // Does the given file exist?
209 bool fexists (char* path) { 207 bool fexists (string path) {
210 if (FILE* test = fopen (path, "r")) { 208 if (FILE* test = fopen (path, "r")) {
211 fclose (test); 209 fclose (test);
212 return true; 210 return true;
213 } 211 }
212
214 return false; 213 return false;
215 } 214 }
216 215
217 // ============================================================================ 216 // ============================================================================
218 // Generic error 217 // Generic error
219 void error (const char* text, ...) { 218 void error (const char* text, ...) {
220 PERFORM_FORMAT (text, c); 219 va_list va;
221 fprintf (stderr, "error: %s", c); 220 va_start (va, text);
221 fprintf (stderr, "error: ");
222 vfprintf (stderr, text, va);
223 va_end (va);
222 exit (1); 224 exit (1);
223 } 225 }
224 226
225 // ============================================================================ 227 // ============================================================================
226 // Mutates given filename to an object filename 228 // Mutates given filename to an object filename
227 char* ObjectFileName (str s) { 229 string ObjectFileName (string s) {
228 // Locate the extension and chop it out 230 // Locate the extension and chop it out
229 unsigned int extdot = s.last ("."); 231 int extdot = s.last (".");
230 if (extdot >= s.len()-4) 232
233 if (extdot >= s.len() - 4)
231 s -= (s.len() - extdot); 234 s -= (s.len() - extdot);
232 235
233 s += ".o"; 236 s += ".o";
234 return s.chars(); 237 return s;
235 } 238 }
236 239
237 // ============================================================================ 240 // ============================================================================
238 // Is the given argument a reserved keyword? 241 // Is the given argument a reserved keyword?
239 bool IsKeyword (str s) { 242 bool IsKeyword (string s) {
240 for (unsigned int u = 0; u < NumKeywords (); u++) 243 for (unsigned int u = 0; u < NumKeywords (); u++)
241 if (!s.icompare (g_Keywords[u])) 244 if (s.to_uppercase() == g_Keywords[u].to_uppercase())
242 return true; 245 return true;
243 return false; 246 return false;
244 } 247 }
245 248
246 unsigned int NumKeywords () { 249 unsigned int NumKeywords () {
247 return sizeof (g_Keywords) / sizeof (const char*); 250 return sizeof (g_Keywords) / sizeof (const char*);
248 } 251 }
249 252
250 // ============================================================================ 253 // ============================================================================
251 type_e GetTypeByName (str t) { 254 type_e GetTypeByName (string t) {
252 t = t.tolower(); 255 t = t.to_lowercase();
253 return (t == "int") ? TYPE_INT : 256 return (t == "int") ? TYPE_INT :
254 (t == "str") ? TYPE_STRING : 257 (t == "str") ? TYPE_STRING :
255 (t == "void") ? TYPE_VOID : 258 (t == "void") ? TYPE_VOID :
256 (t == "bool") ? TYPE_BOOL : 259 (t == "bool") ? TYPE_BOOL :
257 TYPE_UNKNOWN; 260 TYPE_UNKNOWN;
258 } 261 }
259 262
260 263
261 // ============================================================================ 264 // ============================================================================
262 // Inverse operation - type name by value 265 // Inverse operation - type name by value
263 str GetTypeName (type_e type) { 266 string GetTypeName (type_e type) {
264 switch (type) { 267 switch (type) {
265 case TYPE_INT: return "int"; break; 268 case TYPE_INT: return "int"; break;
266 case TYPE_STRING: return "str"; break; 269 case TYPE_STRING: return "str"; break;
267 case TYPE_VOID: return "void"; break; 270 case TYPE_VOID: return "void"; break;
268 case TYPE_BOOL: return "bool"; break; 271 case TYPE_BOOL: return "bool"; break;

mercurial