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

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

Update SBI to rev. 174.

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