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

Last change on this file was 1433ecda, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix cstyle: make ccheck-fix and commit only files where all the changes are good.

  • Property mode set to 100644
File size: 10.5 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>
[38aaacc2]42#include "builtin/bi_boxed.h"
[23de644]43#include "builtin/bi_error.h"
[c5cb943d]44#include "builtin/bi_char.h"
[051b3db8]45#include "builtin/bi_console.h"
[c5cb943d]46#include "builtin/bi_int.h"
[051b3db8]47#include "builtin/bi_task.h"
[37f527b]48#include "builtin/bi_textfile.h"
[051bc69a]49#include "builtin/bi_string.h"
[37f527b]50#include "input.h"
51#include "intmap.h"
52#include "lex.h"
[09ababb7]53#include "list.h"
54#include "mytypes.h"
[94d484a]55#include "os/os.h"
[37f527b]56#include "parse.h"
[c5cb943d]57#include "rdata.h"
[09ababb7]58#include "run.h"
59#include "stree.h"
60#include "strtab.h"
[94d484a]61#include "symbol.h"
[09ababb7]62
63#include "builtin.h"
64
[37f527b]65static builtin_t *builtin_new(void);
[09ababb7]66
67/** Declare builtin symbols in the program.
68 *
[d0febca]69 * Declares symbols that will be hooked to builtin interpreter procedures.
[1ebc1a62]70 *
71 * @param program Program in which to declare builtin symbols.
[09ababb7]72 */
73void builtin_declare(stree_program_t *program)
74{
[37f527b]75 builtin_t *bi;
76
77 bi = builtin_new();
78 bi->program = program;
79 program->builtin = bi;
80
81 /*
82 * Declare grandfather class.
83 */
84
85 builtin_code_snippet(bi,
[1433ecda]86 "class Object is\n"
87 "end\n");
[37f527b]88 bi->gf_class = builtin_find_lvl0(bi, "Object");
89
90 /*
91 * Declare other builtin classes/functions.
92 */
93
[23de644]94 bi_error_declare(bi);
[c5cb943d]95 bi_char_declare(bi);
[051b3db8]96 bi_console_declare(bi);
[c5cb943d]97 bi_int_declare(bi);
[051b3db8]98 bi_task_declare(bi);
[37f527b]99 bi_textfile_declare(bi);
[051bc69a]100 bi_string_declare(bi);
[38aaacc2]101}
[37f527b]102
[38aaacc2]103/** Bind internal interpreter references to symbols in the program.
104 *
105 * This is performed in separate phase for several reasons. First,
106 * symbol lookups do not work until ancestry is processed. Second,
107 * this gives a chance to process the library first and thus bind
108 * to symbols defined there.
109 */
110void builtin_bind(builtin_t *bi)
111{
112 bi_boxed_bind(bi);
[23de644]113 bi_error_bind(bi);
[c5cb943d]114 bi_char_bind(bi);
[051b3db8]115 bi_console_bind(bi);
[c5cb943d]116 bi_int_bind(bi);
[051b3db8]117 bi_task_bind(bi);
[37f527b]118 bi_textfile_bind(bi);
[051bc69a]119 bi_string_bind(bi);
[37f527b]120}
121
[1ebc1a62]122/** Get grandfather class.
123 *
124 * Grandfather class is the class from which all other classes are
125 * (directly or indirectly) derived.
126 *
127 * @param builtin Builtin context (corresponsds to program).
128 * @return Grandfather class (CSI).
129 */
[37f527b]130stree_csi_t *builtin_get_gf_class(builtin_t *builtin)
131{
132 if (builtin->gf_class == NULL)
133 return NULL;
134
135 return symbol_to_csi(builtin->gf_class);
136}
137
[1ebc1a62]138/** Allocate new builtin context object.
139 *
140 * @return Builtin context object.
141 */
[37f527b]142static builtin_t *builtin_new(void)
143{
144 builtin_t *builtin;
145
146 builtin = calloc(1, sizeof(builtin_t));
147 if (builtin == NULL) {
148 printf("Memory allocation failed.\n");
149 exit(1);
150 }
151
152 return builtin;
153}
154
155/** Parse a declaration code snippet.
156 *
157 * Parses a piece of code from a string at the module level. This can be
158 * used to declare builtin symbols easily and without need for an external
159 * file.
160 */
161void builtin_code_snippet(builtin_t *bi, const char *snippet)
162{
163 input_t *input;
164 lex_t lex;
165 parse_t parse;
166
167 input_new_string(&input, snippet);
168 lex_init(&lex, input);
169 parse_init(&parse, bi->program, &lex);
170 parse_module(&parse);
171}
172
[1ebc1a62]173/** Simplifed search for a global symbol.
174 *
175 * The specified symbol must exist.
176 *
177 * @param bi Builtin context object.
178 * @param sym_name Name of symbol to find.
179 * @return Symbol.
180 */
[37f527b]181stree_symbol_t *builtin_find_lvl0(builtin_t *bi, const char *sym_name)
182{
183 stree_symbol_t *sym;
[09ababb7]184 stree_ident_t *ident;
185
186 ident = stree_ident_new();
187
[37f527b]188 ident->sid = strtab_get_sid(sym_name);
189 sym = symbol_lookup_in_csi(bi->program, NULL, ident);
[1ebc1a62]190 assert(sym != NULL);
[09ababb7]191
[37f527b]192 return sym;
193}
[09ababb7]194
[1ebc1a62]195/** Simplifed search for a level 1 symbol.
196 *
197 * The specified symbol must exist.
198 *
199 * @param bi Builtin context object.
200 * @param csi_name CSI in which to look for symbol.
201 * @param sym_name Name of symbol to find.
202 * @return Symbol.
203 */
[37f527b]204stree_symbol_t *builtin_find_lvl1(builtin_t *bi, const char *csi_name,
205 const char *sym_name)
206{
207 stree_symbol_t *csi_sym;
208 stree_csi_t *csi;
209
210 stree_symbol_t *mbr_sym;
211 stree_ident_t *ident;
[09ababb7]212
[37f527b]213 ident = stree_ident_new();
[09ababb7]214
[37f527b]215 ident->sid = strtab_get_sid(csi_name);
216 csi_sym = symbol_lookup_in_csi(bi->program, NULL, ident);
[1ebc1a62]217 assert(csi_sym != NULL);
[37f527b]218 csi = symbol_to_csi(csi_sym);
219 assert(csi != NULL);
[94d484a]220
[37f527b]221 ident->sid = strtab_get_sid(sym_name);
222 mbr_sym = symbol_lookup_in_csi(bi->program, csi, ident);
[1ebc1a62]223 assert(mbr_sym != NULL);
[94d484a]224
[37f527b]225 return mbr_sym;
226}
227
[1ebc1a62]228/** Bind level 1 member function to external implementation.
229 *
230 * Binds a member function (of a global class) to external implementation.
231 * The specified CSI and member function must exist.
232 *
233 * @param bi Builtin context object.
234 * @param csi_name CSI which contains the function.
235 * @param sym_name Function name.
236 * @param bproc Pointer to C function implementation.
237 */
[37f527b]238void builtin_fun_bind(builtin_t *bi, const char *csi_name,
239 const char *sym_name, builtin_proc_t bproc)
240{
241 stree_symbol_t *fun_sym;
242 stree_fun_t *fun;
243
244 fun_sym = builtin_find_lvl1(bi, csi_name, sym_name);
245 assert(fun_sym != NULL);
246 fun = symbol_to_fun(fun_sym);
247 assert(fun != NULL);
248
249 fun->proc->bi_handler = bproc;
[94d484a]250}
251
[1ebc1a62]252/** Execute a builtin procedure.
253 *
254 * Executes a procedure that has an external implementation.
255 *
256 * @param run Runner object.
257 * @param proc Procedure that has an external implementation.
258 */
[39e8406]259void builtin_run_proc(run_t *run, stree_proc_t *proc)
[94d484a]260{
[39e8406]261 stree_symbol_t *fun_sym;
[37f527b]262 builtin_proc_t bproc;
[39e8406]263
[94d484a]264#ifdef DEBUG_RUN_TRACE
[d0febca]265 printf("Run builtin procedure.\n");
[94d484a]266#endif
[39e8406]267 fun_sym = proc->outer_symbol;
268
[37f527b]269 bproc = proc->bi_handler;
270 if (bproc == NULL) {
271 printf("Error: Unrecognized builtin function '");
272 symbol_print_fqn(fun_sym);
273 printf("'.\n");
274 exit(1);
[94d484a]275 }
[37f527b]276
277 /* Run the builtin procedure handler. */
278 (*bproc)(run);
279}
280
[1ebc1a62]281/** Get pointer to member var of current object.
282 *
283 * Returns the var node that corresponds to a member of the currently
284 * active object with the given name. This member must exist.
285 *
286 * @param run Runner object.
287 * @param mbr_name Name of member to find.
288 * @return Var node of the member.
289 */
[37f527b]290rdata_var_t *builtin_get_self_mbr_var(run_t *run, const char *mbr_name)
291{
292 run_proc_ar_t *proc_ar;
293 rdata_object_t *object;
294 sid_t mbr_name_sid;
295 rdata_var_t *mbr_var;
296
297 proc_ar = run_get_current_proc_ar(run);
298 assert(proc_ar->obj->vc == vc_object);
299 object = proc_ar->obj->u.object_v;
300
301 mbr_name_sid = strtab_get_sid(mbr_name);
302 mbr_var = intmap_get(&object->fields, mbr_name_sid);
303 assert(mbr_var != NULL);
304
305 return mbr_var;
[94d484a]306}
307
[c5cb943d]308/** Return string value from builtin procedure.
309 *
310 * Makes it easy for a builtin procedure to return value of type @c string.
311 *
312 * @param run Runner object
313 * @param str String value. Must be allocated from heap and its
314 * ownership is hereby given up.
315 */
316void builtin_return_string(run_t *run, const char *astr)
317{
318 rdata_string_t *rstring;
319 rdata_var_t *rvar;
320 rdata_value_t *rval;
321 rdata_item_t *ritem;
322
323 run_proc_ar_t *proc_ar;
324
325#ifdef DEBUG_RUN_TRACE
326 printf("Return string '%s' from builtin function.\n", astr);
327#endif
328 rstring = rdata_string_new();
329 rstring->value = astr;
330
331 rvar = rdata_var_new(vc_string);
332 rvar->u.string_v = rstring;
333 rval = rdata_value_new();
334 rval->var = rvar;
335
336 ritem = rdata_item_new(ic_value);
337 ritem->u.value = rval;
338
339 proc_ar = run_get_current_proc_ar(run);
340 proc_ar->retval = ritem;
341}
342
343/** Declare a static builtin function in @a csi.
[1ebc1a62]344 *
345 * Declare a builtin function member of CSI @a csi. Deprecated in favor
346 * of builtin_code_snippet().
347 *
348 * @param csi CSI in which to declare function.
349 * @param name Name of member function to declare.
350 * @return Symbol of newly declared function.
351 */
[37f527b]352stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name)
[94d484a]353{
354 stree_ident_t *ident;
355 stree_fun_t *fun;
[38aaacc2]356 stree_fun_sig_t *sig;
[94d484a]357 stree_csimbr_t *csimbr;
[39e8406]358 stree_symbol_t *fun_sym;
[c5cb943d]359 stree_symbol_attr_t *sym_attr;
[94d484a]360
[09ababb7]361 ident = stree_ident_new();
[94d484a]362 ident->sid = strtab_get_sid(name);
[09ababb7]363
364 fun = stree_fun_new();
365 fun->name = ident;
[39e8406]366 fun->proc = stree_proc_new();
367 fun->proc->body = NULL;
[38aaacc2]368 sig = stree_fun_sig_new();
369 fun->sig = sig;
370
371 list_init(&fun->sig->args);
[09ababb7]372
373 csimbr = stree_csimbr_new(csimbr_fun);
374 csimbr->u.fun = fun;
375
[39e8406]376 fun_sym = stree_symbol_new(sc_fun);
377 fun_sym->u.fun = fun;
378 fun_sym->outer_csi = csi;
[c5cb943d]379
380 sym_attr = stree_symbol_attr_new(sac_static);
381 list_append(&fun_sym->attr, sym_attr);
382
[39e8406]383 fun->symbol = fun_sym;
384 fun->proc->outer_symbol = fun_sym;
[09ababb7]385
386 list_append(&csi->members, csimbr);
387
[39e8406]388 return fun_sym;
[94d484a]389}
390
[1ebc1a62]391/** Add one formal parameter to function.
392 *
393 * Used to incrementally construct formal parameter list of a builtin
394 * function. Deprecated in favor of builtin_code_snippet(). Does not
395 * support type checking.
396 *
397 * @param fun_sym Symbol of function to add parameters to.
398 * @param name Name of parameter to add.
399 */
[37f527b]400void builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name)
[94d484a]401{
[d0febca]402 stree_proc_arg_t *proc_arg;
[94d484a]403 stree_fun_t *fun;
404
405 fun = symbol_to_fun(fun_sym);
406 assert(fun != NULL);
407
[d0febca]408 proc_arg = stree_proc_arg_new();
409 proc_arg->name = stree_ident_new();
410 proc_arg->name->sid = strtab_get_sid(name);
411 proc_arg->type = NULL; /* XXX */
[09ababb7]412
[38aaacc2]413 list_append(&fun->sig->args, proc_arg);
[09ababb7]414}
Note: See TracBrowser for help on using the repository browser.