Changeset 37f527b in mainline for uspace/app/sbi/src/builtin.c


Ignore:
Timestamp:
2010-03-26T21:55:23Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4204ad9
Parents:
b535aeb
Message:

Update SBI to rev. 144.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sbi/src/builtin.c

    rb535aeb r37f527b  
    2727 */
    2828
    29 /** @file Builtin procedures. */
     29/** @file Builtin symbol binding. */
    3030
    3131#include <stdio.h>
    3232#include <stdlib.h>
    3333#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"
    3440#include "list.h"
    3541#include "mytypes.h"
    3642#include "os/os.h"
     43#include "parse.h"
    3744#include "run.h"
    3845#include "stree.h"
     
    4249#include "builtin.h"
    4350
    44 static stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name);
    45 static void builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name);
    46 static void builtin_fun_add_vararg(stree_symbol_t *fun_sym, const char *name,
    47     stree_texpr_t *type);
    48 
    49 static stree_texpr_t *builtin_mktype_string_array(void);
    50 
    51 static void builtin_write_line(run_t *run);
    52 static void builtin_exec(run_t *run);
    53 
    54 static stree_symbol_t *bi_write_line;
    55 static stree_symbol_t *bi_exec;
     51static builtin_t *builtin_new(void);
    5652
    5753/** Declare builtin symbols in the program.
     
    6157void builtin_declare(stree_program_t *program)
    6258{
    63         stree_modm_t *modm;
     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;
    64147        stree_csi_t *csi;
     148
     149        stree_symbol_t *mbr_sym;
    65150        stree_ident_t *ident;
    66         stree_symbol_t *symbol;
    67151
    68152        ident = stree_ident_new();
    69         ident->sid = strtab_get_sid("Builtin");
    70 
    71         csi = stree_csi_new(csi_class);
    72         csi->name = ident;
    73         list_init(&csi->members);
    74 
    75         modm = stree_modm_new(mc_csi);
    76         modm->u.csi = csi;
    77 
    78         symbol = stree_symbol_new(sc_csi);
    79         symbol->u.csi = csi;
    80         symbol->outer_csi = NULL;
    81         csi->symbol = symbol;
    82 
    83         list_append(&program->module->members, modm);
    84 
    85         /* Declare builtin procedures. */
    86 
    87         bi_write_line = builtin_declare_fun(csi, "WriteLine");
    88         builtin_fun_add_arg(bi_write_line, "arg");
    89 
    90         bi_exec = builtin_declare_fun(csi, "Exec");
    91         builtin_fun_add_vararg(bi_exec, "args",
    92             builtin_mktype_string_array());
     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;
    93177}
    94178
     
    96180{
    97181        stree_symbol_t *fun_sym;
     182        builtin_t *bi;
     183        builtin_proc_t bproc;
    98184
    99185#ifdef DEBUG_RUN_TRACE
     
    101187#endif
    102188        fun_sym = proc->outer_symbol;
    103 
    104         if (fun_sym == bi_write_line) {
    105                 builtin_write_line(run);
    106         } else if (fun_sym == bi_exec) {
    107                 builtin_exec(run);
    108         } else {
    109                 assert(b_false);
     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);
    110197        }
     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;
    111220}
    112221
    113222/** Declare a builtin function in @a csi. */
    114 static stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name)
     223stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name)
    115224{
    116225        stree_ident_t *ident;
     
    143252
    144253/** Add one formal parameter to function. */
    145 static void builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name)
     254void builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name)
    146255{
    147256        stree_proc_arg_t *proc_arg;
     
    158267        list_append(&fun->args, proc_arg);
    159268}
    160 
    161 /** Add variadic formal parameter to function. */
    162 static void builtin_fun_add_vararg(stree_symbol_t *fun_sym, const char *name,
    163     stree_texpr_t *type)
    164 {
    165         stree_proc_arg_t *proc_arg;
    166         stree_fun_t *fun;
    167 
    168         fun = symbol_to_fun(fun_sym);
    169         assert(fun != NULL);
    170 
    171         proc_arg = stree_proc_arg_new();
    172         proc_arg->name = stree_ident_new();
    173         proc_arg->name->sid = strtab_get_sid(name);
    174         proc_arg->type = type;
    175 
    176         fun->varg = proc_arg;
    177 }
    178 
    179 /** Construct a @c string[] type expression. */
    180 static stree_texpr_t *builtin_mktype_string_array(void)
    181 {
    182         stree_texpr_t *tstring;
    183         stree_texpr_t *tsarray;
    184         stree_tliteral_t *tliteral;
    185         stree_tindex_t *tindex;
    186 
    187         /* Construct @c string */
    188         tstring = stree_texpr_new(tc_tliteral);
    189         tliteral = stree_tliteral_new(tlc_string);
    190         tstring->u.tliteral = tliteral;
    191 
    192         /* Construct the indexing node */
    193         tsarray = stree_texpr_new(tc_tindex);
    194         tindex = stree_tindex_new();
    195         tsarray->u.tindex = tindex;
    196 
    197         tindex->base_type = tstring;
    198         tindex->n_args = 1;
    199         list_init(&tindex->args);
    200 
    201         return tsarray;
    202 }
    203 
    204 static void builtin_write_line(run_t *run)
    205 {
    206         rdata_var_t *var;
    207 
    208 #ifdef DEBUG_RUN_TRACE
    209         printf("Called Builtin.WriteLine()\n");
    210 #endif
    211         var = run_local_vars_lookup(run, strtab_get_sid("arg"));
    212         assert(var);
    213 
    214         switch (var->vc) {
    215         case vc_int:
    216                 printf("%d\n", var->u.int_v->value);
    217                 break;
    218         case vc_string:
    219                 printf("%s\n", var->u.string_v->value);
    220                 break;
    221         default:
    222                 printf("Unimplemented: writeLine() with unsupported type.\n");
    223                 exit(1);
    224         }
    225 }
    226 
    227 /** Start an executable and wait for it to finish. */
    228 static void builtin_exec(run_t *run)
    229 {
    230         rdata_var_t *args;
    231         rdata_var_t *var;
    232         rdata_array_t *array;
    233         rdata_var_t *arg;
    234         int idx, dim;
    235         char **cmd;
    236 
    237 #ifdef DEBUG_RUN_TRACE
    238         printf("Called Builtin.Exec()\n");
    239 #endif
    240         args = run_local_vars_lookup(run, strtab_get_sid("args"));
    241 
    242         assert(args);
    243         assert(args->vc == vc_ref);
    244 
    245         var = args->u.ref_v->vref;
    246         assert(var->vc == vc_array);
    247 
    248         array = var->u.array_v;
    249         assert(array->rank == 1);
    250         dim = array->extent[0];
    251 
    252         if (dim == 0) {
    253                 printf("Error: Builtin.Exec() expects at least one argument.\n");
    254                 exit(1);
    255         }
    256 
    257         cmd = calloc(dim + 1, sizeof(char *));
    258         if (cmd == NULL) {
    259                 printf("Memory allocation failed.\n");
    260                 exit(1);
    261         }
    262 
    263         for (idx = 0; idx < dim; ++idx) {
    264                 arg = array->element[idx];
    265                 if (arg->vc != vc_string) {
    266                         printf("Error: Argument to Builtin.Exec() must be "
    267                             "string (found %d).\n", arg->vc);
    268                         exit(1);
    269                 }
    270 
    271                 cmd[idx] = arg->u.string_v->value;
    272         }
    273 
    274         cmd[dim] = '\0';
    275 
    276         if (os_exec(cmd) != EOK) {
    277                 printf("Error: Exec failed.\n");
    278                 exit(1);
    279         }
    280 }
Note: See TracChangeset for help on using the changeset viewer.