source: mainline/uspace/app/sbi/src/builtin.c@ 883fedc

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 883fedc was 38aaacc2, checked in by Jiri Svoboda <jiri@…>, 16 years ago

Update SBI to rev. 207.

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/*
2 * Copyright (c) 2010 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file Builtin symbol binding.
30 *
31 * 'Builtin' symbols are implemented outside of the language itself.
32 * Here we refer to entities residing within the interpreted universe
33 * as 'internal', while anything implemented outside this universe
34 * as 'external'. This module facilitates declaration of builtin
35 * symbols and the binding of these symbols to their external
36 * implementation.
37 */
38
39#include <stdio.h>
40#include <stdlib.h>
41#include <assert.h>
42#include "builtin/bi_boxed.h"
43#include "builtin/bi_error.h"
44#include "builtin/bi_fun.h"
45#include "builtin/bi_textfile.h"
46#include "input.h"
47#include "intmap.h"
48#include "lex.h"
49#include "list.h"
50#include "mytypes.h"
51#include "os/os.h"
52#include "parse.h"
53#include "run.h"
54#include "stree.h"
55#include "strtab.h"
56#include "symbol.h"
57
58#include "builtin.h"
59
60static builtin_t *builtin_new(void);
61
62/** Declare builtin symbols in the program.
63 *
64 * Declares symbols that will be hooked to builtin interpreter procedures.
65 *
66 * @param program Program in which to declare builtin symbols.
67 */
68void builtin_declare(stree_program_t *program)
69{
70 builtin_t *bi;
71
72 bi = builtin_new();
73 bi->program = program;
74 program->builtin = bi;
75
76 /*
77 * Declare grandfather class.
78 */
79
80 builtin_code_snippet(bi,
81 "class Object is\n"
82 "end\n");
83 bi->gf_class = builtin_find_lvl0(bi, "Object");
84
85 /*
86 * Declare other builtin classes/functions.
87 */
88
89 bi_error_declare(bi);
90 bi_fun_declare(bi);
91 bi_textfile_declare(bi);
92}
93
94/** Bind internal interpreter references to symbols in the program.
95 *
96 * This is performed in separate phase for several reasons. First,
97 * symbol lookups do not work until ancestry is processed. Second,
98 * this gives a chance to process the library first and thus bind
99 * to symbols defined there.
100 */
101void builtin_bind(builtin_t *bi)
102{
103 bi_boxed_bind(bi);
104 bi_error_bind(bi);
105 bi_fun_bind(bi);
106 bi_textfile_bind(bi);
107}
108
109/** Get grandfather class.
110 *
111 * Grandfather class is the class from which all other classes are
112 * (directly or indirectly) derived.
113 *
114 * @param builtin Builtin context (corresponsds to program).
115 * @return Grandfather class (CSI).
116 */
117stree_csi_t *builtin_get_gf_class(builtin_t *builtin)
118{
119 if (builtin->gf_class == NULL)
120 return NULL;
121
122 return symbol_to_csi(builtin->gf_class);
123}
124
125/** Allocate new builtin context object.
126 *
127 * @return Builtin context object.
128 */
129static builtin_t *builtin_new(void)
130{
131 builtin_t *builtin;
132
133 builtin = calloc(1, sizeof(builtin_t));
134 if (builtin == NULL) {
135 printf("Memory allocation failed.\n");
136 exit(1);
137 }
138
139 return builtin;
140}
141
142/** Parse a declaration code snippet.
143 *
144 * Parses a piece of code from a string at the module level. This can be
145 * used to declare builtin symbols easily and without need for an external
146 * file.
147 */
148void builtin_code_snippet(builtin_t *bi, const char *snippet)
149{
150 input_t *input;
151 lex_t lex;
152 parse_t parse;
153
154 input_new_string(&input, snippet);
155 lex_init(&lex, input);
156 parse_init(&parse, bi->program, &lex);
157 parse_module(&parse);
158}
159
160/** Simplifed search for a global symbol.
161 *
162 * The specified symbol must exist.
163 *
164 * @param bi Builtin context object.
165 * @param sym_name Name of symbol to find.
166 * @return Symbol.
167 */
168stree_symbol_t *builtin_find_lvl0(builtin_t *bi, const char *sym_name)
169{
170 stree_symbol_t *sym;
171 stree_ident_t *ident;
172
173 ident = stree_ident_new();
174
175 ident->sid = strtab_get_sid(sym_name);
176 sym = symbol_lookup_in_csi(bi->program, NULL, ident);
177 assert(sym != NULL);
178
179 return sym;
180}
181
182/** Simplifed search for a level 1 symbol.
183 *
184 * The specified symbol must exist.
185 *
186 * @param bi Builtin context object.
187 * @param csi_name CSI in which to look for symbol.
188 * @param sym_name Name of symbol to find.
189 * @return Symbol.
190 */
191stree_symbol_t *builtin_find_lvl1(builtin_t *bi, const char *csi_name,
192 const char *sym_name)
193{
194 stree_symbol_t *csi_sym;
195 stree_csi_t *csi;
196
197 stree_symbol_t *mbr_sym;
198 stree_ident_t *ident;
199
200 ident = stree_ident_new();
201
202 ident->sid = strtab_get_sid(csi_name);
203 csi_sym = symbol_lookup_in_csi(bi->program, NULL, ident);
204 assert(csi_sym != NULL);
205 csi = symbol_to_csi(csi_sym);
206 assert(csi != NULL);
207
208 ident->sid = strtab_get_sid(sym_name);
209 mbr_sym = symbol_lookup_in_csi(bi->program, csi, ident);
210 assert(mbr_sym != NULL);
211
212 return mbr_sym;
213}
214
215/** Bind level 1 member function to external implementation.
216 *
217 * Binds a member function (of a global class) to external implementation.
218 * The specified CSI and member function must exist.
219 *
220 * @param bi Builtin context object.
221 * @param csi_name CSI which contains the function.
222 * @param sym_name Function name.
223 * @param bproc Pointer to C function implementation.
224 */
225void builtin_fun_bind(builtin_t *bi, const char *csi_name,
226 const char *sym_name, builtin_proc_t bproc)
227{
228 stree_symbol_t *fun_sym;
229 stree_fun_t *fun;
230
231 fun_sym = builtin_find_lvl1(bi, csi_name, sym_name);
232 assert(fun_sym != NULL);
233 fun = symbol_to_fun(fun_sym);
234 assert(fun != NULL);
235
236 fun->proc->bi_handler = bproc;
237}
238
239/** Execute a builtin procedure.
240 *
241 * Executes a procedure that has an external implementation.
242 *
243 * @param run Runner object.
244 * @param proc Procedure that has an external implementation.
245 */
246void builtin_run_proc(run_t *run, stree_proc_t *proc)
247{
248 stree_symbol_t *fun_sym;
249 builtin_t *bi;
250 builtin_proc_t bproc;
251
252#ifdef DEBUG_RUN_TRACE
253 printf("Run builtin procedure.\n");
254#endif
255 fun_sym = proc->outer_symbol;
256 bi = run->program->builtin;
257
258 bproc = proc->bi_handler;
259 if (bproc == NULL) {
260 printf("Error: Unrecognized builtin function '");
261 symbol_print_fqn(fun_sym);
262 printf("'.\n");
263 exit(1);
264 }
265
266 /* Run the builtin procedure handler. */
267 (*bproc)(run);
268}
269
270/** Get pointer to member var of current object.
271 *
272 * Returns the var node that corresponds to a member of the currently
273 * active object with the given name. This member must exist.
274 *
275 * @param run Runner object.
276 * @param mbr_name Name of member to find.
277 * @return Var node of the member.
278 */
279rdata_var_t *builtin_get_self_mbr_var(run_t *run, const char *mbr_name)
280{
281 run_proc_ar_t *proc_ar;
282 rdata_object_t *object;
283 sid_t mbr_name_sid;
284 rdata_var_t *mbr_var;
285
286 proc_ar = run_get_current_proc_ar(run);
287 assert(proc_ar->obj->vc == vc_object);
288 object = proc_ar->obj->u.object_v;
289
290 mbr_name_sid = strtab_get_sid(mbr_name);
291 mbr_var = intmap_get(&object->fields, mbr_name_sid);
292 assert(mbr_var != NULL);
293
294 return mbr_var;
295}
296
297/** Declare a builtin function in @a csi.
298 *
299 * Declare a builtin function member of CSI @a csi. Deprecated in favor
300 * of builtin_code_snippet().
301 *
302 * @param csi CSI in which to declare function.
303 * @param name Name of member function to declare.
304 * @return Symbol of newly declared function.
305 */
306stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name)
307{
308 stree_ident_t *ident;
309 stree_fun_t *fun;
310 stree_fun_sig_t *sig;
311 stree_csimbr_t *csimbr;
312 stree_symbol_t *fun_sym;
313
314 ident = stree_ident_new();
315 ident->sid = strtab_get_sid(name);
316
317 fun = stree_fun_new();
318 fun->name = ident;
319 fun->proc = stree_proc_new();
320 fun->proc->body = NULL;
321 sig = stree_fun_sig_new();
322 fun->sig = sig;
323
324 list_init(&fun->sig->args);
325
326 csimbr = stree_csimbr_new(csimbr_fun);
327 csimbr->u.fun = fun;
328
329 fun_sym = stree_symbol_new(sc_fun);
330 fun_sym->u.fun = fun;
331 fun_sym->outer_csi = csi;
332 fun->symbol = fun_sym;
333 fun->proc->outer_symbol = fun_sym;
334
335 list_append(&csi->members, csimbr);
336
337 return fun_sym;
338}
339
340/** Add one formal parameter to function.
341 *
342 * Used to incrementally construct formal parameter list of a builtin
343 * function. Deprecated in favor of builtin_code_snippet(). Does not
344 * support type checking.
345 *
346 * @param fun_sym Symbol of function to add parameters to.
347 * @param name Name of parameter to add.
348 */
349void builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name)
350{
351 stree_proc_arg_t *proc_arg;
352 stree_fun_t *fun;
353
354 fun = symbol_to_fun(fun_sym);
355 assert(fun != NULL);
356
357 proc_arg = stree_proc_arg_new();
358 proc_arg->name = stree_ident_new();
359 proc_arg->name->sid = strtab_get_sid(name);
360 proc_arg->type = NULL; /* XXX */
361
362 list_append(&fun->sig->args, proc_arg);
363}
Note: See TracBrowser for help on using the repository browser.