00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
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
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;
00412
00413 list_append(&fun->sig->args, proc_arg);
00414 }