Changeset 37f527b in mainline for uspace/app/sbi/src/builtin.c
- Timestamp:
- 2010-03-26T21:55:23Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4204ad9
- Parents:
- b535aeb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/src/builtin.c
rb535aeb r37f527b 27 27 */ 28 28 29 /** @file Builtin procedures. */29 /** @file Builtin symbol binding. */ 30 30 31 31 #include <stdio.h> 32 32 #include <stdlib.h> 33 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" 34 40 #include "list.h" 35 41 #include "mytypes.h" 36 42 #include "os/os.h" 43 #include "parse.h" 37 44 #include "run.h" 38 45 #include "stree.h" … … 42 49 #include "builtin.h" 43 50 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; 51 static builtin_t *builtin_new(void); 56 52 57 53 /** Declare builtin symbols in the program. … … 61 57 void builtin_declare(stree_program_t *program) 62 58 { 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. */ 89 stree_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 97 static 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 */ 116 void 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. */ 129 stree_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. */ 143 stree_symbol_t *builtin_find_lvl1(builtin_t *bi, const char *csi_name, 144 const char *sym_name) 145 { 146 stree_symbol_t *csi_sym; 64 147 stree_csi_t *csi; 148 149 stree_symbol_t *mbr_sym; 65 150 stree_ident_t *ident; 66 stree_symbol_t *symbol;67 151 68 152 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 m odm->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 165 void 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; 93 177 } 94 178 … … 96 180 { 97 181 stree_symbol_t *fun_sym; 182 builtin_t *bi; 183 builtin_proc_t bproc; 98 184 99 185 #ifdef DEBUG_RUN_TRACE … … 101 187 #endif 102 188 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); 110 197 } 198 199 /* Run the builtin procedure handler. */ 200 (*bproc)(run); 201 } 202 203 /** Get pointer to member var of current object. */ 204 rdata_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; 111 220 } 112 221 113 222 /** Declare a builtin function in @a csi. */ 114 st atic stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name)223 stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name) 115 224 { 116 225 stree_ident_t *ident; … … 143 252 144 253 /** Add one formal parameter to function. */ 145 staticvoid builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name)254 void builtin_fun_add_arg(stree_symbol_t *fun_sym, const char *name) 146 255 { 147 256 stree_proc_arg_t *proc_arg; … … 158 267 list_append(&fun->args, proc_arg); 159 268 } 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_TRACE209 printf("Called Builtin.WriteLine()\n");210 #endif211 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_TRACE238 printf("Called Builtin.Exec()\n");239 #endif240 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.