parser.cxx

changeset 8
c8bfa7e6ae1b
parent 7
118d3d5db64f
child 9
d279af9afd6d
equal deleted inserted replaced
7:118d3d5db64f 8:c8bfa7e6ae1b
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;
90 w->Write (DH_STATEIDX); 89 w->Write (DH_STATEIDX);
91 w->Write (g_NumStates); 90 w->Write (g_NumStates);
92 91
93 g_NumStates++; 92 g_NumStates++;
94 g_CurState = statename; 93 g_CurState = statename;
95 } else if (TOKEN_IS ("event")) { 94 } else if (!token.compare ("event")) {
96 MUST_TOPLEVEL 95 MUST_TOPLEVEL
97 96
98 // Event definition 97 // Event definition
99 MustNext (); 98 MustNext ();
100 99
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");

mercurial