Added ability to define multiple functions (without parameters) and
[zilutils.git] / zilasm / directives.cpp
1 /*
2  * directives.c -- part of ZilUtils/ZilAsm
3  *
4  * Copyright (C) 2016, 2020 Jason Self <j@jxself.org>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as
8  * published by the Free Software Foundation, either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>
18  *
19  * SPDX-License-Identifier: AGPL-3.0-or-later
20  */
21
22 #include "include_all.h"
23
24 #define ARRAY_SIZE(x)  ((sizeof(x)) / (sizeof(x[0])))
25
26 int g_stopParsing = 0;
27 stack<FILE*> g_fileHandlers;
28
29
30
31 static int
32 byte_handler (const char *args, CParser* parser)
33 {
34   /* !!! TODO !!! */
35   return 0;
36 }
37
38 static int
39 end_handler (const char *args, CParser* parser)
40 {
41         g_stopParsing = 1;
42         return 0;
43 }
44
45 static int
46 endi_handler (const char *args, CParser* parser)
47 {
48   /* !!! TODO !!! */
49   return 0;
50 }
51
52 static int
53 endt_handler (const char *args, CParser* parser)
54 {
55   /* !!! TODO !!! */
56   return 0;
57 }
58
59 static int
60 fstr_handler (const char *args, CParser* parser)
61 {
62   /* !!! TODO !!! */
63   return 0;
64 }
65
66 static int
67 funct_handler (const char *args, CParser* parser)
68 {
69   /* !!! TODO !!! */
70   
71         parser->add_function(args);
72         return 0;
73 }
74
75 static int
76 gstr_handler (const char *args, CParser* parser)
77 {
78   /* !!! TODO !!! */
79   return 0;
80 }
81
82 static int
83 gvar_handler (const char *args, CParser* parser)
84 {
85   /* !!! TODO !!! */
86   return 0;
87 }
88
89 static int
90 insert_handler (const char *args, CParser* parser)
91 {
92         string file_name;
93         char *p = (char*)args;
94         while (*p == ' ') p++;
95
96         if (*p == '"')
97         {
98                 p++;
99                 do
100                 {
101                         file_name += *p;
102                         p++;
103                 }
104                 while (*p != '"' && *p != 0 ) ;
105         }
106         else
107         {
108                 do
109                 {
110                         file_name += *p;
111                         p++;
112                 } while (*p != ' ' && *p != '\n' && *p != '\r' && *p != '\t' && *p != 0);
113         }
114         
115         if (file_name.find('.') == string::npos)
116         {
117                 file_name += ".zap";
118         }
119
120 #ifdef WIN32
121         char delimeter = '\\';
122 #else
123         char delimeter = '/';
124 #endif
125
126         Parsing_Context pc;
127         if (file_name.rfind(delimeter) == string::npos)
128         {
129                 pc.current_directory = "";
130                 pc.current_file_name = file_name;
131         }
132         else
133         {
134                 pc.current_directory = file_name.substr(0, file_name.rfind(delimeter)+1);
135                 pc.current_file_name = file_name.substr(file_name.rfind(delimeter)+1);
136         }
137
138         pc.current_directory = g_parsing_contexts.top().current_directory + pc.current_directory;
139         //pc.current_file_name = s;
140         g_parsing_contexts.push(pc);
141         
142         unsigned saveLineNumber = parser->m_current_line_number;
143         parser->parse_file(); //s.c_str());
144         parser->m_current_line_number = saveLineNumber;
145         return strlen(args);
146 }
147
148 static int
149 len_handler (const char *args, CParser* parser)
150 {
151   /* !!! TODO !!! */
152   return 0;
153 }
154
155 static int
156 newdirective_handler (const char *args, CParser* parser)
157 {
158   /* !!! TODO !!! */
159   return 0;
160 }
161
162 static int
163 object_handler (const char *args, CParser* parser)
164 {
165   /* !!! TODO !!! */
166   return 0;
167 }
168
169 static int
170 prop_handler (const char *args, CParser* parser)
171 {
172   /* !!! TODO !!! */
173   return 0;
174 }
175
176 static int
177 str_handler (const char *args, CParser* parser)
178 {
179   /* !!! TODO !!! */
180   return 0;
181 }
182
183 static int
184 strl_handler (const char *args, CParser* parser)
185 {
186   /* !!! TODO !!! */
187   return 0;
188 }
189
190 static int
191 table_handler (const char *args, CParser* parser)
192 {
193   /* !!! TODO !!! */
194   return 0;
195 }
196
197 static int
198 vocbeg_handler (const char *args, CParser* parser)
199 {
200   /* !!! TODO !!! */
201   return 0;
202 }
203
204 static int
205 vocend_handler (const char *args, CParser* parser)
206 {
207   /* !!! TODO !!! */
208   return 0;
209 }
210
211 static int
212 word_handler (const char *args, CParser* parser)
213 {
214   /* !!! TODO !!! */
215   return 0;
216 }
217
218 static int
219 zword_handler (const char *args, CParser* parser)
220 {
221   /* !!! TODO !!! */
222   return 0;
223 }
224
225
226
227 typedef struct
228 {
229   const char *contents;
230   unsigned length;
231 } Name;
232
233 static int
234 namecmp (const void *key, const void *elem)
235 {
236   const Name *p = (Name *) key;
237   const Directive *d = (Directive *) elem;
238
239   int len1 = p->length;
240   int len2 = strlen (d->name);
241
242   int rc = memcmp (p->contents, elem, len1 < len2 ? len1 : len2);
243   return rc ? rc : (len1 - len2);
244 }
245
246 Directive_handler
247 CDirectives::directive_lookup (const char *name, unsigned namelen)
248 {
249         // Sorted array
250         static Directive Directives[] = {
251                 "BYTE", byte_handler,
252                 "END", end_handler,
253                 "ENDI", endi_handler,
254                 "ENDT", endt_handler,
255                 "FSTR", fstr_handler,
256                 "FUNCT", funct_handler,
257                 "GSTR", gstr_handler,
258                 "GVAR", gvar_handler,
259                 "INSERT", insert_handler,
260                 "LEN", len_handler,
261                 "NEW", newdirective_handler,
262                 "OBJECT", object_handler,
263                 "PROP", prop_handler,
264                 "STR", str_handler,
265                 "STRL", strl_handler,
266                 "TABLE", table_handler,
267                 "VOCBEG", vocbeg_handler,
268                 "VOCEND", vocend_handler,
269                 "WORD", word_handler,
270                 "ZWORD", zword_handler
271         };
272         
273         Name n = { name, namelen };
274   Directive *p =
275     (Directive *) bsearch (&n, Directives, ARRAY_SIZE (Directives),
276                            sizeof (Directive), namecmp);
277   return p ? p->handler : NULL;
278 }
279
280
281 CDirectives::CDirectives(CParser *parser) :m_parser(parser)
282 {
283 }