source: mainline/uspace/app/sbi/src/builtin.c@ 9f10660f

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

Update SBI to rev. 157.

  • Property mode set to 100644
File size: 8.9 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 "ancr.h"
43#include "builtin/bi_fun.h"
44#include "builtin/bi_textfile.h"
45#include "input.h"
46#include "intmap.h"
47#include "lex.h"
48#include "list.h"
49#include "mytypes.h"
50#include "os/os.h"
51#include "parse.h"
52#include "run.h"
53#include "stree.h"
54#include "strtab.h"
55#include "symbol.h"
56
57#include "builtin.h"
58
59static builtin_t *builtin_new(void);
60
61/** Declare builtin symbols in the program.
62 *
63 * Declares symbols that will be hooked to builtin interpreter procedures.
64 *
65 * @param program Program in which to declare builtin symbols.
66 */
67void builtin_declare(stree_program_t *program)
68{
69 builtin_t *bi;
70
71 bi = builtin_new();
72 bi->program = program;
73 program->builtin = bi;
74
75 /*
76 * Declare grandfather class.
77 */
78
79 builtin_code_snippet(bi,
80 "class Object is\n"
81 "end\n");
82 bi->gf_class = builtin_find_lvl0(bi, "Object");
83
84 /*
85 * Declare other builtin classes/functions.
86 */
87
88 bi_fun_declare(bi);
89 bi_textfile_declare(bi);
90
91 /* Need to process ancestry so that symbol lookups work. */
92 ancr_module_process(program, program->module);
93
94 bi_fun_bind(bi);
95 bi_textfile_bind(bi);
96}
97
98/** Get grandfather class.
99 *
100 * Grandfather class is the class from which all other classes are
101 * (directly or indirectly) derived.
102 *
103 * @param builtin Builtin context (corresponsds to program).
104 * @return Grandfather class (CSI).
105 */
106stree_csi_t *builtin_get_gf_class(builtin_t *builtin)
107{
108 if (builtin->gf_class == NULL)
109 return NULL;
110
111 return symbol_to_csi(builtin->gf_class);
112}
113
114/** Allocate new builtin context object.
115 *
116 * @return Builtin context object.
117 */
118static builtin_t *builtin_new(void)
119{
120 builtin_t *builtin;
121
122 builtin = calloc(1, sizeof(builtin_t));
123 if (builtin == NULL) {
124 printf("Memory allocation failed.\n");
125 exit(1);
126 }
127
128 return builtin;
129}
130
131/** Parse a declaration code snippet.
132 *
133 * Parses a piece of code from a string at the module level. This can be
134 * used to declare builtin symbols easily and without need for an external
135 * file.
136 */
137void builtin_code_snippet(builtin_t *bi, const char *snippet)
138{
139 input_t *input;
140 lex_t lex;
141 parse_t parse;
142
143 input_new_string(&input, snippet);
144 lex_init(&lex, input);
145 parse_init(&parse, bi->program, &lex);
146 parse_module(&parse);
147}
148
149/** Simplifed search for a global symbol.
150 *
151 * The specified symbol must exist.
152 *
153 * @param bi Builtin context object.
154 * @param sym_name Name of symbol to find.
155 * @return Symbol.
156 */
157stree_symbol_t *builtin_find_lvl0(builtin_t *bi, const char *sym_name)
158{
159 stree_symbol_t *sym;
160 stree_ident_t *ident;
161
162 ident = stree_ident_new();
163
164 ident->sid = strtab_get_sid(sym_name);
165 sym = symbol_lookup_in_csi(bi->program, NULL, ident);
166 assert(sym != NULL);
167
168 return sym;
169}
170
171/** Simplifed search for a level 1 symbol.
172 *
173 * The specified symbol must exist.
174 *
175 * @param bi Builtin context object.
176 * @param csi_name CSI in which to look for symbol.
177 * @param sym_name Name of symbol to find.
178 * @return Symbol.
179 */
180stree_symbol_t *builtin_find_lvl1(builtin_t *bi, const char *csi_name,
181 const char *sym_name)
182{
183 stree_symbol_t *csi_sym;
184 stree_csi_t *csi;
185
186 stree_symbol_t *mbr_sym;
187 stree_ident_t *ident;
188
189 ident = stree_ident_new();
190
191 ident->sid = strtab_get_sid(csi_name);
192 csi_sym = symbol_lookup_in_csi(bi->program, NULL, ident);
193 assert(csi_sym != NULL);
194 csi = symbol_to_csi(csi_sym);
195 assert(csi != NULL);
196
197 ident->sid = strtab_get_sid(sym_name);
198 mbr_sym = symbol_lookup_in_csi(bi->program, csi, ident);
199 assert(mbr_sym != NULL);
200
201 return mbr_sym;
202}
203
204/** Bind level 1 member function to external implementation.
205 *
206 * Binds a member function (of a global class) to external implementation.
207 * The specified CSI and member function must exist.
208 *
209 * @param bi Builtin context object.
210 * @param csi_name CSI which contains the function.
211 * @param sym_name Function name.
212 * @param bproc Pointer to C function implementation.
213 */
214void builtin_fun_bind(builtin_t *bi, const char *csi_name,
215 const char *sym_name, builtin_proc_t bproc)
216{
217 stree_symbol_t *fun_sym;
218 stree_fun_t *fun;
219
220 fun_sym = builtin_find_lvl1(bi, csi_name, sym_name);
221 assert(fun_sym != NULL);
222 fun = symbol_to_fun(fun_sym);
223 assert(fun != NULL);
224
225 fun->proc->bi_handler = bproc;
226}
227
228/** Execute a builtin procedure.
229 *
230 * Executes a procedure that has an external implementation.
231 *
232 * @param run Runner object.
233 * @param proc Procedure that has an external implementation.
234 */
235void builtin_run_proc(run_t *run, stree_proc_t *proc)
236{
237 stree_symbol_t *fun_sym;
238 builtin_t *bi;
239 builtin_proc_t bproc;
240
241#ifdef DEBUG_RUN_TRACE
242 printf("Run builtin procedure.\n");
243#endif
244 fun_sym = proc->outer_symbol;
245 bi = run->program->builtin;
246
247 bproc = proc->bi_handler;
248 if (bproc == NULL) {
249 printf("Error: Unrecognized builtin function '");
250 symbol_print_fqn(fun_sym);
251 printf("'.\n");
252 exit(1);
253 }
254
255 /* Run the builtin procedure handler. */
256 (*bproc)(run);
257}
258
259/** Get pointer to member var of current object.
260 *
261 * Returns the var node that corresponds to a member of the currently
262 * active object with the given name. This member must exist.
263 *
264 * @param run Runner object.
265 * @param mbr_name Name of member to find.
266 * @return Var node of the member.
267 */
268rdata_var_t *builtin_get_self_mbr_var(run_t *run, const char *mbr_name)
269{
270 run_proc_ar_t *proc_ar;
271 rdata_object_t *object;
272 sid_t mbr_name_sid;
273 rdata_var_t *mbr_var;
274
275 proc_ar = run_get_current_proc_ar(run);
276 assert(proc_ar->obj->vc == vc_object);
277 object = proc_ar->obj->u.object_v;
278
279 mbr_name_sid = strtab_get_sid(mbr_name);
280 mbr_var = intmap_get(&object->fields, mbr_name_sid);
281 assert(mbr_var != NULL);
282
283 return mbr_var;
284}
285
286/** Declare a builtin function in @a csi.
287 *
288 * Declare a builtin function member of CSI @a csi. Deprecated in favor
289 * of builtin_code_snippet().
290 *
291 * @param csi CSI in which to declare function.
292 * @param name Name of member function to declare.
293 * @return Symbol of newly declared function.
294 */
295stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name)
296{
297 stree_ident_t *ident;
298 stree_fun_t *fun;
299 stree_csimbr_t *csimbr;
300 stree_symbol_t *fun_sym;
301
302 ident = stree_ident_new();
303 ident->sid = strtab_get_sid(name);
304
305 fun = stree_fun_new();
306 fun->name = ident;
307 fun->proc = stree_proc_new();
308 fun->proc->body = NULL;
309 list_init(&fun->args);
310
311 csimbr = stree_csimbr_new(csimbr_fun);
312 csimbr->u.fun = fun;
313
314 fun_sym = stree_symbol_new(sc_fun);
315 fun_sym->u.fun = fun;
316 fun_sym->outer_csi = csi;
317 fun->symbol = fun_sym;
318 fun->proc->outer_symbol = fun_sym;
319
320 list_append(&csi->members, csimbr);
321
322 return fun_sym;
323}
324
325/** Add one formal parameter to function.
326 *
327 * Used to incrementally construct formal parameter list of a builtin
328 * function. Deprecated in favor of builtin_code_snippet(). Does not
329 * support type checking.
330 *
331 * @param fun_sym Symbol of function to add parameters to.
332 * @param name Name of parameter to add.
333 */
334void builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name)
335{
336 stree_proc_arg_t *proc_arg;
337 stree_fun_t *fun;
338
339 fun = symbol_to_fun(fun_sym);
340 assert(fun != NULL);
341
342 proc_arg = stree_proc_arg_new();
343 proc_arg->name = stree_ident_new();
344 proc_arg->name->sid = strtab_get_sid(name);
345 proc_arg->type = NULL; /* XXX */
346
347 list_append(&fun->args, proc_arg);
348}
Note: See TracBrowser for help on using the repository browser.