builtin.c

00001 /*
00002  * Copyright (c) 2010 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <assert.h>
00042 #include "builtin/bi_boxed.h"
00043 #include "builtin/bi_error.h"
00044 #include "builtin/bi_char.h"
00045 #include "builtin/bi_console.h"
00046 #include "builtin/bi_int.h"
00047 #include "builtin/bi_task.h"
00048 #include "builtin/bi_textfile.h"
00049 #include "builtin/bi_string.h"
00050 #include "input.h"
00051 #include "intmap.h"
00052 #include "lex.h"
00053 #include "list.h"
00054 #include "mytypes.h"
00055 #include "os/os.h"
00056 #include "parse.h"
00057 #include "rdata.h"
00058 #include "run.h"
00059 #include "stree.h"
00060 #include "strtab.h"
00061 #include "symbol.h"
00062 
00063 #include "builtin.h"
00064 
00065 static builtin_t *builtin_new(void);
00066 
00073 void builtin_declare(stree_program_t *program)
00074 {
00075         builtin_t *bi;
00076 
00077         bi = builtin_new();
00078         bi->program = program;
00079         program->builtin = bi;
00080 
00081         /*
00082          * Declare grandfather class.
00083          */
00084 
00085         builtin_code_snippet(bi,
00086                 "class Object is\n"
00087                 "end\n");
00088         bi->gf_class = builtin_find_lvl0(bi, "Object");
00089 
00090         /*
00091          * Declare other builtin classes/functions.
00092          */
00093 
00094         bi_error_declare(bi);
00095         bi_char_declare(bi);
00096         bi_console_declare(bi);
00097         bi_int_declare(bi);
00098         bi_task_declare(bi);
00099         bi_textfile_declare(bi);
00100         bi_string_declare(bi);
00101 }
00102 
00110 void builtin_bind(builtin_t *bi)
00111 {
00112         bi_boxed_bind(bi);
00113         bi_error_bind(bi);
00114         bi_char_bind(bi);
00115         bi_console_bind(bi);
00116         bi_int_bind(bi);
00117         bi_task_bind(bi);
00118         bi_textfile_bind(bi);
00119         bi_string_bind(bi);
00120 }
00121 
00130 stree_csi_t *builtin_get_gf_class(builtin_t *builtin)
00131 {
00132         if (builtin->gf_class == NULL)
00133                 return NULL;
00134 
00135         return symbol_to_csi(builtin->gf_class);
00136 }
00137 
00142 static builtin_t *builtin_new(void)
00143 {
00144         builtin_t *builtin;
00145 
00146         builtin = calloc(1, sizeof(builtin_t));
00147         if (builtin == NULL) {
00148                 printf("Memory allocation failed.\n");
00149                 exit(1);
00150         }
00151 
00152         return builtin;
00153 }
00154 
00161 void builtin_code_snippet(builtin_t *bi, const char *snippet)
00162 {
00163         input_t *input;
00164         lex_t lex;
00165         parse_t parse;
00166 
00167         input_new_string(&input, snippet);
00168         lex_init(&lex, input);
00169         parse_init(&parse, bi->program, &lex);
00170         parse_module(&parse);
00171 }
00172 
00181 stree_symbol_t *builtin_find_lvl0(builtin_t *bi, const char *sym_name)
00182 {
00183         stree_symbol_t *sym;
00184         stree_ident_t *ident;
00185 
00186         ident = stree_ident_new();
00187 
00188         ident->sid = strtab_get_sid(sym_name);
00189         sym = symbol_lookup_in_csi(bi->program, NULL, ident);
00190         assert(sym != NULL);
00191 
00192         return sym;
00193 }
00194 
00204 stree_symbol_t *builtin_find_lvl1(builtin_t *bi, const char *csi_name,
00205     const char *sym_name)
00206 {
00207         stree_symbol_t *csi_sym;
00208         stree_csi_t *csi;
00209 
00210         stree_symbol_t *mbr_sym;
00211         stree_ident_t *ident;
00212 
00213         ident = stree_ident_new();
00214 
00215         ident->sid = strtab_get_sid(csi_name);
00216         csi_sym = symbol_lookup_in_csi(bi->program, NULL, ident);
00217         assert(csi_sym != NULL);
00218         csi = symbol_to_csi(csi_sym);
00219         assert(csi != NULL);
00220 
00221         ident->sid = strtab_get_sid(sym_name);
00222         mbr_sym = symbol_lookup_in_csi(bi->program, csi, ident);
00223         assert(mbr_sym != NULL);
00224 
00225         return mbr_sym;
00226 }
00227 
00238 void builtin_fun_bind(builtin_t *bi, const char *csi_name,
00239     const char *sym_name, builtin_proc_t bproc)
00240 {
00241         stree_symbol_t *fun_sym;
00242         stree_fun_t *fun;
00243 
00244         fun_sym = builtin_find_lvl1(bi, csi_name, sym_name);
00245         assert(fun_sym != NULL);
00246         fun = symbol_to_fun(fun_sym);
00247         assert(fun != NULL);
00248 
00249         fun->proc->bi_handler = bproc;
00250 }
00251 
00259 void builtin_run_proc(run_t *run, stree_proc_t *proc)
00260 {
00261         stree_symbol_t *fun_sym;
00262         builtin_proc_t bproc;
00263 
00264 #ifdef DEBUG_RUN_TRACE
00265         printf("Run builtin procedure.\n");
00266 #endif
00267         fun_sym = proc->outer_symbol;
00268 
00269         bproc = proc->bi_handler;
00270         if (bproc == NULL) {
00271                 printf("Error: Unrecognized builtin function '");
00272                 symbol_print_fqn(fun_sym);
00273                 printf("'.\n");
00274                 exit(1);
00275         }
00276 
00277         /* Run the builtin procedure handler. */
00278         (*bproc)(run);
00279 }
00280 
00290 rdata_var_t *builtin_get_self_mbr_var(run_t *run, const char *mbr_name)
00291 {
00292         run_proc_ar_t *proc_ar;
00293         rdata_object_t *object;
00294         sid_t mbr_name_sid;
00295         rdata_var_t *mbr_var;
00296 
00297         proc_ar = run_get_current_proc_ar(run);
00298         assert(proc_ar->obj->vc == vc_object);
00299         object = proc_ar->obj->u.object_v;
00300 
00301         mbr_name_sid = strtab_get_sid(mbr_name);
00302         mbr_var = intmap_get(&object->fields, mbr_name_sid);
00303         assert(mbr_var != NULL);
00304 
00305         return mbr_var;
00306 }
00307 
00316 void builtin_return_string(run_t *run, const char *astr)
00317 {
00318         rdata_string_t *rstring;
00319         rdata_var_t *rvar;
00320         rdata_value_t *rval;
00321         rdata_item_t *ritem;
00322 
00323         run_proc_ar_t *proc_ar;
00324 
00325 #ifdef DEBUG_RUN_TRACE
00326         printf("Return string '%s' from builtin function.\n", astr);
00327 #endif
00328         rstring = rdata_string_new();
00329         rstring->value = astr;
00330 
00331         rvar = rdata_var_new(vc_string);
00332         rvar->u.string_v = rstring;
00333         rval = rdata_value_new();
00334         rval->var = rvar;
00335 
00336         ritem = rdata_item_new(ic_value);
00337         ritem->u.value = rval;
00338 
00339         proc_ar = run_get_current_proc_ar(run);
00340         proc_ar->retval = ritem;
00341 }
00342 
00352 stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name)
00353 {
00354         stree_ident_t *ident;
00355         stree_fun_t *fun;
00356         stree_fun_sig_t *sig;
00357         stree_csimbr_t *csimbr;
00358         stree_symbol_t *fun_sym;
00359         stree_symbol_attr_t *sym_attr;
00360 
00361         ident = stree_ident_new();
00362         ident->sid = strtab_get_sid(name);
00363 
00364         fun = stree_fun_new();
00365         fun->name = ident;
00366         fun->proc = stree_proc_new();
00367         fun->proc->body = NULL;
00368         sig = stree_fun_sig_new();
00369         fun->sig = sig;
00370 
00371         list_init(&fun->sig->args);
00372 
00373         csimbr = stree_csimbr_new(csimbr_fun);
00374         csimbr->u.fun = fun;
00375 
00376         fun_sym = stree_symbol_new(sc_fun);
00377         fun_sym->u.fun = fun;
00378         fun_sym->outer_csi = csi;
00379 
00380         sym_attr = stree_symbol_attr_new(sac_static);
00381         list_append(&fun_sym->attr, sym_attr);
00382 
00383         fun->symbol = fun_sym;
00384         fun->proc->outer_symbol = fun_sym;
00385 
00386         list_append(&csi->members, csimbr);
00387 
00388         return fun_sym;
00389 }
00390 
00400 void builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name)
00401 {
00402         stree_proc_arg_t *proc_arg;
00403         stree_fun_t *fun;
00404 
00405         fun = symbol_to_fun(fun_sym);
00406         assert(fun != NULL);
00407 
00408         proc_arg = stree_proc_arg_new();
00409         proc_arg->name = stree_ident_new();
00410         proc_arg->name->sid = strtab_get_sid(name);
00411         proc_arg->type = NULL; /* XXX */
00412 
00413         list_append(&fun->sig->args, proc_arg);
00414 }

Generated on Thu Jun 2 07:45:42 2011 for HelenOS/USB by  doxygen 1.4.7