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

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

Update SBI to rev. 144.

  • Property mode set to 100644
File size: 6.5 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#include <stdio.h>
32#include <stdlib.h>
33#include <assert.h>
34#include "ancr.h"
35#include "builtin/bi_fun.h"
36#include "builtin/bi_textfile.h"
37#include "input.h"
38#include "intmap.h"
39#include "lex.h"
40#include "list.h"
41#include "mytypes.h"
42#include "os/os.h"
43#include "parse.h"
44#include "run.h"
45#include "stree.h"
46#include "strtab.h"
47#include "symbol.h"
48
49#include "builtin.h"
50
51static builtin_t *builtin_new(void);
52
53/** Declare builtin symbols in the program.
54 *
55 * Declares symbols that will be hooked to builtin interpreter procedures.
56 */
57void builtin_declare(stree_program_t *program)
58{
59 builtin_t *bi;
60
61 bi = builtin_new();
62 bi->program = program;
63 program->builtin = bi;
64
65 /*
66 * Declare grandfather class.
67 */
68
69 builtin_code_snippet(bi,
70 "class Object is\n"
71 "end\n");
72 bi->gf_class = builtin_find_lvl0(bi, "Object");
73
74 /*
75 * Declare other builtin classes/functions.
76 */
77
78 bi_fun_declare(bi);
79 bi_textfile_declare(bi);
80
81 /* Need to process ancestry so that symbol lookups work. */
82 ancr_module_process(program, program->module);
83
84 bi_fun_bind(bi);
85 bi_textfile_bind(bi);
86}
87
88/** Get grandfather class. */
89stree_csi_t *builtin_get_gf_class(builtin_t *builtin)
90{
91 if (builtin->gf_class == NULL)
92 return NULL;
93
94 return symbol_to_csi(builtin->gf_class);
95}
96
97static builtin_t *builtin_new(void)
98{
99 builtin_t *builtin;
100
101 builtin = calloc(1, sizeof(builtin_t));
102 if (builtin == NULL) {
103 printf("Memory allocation failed.\n");
104 exit(1);
105 }
106
107 return builtin;
108}
109
110/** Parse a declaration code snippet.
111 *
112 * Parses a piece of code from a string at the module level. This can be
113 * used to declare builtin symbols easily and without need for an external
114 * file.
115 */
116void builtin_code_snippet(builtin_t *bi, const char *snippet)
117{
118 input_t *input;
119 lex_t lex;
120 parse_t parse;
121
122 input_new_string(&input, snippet);
123 lex_init(&lex, input);
124 parse_init(&parse, bi->program, &lex);
125 parse_module(&parse);
126}
127
128/** Simplifed search for a global symbol. */
129stree_symbol_t *builtin_find_lvl0(builtin_t *bi, const char *sym_name)
130{
131 stree_symbol_t *sym;
132 stree_ident_t *ident;
133
134 ident = stree_ident_new();
135
136 ident->sid = strtab_get_sid(sym_name);
137 sym = symbol_lookup_in_csi(bi->program, NULL, ident);
138
139 return sym;
140}
141
142/** Simplifed search for a level 1 symbol. */
143stree_symbol_t *builtin_find_lvl1(builtin_t *bi, const char *csi_name,
144 const char *sym_name)
145{
146 stree_symbol_t *csi_sym;
147 stree_csi_t *csi;
148
149 stree_symbol_t *mbr_sym;
150 stree_ident_t *ident;
151
152 ident = stree_ident_new();
153
154 ident->sid = strtab_get_sid(csi_name);
155 csi_sym = symbol_lookup_in_csi(bi->program, NULL, ident);
156 csi = symbol_to_csi(csi_sym);
157 assert(csi != NULL);
158
159 ident->sid = strtab_get_sid(sym_name);
160 mbr_sym = symbol_lookup_in_csi(bi->program, csi, ident);
161
162 return mbr_sym;
163}
164
165void builtin_fun_bind(builtin_t *bi, const char *csi_name,
166 const char *sym_name, builtin_proc_t bproc)
167{
168 stree_symbol_t *fun_sym;
169 stree_fun_t *fun;
170
171 fun_sym = builtin_find_lvl1(bi, csi_name, sym_name);
172 assert(fun_sym != NULL);
173 fun = symbol_to_fun(fun_sym);
174 assert(fun != NULL);
175
176 fun->proc->bi_handler = bproc;
177}
178
179void builtin_run_proc(run_t *run, stree_proc_t *proc)
180{
181 stree_symbol_t *fun_sym;
182 builtin_t *bi;
183 builtin_proc_t bproc;
184
185#ifdef DEBUG_RUN_TRACE
186 printf("Run builtin procedure.\n");
187#endif
188 fun_sym = proc->outer_symbol;
189 bi = run->program->builtin;
190
191 bproc = proc->bi_handler;
192 if (bproc == NULL) {
193 printf("Error: Unrecognized builtin function '");
194 symbol_print_fqn(fun_sym);
195 printf("'.\n");
196 exit(1);
197 }
198
199 /* Run the builtin procedure handler. */
200 (*bproc)(run);
201}
202
203/** Get pointer to member var of current object. */
204rdata_var_t *builtin_get_self_mbr_var(run_t *run, const char *mbr_name)
205{
206 run_proc_ar_t *proc_ar;
207 rdata_object_t *object;
208 sid_t mbr_name_sid;
209 rdata_var_t *mbr_var;
210
211 proc_ar = run_get_current_proc_ar(run);
212 assert(proc_ar->obj->vc == vc_object);
213 object = proc_ar->obj->u.object_v;
214
215 mbr_name_sid = strtab_get_sid(mbr_name);
216 mbr_var = intmap_get(&object->fields, mbr_name_sid);
217 assert(mbr_var != NULL);
218
219 return mbr_var;
220}
221
222/** Declare a builtin function in @a csi. */
223stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name)
224{
225 stree_ident_t *ident;
226 stree_fun_t *fun;
227 stree_csimbr_t *csimbr;
228 stree_symbol_t *fun_sym;
229
230 ident = stree_ident_new();
231 ident->sid = strtab_get_sid(name);
232
233 fun = stree_fun_new();
234 fun->name = ident;
235 fun->proc = stree_proc_new();
236 fun->proc->body = NULL;
237 list_init(&fun->args);
238
239 csimbr = stree_csimbr_new(csimbr_fun);
240 csimbr->u.fun = fun;
241
242 fun_sym = stree_symbol_new(sc_fun);
243 fun_sym->u.fun = fun;
244 fun_sym->outer_csi = csi;
245 fun->symbol = fun_sym;
246 fun->proc->outer_symbol = fun_sym;
247
248 list_append(&csi->members, csimbr);
249
250 return fun_sym;
251}
252
253/** Add one formal parameter to function. */
254void builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name)
255{
256 stree_proc_arg_t *proc_arg;
257 stree_fun_t *fun;
258
259 fun = symbol_to_fun(fun_sym);
260 assert(fun != NULL);
261
262 proc_arg = stree_proc_arg_new();
263 proc_arg->name = stree_ident_new();
264 proc_arg->name->sid = strtab_get_sid(name);
265 proc_arg->type = NULL; /* XXX */
266
267 list_append(&fun->args, proc_arg);
268}
Note: See TracBrowser for help on using the repository browser.