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 __PARSER_CXX__ |
|
42 |
41 #include <stdio.h> |
43 #include <stdio.h> |
42 #include <stdlib.h> |
44 #include <stdlib.h> |
43 #include "common.h" |
45 #include "common.h" |
44 #include "str.h" |
46 #include "str.h" |
45 #include "objwriter.h" |
47 #include "objwriter.h" |
46 #include "scriptreader.h" |
48 #include "scriptreader.h" |
47 |
49 |
48 #define TOKEN_CHARS token.chars() |
50 #define TOKEN_CHARS token.chars() |
49 #define TOKEN_IS(s) !token.compare (s) |
51 #define TOKEN_IS(s) !token.compare (s) |
50 #define MUST_TOPLEVEL if (curmode != MODE_TOPLEVEL) \ |
52 #define MUST_TOPLEVEL if (g_CurMode != MODE_TOPLEVEL) \ |
51 ParseError ("%ss may only be defined at top level!", token.chars()); |
53 ParseError ("%ss may only be defined at top level!", token.chars()); |
52 |
54 |
|
55 int g_NumStates = 0; |
|
56 int g_NumEvents = 0; |
|
57 int g_CurMode = MODE_TOPLEVEL; |
|
58 str g_CurState = ""; |
|
59 |
53 void ScriptReader::BeginParse (ObjWriter* w) { |
60 void ScriptReader::BeginParse (ObjWriter* w) { |
54 // Script starts at top level |
|
55 curmode = MODE_TOPLEVEL; |
|
56 curstate = ""; |
|
57 |
|
58 while (Next()) { |
61 while (Next()) { |
59 printf ("got token %s\n", (char*)token); |
62 // printf ("got token %s\n", token.chars()); |
60 if (TOKEN_IS ("state")) { |
63 if (TOKEN_IS ("#include")) { |
|
64 MustNext (); |
|
65 // First ensure that the file can be opened |
|
66 FILE* newfile = fopen (token.chars(), "r"); |
|
67 if (!newfile) |
|
68 ParseError ("couldn't open included file `%s`!", token.chars()); |
|
69 fclose (newfile); |
|
70 ScriptReader* newreader = new ScriptReader (token.chars()); |
|
71 newreader->BeginParse (w); |
|
72 } else if (TOKEN_IS ("state")) { |
61 MUST_TOPLEVEL |
73 MUST_TOPLEVEL |
62 |
74 |
63 MustNext (); |
75 MustNext (); |
64 |
76 |
65 str statename = token; |
77 str statename = token; |
66 |
78 |
67 // State name must be a word. |
79 // State name must be a word. |
68 if (statename.first (" ") != statename.len()) |
80 if (statename.first (" ") != statename.len()) |
69 ParseError ("state name must be a single word! got `%s`", (char*)statename); |
81 ParseError ("state name must be a single word! got `%s`", (char*)statename); |
70 |
82 |
71 |
|
72 // Must end in a colon |
83 // Must end in a colon |
73 MustNext (":"); |
84 MustNext (":"); |
74 |
85 |
75 w->WriteState (statename); |
86 w->Write (DH_STATENAME); |
76 curstate = statename; |
87 w->Write (statename.len()); |
|
88 w->WriteString (statename); |
|
89 w->Write (DH_STATEIDX); |
|
90 w->Write (g_NumStates); |
|
91 |
|
92 g_NumStates++; |
|
93 g_CurState = statename; |
77 } else if (TOKEN_IS ("event")) { |
94 } else if (TOKEN_IS ("event")) { |
78 MUST_TOPLEVEL |
95 MUST_TOPLEVEL |
79 |
96 |
80 // Event definition |
97 // Event definition |
81 MustNext (); |
98 MustNext (); |
93 |
110 |
94 #endif |
111 #endif |
95 |
112 |
96 MustNext ("{"); |
113 MustNext ("{"); |
97 |
114 |
98 curmode = MODE_EVENT; |
115 g_CurMode = MODE_EVENT; |
99 |
116 |
100 w->Write (DH_EVENT); |
117 w->Write (DH_EVENT); |
101 // w->Write<long> (u); |
118 // w->Write<long> (u); |
102 numevents++; |
119 g_NumEvents++; |
103 } else if (TOKEN_IS ("}")) { |
120 } else if (TOKEN_IS ("}")) { |
104 // Closing brace.. |
121 // Closing brace.. |
105 switch (curmode) { |
122 switch (g_CurMode) { |
106 case MODE_EVENT: |
123 case MODE_EVENT: |
107 // Brace closes event. |
124 // Brace closes event. |
108 w->Write (DH_ENDEVENT); |
125 w->Write (DH_ENDEVENT); |
109 curmode = MODE_TOPLEVEL; |
126 g_CurMode = MODE_TOPLEVEL; |
110 break; |
127 break; |
111 default: |
128 default: |
112 ParseError ("unexpected `}`"); |
129 ParseError ("unexpected `}`"); |
113 } |
130 } |
114 } else { |
131 } else { |
115 ParseError ("unknown keyword `%s`!", TOKEN_CHARS); |
132 ParseError ("unknown keyword `%s`!", TOKEN_CHARS); |
116 } |
133 } |
117 } |
134 } |
118 |
135 |
119 if (curmode != MODE_TOPLEVEL) |
136 if (g_CurMode != MODE_TOPLEVEL) |
120 ParseError ("script did not end at top level! did you forget a `}`?\n"); |
137 ParseError ("script did not end at top level! did you forget a `}`?\n"); |
121 |
138 |
122 /* |
139 /* |
123 // State |
140 // State |
124 w->WriteState ("stateSpawn"); |
141 w->WriteState ("stateSpawn"); |