Changes in / [f4f866c:80badbe] in mainline
- Location:
- uspace
- Files:
-
- 6 deleted
- 39 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/Makefile
rf4f866c r80badbe 34 34 35 35 SOURCES = \ 36 src/builtin/bi_boxed.c \37 36 src/builtin/bi_error.c \ 38 37 src/builtin/bi_fun.c \ -
uspace/app/sbi/src/builtin.c
rf4f866c r80badbe 40 40 #include <stdlib.h> 41 41 #include <assert.h> 42 #include " builtin/bi_boxed.h"42 #include "ancr.h" 43 43 #include "builtin/bi_error.h" 44 44 #include "builtin/bi_fun.h" … … 90 90 bi_fun_declare(bi); 91 91 bi_textfile_declare(bi); 92 } 93 94 /** Bind internal interpreter references to symbols in the program. 95 * 96 * This is performed in separate phase for several reasons. First, 97 * symbol lookups do not work until ancestry is processed. Second, 98 * this gives a chance to process the library first and thus bind 99 * to symbols defined there. 100 */ 101 void builtin_bind(builtin_t *bi) 102 { 103 bi_boxed_bind(bi); 92 93 /* Need to process ancestry so that symbol lookups work. */ 94 ancr_module_process(program, program->module); 95 104 96 bi_error_bind(bi); 105 97 bi_fun_bind(bi); … … 308 300 stree_ident_t *ident; 309 301 stree_fun_t *fun; 310 stree_fun_sig_t *sig;311 302 stree_csimbr_t *csimbr; 312 303 stree_symbol_t *fun_sym; … … 319 310 fun->proc = stree_proc_new(); 320 311 fun->proc->body = NULL; 321 sig = stree_fun_sig_new(); 322 fun->sig = sig; 323 324 list_init(&fun->sig->args); 312 list_init(&fun->args); 325 313 326 314 csimbr = stree_csimbr_new(csimbr_fun); … … 360 348 proc_arg->type = NULL; /* XXX */ 361 349 362 list_append(&fun-> sig->args, proc_arg);363 } 350 list_append(&fun->args, proc_arg); 351 } -
uspace/app/sbi/src/builtin.h
rf4f866c r80badbe 33 33 34 34 void builtin_declare(stree_program_t *program); 35 void builtin_bind(builtin_t *bi);36 35 void builtin_code_snippet(builtin_t *bi, const char *snippet); 37 36 -
uspace/app/sbi/src/builtin/bi_error.c
rf4f866c r80badbe 36 36 #include "bi_error.h" 37 37 38 /** Declare error class hierarchy. 39 * 40 * @param bi Builtin object 41 */ 38 /** Declare error class hierarchy. */ 42 39 void bi_error_declare(builtin_t *bi) 43 40 { … … 60 57 "end\n");} 61 58 62 /** Bind error class hierarchy. 63 * 64 * @param bi Builtin object 65 */ 59 /** Bind error class hierarchy. */ 66 60 void bi_error_bind(builtin_t *bi) 67 61 { -
uspace/app/sbi/src/builtin/bi_fun.c
rf4f866c r80badbe 44 44 #include "bi_fun.h" 45 45 46 static void bi_fun_builtin_write(run_t *run);47 46 static void bi_fun_builtin_writeline(run_t *run); 48 47 static void bi_fun_task_exec(run_t *run); 49 48 50 /** Declare builtin functions. 51 * 52 * @param bi Builtin object 53 */ 49 /** Declare builtin functions. */ 54 50 void bi_fun_declare(builtin_t *bi) 55 51 { … … 67 63 csi = stree_csi_new(csi_class); 68 64 csi->name = ident; 69 list_init(&csi->targ);70 65 list_init(&csi->members); 71 66 … … 79 74 80 75 list_append(&bi->program->module->members, modm); 81 82 /* Declare Builtin.Write(). */83 84 fun_sym = builtin_declare_fun(csi, "Write");85 builtin_fun_add_arg(fun_sym, "arg");86 76 87 77 /* Declare Builtin.WriteLine(). */ … … 98 88 } 99 89 100 /** Bind builtin functions. 101 * 102 * @param bi Builtin object 103 */ 90 /** Bind builtin functions. */ 104 91 void bi_fun_bind(builtin_t *bi) 105 92 { 106 builtin_fun_bind(bi, "Builtin", "Write", bi_fun_builtin_write);107 93 builtin_fun_bind(bi, "Builtin", "WriteLine", bi_fun_builtin_writeline); 108 94 builtin_fun_bind(bi, "Task", "Exec", bi_fun_task_exec); 109 95 } 110 96 111 /** Write to the console. 112 * 113 * @param run Runner object 114 */ 115 static void bi_fun_builtin_write(run_t *run) 97 /** Write a line of output. */ 98 static void bi_fun_builtin_writeline(run_t *run) 116 99 { 117 100 rdata_var_t *var; … … 120 103 121 104 #ifdef DEBUG_RUN_TRACE 122 printf("Called Builtin.Write ()\n");105 printf("Called Builtin.WriteLine()\n"); 123 106 #endif 124 107 var = run_local_vars_lookup(run, strtab_get_sid("arg")); … … 126 109 127 110 switch (var->vc) { 128 case vc_bool:129 printf("%s", var->u.bool_v->value ? "true" : "false");130 break;131 111 case vc_char: 132 112 rc = bigint_get_value_int(&var->u.char_v->value, &char_val); 133 113 if (rc == EOK) 134 printf("%lc ", char_val);114 printf("%lc\n", char_val); 135 115 else 136 printf("??? ");116 printf("???\n"); 137 117 break; 138 118 case vc_int: 139 119 bigint_print(&var->u.int_v->value); 120 putchar('\n'); 140 121 break; 141 122 case vc_string: 142 printf("%s ", var->u.string_v->value);123 printf("%s\n", var->u.string_v->value); 143 124 break; 144 125 default: 145 printf("Unimplemented: Write() with unsupported type.\n");126 printf("Unimplemented: writeLine() with unsupported type.\n"); 146 127 exit(1); 147 128 } 148 129 } 149 130 150 /** Write a line of output. 151 * 152 * @param run Runner object 153 */ 154 static void bi_fun_builtin_writeline(run_t *run) 155 { 156 #ifdef DEBUG_RUN_TRACE 157 printf("Called Builtin.WriteLine()\n"); 158 #endif 159 bi_fun_builtin_write(run); 160 putchar('\n'); 161 } 162 163 /** Start an executable and wait for it to finish. 164 * 165 * @param run Runner object 166 */ 131 /** Start an executable and wait for it to finish. */ 167 132 static void bi_fun_task_exec(run_t *run) 168 133 { … … 172 137 rdata_var_t *arg; 173 138 int idx, dim; 174 c onst char **cmd;139 char **cmd; 175 140 176 141 #ifdef DEBUG_RUN_TRACE … … 213 178 cmd[dim] = '\0'; 214 179 215 if (os_exec( (char * const *)cmd) != EOK) {180 if (os_exec(cmd) != EOK) { 216 181 printf("Error: Exec failed.\n"); 217 182 exit(1); -
uspace/app/sbi/src/builtin/bi_textfile.c
rf4f866c r80badbe 53 53 static void bi_textfile_is_eof(run_t *run); 54 54 55 /** Declare TextFile builtin. 56 * 57 * @param bi Builtin object 58 */ 55 /** Declare TextFile builtin. */ 59 56 void bi_textfile_declare(builtin_t *bi) 60 57 { … … 82 79 } 83 80 84 /** Bind TextFile builtin. 85 * 86 * @param bi Builtin object 87 */ 81 /** Bind TextFile builtin. */ 88 82 void bi_textfile_bind(builtin_t *bi) 89 83 { … … 96 90 } 97 91 98 /** Open a text file for reading. 99 * 100 * @param run Runner object 101 */ 92 /** Open a text file for reading. */ 102 93 static void bi_textfile_openread(run_t *run) 103 94 { 104 95 rdata_var_t *fname_var; 105 c onst char *fname;96 char *fname; 106 97 FILE *file; 107 98 … … 139 130 } 140 131 141 /** Open a text file for writing. 142 * 143 * @param run Runner object 144 */ 132 /** Open a text file for writing. */ 145 133 static void bi_textfile_openwrite(run_t *run) 146 134 { 147 135 rdata_var_t *fname_var; 148 c onst char *fname;136 char *fname; 149 137 FILE *file; 150 138 … … 182 170 } 183 171 184 /** Close a text file. 185 * 186 * @param run Runner object 187 */ 172 /** Close a text file. */ 188 173 static void bi_textfile_close(run_t *run) 189 174 { … … 220 205 221 206 222 /** Read one line from a text file. 223 * 224 * @param run Runner object 225 */ 207 /** Read one line from a text file. */ 226 208 static void bi_textfile_readline(run_t *run) 227 209 { … … 290 272 } 291 273 292 /** Write one line to a text file. 293 * 294 * @param run Runner object 295 */ 274 /** Write one line to a text file. */ 296 275 static void bi_textfile_writeline(run_t *run) 297 276 { … … 299 278 rdata_var_t *self_f_var; 300 279 rdata_var_t *line_var; 301 c onst char *line;280 char *line; 302 281 303 282 run_proc_ar_t *proc_ar; … … 333 312 } 334 313 335 /** Return value of EOF flag. 336 * 337 * @param run Runner object 338 */ 314 /** Return value of EOF flag. */ 339 315 static void bi_textfile_is_eof(run_t *run) 340 316 { -
uspace/app/sbi/src/builtin_t.h
rf4f866c r80badbe 43 43 struct stree_symbol *gf_class; 44 44 45 /** Boxed variants of primitive types */ 46 struct stree_symbol *boxed_bool; 47 struct stree_symbol *boxed_char; 48 struct stree_symbol *boxed_int; 49 struct stree_symbol *boxed_string; 50 51 /** Error class for nil reference access */ 45 /** Error class for nil reference access. */ 52 46 struct stree_csi *error_nilreference; 53 47 54 /** Error class for out-of-bounds array access */48 /** Error class for out-of-bounds array access. */ 55 49 struct stree_csi *error_outofbounds; 56 50 } builtin_t; -
uspace/app/sbi/src/debug.h
rf4f866c r80badbe 34 34 35 35 /** 36 * 36 *Uncomment this to get extra verbose messages from parser's lexing 37 37 * primitives. 38 38 */ -
uspace/app/sbi/src/imode.c
rf4f866c r80badbe 98 98 ancr_module_process(program, program->module); 99 99 100 /* Bind internal interpreter references to symbols. */101 builtin_bind(program->builtin);102 103 /* Resolve ancestry. */104 ancr_module_process(program, program->module);105 106 100 /* Construct typing context. */ 107 101 stype.program = program; -
uspace/app/sbi/src/lex.c
rf4f866c r80badbe 80 80 { lc_class, "class" }, 81 81 { lc_constructor, "constructor" }, 82 { lc_deleg, "deleg" },83 82 { lc_do, "do" }, 84 83 { lc_else, "else" }, … … 211 210 switch (lem->lclass) { 212 211 case lc_ident: 213 printf("( '%s')", strtab_get_str(lem->u.ident.sid));212 printf("(%d)", lem->u.ident.sid); 214 213 break; 215 214 case lc_lit_int: -
uspace/app/sbi/src/lex_t.h
rf4f866c r80badbe 49 49 lc_class, 50 50 lc_constructor, 51 lc_deleg,52 51 lc_do, 53 52 lc_else, -
uspace/app/sbi/src/main.c
rf4f866c r80badbe 92 92 return 1; 93 93 94 /* Resolve ancestry. */95 ancr_module_process(program, program->module);96 97 /* Bind internal interpreter references to symbols. */98 builtin_bind(program->builtin);99 100 94 /* Process all source files specified in command-line arguments. */ 101 95 while (argc > 0) { -
uspace/app/sbi/src/os/helenos.c
rf4f866c r80badbe 48 48 static tinput_t *tinput = NULL; 49 49 50 /** Concatenate two strings. 51 * 52 * @param a First string 53 * @param b Second string 54 * @return New string, concatenation of @a a and @a b. 55 */ 50 /** Concatenate two strings. */ 56 51 char *os_str_acat(const char *a, const char *b) 57 52 { … … 75 70 } 76 71 77 /** Compare two strings. 78 * 79 * @param a First string 80 * @param b Second string 81 * @return Zero if equal, nonzero if not equal 82 */ 72 /** Compare two strings. */ 83 73 int os_str_cmp(const char *a, const char *b) 84 74 { … … 86 76 } 87 77 88 /** Return number of characters in string. 89 * 90 * @param str String 91 * @return Number of characters in @a str. 92 */ 78 /** Return number of characters in string. */ 93 79 size_t os_str_length(const char *str) 94 80 { … … 96 82 } 97 83 98 /** Duplicate string. 99 * 100 * @param str String 101 * @return New string, duplicate of @a str. 102 */ 84 /** Duplicate string. */ 103 85 char *os_str_dup(const char *str) 104 86 { … … 106 88 } 107 89 108 /** Get character from string at the given index. 109 * 110 * @param str String 111 * @param index Character index (starting from zero). 112 * @param out_char Place to store character. 113 * @return EOK on success, EINVAL if index is out of bounds, 114 * EIO on decoding error. 115 */ 90 /** Get character from string at the given index. */ 116 91 int os_str_get_char(const char *str, int index, int *out_char) 117 92 { … … 142 117 } 143 118 144 /** Read one line of input from the user. 145 * 146 * @param ptr Place to store pointer to new string. 147 */ 119 /** Read one line of input from the user. */ 148 120 int os_input_line(char **ptr) 149 121 { … … 176 148 } 177 149 178 /** Simple command execution. 179 * 180 * @param cmd Command and arguments (NULL-terminated list of strings.) 181 * Command is present just one, not duplicated. 182 */ 150 /** Simple command execution. */ 183 151 int os_exec(char *const cmd[]) 184 152 { … … 200 168 } 201 169 202 /** Store the executable file path via which we were executed. 203 * 204 * @param path Executable path via which we were executed. 205 */ 170 /** Store the executable file path via which we were executed. */ 206 171 void os_store_ef_path(char *path) 207 172 { -
uspace/app/sbi/src/os/os.h
rf4f866c r80badbe 37 37 void os_input_disp_help(void); 38 38 int os_input_line(char **ptr); 39 int os_exec(char * 39 int os_exec(char *const cmd[]); 40 40 41 41 void os_store_ef_path(char *path); -
uspace/app/sbi/src/os/posix.c
rf4f866c r80badbe 47 47 * The string functions are in fact standard C, but would not work under 48 48 * HelenOS. 49 *50 * XXX String functions used here only work with 8-bit text encoding.51 49 */ 52 50 53 /** Concatenate two strings. 54 * 55 * @param a First string 56 * @param b Second string 57 * @return New string, concatenation of @a a and @a b. 58 */ 51 /** Concatenate two strings. */ 59 52 char *os_str_acat(const char *a, const char *b) 60 53 { … … 78 71 } 79 72 80 /** Compare two strings. 81 * 82 * @param a First string 83 * @param b Second string 84 * @return Zero if equal, nonzero if not equal 85 */ 73 /** Compare two strings. */ 86 74 int os_str_cmp(const char *a, const char *b) 87 75 { … … 89 77 } 90 78 91 /** Return number of characters in string. 92 * 93 * @param str String 94 * @return Number of characters in @a str. 95 */ 79 /** Return number of characters in string. */ 96 80 size_t os_str_length(const char *str) 97 81 { … … 99 83 } 100 84 101 /** Duplicate string. 102 * 103 * @param str String 104 * @return New string, duplicate of @a str. 105 */ 85 /** Duplicate string. */ 106 86 char *os_str_dup(const char *str) 107 87 { … … 109 89 } 110 90 111 /** Get character from string at the given index. 112 * 113 * @param str String 114 * @param index Character index (starting from zero). 115 * @param out_char Place to store character. 116 * @return EOK on success, EINVAL if index is out of bounds, 117 * EIO on decoding error. 118 */ 91 /** Get character from string at the given index. */ 119 92 int os_str_get_char(const char *str, int index, int *out_char) 120 93 { … … 138 111 } 139 112 140 /** Read one line of input from the user. 141 * 142 * @param ptr Place to store pointer to new string. 143 */ 113 /** Read one line of input from the user. */ 144 114 int os_input_line(char **ptr) 145 115 { … … 156 126 } 157 127 158 /** Simple command execution. 159 * 160 * @param cmd Command and arguments (NULL-terminated list of strings.) 161 * Command is present just one, not duplicated. 162 */ 128 /** Simple command execution. */ 163 129 int os_exec(char *const cmd[]) 164 130 { … … 191 157 } 192 158 193 /** Store the executable file path via which we were executed. 194 * 195 * @param path Executable path via which we were executed. 196 */ 159 /** Store the executable file path via which we were executed. */ 197 160 void os_store_ef_path(char *path) 198 161 { -
uspace/app/sbi/src/parse.c
rf4f866c r80badbe 54 54 static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi); 55 55 56 static stree_deleg_t *parse_deleg(parse_t *parse, stree_csi_t *outer_csi);57 56 static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi); 58 57 static stree_var_t *parse_var(parse_t *parse, stree_csi_t *outer_csi); … … 63 62 static stree_proc_arg_t *parse_proc_arg(parse_t *parse); 64 63 static stree_arg_attr_t *parse_arg_attr(parse_t *parse); 65 static stree_fun_sig_t *parse_fun_sig(parse_t *parse);66 67 64 68 65 /* … … 160 157 stree_symbol_t *symbol; 161 158 stree_ident_t *targ_name; 162 stree_targ_t *targ;163 159 164 160 switch (dclass) { … … 174 170 csi->name = parse_ident(parse); 175 171 176 list_init(&csi->targ );172 list_init(&csi->targ_names); 177 173 178 174 while (lcur_lc(parse) == lc_slash) { 179 175 lskip(parse); 180 176 targ_name = parse_ident(parse); 181 182 targ = stree_targ_new(); 183 targ->name = targ_name; 184 185 list_append(&csi->targ, targ); 177 list_append(&csi->targ_names, targ_name); 186 178 } 187 179 … … 209 201 while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) { 210 202 csimbr = parse_csimbr(parse, csi); 211 if (csimbr == NULL)212 break;213 214 203 list_append(&csi->members, csimbr); 215 204 } … … 224 213 * @param parse Parser object. 225 214 * @param outer_csi CSI containing this declaration or @c NULL if global. 226 * @return New syntax tree node. In case of parse error, 227 * @c NULL may (but need not) be returned. 215 * @return New syntax tree node. 228 216 */ 229 217 static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi) … … 232 220 233 221 stree_csi_t *csi; 234 stree_deleg_t *deleg;235 222 stree_fun_t *fun; 236 223 stree_var_t *var; … … 245 232 csimbr->u.csi = csi; 246 233 break; 247 case lc_deleg:248 deleg = parse_deleg(parse, outer_csi);249 csimbr = stree_csimbr_new(csimbr_deleg);250 csimbr->u.deleg = deleg;251 break;252 234 case lc_fun: 253 235 fun = parse_fun(parse, outer_csi); … … 268 250 lunexpected_error(parse); 269 251 lex_next(parse->lex); 270 csimbr = NULL;271 break;272 252 } 273 253 … … 275 255 } 276 256 277 /** Parse delegate. 257 258 /** Parse member function. 278 259 * 279 260 * @param parse Parser object. … … 281 262 * @return New syntax tree node. 282 263 */ 283 static stree_deleg_t *parse_deleg(parse_t *parse, stree_csi_t *outer_csi)284 {285 stree_deleg_t *deleg;286 stree_symbol_t *symbol;287 stree_symbol_attr_t *attr;288 289 deleg = stree_deleg_new();290 symbol = stree_symbol_new(sc_deleg);291 292 symbol->u.deleg = deleg;293 symbol->outer_csi = outer_csi;294 deleg->symbol = symbol;295 296 lmatch(parse, lc_deleg);297 deleg->name = parse_ident(parse);298 299 #ifdef DEBUG_PARSE_TRACE300 printf("Parsing delegate '%s'.\n", strtab_get_str(deleg->name->sid));301 #endif302 303 deleg->sig = parse_fun_sig(parse);304 305 list_init(&symbol->attr);306 307 /* Parse attributes. */308 while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {309 lskip(parse);310 attr = parse_symbol_attr(parse);311 list_append(&symbol->attr, attr);312 }313 314 lmatch(parse, lc_scolon);315 316 return deleg;317 }318 319 /** Parse member function.320 *321 * @param parse Parser object.322 * @param outer_csi CSI containing this declaration or @c NULL if global.323 * @return New syntax tree node.324 */325 264 static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi) 326 265 { 327 266 stree_fun_t *fun; 267 stree_proc_arg_t *arg; 328 268 stree_symbol_t *symbol; 329 269 stree_symbol_attr_t *attr; … … 338 278 lmatch(parse, lc_fun); 339 279 fun->name = parse_ident(parse); 280 lmatch(parse, lc_lparen); 340 281 341 282 #ifdef DEBUG_PARSE_TRACE 342 283 printf("Parsing function '%s'.\n", strtab_get_str(fun->name->sid)); 343 284 #endif 344 fun->sig = parse_fun_sig(parse); 285 286 list_init(&fun->args); 287 288 if (lcur_lc(parse) != lc_rparen) { 289 290 /* Parse formal parameters. */ 291 while (!parse_is_error(parse)) { 292 arg = parse_proc_arg(parse); 293 294 if (stree_arg_has_attr(arg, aac_packed)) { 295 fun->varg = arg; 296 break; 297 } else { 298 list_append(&fun->args, arg); 299 } 300 301 if (lcur_lc(parse) == lc_rparen) 302 break; 303 304 lmatch(parse, lc_scolon); 305 } 306 } 307 308 lmatch(parse, lc_rparen); 309 310 if (lcur_lc(parse) == lc_colon) { 311 lskip(parse); 312 fun->rtype = parse_texpr(parse); 313 } else { 314 fun->rtype = NULL; 315 } 345 316 346 317 list_init(&symbol->attr); … … 551 522 arg->type = parse_texpr(parse); 552 523 553 #ifdef DEBUG_PARSE_TRACE 554 printf("Parse procedure argument.\n"); 555 #endif 556 list_init(&arg->attr); 524 list_init(&arg->attr); 557 525 558 526 /* Parse attributes. */ … … 563 531 } 564 532 533 #ifdef DEBUG_PARSE_TRACE 534 printf("Parsed arg attr, type=%p.\n", arg->type); 535 #endif 565 536 return arg; 566 537 } … … 586 557 attr = stree_arg_attr_new(aac_packed); 587 558 return attr; 588 }589 590 /** Parse function signature.591 *592 * @param parse Parser object.593 * @return New syntax tree node.594 */595 static stree_fun_sig_t *parse_fun_sig(parse_t *parse)596 {597 stree_fun_sig_t *sig;598 stree_proc_arg_t *arg;599 600 sig = stree_fun_sig_new();601 602 lmatch(parse, lc_lparen);603 604 #ifdef DEBUG_PARSE_TRACE605 printf("Parsing function signature.\n");606 #endif607 608 list_init(&sig->args);609 610 if (lcur_lc(parse) != lc_rparen) {611 612 /* Parse formal parameters. */613 while (!parse_is_error(parse)) {614 arg = parse_proc_arg(parse);615 616 if (stree_arg_has_attr(arg, aac_packed)) {617 sig->varg = arg;618 break;619 } else {620 list_append(&sig->args, arg);621 }622 623 if (lcur_lc(parse) == lc_rparen)624 break;625 626 lmatch(parse, lc_scolon);627 }628 }629 630 lmatch(parse, lc_rparen);631 632 if (lcur_lc(parse) == lc_colon) {633 lskip(parse);634 sig->rtype = parse_texpr(parse);635 } else {636 sig->rtype = NULL;637 }638 639 return sig;640 559 } 641 560 -
uspace/app/sbi/src/rdata.c
rf4f866c r80badbe 529 529 static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest) 530 530 { 531 *dest = rdata_deleg_new();532 (*dest)->obj = src->obj;533 (*dest)->sym = src->sym;531 (void) src; (void) dest; 532 printf("Unimplemented: Copy delegate.\n"); 533 exit(1); 534 534 } 535 535 … … 711 711 break; 712 712 case vc_ref: 713 if (var->u.ref_v->vref != NULL) { 714 printf("ref("); 715 rdata_var_print(var->u.ref_v->vref); 716 printf(")"); 717 } else { 718 printf("nil"); 719 } 713 printf("ref("); 714 rdata_var_print(var->u.ref_v->vref); 715 printf(")"); 720 716 break; 721 717 case vc_deleg: 722 718 printf("deleg("); 723 if (var->u.deleg_v->sym != NULL) { 724 if (var->u.deleg_v->obj != NULL) { 725 rdata_var_print(var->u.deleg_v->obj); 726 printf(","); 727 } 728 symbol_print_fqn(var->u.deleg_v->sym); 729 } else { 730 printf("nil"); 719 if (var->u.deleg_v->obj != NULL) { 720 rdata_var_print(var->u.deleg_v->obj); 721 printf(","); 731 722 } 723 symbol_print_fqn(var->u.deleg_v->sym); 732 724 printf(")"); 733 725 break; -
uspace/app/sbi/src/rdata_t.h
rf4f866c r80badbe 60 60 /** String variable */ 61 61 typedef struct { 62 c onst char *value;62 char *value; 63 63 } rdata_string_t; 64 64 -
uspace/app/sbi/src/run.c
rf4f866c r80badbe 67 67 rdata_value_t *value); 68 68 69 static void run_var_new_tprimitive(run_t *run, tdata_primitive_t *tprimitive, 70 rdata_var_t **rvar); 71 static void run_var_new_null_ref(run_t *run, rdata_var_t **rvar); 72 static void run_var_new_deleg(run_t *run, rdata_var_t **rvar); 73 74 75 /** Initialize runner instance. 76 * 77 * @param run Runner object 78 */ 69 /** Initialize runner instance. */ 79 70 void run_init(run_t *run) 80 71 { … … 82 73 } 83 74 84 /** Run program. 85 * 86 * Associates the program @a prog with the runner object and executes 87 * it. If a run-time error occurs during the execution (e.g. an unhandled 88 * exception), @a run->error will be set to @c b_true when this function 89 * returns. 90 * 91 * @param run Runner object 92 * @param prog Program to run 93 */ 75 /** Run program */ 94 76 void run_program(run_t *run, stree_program_t *prog) 95 77 { … … 137 119 } 138 120 139 /** Run procedure. 140 * 141 * Inserts the provided procedure AR @a proc_ar on the execution stack 142 * (in the thread AR) and executes the procedure. The return value 143 * of the procedure is stored to *(@a res). @c NULL is stored if the 144 * procedure returns no value. 145 * 146 * If the procedure execution bails out due to an exception, this 147 * can be determined by looking at @c bo_mode in thread AR. Also, 148 * in this case @c NULL is stored into *(@a res). 149 * 150 * @param run Runner object 151 * @param proc_ar Procedure activation record 152 * @param res Place to store procedure return value 153 */ 121 /** Run procedure. */ 154 122 void run_proc(run_t *run, run_proc_ar_t *proc_ar, rdata_item_t **res) 155 123 { … … 203 171 } 204 172 205 /** Run code block. 206 * 207 * @param run Runner object 208 * @param block Block to run 209 */ 173 /** Run code block */ 210 174 static void run_block(run_t *run, stree_block_t *block) 211 175 { … … 254 218 * @a res. 255 219 * 256 * @param run Runner object 257 * @param stat Statement to run 258 * @param res Place to store exps result or NULL if not interested 220 * @param run Runner object. 221 * @param stat Statement to run. 222 * @param res Place to store exps result or NULL if not interested. 259 223 */ 260 224 void run_stat(run_t *run, stree_stat_t *stat, rdata_item_t **res) … … 302 266 * of the expression (or NULL if it has no value) will be stored to @a res. 303 267 * 304 * @param run Runner object 305 * @param exps Expression statement to run 306 * @param res Place to store exps result or NULL if not interested 268 * @param run Runner object. 269 * @param exps Expression statement to run. 270 * @param res Place to store exps result or NULL if not interested. 307 271 */ 308 272 static void run_exps(run_t *run, stree_exps_t *exps, rdata_item_t **res) … … 319 283 } 320 284 321 /** Run variable declaration statement. 322 * 323 * @param run Runner object 324 * @param vdecl Variable declaration statement to run 325 */ 285 /** Run variable declaration statement. */ 326 286 static void run_vdecl(run_t *run, stree_vdecl_t *vdecl) 327 287 { 328 288 run_block_ar_t *block_ar; 329 289 rdata_var_t *var, *old_var; 330 tdata_item_t *var_ti;290 rdata_int_t *int_v; 331 291 332 292 #ifdef DEBUG_RUN_TRACE 333 293 printf("Executing variable declaration statement.\n"); 334 294 #endif 335 /* Compute variable type. XXX Memoize. */ 336 run_texpr(run->program, run_get_current_csi(run), vdecl->type, 337 &var_ti); 338 339 /* Create variable and initialize with default value. */ 340 run_var_new(run, var_ti, &var); 295 296 /* XXX Need to support other variables than int. */ 297 298 var = rdata_var_new(vc_int); 299 int_v = rdata_int_new(); 300 301 var->u.int_v = int_v; 302 bigint_init(&int_v->value, 0); 341 303 342 304 block_ar = run_get_current_block_ar(run); … … 356 318 } 357 319 358 /** Run @c if statement. 359 * 360 * @param run Runner object 361 * @param if_s If statement to run 362 */ 320 /** Run @c if statement. */ 363 321 static void run_if(run_t *run, stree_if_t *if_s) 364 322 { … … 390 348 } 391 349 392 /** Run @c while statement. 393 * 394 * @param run Runner object 395 * @param while_s While statement to run 396 */ 350 /** Run @c while statement. */ 397 351 static void run_while(run_t *run, stree_while_t *while_s) 398 352 { … … 421 375 } 422 376 423 /** Run @c raise statement. 424 * 425 * @param run Runner object 426 * @param raise_s Raise statement to run 427 */ 377 /** Run @c raise statement. */ 428 378 static void run_raise(run_t *run, stree_raise_t *raise_s) 429 379 { … … 447 397 } 448 398 449 /** Run @c return statement. 450 * 451 * Sets the return value in procedure AR and forces control to return 452 * from the function by setting bailout mode to @c bm_proc. 453 * 454 * @param run Runner object 455 * @param raise_s Return statement to run 456 */ 399 /** Run @c return statement. */ 457 400 static void run_return(run_t *run, stree_return_t *return_s) 458 401 { … … 470 413 run_cvt_value_item(run, rexpr, &rexpr_vi); 471 414 472 /* Store expression result in procedureAR. */415 /* Store expression result in function AR. */ 473 416 proc_ar = run_get_current_proc_ar(run); 474 417 proc_ar->retval = rexpr_vi; … … 479 422 } 480 423 481 /** Run @c with-except-finally statement. 482 * 483 * Note: 'With' clause is not implemented. 484 * 485 * @param run Runner object 486 * @param wef_s With-except-finally statement to run 487 */ 424 /** Run @c with-except-finally statement. */ 488 425 static void run_wef(run_t *run, stree_wef_t *wef_s) 489 426 { … … 552 489 * matches except clause @c except_c. 553 490 * 554 * @param run Runner object 555 * @param except_c @c except clause 556 * @return @c b_true if there is a match, @c b_false otherwise 491 * @param run Runner object. 492 * @param except_c @c except clause. 493 * @return @c b_true if there is a match, @c b_false otherwise. 557 494 */ 558 495 static bool_t run_exc_match(run_t *run, stree_except_t *except_c) … … 569 506 570 507 /* Determine if active exc. is derived from type in exc. clause. */ 571 /* XXX This is wrong, it does not work with generics. */572 508 return tdata_is_csi_derived_from_ti(exc_csi, etype); 573 509 } … … 575 511 /** Return CSI of the active exception. 576 512 * 577 * @param run Runner object 578 * @return CSI of the active exception 513 * @param run Runner object. 514 * @return CSI of the active exception. 579 515 */ 580 516 static stree_csi_t *run_exc_payload_get_csi(run_t *run) … … 621 557 * error message and raises a run-time error. 622 558 * 623 * @param run Runner object 559 * @param run Runner object. 624 560 */ 625 561 void run_exc_check_unhandled(run_t *run) … … 643 579 * 644 580 * Raises an error that cannot be handled by the user program. 645 *646 * @param run Runner object647 581 */ 648 582 void run_raise_error(run_t *run) … … 652 586 } 653 587 654 /** Construct a special recovery item. 655 * 656 * @param run Runner object 657 */ 588 /** Construct a special recovery item. */ 658 589 rdata_item_t *run_recovery_item(run_t *run) 659 590 { … … 662 593 } 663 594 664 /** Find a local variable in the currently active function. 665 * 666 * @param run Runner object 667 * @param name Name SID of the local variable 668 * @return Pointer to var node or @c NULL if not found 669 */ 595 /** Find a local variable in the currently active function. */ 670 596 rdata_var_t *run_local_vars_lookup(run_t *run, sid_t name) 671 597 { … … 692 618 } 693 619 694 /** Get current procedure activation record. 695 * 696 * @param run Runner object 697 * @return Active procedure AR 698 */ 620 /** Get current function activation record. */ 699 621 run_proc_ar_t *run_get_current_proc_ar(run_t *run) 700 622 { … … 705 627 } 706 628 707 /** Get current block activation record. 708 * 709 * @param run Runner object 710 * @return Active block AR 711 */ 629 /** Get current block activation record. */ 712 630 run_block_ar_t *run_get_current_block_ar(run_t *run) 713 631 { … … 721 639 } 722 640 723 /** Get current CSI. 724 * 725 * @param run Runner object 726 * @return Active CSI 727 */ 641 /** Get current CSI. */ 728 642 stree_csi_t *run_get_current_csi(run_t *run) 729 643 { … … 740 654 * (1) Create a variable of the desired type. 741 655 * (2) Initialize the variable with the provided value. 742 *743 * @param item Value item (initial value for variable).744 * @param var Place to store new var node.745 656 */ 746 657 void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var) 747 658 { 748 rdata_bool_t *bool_v;749 659 rdata_char_t *char_v; 750 rdata_deleg_t *deleg_v;751 660 rdata_int_t *int_v; 752 661 rdata_string_t *string_v; … … 758 667 759 668 switch (in_var->vc) { 760 case vc_bool:761 *var = rdata_var_new(vc_bool);762 bool_v = rdata_bool_new();763 764 (*var)->u.bool_v = bool_v;765 bool_v->value = item->u.value->var->u.bool_v->value;766 break;767 669 case vc_char: 768 670 *var = rdata_var_new(vc_char); … … 773 675 &char_v->value); 774 676 break; 775 case vc_deleg:776 *var = rdata_var_new(vc_deleg);777 deleg_v = rdata_deleg_new();778 779 (*var)->u.deleg_v = deleg_v;780 deleg_v->obj = item->u.value->var->u.deleg_v->obj;781 deleg_v->sym = item->u.value->var->u.deleg_v->sym;782 break;783 677 case vc_int: 784 678 *var = rdata_var_new(vc_int); … … 810 704 } 811 705 812 /** Construct a procedure AR. 813 * 814 * @param run Runner object 815 * @param obj Object whose procedure is being activated 816 * @param proc Procedure that is being activated 817 * @param rproc_ar Place to store pointer to new activation record 818 */ 706 /** Construct a function AR. */ 819 707 void run_proc_ar_create(run_t *run, rdata_var_t *obj, stree_proc_t *proc, 820 708 run_proc_ar_t **rproc_ar) … … 845 733 * When invoking a procedure this is used to store the argument values 846 734 * in the activation record. 847 *848 * @param run Runner object849 * @param proc_ar Existing procedure activation record where to store850 * the values851 * @param arg_vals List of value items (rdata_item_t *) -- real852 * argument values853 735 */ 854 736 void run_proc_ar_set_args(run_t *run, run_proc_ar_t *proc_ar, list_t *arg_vals) … … 885 767 case sc_fun: 886 768 fun = symbol_to_fun(outer_symbol); 887 args = &fun-> sig->args;888 varg = fun-> sig->varg;769 args = &fun->args; 770 varg = fun->varg; 889 771 break; 890 772 case sc_prop: … … 983 865 * When invoking a setter this is used to store its argument value in its 984 866 * procedure activation record. 985 *986 * @param run Runner object987 * @param proc_ar Existing procedure activation record where to store988 * the setter argument989 * @param arg_val Value items (rdata_item_t *) -- real argument value990 867 */ 991 868 void run_proc_ar_set_setter_arg(run_t *run, run_proc_ar_t *proc_ar, … … 1021 898 } 1022 899 1023 /** Print function activation backtrace. 1024 * 1025 * Prints a backtrace of activated functions for debugging purposes. 1026 * 1027 * @param run Runner object 1028 */ 900 /** Print function activation backtrace. */ 1029 901 void run_print_fun_bt(run_t *run) 1030 902 { … … 1048 920 * If @a item is a value, we just return a copy. If @a item is an address, 1049 921 * we read from the address. 1050 *1051 * @param run Runner object1052 * @param item Input item (value or address)1053 * @param ritem Place to store pointer to new value item1054 922 */ 1055 923 void run_cvt_value_item(run_t *run, rdata_item_t *item, rdata_item_t **ritem) … … 1083 951 * Get var-class of @a item, regardless whether it is a value or address. 1084 952 * (I.e. the var class of the value or variable at the given address). 1085 *1086 * @param run Runner object1087 * @param item Value or address item1088 * @return Varclass of @a item1089 953 */ 1090 954 var_class_t run_item_get_vc(run_t *run, rdata_item_t *item) … … 1128 992 * copy. 1129 993 * 1130 * @param run Runner object 1131 * @param addr Address of class @c ac_prop 1132 * @ return Pointer to var node994 * @param run Runner object. 995 * @param addr Address of class @c ac_prop. 996 * @param Pointer to var node. 1133 997 */ 1134 998 static rdata_var_t *run_aprop_get_tpos(run_t *run, rdata_address_t *addr) … … 1151 1015 /** Read data from an address. 1152 1016 * 1153 * Read value from the specified address. 1154 * 1155 * @param run Runner object 1156 * @param address Address to read 1157 * @param ritem Place to store pointer to the value that was read 1017 * Return value stored in a variable at the specified address. 1158 1018 */ 1159 1019 void run_address_read(run_t *run, rdata_address_t *address, … … 1176 1036 /** Write data to an address. 1177 1037 * 1178 * Store value @a value at address @a address. 1179 * 1180 * @param run Runner object 1181 * @param address Address to write 1182 * @param value Value to store at the address 1038 * Store @a value to the variable at @a address. 1183 1039 */ 1184 1040 void run_address_write(run_t *run, rdata_address_t *address, … … 1197 1053 } 1198 1054 1199 /** Read data from a property address.1200 *1201 * This involves invoking the property getter procedure.1202 *1203 * @param run Runner object.1204 * @param addr_prop Property address to read.1205 * @param ritem Place to store pointer to the value that was read.1206 */1207 1055 static void run_aprop_read(run_t *run, rdata_addr_prop_t *addr_prop, 1208 1056 rdata_item_t **ritem) … … 1268 1116 } 1269 1117 1270 /** Write data to a property address.1271 *1272 * This involves invoking the property setter procedure.1273 *1274 * @param run Runner object1275 * @param addr_prop Property address to write1276 * @param value Value to store at the address1277 */1278 1118 static void run_aprop_write(run_t *run, rdata_addr_prop_t *addr_prop, 1279 1119 rdata_value_t *value) … … 1341 1181 * 1342 1182 * Constructs a reference (value item) pointing to @a var. 1343 *1344 * @param run Runner object1345 * @param var Variable node that is being referenced1346 * @param res Place to store pointer to new reference.1347 1183 */ 1348 1184 void run_reference(run_t *run, rdata_var_t *var, rdata_item_t **res) … … 1374 1210 * Takes a reference (address or value) and returns the address (item) of 1375 1211 * the target of the reference. 1376 *1377 * @param run Runner object1378 * @param ref Reference1379 * @param rtitem Place to store pointer to the resulting address.1380 1212 */ 1381 1213 void run_dereference(run_t *run, rdata_item_t *ref, rdata_item_t **ritem) … … 1420 1252 * error (not for the @c raise statement). 1421 1253 * 1422 * @param run Runner object 1423 * @param csi Exception class 1254 * @param run Runner object. 1255 * @param csi Exception class. 1424 1256 */ 1425 1257 void run_raise_exc(run_t *run, stree_csi_t *csi) … … 1438 1270 } 1439 1271 1440 /** Determine if we are bailing out. 1441 * 1442 * @param run Runner object 1443 * @return @c b_true if we are bailing out, @c b_false otherwise 1444 */ 1272 /** Determine if we are bailing out. */ 1445 1273 bool_t run_is_bo(run_t *run) 1446 1274 { … … 1448 1276 } 1449 1277 1450 /** Construct a new variable of the given type.1451 *1452 * The variable is allocated and initialized with a default value1453 * based on type item @a ti. For reference types the default value1454 * is a null reference. At this point this does not work for generic1455 * types (we need RTTI).1456 *1457 * @param run Runner object1458 * @param ti Type of variable to create (type item)1459 * @param rvar Place to store pointer to new variable1460 */1461 void run_var_new(run_t *run, tdata_item_t *ti, rdata_var_t **rvar)1462 {1463 rdata_var_t *var;1464 1465 switch (ti->tic) {1466 case tic_tprimitive:1467 run_var_new_tprimitive(run, ti->u.tprimitive, rvar);1468 break;1469 case tic_tobject:1470 case tic_tarray:1471 run_var_new_null_ref(run, rvar);1472 break;1473 case tic_tdeleg:1474 case tic_tfun:1475 run_var_new_deleg(run, rvar);1476 break;1477 case tic_tvref:1478 /*1479 * XXX Need to obtain run-time value of type argument to1480 * initialize variable properly.1481 */1482 var = rdata_var_new(vc_int);1483 var->u.int_v = rdata_int_new();1484 bigint_init(&var->u.int_v->value, 0);1485 *rvar = var;1486 break;1487 case tic_ignore:1488 assert(b_false);1489 }1490 }1491 1492 /** Construct a new variable of primitive type.1493 *1494 * The variable is allocated and initialized with a default value1495 * based on primitive type item @a tprimitive.1496 *1497 * @param run Runner object1498 * @param ti Primitive type of variable to create1499 * @param rvar Place to store pointer to new variable1500 */1501 static void run_var_new_tprimitive(run_t *run, tdata_primitive_t *tprimitive,1502 rdata_var_t **rvar)1503 {1504 rdata_var_t *var;1505 1506 (void) run;1507 1508 switch (tprimitive->tpc) {1509 case tpc_bool:1510 var = rdata_var_new(vc_bool);1511 var->u.bool_v = rdata_bool_new();1512 var->u.bool_v->value = b_false;1513 break;1514 case tpc_char:1515 var = rdata_var_new(vc_char);1516 var->u.char_v = rdata_char_new();1517 bigint_init(&var->u.char_v->value, 0);1518 break;1519 case tpc_int:1520 var = rdata_var_new(vc_int);1521 var->u.int_v = rdata_int_new();1522 bigint_init(&var->u.int_v->value, 0);1523 break;1524 case tpc_nil:1525 assert(b_false);1526 case tpc_string:1527 var = rdata_var_new(vc_string);1528 var->u.string_v = rdata_string_new();1529 var->u.string_v->value = "";1530 break;1531 case tpc_resource:1532 var = rdata_var_new(vc_resource);1533 var->u.resource_v = rdata_resource_new();1534 var->u.resource_v->data = NULL;1535 break;1536 }1537 1538 *rvar = var;1539 }1540 1541 /** Construct a new variable containing null reference.1542 *1543 * @param run Runner object1544 * @param rvar Place to store pointer to new variable1545 */1546 static void run_var_new_null_ref(run_t *run, rdata_var_t **rvar)1547 {1548 rdata_var_t *var;1549 1550 (void) run;1551 1552 /* Return null reference. */1553 var = rdata_var_new(vc_ref);1554 var->u.ref_v = rdata_ref_new();1555 1556 *rvar = var;1557 }1558 1559 /** Construct a new variable containing invalid delegate.1560 *1561 * @param run Runner object1562 * @param rvar Place to store pointer to new variable1563 */1564 static void run_var_new_deleg(run_t *run, rdata_var_t **rvar)1565 {1566 rdata_var_t *var;1567 1568 (void) run;1569 1570 /* Return null reference. */1571 var = rdata_var_new(vc_deleg);1572 var->u.deleg_v = rdata_deleg_new();1573 1574 *rvar = var;1575 }1576 1577 /** Construct a new thread activation record.1578 *1579 * @param run Runner object1580 * @return New thread AR.1581 */1582 1278 run_thread_ar_t *run_thread_ar_new(void) 1583 1279 { … … 1593 1289 } 1594 1290 1595 /** Construct a new procedure activation record.1596 *1597 * @param run Runner object1598 * @return New procedure AR.1599 */1600 1291 run_proc_ar_t *run_proc_ar_new(void) 1601 1292 { … … 1611 1302 } 1612 1303 1613 /** Construct a new block activation record.1614 *1615 * @param run Runner object1616 * @return New block AR.1617 */1618 1304 run_block_ar_t *run_block_ar_new(void) 1619 1305 { -
uspace/app/sbi/src/run.h
rf4f866c r80badbe 68 68 bool_t run_is_bo(run_t *run); 69 69 70 void run_var_new(run_t *run, tdata_item_t *ti, rdata_var_t **rvar);71 72 70 run_thread_ar_t *run_thread_ar_new(void); 73 71 run_proc_ar_t *run_proc_ar_new(void); -
uspace/app/sbi/src/run_expr.c
rf4f866c r80badbe 27 27 */ 28 28 29 /** @file Run expressions. */29 /** @file Runner (executes the code). */ 30 30 31 31 #include <stdio.h> … … 109 109 static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res); 110 110 static void run_as(run_t *run, stree_as_t *as_op, rdata_item_t **res); 111 static void run_box(run_t *run, stree_box_t *box, rdata_item_t **res); 112 113 /** Evaluate expression. 114 * 115 * Run the expression @a expr and store pointer to the result in *(@a res). 116 * If the expression has on value (assignment) then @c NULL is returned. 117 * @c NULL is also returned if an error or exception occurs. 118 * 119 * @param run Runner object 120 * @param expr Expression to run 121 * @param res Place to store result 122 */ 111 112 /** Evaluate expression. */ 123 113 void run_expr(run_t *run, stree_expr_t *expr, rdata_item_t **res) 124 114 { … … 161 151 run_as(run, expr->u.as_op, res); 162 152 break; 163 case ec_box:164 run_box(run, expr->u.box, res);165 break;166 153 } 167 154 … … 173 160 } 174 161 175 /** Evaluate name reference expression. 176 * 177 * @param run Runner object 178 * @param nameref Name reference 179 * @param res Place to store result 180 */ 162 /** Evaluate name reference expression. */ 181 163 static void run_nameref(run_t *run, stree_nameref_t *nameref, 182 164 rdata_item_t **res) … … 265 247 assert(csi != NULL); 266 248 267 if (symbol_search_csi(run->program, csi, nameref->name) 268 == NULL) { 249 if (sym->outer_csi != csi) { 269 250 /* Function is not in the current object. */ 270 251 printf("Error: Cannot access non-static member " … … 302 283 assert(obj != NULL); 303 284 304 if (symbol_search_csi(run->program, csi, nameref->name) 305 == NULL) { 285 if (sym->outer_csi != csi) { 306 286 /* Variable is not in the current object. */ 307 287 printf("Error: Cannot access non-static member " … … 336 316 } 337 317 338 /** Evaluate literal. 339 * 340 * @param run Runner object 341 * @param literal Literal 342 * @param res Place to store result 343 */ 318 /** Evaluate literal. */ 344 319 static void run_literal(run_t *run, stree_literal_t *literal, 345 320 rdata_item_t **res) … … 367 342 } 368 343 369 /** Evaluate Boolean literal. 370 * 371 * @param run Runner object 372 * @param lit_bool Boolean literal 373 * @param res Place to store result 374 */ 344 /** Evaluate Boolean literal. */ 375 345 static void run_lit_bool(run_t *run, stree_lit_bool_t *lit_bool, 376 346 rdata_item_t **res) … … 426 396 } 427 397 428 /** Evaluate integer literal. 429 * 430 * @param run Runner object 431 * @param lit_int Integer literal 432 * @param res Place to store result 433 */ 398 /** Evaluate integer literal. */ 434 399 static void run_lit_int(run_t *run, stree_lit_int_t *lit_int, 435 400 rdata_item_t **res) … … 458 423 } 459 424 460 /** Evaluate reference literal (@c nil). 461 * 462 * @param run Runner object 463 * @param lit_ref Reference literal 464 * @param res Place to store result 465 */ 425 /** Evaluate reference literal (@c nil). */ 466 426 static void run_lit_ref(run_t *run, stree_lit_ref_t *lit_ref, 467 427 rdata_item_t **res) … … 491 451 } 492 452 493 /** Evaluate string literal. 494 * 495 * @param run Runner object 496 * @param lit_string String literal 497 * @param res Place to store result 498 */ 453 /** Evaluate string literal. */ 499 454 static void run_lit_string(run_t *run, stree_lit_string_t *lit_string, 500 455 rdata_item_t **res) … … 523 478 } 524 479 525 /** Evaluate @c self reference. 526 * 527 * @param run Runner object 528 * @param self_ref Self reference 529 * @param res Place to store result 530 */ 480 /** Evaluate @c self reference. */ 531 481 static void run_self_ref(run_t *run, stree_self_ref_t *self_ref, 532 482 rdata_item_t **res) … … 544 494 } 545 495 546 /** Evaluate binary operation. 547 * 548 * @param run Runner object 549 * @param binop Binary operation 550 * @param res Place to store result 551 */ 496 /** Evaluate binary operation. */ 552 497 static void run_binop(run_t *run, stree_binop_t *binop, rdata_item_t **res) 553 498 { … … 629 574 } 630 575 631 /** Evaluate binary operation on bool arguments. 632 * 633 * @param run Runner object 634 * @param binop Binary operation 635 * @param v1 Value of first argument 636 * @param v2 Value of second argument 637 * @param res Place to store result 638 */ 576 /** Evaluate binary operation on bool arguments. */ 639 577 static void run_binop_bool(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 640 578 rdata_value_t *v2, rdata_item_t **res) … … 690 628 } 691 629 692 /** Evaluate binary operation on char arguments. 693 * 694 * @param run Runner object 695 * @param binop Binary operation 696 * @param v1 Value of first argument 697 * @param v2 Value of second argument 698 * @param res Place to store result 699 */ 630 /** Evaluate binary operation on char arguments. */ 700 631 static void run_binop_char(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 701 632 rdata_value_t *v2, rdata_item_t **res) … … 760 691 } 761 692 762 /** Evaluate binary operation on int arguments. 763 * 764 * @param run Runner object 765 * @param binop Binary operation 766 * @param v1 Value of first argument 767 * @param v2 Value of second argument 768 * @param res Place to store result 769 */ 693 /** Evaluate binary operation on int arguments. */ 770 694 static void run_binop_int(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 771 695 rdata_value_t *v2, rdata_item_t **res) … … 857 781 } 858 782 859 /** Evaluate binary operation on string arguments. 860 * 861 * @param run Runner object 862 * @param binop Binary operation 863 * @param v1 Value of first argument 864 * @param v2 Value of second argument 865 * @param res Place to store result 866 */ 783 /** Evaluate binary operation on string arguments. */ 867 784 static void run_binop_string(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 868 785 rdata_value_t *v2, rdata_item_t **res) … … 873 790 rdata_string_t *string_v; 874 791 875 c onst char *s1, *s2;792 char *s1, *s2; 876 793 877 794 (void) run; … … 903 820 } 904 821 905 /** Evaluate binary operation on ref arguments. 906 * 907 * @param run Runner object 908 * @param binop Binary operation 909 * @param v1 Value of first argument 910 * @param v2 Value of second argument 911 * @param res Place to store result 912 */ 822 /** Evaluate binary operation on ref arguments. */ 913 823 static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 914 824 rdata_value_t *v2, rdata_item_t **res) … … 952 862 953 863 954 /** Evaluate unary operation. 955 * 956 * @param run Runner object 957 * @param unop Unary operation 958 * @param res Place to store result 959 */ 864 /** Evaluate unary operation. */ 960 865 static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res) 961 866 { … … 993 898 } 994 899 995 /** Evaluate unary operation on int argument. 996 * 997 * @param run Runner object 998 * @param unop Unary operation 999 * @param val Value of argument 1000 * @param res Place to store result 1001 */ 900 /** Evaluate unary operation on int argument. */ 1002 901 static void run_unop_int(run_t *run, stree_unop_t *unop, rdata_value_t *val, 1003 902 rdata_item_t **res) … … 1033 932 1034 933 1035 /** Evaluate @c new operation. 1036 * 1037 * Evaluates operation per the @c new operator that creates a new 1038 * instance of some type. 1039 * 1040 * @param run Runner object 1041 * @param unop Unary operation 1042 * @param res Place to store result 1043 */ 934 /** Evaluate @c new operation. */ 1044 935 static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res) 1045 936 { … … 1067 958 } 1068 959 1069 /** Create new array. 1070 * 1071 * @param run Runner object 1072 * @param new_op New operation 1073 * @param titem Type of new var node (tic_tarray) 1074 * @param res Place to store result 1075 */ 960 /** Create new array. */ 1076 961 static void run_new_array(run_t *run, stree_new_t *new_op, 1077 962 tdata_item_t *titem, rdata_item_t **res) … … 1161 1046 /* Create member variables */ 1162 1047 for (i = 0; i < length; ++i) { 1163 /* Create and initialize element. */ 1164 run_var_new(run, tarray->base_ti, &elem_var); 1048 /* XXX Depends on member variable type. */ 1049 elem_var = rdata_var_new(vc_int); 1050 elem_var->u.int_v = rdata_int_new(); 1051 bigint_init(&elem_var->u.int_v->value, 0); 1165 1052 1166 1053 array->element[i] = elem_var; … … 1175 1062 } 1176 1063 1177 /** Create new object. 1178 * 1179 * @param run Runner object 1180 * @param new_op New operation 1181 * @param titem Type of new var node (tic_tobject) 1182 * @param res Place to store result 1183 */ 1064 /** Create new object. */ 1184 1065 static void run_new_object(run_t *run, stree_new_t *new_op, 1185 1066 tdata_item_t *titem, rdata_item_t **res) … … 1200 1081 } 1201 1082 1202 /** Evaluate member acccess. 1203 * 1204 * Evaluate operation per the member access ('.') operator. 1205 * 1206 * @param run Runner object 1207 * @param access Access operation 1208 * @param res Place to store result 1209 */ 1083 /** Evaluate member acccess. */ 1210 1084 static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res) 1211 1085 { … … 1229 1103 } 1230 1104 1231 /** Evaluate member acccess (with base already evaluated). 1232 * 1233 * @param run Runner object 1234 * @param access Access operation 1235 * @param arg Evaluated base expression 1236 * @param res Place to store result 1237 */ 1105 /** Evaluate member acccess (with base already evaluated). */ 1238 1106 static void run_access_item(run_t *run, stree_access_t *access, 1239 1107 rdata_item_t *arg, rdata_item_t **res) … … 1263 1131 } 1264 1132 1265 /** Evaluate reference acccess. 1266 * 1267 * @param run Runner object 1268 * @param access Access operation 1269 * @param arg Evaluated base expression 1270 * @param res Place to store result 1271 */ 1133 /** Evaluate reference acccess. */ 1272 1134 static void run_access_ref(run_t *run, stree_access_t *access, 1273 1135 rdata_item_t *arg, rdata_item_t **res) … … 1287 1149 } 1288 1150 1289 /** Evaluate delegate-member acccess. 1290 * 1291 * @param run Runner object 1292 * @param access Access operation 1293 * @param arg Evaluated base expression 1294 * @param res Place to store result 1295 */ 1151 /** Evaluate delegate-member acccess. */ 1296 1152 static void run_access_deleg(run_t *run, stree_access_t *access, 1297 1153 rdata_item_t *arg, rdata_item_t **res) … … 1336 1192 } 1337 1193 1338 /** Evaluate object member acccess. 1339 * 1340 * @param run Runner object 1341 * @param access Access operation 1342 * @param arg Evaluated base expression 1343 * @param res Place to store result 1344 */ 1194 /** Evaluate object member acccess. */ 1345 1195 static void run_access_object(run_t *run, stree_access_t *access, 1346 1196 rdata_item_t *arg, rdata_item_t **res) … … 1390 1240 printf("Error: Accessing object member which is nested CSI.\n"); 1391 1241 exit(1); 1392 case sc_deleg:1393 printf("Error: Accessing object member which is a delegate.\n");1394 exit(1);1395 1242 case sc_fun: 1396 /* Construct anonymousdelegate. */1243 /* Construct delegate. */ 1397 1244 ritem = rdata_item_new(ic_value); 1398 1245 value = rdata_value_new(); … … 1441 1288 } 1442 1289 1443 /** Call a function. 1444 * 1445 * Call a function and return the result in @a res. 1446 * 1447 * @param run Runner object 1448 * @param call Call operation 1449 * @param res Place to store result 1450 */ 1290 /** Call a function. */ 1451 1291 static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res) 1452 1292 { 1453 rdata_item_t *r deleg, *rdeleg_vi;1293 rdata_item_t *rfun; 1454 1294 rdata_deleg_t *deleg_v; 1455 1295 list_t arg_vals; … … 1464 1304 printf("Run call operation.\n"); 1465 1305 #endif 1466 run_expr(run, call->fun, &r deleg);1306 run_expr(run, call->fun, &rfun); 1467 1307 if (run_is_bo(run)) { 1468 1308 *res = NULL; … … 1475 1315 } 1476 1316 1477 run_cvt_value_item(run, rdeleg, &rdeleg_vi); 1478 assert(rdeleg_vi->ic == ic_value); 1479 1480 if (rdeleg_vi->u.value->var->vc != vc_deleg) { 1481 printf("Unimplemented: Call expression of this type ("); 1482 rdata_item_print(rdeleg_vi); 1483 printf(").\n"); 1317 if (rfun->ic != ic_value || rfun->u.value->var->vc != vc_deleg) { 1318 printf("Unimplemented: Call expression of this type.\n"); 1484 1319 exit(1); 1485 1320 } 1486 1321 1487 deleg_v = r deleg_vi->u.value->var->u.deleg_v;1322 deleg_v = rfun->u.value->var->u.deleg_v; 1488 1323 1489 1324 if (deleg_v->sym->sc != sc_fun) { … … 1532 1367 } 1533 1368 1534 /** Run index operation. 1535 * 1536 * Evaluate operation per the indexing ('[', ']') operator. 1537 * 1538 * @param run Runner object 1539 * @param index Index operation 1540 * @param res Place to store result 1541 */ 1369 /** Run index operation. */ 1542 1370 static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res) 1543 1371 { … … 1605 1433 } 1606 1434 1607 /** Run index operation on array. 1608 * 1609 * @param run Runner object 1610 * @param index Index operation 1611 * @param base Evaluated base expression 1612 * @param args Evaluated indices (list of rdata_item_t) 1613 * @param res Place to store result 1614 */ 1435 /** Run index operation on array. */ 1615 1436 static void run_index_array(run_t *run, stree_index_t *index, 1616 1437 rdata_item_t *base, list_t *args, rdata_item_t **res) … … 1704 1525 } 1705 1526 1706 /** Index an object (via its indexer). 1707 * 1708 * @param run Runner object 1709 * @param index Index operation 1710 * @param base Evaluated base expression 1711 * @param args Evaluated indices (list of rdata_item_t) 1712 * @param res Place to store result 1713 */ 1527 /** Index an object (via its indexer). */ 1714 1528 static void run_index_object(run_t *run, stree_index_t *index, 1715 1529 rdata_item_t *base, list_t *args, rdata_item_t **res) … … 1783 1597 } 1784 1598 1785 /** Run index operation on string. 1786 * 1787 * @param run Runner object 1788 * @param index Index operation 1789 * @param base Evaluated base expression 1790 * @param args Evaluated indices (list of rdata_item_t) 1791 * @param res Place to store result 1792 */ 1599 /** Run index operation on string. */ 1793 1600 static void run_index_string(run_t *run, stree_index_t *index, 1794 1601 rdata_item_t *base, list_t *args, rdata_item_t **res) … … 1883 1690 } 1884 1691 1885 /** Run assignment. 1886 * 1887 * Executes an assignment. @c NULL is always stored to @a res because 1888 * an assignment does not have a value. 1889 * 1890 * @param run Runner object 1891 * @param assign Assignment expression 1892 * @param res Place to store result 1893 */ 1692 /** Execute assignment. */ 1894 1693 static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res) 1895 1694 { … … 1928 1727 } 1929 1728 1930 /** Execute @c as conversion. 1931 * 1932 * @param run Runner object 1933 * @param as_op @c as conversion expression 1934 * @param res Place to store result 1935 */ 1729 /** Execute @c as conversion. */ 1936 1730 static void run_as(run_t *run, stree_as_t *as_op, rdata_item_t **res) 1937 1731 { … … 2000 1794 } 2001 1795 2002 /** Execute boxing operation. 2003 * 2004 * XXX We can scrap this special operation once we have constructors. 2005 * 2006 * @param run Runner object 2007 * @param box Boxing operation 2008 * @param res Place to store result 2009 */ 2010 static void run_box(run_t *run, stree_box_t *box, rdata_item_t **res) 2011 { 2012 rdata_item_t *rarg_i; 2013 rdata_item_t *rarg_vi; 2014 2015 stree_symbol_t *csi_sym; 2016 stree_csi_t *csi; 2017 builtin_t *bi; 2018 rdata_var_t *var; 2019 rdata_object_t *object; 2020 2021 sid_t mbr_name_sid; 2022 rdata_var_t *mbr_var; 2023 2024 #ifdef DEBUG_RUN_TRACE 2025 printf("Run boxing operation.\n"); 2026 #endif 2027 run_expr(run, box->arg, &rarg_i); 2028 if (run_is_bo(run)) { 2029 *res = NULL; 2030 return; 2031 } 2032 2033 run_cvt_value_item(run, rarg_i, &rarg_vi); 2034 assert(rarg_vi->ic == ic_value); 2035 2036 bi = run->program->builtin; 2037 2038 /* Just to keep the compiler happy. */ 2039 csi_sym = NULL; 2040 2041 switch (rarg_vi->u.value->var->vc) { 2042 case vc_bool: csi_sym = bi->boxed_bool; break; 2043 case vc_char: csi_sym = bi->boxed_char; break; 2044 case vc_int: csi_sym = bi->boxed_int; break; 2045 case vc_string: csi_sym = bi->boxed_string; break; 2046 2047 case vc_ref: 2048 case vc_deleg: 2049 case vc_array: 2050 case vc_object: 2051 case vc_resource: 2052 assert(b_false); 2053 } 2054 2055 csi = symbol_to_csi(csi_sym); 2056 assert(csi != NULL); 2057 2058 /* Construct object of the relevant boxed type. */ 2059 run_new_csi_inst(run, csi, res); 2060 2061 /* Set the 'Value' field */ 2062 2063 assert((*res)->ic == ic_value); 2064 assert((*res)->u.value->var->vc == vc_ref); 2065 var = (*res)->u.value->var->u.ref_v->vref; 2066 assert(var->vc == vc_object); 2067 object = var->u.object_v; 2068 2069 mbr_name_sid = strtab_get_sid("Value"); 2070 mbr_var = intmap_get(&object->fields, mbr_name_sid); 2071 assert(mbr_var != NULL); 2072 2073 rdata_var_write(mbr_var, rarg_vi->u.value); 2074 } 2075 2076 /** Create new CSI instance. 2077 * 2078 * Create a new object, instance of @a csi. 2079 * XXX This does not work with generics as @a csi cannot specify a generic 2080 * type. 2081 * 2082 * Initialize the fields with default values of their types, but do not 2083 * run any constructor. 2084 * 2085 * @param run Runner object 2086 * @param as_op @c as conversion expression 2087 * @param res Place to store result 2088 */ 1796 /** Create new CSI instance. */ 2089 1797 void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res) 2090 1798 { … … 2096 1804 2097 1805 rdata_var_t *mbr_var; 1806 2098 1807 list_node_t *node; 2099 tdata_item_t *field_ti;2100 1808 2101 1809 csi_sym = csi_to_symbol(csi); … … 2116 1824 2117 1825 /* Create object fields. */ 2118 while (csi != NULL) { 2119 node = list_first(&csi->members); 2120 while (node != NULL) { 2121 csimbr = list_node_data(node, stree_csimbr_t *); 2122 if (csimbr->cc == csimbr_var) { 2123 /* Compute field type. XXX Memoize. */ 2124 run_texpr(run->program, csi, 2125 csimbr->u.var->type, 2126 &field_ti); 2127 2128 /* Create and initialize field. */ 2129 run_var_new(run, field_ti, &mbr_var); 2130 2131 /* Add to field map. */ 2132 intmap_set(&obj->fields, 2133 csimbr->u.var->name->sid, 2134 mbr_var); 2135 } 2136 2137 node = list_next(&csi->members, node); 1826 node = list_first(&csi->members); 1827 while (node != NULL) { 1828 csimbr = list_node_data(node, stree_csimbr_t *); 1829 if (csimbr->cc == csimbr_var) { 1830 /* XXX Depends on member variable type. */ 1831 mbr_var = rdata_var_new(vc_int); 1832 mbr_var->u.int_v = rdata_int_new(); 1833 bigint_init(&mbr_var->u.int_v->value, 0); 1834 1835 intmap_set(&obj->fields, csimbr->u.var->name->sid, 1836 mbr_var); 2138 1837 } 2139 1838 2140 /* Continue with base CSI */ 2141 csi = csi->base_csi; 1839 node = list_next(&csi->members, node); 2142 1840 } 2143 1841 … … 2148 1846 /** Return boolean value of an item. 2149 1847 * 2150 * Try to interpret @a item as a boolean value. If it is not a boolean 2151 * value, generate an error. 2152 * 2153 * @param run Runner object 2154 * @param item Input item 2155 * @return Resulting boolean value 1848 * Tries to interpret @a item as a boolean value. If it is not a boolean 1849 * value, this generates an error. 2156 1850 */ 2157 1851 bool_t run_item_boolean_value(run_t *run, rdata_item_t *item) -
uspace/app/sbi/src/run_texpr.c
rf4f866c r80badbe 27 27 */ 28 28 29 /** @file Evaluate type expressions. */29 /** @file Evaluates type expressions. */ 30 30 31 31 #include <assert.h> 32 32 #include <stdlib.h> 33 #include "debug.h"34 33 #include "list.h" 35 34 #include "mytypes.h" 36 #include "stree.h"37 35 #include "strtab.h" 38 36 #include "symbol.h" … … 52 50 stree_tapply_t *tapply, tdata_item_t **res); 53 51 54 /** Evaluate type expression.55 *56 * Evaluate type expression (this produces a type item). If a type error57 * occurs, the resulting type item is of class @c tic_ignore.58 *59 * @param prog Program60 * @param ctx Current CSI (context)61 * @param texpr Type expression to evaluate62 * @param res Place to store type result63 */64 52 void run_texpr(stree_program_t *prog, stree_csi_t *ctx, stree_texpr_t *texpr, 65 53 tdata_item_t **res) … … 84 72 } 85 73 86 /** Evaluate type access expression.87 *88 * Evaluate operation per the type access ('.') operator.89 *90 * @param prog Program91 * @param ctx Current CSI (context)92 * @param taccess Type access expression to evaluate93 * @param res Place to store type result94 */95 74 static void run_taccess(stree_program_t *prog, stree_csi_t *ctx, 96 75 stree_taccess_t *taccess, tdata_item_t **res) … … 100 79 tdata_item_t *titem; 101 80 tdata_object_t *tobject; 102 tdata_deleg_t *tdeleg;103 81 stree_csi_t *base_csi; 104 82 … … 133 111 } 134 112 135 switch (sym->sc) { 136 case sc_csi: 137 /* Construct type item. */ 138 titem = tdata_item_new(tic_tobject); 139 tobject = tdata_object_new(); 140 titem->u.tobject = tobject; 141 142 tobject->static_ref = b_false; 143 tobject->csi = sym->u.csi; 144 list_init(&tobject->targs); /* XXX */ 145 break; 146 case sc_deleg: 147 /* Construct type item. */ 148 titem = tdata_item_new(tic_tdeleg); 149 tdeleg = tdata_deleg_new(); 150 titem->u.tdeleg = tdeleg; 151 152 tdeleg->deleg = sym->u.deleg; 153 break; 154 case sc_fun: 155 case sc_var: 156 case sc_prop: 113 if (sym->sc != sc_csi) { 157 114 printf("Error: Symbol '"); 158 115 symbol_print_fqn(sym); 159 printf("' is not a type.\n"); 160 titem = tdata_item_new(tic_ignore); 161 break; 162 } 163 164 *res = titem; 165 } 166 167 /** Evaluate type indexing expression. 168 * 169 * Evaluate operation per the type indexing ('[', ']') operator. 170 * A type indexing operation may have extents specified or only rank 171 * specified. 172 * 173 * @param prog Program 174 * @param ctx Current CSI (context) 175 * @param tindex Type indexing expression to evaluate 176 * @param res Place to store type result 177 */ 116 printf("' is not a CSI.\n"); 117 *res = tdata_item_new(tic_ignore); 118 return; 119 } 120 121 /* Construct type item. */ 122 titem = tdata_item_new(tic_tobject); 123 tobject = tdata_object_new(); 124 titem->u.tobject = tobject; 125 126 tobject->static_ref = b_false; 127 tobject->csi = sym->u.csi; 128 129 *res = titem; 130 } 131 178 132 static void run_tindex(stree_program_t *prog, stree_csi_t *ctx, 179 133 stree_tindex_t *tindex, tdata_item_t **res) … … 217 171 } 218 172 219 /** Evaluate type literal expression.220 *221 * @param prog Program222 * @param ctx Current CSI (context)223 * @param tliteral Type literal224 * @param res Place to store type result225 */226 173 static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx, 227 174 stree_tliteral_t *tliteral, tdata_item_t **res) … … 260 207 tdata_item_t *titem; 261 208 tdata_object_t *tobject; 262 stree_targ_t *targ;263 tdata_vref_t *tvref;264 stree_deleg_t *deleg;265 tdata_deleg_t *tdeleg;266 209 267 210 #ifdef DEBUG_RUN_TRACE 268 211 printf("Evaluating type name reference.\n"); 269 printf("'%s'\n", strtab_get_str(tnameref->name->sid)); 270 #endif 271 /* In interactive mode we are not in a class */ 272 if (ctx != NULL) { 273 /* Look for type argument */ 274 targ = stree_csi_find_targ(ctx, tnameref->name); 275 276 if (targ != NULL) { 277 /* Found type argument */ 278 #ifdef DEBUG_RUN_TRACE 279 printf("Found type argument '%s'.\n", 280 strtab_get_str(tnameref->name->sid)); 281 #endif 282 titem = tdata_item_new(tic_tvref); 283 tvref = tdata_vref_new(); 284 titem->u.tvref = tvref; 285 tvref->targ = targ; 286 287 *res = titem; 288 return; 289 } 290 } 291 292 /* Look for symbol */ 212 #endif 293 213 sym = symbol_lookup_in_csi(prog, ctx, tnameref->name); 294 214 if (sym == NULL) { … … 299 219 } 300 220 301 switch (sym->sc) { 302 case sc_csi: 303 /* Construct type item. */ 304 titem = tdata_item_new(tic_tobject); 305 tobject = tdata_object_new(); 306 titem->u.tobject = tobject; 307 308 tobject->static_ref = b_false; 309 tobject->csi = sym->u.csi; 310 list_init(&tobject->targs); /* XXX */ 311 break; 312 case sc_deleg: 313 /* Fetch stored delegate type. */ 314 deleg = symbol_to_deleg(sym); 315 assert(deleg != NULL); 316 if (deleg->titem == NULL) { 317 /* 318 * Prepare a partial delegate which will be completed 319 * later. 320 */ 321 titem = tdata_item_new(tic_tdeleg); 322 tdeleg = tdata_deleg_new(); 323 titem->u.tdeleg = tdeleg; 324 tdeleg->deleg = deleg; 325 tdeleg->tsig = NULL; 326 327 deleg->titem = titem; 328 } else { 329 titem = deleg->titem; 330 } 331 break; 332 case sc_fun: 333 case sc_var: 334 case sc_prop: 221 if (sym->sc != sc_csi) { 335 222 printf("Error: Symbol '"); 336 223 symbol_print_fqn(sym); 337 printf("' is not a type.\n"); 338 titem = tdata_item_new(tic_ignore); 339 break; 340 } 341 342 *res = titem; 343 } 344 345 /** Evaluate type application expression. 346 * 347 * In a type application expression type arguments are applied to a generic 348 * CSI. 349 * 350 * @param prog Program 351 * @param ctx Current CSI (context) 352 * @param tapply Type application expression 353 * @param res Place to store type result 354 */ 355 static void run_tapply(stree_program_t *prog, stree_csi_t *ctx, 356 stree_tapply_t *tapply, tdata_item_t **res) 357 { 358 tdata_item_t *base_ti; 359 tdata_item_t *arg_ti; 360 tdata_item_t *titem; 361 tdata_object_t *tobject; 362 363 list_node_t *arg_n; 364 stree_texpr_t *arg; 365 366 list_node_t *farg_n; 367 stree_targ_t *farg; 368 369 #ifdef DEBUG_RUN_TRACE 370 printf("Evaluating type apply operation.\n"); 371 #endif 224 printf("' is not a CSI.\n"); 225 *res = tdata_item_new(tic_ignore); 226 return; 227 } 228 372 229 /* Construct type item. */ 373 230 titem = tdata_item_new(tic_tobject); … … 375 232 titem->u.tobject = tobject; 376 233 234 tobject->static_ref = b_false; 235 tobject->csi = sym->u.csi; 236 237 *res = titem; 238 } 239 240 static void run_tapply(stree_program_t *prog, stree_csi_t *ctx, 241 stree_tapply_t *tapply, tdata_item_t **res) 242 { 243 tdata_item_t *base_ti; 244 tdata_item_t *arg_ti; 245 tdata_item_t *titem; 246 tdata_object_t *tobject; 247 248 list_node_t *arg_n; 249 stree_texpr_t *arg; 250 251 #ifdef DEBUG_RUN_TRACE 252 printf("Evaluating type apply operation.\n"); 253 #endif 254 /* Construct type item. */ 255 titem = tdata_item_new(tic_tobject); 256 tobject = tdata_object_new(); 257 titem->u.tobject = tobject; 258 377 259 /* Evaluate base (generic) type. */ 378 260 run_texpr(prog, ctx, tapply->gtype, &base_ti); … … 390 272 391 273 /* Evaluate type arguments. */ 392 farg_n = list_first(&tobject->csi->targ);393 274 arg_n = list_first(&tapply->targs); 394 while (farg_n != NULL && arg_n != NULL) { 395 farg = list_node_data(farg_n, stree_targ_t *); 275 while (arg_n != NULL) { 396 276 arg = list_node_data(arg_n, stree_texpr_t *); 397 398 277 run_texpr(prog, ctx, arg, &arg_ti); 399 278 … … 405 284 list_append(&tobject->targs, arg_ti); 406 285 407 farg_n = list_next(&tobject->csi->targ, farg_n);408 286 arg_n = list_next(&tapply->targs, arg_n); 409 287 } 410 288 411 if (farg_n != NULL || arg_n != NULL) { 412 printf("Error: Incorrect number of type arguments.\n"); 413 *res = tdata_item_new(tic_ignore); 414 return; 415 } 416 417 *res = titem; 418 } 289 *res = titem; 290 } -
uspace/app/sbi/src/stree.c
rf4f866c r80badbe 37 37 #include "stree.h" 38 38 39 /** Allocate new module.40 *41 * @return New module42 */43 39 stree_module_t *stree_module_new(void) 44 40 { … … 55 51 } 56 52 57 /** Allocate new module member.58 *59 * @param mc Module member class60 * @return New module member61 */62 53 stree_modm_t *stree_modm_new(modm_class_t mc) 63 54 { … … 74 65 } 75 66 76 /** Allocate new CSI.77 *78 * @param cc CSI class79 * @return New CSI80 */81 67 stree_csi_t *stree_csi_new(csi_class_t cc) 82 68 { … … 97 83 } 98 84 99 /** Allocate new CSI member.100 *101 * @param cc CSI member class102 * @return New CSI member103 */104 85 stree_csimbr_t *stree_csimbr_new(csimbr_class_t cc) 105 86 { … … 116 97 } 117 98 118 /** Allocate new member delegate.119 *120 * @return New member delegate121 */122 stree_deleg_t *stree_deleg_new(void)123 {124 stree_deleg_t *deleg;125 126 deleg = calloc(1, sizeof(stree_deleg_t));127 if (deleg == NULL) {128 printf("Memory allocation failed.\n");129 exit(1);130 }131 132 return deleg;133 }134 135 /** Allocate new member function.136 *137 * @return New member function138 */139 99 stree_fun_t *stree_fun_new(void) 140 100 { … … 150 110 } 151 111 152 /** Allocate new member variable.153 *154 * @return New member variable155 */156 112 stree_var_t *stree_var_new(void) 157 113 { … … 167 123 } 168 124 169 /** Allocate new property.170 *171 * @return New property172 */173 125 stree_prop_t *stree_prop_new(void) 174 126 { … … 184 136 } 185 137 186 /** Allocate new type argument.187 *188 * @return New type argument189 */190 stree_targ_t *stree_targ_new(void)191 {192 stree_targ_t *targ;193 194 targ = calloc(1, sizeof(stree_targ_t));195 if (targ == NULL) {196 printf("Memory allocation failed.\n");197 exit(1);198 }199 200 return targ;201 }202 203 /** Allocate new symbol attribute.204 *205 * @param sac Symbol attribute class206 * @return New symbol attribute207 */208 138 stree_symbol_attr_t *stree_symbol_attr_new(symbol_attr_class_t sac) 209 139 { … … 220 150 } 221 151 222 /** Allocate new procedure.223 *224 * @return New procedure225 */226 152 stree_proc_t *stree_proc_new(void) 227 153 { … … 237 163 } 238 164 239 /** Allocate new procedure argument.240 *241 * @return New procedure argument242 */243 165 stree_proc_arg_t *stree_proc_arg_new(void) 244 166 { … … 254 176 } 255 177 256 /** Allocate new function signature.257 *258 * @return New procedure argument259 */260 stree_fun_sig_t *stree_fun_sig_new(void)261 {262 stree_fun_sig_t *fun_sig;263 264 fun_sig = calloc(1, sizeof(stree_fun_sig_t));265 if (fun_sig == NULL) {266 printf("Memory allocation failed.\n");267 exit(1);268 }269 270 return fun_sig;271 }272 273 /** Allocate new procedure argument attribute.274 *275 * @param Argument attribute class276 * @return New procedure argument attribute277 */278 178 stree_arg_attr_t *stree_arg_attr_new(arg_attr_class_t aac) 279 179 { … … 290 190 } 291 191 292 /** Allocate new statement.293 *294 * @param sc Statement class295 * @return New statement296 */297 192 stree_stat_t *stree_stat_new(stat_class_t sc) 298 193 { … … 309 204 } 310 205 311 /** Allocate new local variable declaration.312 *313 * @return New local variable declaration314 */315 206 stree_vdecl_t *stree_vdecl_new(void) 316 207 { … … 326 217 } 327 218 328 /** Allocate new @c if statement.329 *330 * @return New @c if statement331 */332 219 stree_if_t *stree_if_new(void) 333 220 { … … 343 230 } 344 231 345 /** Allocate new @c while statement.346 *347 * @return New @c while statement348 */349 232 stree_while_t *stree_while_new(void) 350 233 { … … 360 243 } 361 244 362 /** Allocate new @c for statement.363 *364 * @return New @c for statement365 */366 245 stree_for_t *stree_for_new(void) 367 246 { … … 377 256 } 378 257 379 /** Allocate new @c raise statement.380 *381 * @return New @c raise statement382 */383 258 stree_raise_t *stree_raise_new(void) 384 259 { … … 394 269 } 395 270 396 /** Allocate new @c return statement.397 *398 * @return New @c return statement399 */400 271 stree_return_t *stree_return_new(void) 401 272 { … … 411 282 } 412 283 413 /** Allocate new with-except-finally statement.414 *415 * @return New with-except-finally statement.416 */417 284 stree_wef_t *stree_wef_new(void) 418 285 { … … 428 295 } 429 296 430 /** Allocate new expression statement.431 *432 * @return New expression statement433 */434 297 stree_exps_t *stree_exps_new(void) 435 298 { … … 445 308 } 446 309 447 /** Allocate new @c except clause.448 *449 * @return New @c except clause450 */451 310 stree_except_t *stree_except_new(void) 452 311 { … … 462 321 } 463 322 464 /** Allocate new statement block.465 *466 * @return New statement block467 */468 323 stree_block_t *stree_block_new(void) 469 324 { … … 479 334 } 480 335 481 /** Allocate new expression.482 *483 * @param ec Expression class484 * @return New expression485 */486 336 stree_expr_t *stree_expr_new(expr_class_t ec) 487 337 { … … 498 348 } 499 349 500 /** Allocate new assignment.501 *502 * @param ac Assignment class503 * @return New assignment504 */505 350 stree_assign_t *stree_assign_new(assign_class_t ac) 506 351 { … … 517 362 } 518 363 519 /** Allocate new binary operation.520 *521 * @return New binary operation522 */523 364 stree_binop_t *stree_binop_new(binop_class_t bc) 524 365 { … … 535 376 } 536 377 537 /** Allocate new unary operation.538 *539 * @param uc Unary operation class540 * @return New unary operation541 */542 378 stree_unop_t *stree_unop_new(unop_class_t uc) 543 379 { … … 554 390 } 555 391 556 /** Allocate new @c new operation.557 *558 * @return New @c new operation559 */560 392 stree_new_t *stree_new_new(void) 561 393 { … … 571 403 } 572 404 573 /** Allocate new .574 *575 * @return New576 */577 405 stree_access_t *stree_access_new(void) 578 406 { … … 588 416 } 589 417 590 /** Allocate new function call operation.591 *592 * @return New function call operation593 */594 418 stree_call_t *stree_call_new(void) 595 419 { … … 605 429 } 606 430 607 /** Allocate new indexing operation.608 *609 * @return New indexing operation610 */611 431 stree_index_t *stree_index_new(void) 612 432 { … … 622 442 } 623 443 624 /** Allocate new as conversion.625 *626 * @return New as conversion627 */628 444 stree_as_t *stree_as_new(void) 629 445 { … … 639 455 } 640 456 641 /** Allocate new boxing operation.642 *643 * @return New boxing operation644 */645 stree_box_t *stree_box_new(void)646 {647 stree_box_t *box_expr;648 649 box_expr = calloc(1, sizeof(stree_box_t));650 if (box_expr == NULL) {651 printf("Memory allocation failed.\n");652 exit(1);653 }654 655 return box_expr;656 }657 658 /** Allocate new name reference operation.659 *660 * @return New name reference operation661 */662 457 stree_nameref_t *stree_nameref_new(void) 663 458 { … … 673 468 } 674 469 675 /** Allocate new identifier.676 *677 * @return New identifier678 */679 470 stree_ident_t *stree_ident_new(void) 680 471 { … … 690 481 } 691 482 692 /** Allocate new literal.693 *694 * @param ltc Literal class695 * @return New literal696 */697 483 stree_literal_t *stree_literal_new(literal_class_t ltc) 698 484 { … … 709 495 } 710 496 711 /** Allocate new @c self reference.712 *713 * @return New @c self reference714 */715 497 stree_self_ref_t *stree_self_ref_new(void) 716 498 { … … 726 508 } 727 509 728 /** Allocate new type expression729 *730 * @return New type expression731 */732 510 stree_texpr_t *stree_texpr_new(texpr_class_t tc) 733 511 { … … 744 522 } 745 523 746 /** Allocate new type access operation.747 *748 * @return New type access operation749 */750 524 stree_taccess_t *stree_taccess_new(void) 751 525 { … … 761 535 } 762 536 763 /** Allocate new type application operation.764 *765 * @return New type application operation766 */767 537 stree_tapply_t *stree_tapply_new(void) 768 538 { … … 778 548 } 779 549 780 /** Allocate new type indexing operation.781 *782 * @return New type indexing operation783 */784 550 stree_tindex_t *stree_tindex_new(void) 785 551 { … … 795 561 } 796 562 797 /** Allocate new type literal.798 *799 * @return New type literal800 */801 563 stree_tliteral_t *stree_tliteral_new(tliteral_class_t tlc) 802 564 { … … 813 575 } 814 576 815 /** Allocate new type name reference.816 *817 * @return New type name reference818 */819 577 stree_tnameref_t *stree_tnameref_new(void) 820 578 { … … 830 588 } 831 589 832 /** Allocate new symbol.833 *834 * @return New symbol835 */836 590 stree_symbol_t *stree_symbol_new(symbol_class_t sc) 837 591 { … … 848 602 } 849 603 850 /** Allocate new program.851 *852 * @return New program853 */854 604 stree_program_t *stree_program_new(void) 855 605 { … … 865 615 } 866 616 867 /** Determine if @a symbol has attribute of class @a sac. 868 * 869 * @param symbol Symbol 870 * @param sac Symbol attribute class 871 * @return @c b_true if yes, @c b_false if no. 872 */ 617 /** Determine if @a symbol has attribute of class @a sac. */ 873 618 bool_t stree_symbol_has_attr(stree_symbol_t *symbol, symbol_attr_class_t sac) 874 619 { … … 888 633 } 889 634 890 /** Determine if argument @a arg has attribute of class @a aac. 891 * 892 * @param arg Formal procedure argument 893 * @param aac Argument attribute class 894 * @return @c b_true if yes, @c b_false if no. 895 */ 635 /** Determine if argument @a arg has attribute of class @a aac. */ 896 636 bool_t stree_arg_has_attr(stree_proc_arg_t *arg, arg_attr_class_t aac) 897 637 { … … 912 652 913 653 /** Determine wheter @a a is derived (transitively) from @a b. 914 *915 * XXX This does not work right with generics.916 654 * 917 655 * @param a Derived CSI. … … 935 673 return b_false; 936 674 } 937 938 /** Search for CSI type argument of the given name.939 *940 * @param csi CSI to look in.941 * @param ident Identifier of the type argument.942 * @return Type argument definition or @c NULL if not found.943 */944 stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident)945 {946 list_node_t *targ_n;947 stree_targ_t *targ;948 949 targ_n = list_first(&csi->targ);950 while (targ_n != NULL) {951 targ = list_node_data(targ_n, stree_targ_t *);952 if (targ->name->sid == ident->sid)953 return targ;954 955 targ_n = list_next(&csi->targ, targ_n);956 }957 958 /* No match */959 return NULL;960 } -
uspace/app/sbi/src/stree.h
rf4f866c r80badbe 36 36 stree_csi_t *stree_csi_new(csi_class_t cc); 37 37 stree_csimbr_t *stree_csimbr_new(csimbr_class_t cc); 38 stree_deleg_t *stree_deleg_new(void);39 38 stree_fun_t *stree_fun_new(void); 40 39 stree_var_t *stree_var_new(void); 41 40 stree_prop_t *stree_prop_new(void); 42 stree_targ_t *stree_targ_new(void);43 41 44 42 stree_symbol_attr_t *stree_symbol_attr_new(symbol_attr_class_t sac); … … 46 44 stree_proc_t *stree_proc_new(void); 47 45 stree_proc_arg_t *stree_proc_arg_new(void); 48 stree_fun_sig_t *stree_fun_sig_new(void);49 46 stree_arg_attr_t *stree_arg_attr_new(arg_attr_class_t aac); 50 47 … … 71 68 stree_index_t *stree_index_new(void); 72 69 stree_as_t *stree_as_new(void); 73 stree_box_t *stree_box_new(void);74 70 stree_nameref_t *stree_nameref_new(void); 75 71 … … 91 87 bool_t stree_arg_has_attr(stree_proc_arg_t *arg, arg_attr_class_t aac); 92 88 bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b); 93 stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident);94 89 95 90 #endif -
uspace/app/sbi/src/stree_t.h
rf4f866c r80badbe 186 186 } stree_as_t; 187 187 188 /** Boxing of primitive type (pseudo)189 *190 * This pseudo-node is used internally to box a value of primitive type.191 * It is implicitly inserted by stype_convert(). It does not correspond192 * to a an explicit program construct.193 */194 typedef struct {195 /* Primitive type expression */196 struct stree_expr *arg;197 } stree_box_t;198 199 188 /** Arithmetic expression class */ 200 189 typedef enum { … … 209 198 ec_assign, 210 199 ec_index, 211 ec_as, 212 ec_box 200 ec_as 213 201 } expr_class_t; 214 202 … … 231 219 stree_assign_t *assign; 232 220 stree_as_t *as_op; 233 stree_box_t *box;234 221 } u; 235 222 } stree_expr_t; … … 428 415 } stree_proc_arg_t; 429 416 430 /** Function signature.431 *432 * Foormal parameters and return type. This is common to function and delegate433 * delcarations.434 */435 typedef struct {436 /** Formal parameters */437 list_t args; /* of stree_proc_arg_t */438 439 /** Variadic argument or @c NULL if none. */440 stree_proc_arg_t *varg;441 442 /** Return type */443 stree_texpr_t *rtype;444 } stree_fun_sig_t;445 446 417 /** Procedure 447 418 * … … 461 432 } stree_proc_t; 462 433 463 /** Delegate declaration */464 typedef struct stree_deleg {465 /** Delegate name */466 stree_ident_t *name;467 468 /** Symbol */469 struct stree_symbol *symbol;470 471 /** Signature (arguments and return type) */472 stree_fun_sig_t *sig;473 474 /** Type item describing the delegate */475 struct tdata_item *titem;476 } stree_deleg_t;477 478 434 /** Member function declaration */ 479 435 typedef struct stree_fun { … … 484 440 struct stree_symbol *symbol; 485 441 486 /** Signature (arguments and return type) */ 487 stree_fun_sig_t *sig; 442 /** Formal parameters */ 443 list_t args; /* of stree_proc_arg_t */ 444 445 /** Variadic argument or @c NULL if none. */ 446 stree_proc_arg_t *varg; 447 448 /** Return type */ 449 stree_texpr_t *rtype; 488 450 489 451 /** Function implementation */ 490 452 stree_proc_t *proc; 491 492 /** Type item describing the function */493 struct tdata_item *titem;494 453 } stree_fun_t; 495 454 … … 527 486 typedef enum { 528 487 csimbr_csi, 529 csimbr_deleg,530 488 csimbr_fun, 531 489 csimbr_var, … … 539 497 union { 540 498 struct stree_csi *csi; 541 stree_deleg_t *deleg;542 499 stree_fun_t *fun; 543 500 stree_var_t *var; … … 552 509 } csi_class_t; 553 510 554 /** CSI formal type argument */555 typedef struct stree_targ {556 stree_ident_t *name;557 struct stree_symbol *symbol;558 } stree_targ_t;559 560 511 /** Class, struct or interface declaration */ 561 512 typedef struct stree_csi { … … 566 517 stree_ident_t *name; 567 518 568 /** List of type argument s */569 list_t targ ; /* of stree_targ_t */519 /** List of type argument names */ 520 list_t targ_names; /* of stree_ident_t */ 570 521 571 522 /** Symbol for this CSI */ … … 615 566 } stree_symbol_attr_t; 616 567 617 typedef enum { 618 /** CSI (class, struct or interface) */ 568 569 typedef enum { 619 570 sc_csi, 620 /** Member delegate */621 sc_deleg,622 /** Member function */623 571 sc_fun, 624 /** Member variable */625 572 sc_var, 626 /** Member property */627 573 sc_prop 628 574 } symbol_class_t; … … 638 584 union { 639 585 struct stree_csi *csi; 640 stree_deleg_t *deleg;641 586 stree_fun_t *fun; 642 587 stree_var_t *var; -
uspace/app/sbi/src/strtab.c
rf4f866c r80badbe 30 30 * 31 31 * Converts strings to more compact SID (string ID, integer) and back. 32 * (The point is that this deduplicates the strings. Using SID might actually 33 * not be such a big win.) 34 * 35 * The string table is a singleton as there will never be a need for 32 * The string table is not an object as there will never be a need for 36 33 * more than one. 37 *38 * Current implementation uses a linked list and thus it is slow.39 34 */ 40 35 … … 48 43 static list_t str_list; 49 44 50 /** Initialize string table. */51 45 void strtab_init(void) 52 46 { … … 54 48 } 55 49 56 /** Get SID of a string.57 *58 * Return SID of @a str. If @a str is not in the string table yet,59 * it is added and thus a new SID is assigned.60 *61 * @param str String62 * @return SID of @a str.63 */64 50 sid_t strtab_get_sid(const char *str) 65 51 { … … 84 70 } 85 71 86 /** Get string with the given SID.87 *88 * Returns string that has SID @a sid. If no such string exists, this89 * causes a fatal error in the interpreter.90 *91 * @param sid SID of the string.92 * @return Pointer to the string.93 */94 72 char *strtab_get_str(sid_t sid) 95 73 { -
uspace/app/sbi/src/stype.c
rf4f866c r80badbe 30 30 * @file Implements a walk on the program that computes and checks static 31 31 * types. 'Types' the program. 32 *33 * If a type error is encountered, stype_note_error() is called to set34 * the typing error flag.35 32 */ 36 33 … … 56 53 static void stype_prop(stype_t *stype, stree_prop_t *prop); 57 54 58 static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi,59 stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig);60 static void stype_fun_body(stype_t *stype, stree_fun_t *fun);61 55 static void stype_block(stype_t *stype, stree_block_t *block); 62 56 … … 70 64 static void stype_wef(stype_t *stype, stree_wef_t *wef_s); 71 65 72 static stree_expr_t *stype_convert_tprimitive(stype_t *stype, 73 stree_expr_t *expr, tdata_item_t *dest); 74 static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype, 75 stree_expr_t *expr, tdata_item_t *dest); 76 static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr, 77 tdata_item_t *dest); 78 static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr, 79 tdata_item_t *dest); 80 static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr, 81 tdata_item_t *dest); 82 static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype, 83 stree_expr_t *expr, tdata_item_t *dest); 84 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr, 85 tdata_item_t *dest); 86 static void stype_convert_failure(stype_t *stype, tdata_item_t *src, 87 tdata_item_t *dest); 88 89 static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig, 90 tdata_fun_sig_t *sdig); 91 92 /** Type module. 93 * 94 * If the module contains a type error, @a stype->error will be set 95 * when this function returns. 96 * 97 * @param stype Static typing object 98 * @param module Module to type 99 */ 66 /** Type module */ 100 67 void stype_module(stype_t *stype, stree_module_t *module) 101 68 { … … 120 87 } 121 88 122 /** Type CSI. 123 * 124 * @param stype Static typing object 125 * @param csi CSI to type 126 */ 89 /** Type CSI */ 127 90 static void stype_csi(stype_t *stype, stree_csi_t *csi) 128 91 { … … 145 108 switch (csimbr->cc) { 146 109 case csimbr_csi: stype_csi(stype, csimbr->u.csi); break; 147 case csimbr_deleg: stype_deleg(stype, csimbr->u.deleg); break;148 110 case csimbr_fun: stype_fun(stype, csimbr->u.fun); break; 149 111 case csimbr_var: stype_var(stype, csimbr->u.var); break; … … 157 119 } 158 120 159 /** Type delegate. 160 * 161 * @param stype Static typing object. 162 * @param deleg Delegate to type. 163 */ 164 void stype_deleg(stype_t *stype, stree_deleg_t *deleg) 165 { 166 stree_symbol_t *deleg_sym; 167 tdata_item_t *deleg_ti; 168 tdata_deleg_t *tdeleg; 169 tdata_fun_sig_t *tsig; 170 171 #ifdef DEBUG_TYPE_TRACE 172 printf("Type delegate '"); 173 symbol_print_fqn(deleg_to_symbol(deleg)); 174 printf("'.\n"); 175 #endif 176 if (deleg->titem == NULL) { 177 deleg_ti = tdata_item_new(tic_tdeleg); 178 deleg->titem = deleg_ti; 179 tdeleg = tdata_deleg_new(); 180 deleg_ti->u.tdeleg = tdeleg; 181 } else { 182 deleg_ti = deleg->titem; 183 assert(deleg_ti->u.tdeleg != NULL); 184 tdeleg = deleg_ti->u.tdeleg; 185 } 186 187 if (tdeleg->tsig != NULL) 188 return; /* Delegate has already been typed. */ 189 190 deleg_sym = deleg_to_symbol(deleg); 191 192 /* Type function signature. Store result in deleg->titem. */ 193 stype_fun_sig(stype, deleg_sym->outer_csi, deleg->sig, &tsig); 194 195 tdeleg->deleg = deleg; 196 tdeleg->tsig = tsig; 197 } 198 199 /** Type function. 200 * 201 * We split typing of function header and body because at the point we 202 * are typing the body of some function we may encounter function calls. 203 * To type a function call we first need to type the header of the function 204 * being called. 205 * 206 * @param stype Static typing object. 207 * @param fun Function to type. 208 */ 121 /** Type function */ 209 122 static void stype_fun(stype_t *stype, stree_fun_t *fun) 210 123 { 124 list_node_t *arg_n; 125 stree_proc_arg_t *arg; 126 stree_symbol_t *fun_sym; 127 tdata_item_t *titem; 128 211 129 #ifdef DEBUG_TYPE_TRACE 212 130 printf("Type function '"); … … 214 132 printf("'.\n"); 215 133 #endif 216 if (fun->titem == NULL)217 stype_fun_header(stype, fun);218 219 stype_fun_body(stype, fun);220 }221 222 /** Type function header.223 *224 * Types the header of @a fun (but not its body).225 *226 * @param stype Static typing object227 * @param fun Funtction228 */229 void stype_fun_header(stype_t *stype, stree_fun_t *fun)230 {231 stree_symbol_t *fun_sym;232 tdata_item_t *fun_ti;233 tdata_fun_t *tfun;234 tdata_fun_sig_t *tsig;235 236 #ifdef DEBUG_TYPE_TRACE237 printf("Type function '");238 symbol_print_fqn(fun_to_symbol(fun));239 printf("' header.\n");240 #endif241 if (fun->titem != NULL)242 return; /* Function header has already been typed. */243 244 134 fun_sym = fun_to_symbol(fun); 245 246 /* Type function signature. */247 stype_fun_sig(stype, fun_sym->outer_csi, fun->sig, &tsig);248 249 fun_ti = tdata_item_new(tic_tfun);250 tfun = tdata_fun_new();251 fun_ti->u.tfun = tfun;252 tfun->tsig = tsig;253 254 fun->titem = fun_ti;255 }256 257 /** Type function signature.258 *259 * Types the function signature @a sig.260 *261 * @param stype Static typing object262 * @param outer_csi CSI within which the signature is defined.263 * @param sig Function signature264 */265 static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi,266 stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig)267 {268 list_node_t *arg_n;269 stree_proc_arg_t *arg;270 tdata_item_t *titem;271 tdata_fun_sig_t *tsig;272 273 #ifdef DEBUG_TYPE_TRACE274 printf("Type function signature.\n");275 #endif276 tsig = tdata_fun_sig_new();277 278 list_init(&tsig->arg_ti);279 135 280 136 /* 281 137 * Type formal arguments. 138 * XXX Save the results. 282 139 */ 283 arg_n = list_first(& sig->args);140 arg_n = list_first(&fun->args); 284 141 while (arg_n != NULL) { 285 142 arg = list_node_data(arg_n, stree_proc_arg_t *); … … 287 144 /* XXX Because of overloaded builtin WriteLine. */ 288 145 if (arg->type == NULL) { 289 list_append(&tsig->arg_ti, NULL); 290 arg_n = list_next(&sig->args, arg_n); 146 arg_n = list_next(&fun->args, arg_n); 291 147 continue; 292 148 } 293 149 294 run_texpr(stype->program, outer_csi, arg->type, &titem);295 list_append(&tsig->arg_ti,titem);296 297 arg_n = list_next(& sig->args, arg_n);150 run_texpr(stype->program, fun_sym->outer_csi, arg->type, 151 &titem); 152 153 arg_n = list_next(&fun->args, arg_n); 298 154 } 299 155 300 156 /* Variadic argument */ 301 if ( sig->varg != NULL) {157 if (fun->varg != NULL) { 302 158 /* Check type and verify it is an array. */ 303 run_texpr(stype->program, outer_csi, sig->varg->type, &titem);304 tsig->varg_ti = titem;159 run_texpr(stype->program, fun_sym->outer_csi, fun->varg->type, 160 &titem); 305 161 306 162 if (titem->tic != tic_tarray && titem->tic != tic_ignore) { … … 310 166 } 311 167 312 /* Return type */ 313 if (sig->rtype != NULL) { 314 run_texpr(stype->program, outer_csi, sig->rtype, &titem); 315 tsig->rtype = titem; 316 } 317 318 *rtsig = tsig; 319 } 320 321 /** Type function body. 322 * 323 * Types the body of function @a fun (if it has one). 324 * 325 * @param stype Static typing object 326 * @param fun Funtction 327 */ 328 static void stype_fun_body(stype_t *stype, stree_fun_t *fun) 329 { 330 #ifdef DEBUG_TYPE_TRACE 331 printf("Type function '"); 332 symbol_print_fqn(fun_to_symbol(fun)); 333 printf("' body.\n"); 334 #endif 335 assert(stype->proc_vr == NULL); 168 /* 169 * Type function body. 170 */ 336 171 337 172 /* Builtin functions do not have a body. */ … … 349 184 } 350 185 351 /** Type member variable. 352 * 353 * @param stype Static typing object 354 * @param var Member variable 355 */ 186 /** Type member variable */ 356 187 static void stype_var(stype_t *stype, stree_var_t *var) 357 188 { … … 370 201 } 371 202 372 /** Type property. 373 * 374 * @param stype Static typing object 375 * @param prop Property 376 */ 203 /** Type property */ 377 204 static void stype_prop(stype_t *stype, stree_prop_t *prop) 378 205 { … … 399 226 } 400 227 401 /** Type statement block. 402 * 403 * @param stype Static typing object 404 * @param block Statement block 405 */ 228 /** Type statement block */ 406 229 static void stype_block(stype_t *stype, stree_block_t *block) 407 230 { … … 442 265 * for nested statemens). This is used in interactive mode. 443 266 * 444 * @param stype Static typ ing object445 * @param stat Statement to type 446 * @param want_value @c b_true to allow ignoring expression value 267 * @param stype Static typer object. 268 * @param stat Statement to type. 269 * @param want_value @c b_true to allow ignoring expression value. 447 270 */ 448 271 void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value) … … 463 286 } 464 287 465 /** Type local variable declaration statement. 466 * 467 * @param stype Static typing object 468 * @param vdecl_s Variable delcaration statement 469 */ 288 /** Type local variable declaration */ 470 289 static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s) 471 290 { … … 498 317 } 499 318 500 /** Type @c if statement. 501 * 502 * @param stype Static typing object 503 * @param if_s @c if statement 504 */ 319 /** Type @c if statement */ 505 320 static void stype_if(stype_t *stype, stree_if_t *if_s) 506 321 { … … 525 340 } 526 341 527 /** Type @c while statement 528 * 529 * @param stype Static typing object 530 * @param while_s @c while statement 531 */ 342 /** Type @c while statement */ 532 343 static void stype_while(stype_t *stype, stree_while_t *while_s) 533 344 { … … 549 360 } 550 361 551 /** Type @c for statement. 552 * 553 * @param stype Static typing object 554 * @param for_s @c for statement 555 */ 362 /** Type @c for statement */ 556 363 static void stype_for(stype_t *stype, stree_for_t *for_s) 557 364 { … … 562 369 } 563 370 564 /** Type @c raise statement. 565 * 566 * @param stype Static typing object 567 * @param raise_s @c raise statement 568 */ 371 /** Type @c raise statement */ 569 372 static void stype_raise(stype_t *stype, stree_raise_t *raise_s) 570 373 { … … 599 402 600 403 /* XXX Memoize to avoid recomputing. */ 601 run_texpr(stype->program, outer_sym->outer_csi, 602 fun->sig->rtype,&dtype);404 run_texpr(stype->program, outer_sym->outer_csi, fun->rtype, 405 &dtype); 603 406 break; 604 407 case sc_prop: … … 627 430 } 628 431 629 /** Type expression statement. 630 * 631 * @param stype Static typing object 632 * @param exp_s Expression statement 633 */ 432 /** Type expression statement */ 634 433 static void stype_exps(stype_t *stype, stree_exps_t *exp_s, bool_t want_value) 635 434 { … … 643 442 } 644 443 645 /** Type with-except-finally statement. 646 * 647 * @param stype Static typing object 648 * @param wef_s With-except-finally statement 649 */ 444 /** Type With-Except-Finally statement */ 650 445 static void stype_wef(stype_t *stype, stree_wef_t *wef_s) 651 446 { … … 687 482 * Note: No conversion that would require modifying @a expr is implemented 688 483 * yet. 689 *690 * @param stype Static typing object691 * @param expr Expression692 * @param dest Destination type693 484 */ 694 485 stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr, … … 697 488 tdata_item_t *src; 698 489 490 (void) stype; 699 491 src = expr->titem; 700 701 #ifdef DEBUG_TYPE_TRACE702 printf("Convert '");703 tdata_item_print(src);704 printf("' to '");705 tdata_item_print(dest);706 printf("'.\n");707 #endif708 492 709 493 if (dest == NULL) { … … 730 514 } 731 515 732 if (src->tic == tic_tprimitive && dest->tic == tic_tobject) { 733 return stype_convert_tprim_tobj(stype, expr, dest); 734 } 735 736 if (src->tic == tic_tfun && dest->tic == tic_tdeleg) { 737 return stype_convert_tfun_tdeleg(stype, expr, dest); 738 } 739 740 if (src->tic != dest->tic) { 741 stype_convert_failure(stype, src, dest); 742 return expr; 743 } 516 if (src->tic != dest->tic) 517 goto failure; 744 518 745 519 switch (src->tic) { 746 520 case tic_tprimitive: 747 expr = stype_convert_tprimitive(stype, expr, dest); 521 /* Check if both have the same tprimitive class. */ 522 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc) 523 goto failure; 748 524 break; 749 525 case tic_tobject: 750 expr = stype_convert_tobject(stype, expr, dest); 526 /* Check if @c src is derived from @c dest. */ 527 if (stree_is_csi_derived_from_csi(src->u.tobject->csi, 528 dest->u.tobject->csi) != b_true) { 529 goto failure; 530 } 751 531 break; 752 532 case tic_tarray: 753 expr = stype_convert_tarray(stype, expr, dest); 754 break; 755 case tic_tdeleg: 756 expr = stype_convert_tdeleg(stype, expr, dest); 533 /* Compare rank and base type. */ 534 if (src->u.tarray->rank != dest->u.tarray->rank) 535 goto failure; 536 537 /* XXX Should we convert each element? */ 538 if (tdata_item_equal(src->u.tarray->base_ti, 539 dest->u.tarray->base_ti) != b_true) 540 goto failure; 757 541 break; 758 542 case tic_tfun: 759 assert(b_false); 760 case tic_tvref: 761 expr = stype_convert_tvref(stype, expr, dest); 543 printf("Error: Unimplemented: Converting '"); 544 tdata_item_print(src); 545 printf("' to '"); 546 tdata_item_print(dest); 547 printf("'.\n"); 548 stype_note_error(stype); 762 549 break; 763 550 case tic_ignore: … … 766 553 767 554 return expr; 768 } 769 770 /** Convert expression of primitive type to primitive type. 771 * 772 * @param stype Static typing object 773 * @param expr Expression 774 * @param dest Destination type 775 */ 776 static stree_expr_t *stype_convert_tprimitive(stype_t *stype, 777 stree_expr_t *expr, tdata_item_t *dest) 778 { 779 tdata_item_t *src; 780 781 #ifdef DEBUG_TYPE_TRACE 782 printf("Convert primitive type.\n"); 783 #endif 784 src = expr->titem; 785 assert(src->tic == tic_tprimitive); 786 assert(dest->tic == tic_tprimitive); 787 788 /* Check if both have the same tprimitive class. */ 789 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc) 790 stype_convert_failure(stype, src, dest); 791 792 return expr; 793 } 794 795 /** Convert expression of primitive type to object type. 796 * 797 * This function implements autoboxing. It modified the code. 798 * 799 * @param stype Static typing object 800 * @param expr Expression 801 * @param dest Destination type 802 */ 803 static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype, 804 stree_expr_t *expr, tdata_item_t *dest) 805 { 806 tdata_item_t *src; 807 builtin_t *bi; 808 stree_symbol_t *csi_sym; 809 stree_symbol_t *bp_sym; 810 stree_box_t *box; 811 stree_expr_t *bexpr; 812 813 #ifdef DEBUG_TYPE_TRACE 814 printf("Convert primitive type to object.\n"); 815 #endif 816 src = expr->titem; 817 assert(src->tic == tic_tprimitive); 818 assert(dest->tic == tic_tobject); 819 820 bi = stype->program->builtin; 821 csi_sym = csi_to_symbol(dest->u.tobject->csi); 822 823 switch (src->u.tprimitive->tpc) { 824 case tpc_bool: bp_sym = bi->boxed_bool; break; 825 case tpc_char: bp_sym = bi->boxed_char; break; 826 case tpc_int: bp_sym = bi->boxed_int; break; 827 case tpc_nil: assert(b_false); 828 case tpc_string: bp_sym = bi->boxed_string; break; 829 case tpc_resource: 830 stype_convert_failure(stype, src, dest); 831 return expr; 832 } 833 834 /* Target type must be boxed @a src or Object */ 835 if (csi_sym != bp_sym && csi_sym != bi->gf_class) 836 stype_convert_failure(stype, src, dest); 837 838 /* Patch the code to box the primitive value */ 839 box = stree_box_new(); 840 box->arg = expr; 841 bexpr = stree_expr_new(ec_box); 842 bexpr->u.box = box; 843 844 /* No action needed to optionally convert boxed type to Object */ 845 846 return bexpr; 847 } 848 849 /** Convert expression of object type to object type. 850 * 851 * @param stype Static typing object 852 * @param expr Expression 853 * @param dest Destination type 854 */ 855 static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr, 856 tdata_item_t *dest) 857 { 858 tdata_item_t *src; 859 tdata_item_t *cur; 860 stree_csi_t *cur_csi; 861 tdata_tvv_t *tvv; 862 tdata_item_t *b_ti, *bs_ti; 863 864 #ifdef DEBUG_TYPE_TRACE 865 printf("Convert object type.\n"); 866 #endif 867 list_node_t *ca_n, *da_n; 868 tdata_item_t *carg, *darg; 869 870 src = expr->titem; 871 assert(src->tic == tic_tobject); 872 assert(dest->tic == tic_tobject); 873 874 cur = src; 875 876 while (cur->u.tobject->csi != dest->u.tobject->csi) { 877 878 cur_csi = cur->u.tobject->csi; 879 stype_titem_to_tvv(stype, cur, &tvv); 880 881 if (cur_csi->base_csi_ref != NULL) { 882 run_texpr(stype->program, cur_csi, cur_csi->base_csi_ref, &b_ti); 883 if (b_ti->tic == tic_ignore) { 884 /* An error occured. */ 885 stype_note_error(stype); 886 return expr; 887 } 888 889 tdata_item_subst(b_ti, tvv, &bs_ti); 890 cur = bs_ti; 891 assert(cur->tic == tic_tobject); 892 893 } else if (cur_csi->base_csi != NULL) { 894 /* No explicit reference. Use grandfather class. */ 895 cur = tdata_item_new(tic_tobject); 896 cur->u.tobject = tdata_object_new(); 897 cur->u.tobject->csi = cur_csi->base_csi; 898 cur->u.tobject->static_ref = b_false; 899 900 list_init(&cur->u.tobject->targs); 901 } else { 902 /* No match */ 903 stype_convert_failure(stype, src, dest); 904 return expr; 905 } 906 } 907 908 /* Verify that type arguments match */ 909 ca_n = list_first(&cur->u.tobject->targs); 910 da_n = list_first(&dest->u.tobject->targs); 911 912 while (ca_n != NULL && da_n != NULL) { 913 carg = list_node_data(ca_n, tdata_item_t *); 914 darg = list_node_data(da_n, tdata_item_t *); 915 916 if (tdata_item_equal(carg, darg) != b_true) { 917 /* Diferent argument type */ 918 stype_convert_failure(stype, src, dest); 919 printf("Different argument type '"); 920 tdata_item_print(carg); 921 printf("' vs. '"); 922 tdata_item_print(darg); 923 printf("'.\n"); 924 return expr; 925 } 926 927 ca_n = list_next(&cur->u.tobject->targs, ca_n); 928 da_n = list_next(&dest->u.tobject->targs, da_n); 929 } 930 931 if (ca_n != NULL || da_n != NULL) { 932 /* Diferent number of arguments */ 933 stype_convert_failure(stype, src, dest); 934 printf("Different number of arguments.\n"); 935 return expr; 936 } 937 938 return expr; 939 } 940 941 /** Convert expression of array type to array type. 942 * 943 * @param stype Static typing object 944 * @param expr Expression 945 * @param dest Destination type 946 */ 947 static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr, 948 tdata_item_t *dest) 949 { 950 tdata_item_t *src; 951 952 #ifdef DEBUG_TYPE_TRACE 953 printf("Convert array type.\n"); 954 #endif 955 src = expr->titem; 956 assert(src->tic == tic_tarray); 957 assert(dest->tic == tic_tarray); 958 959 /* Compare rank and base type. */ 960 if (src->u.tarray->rank != dest->u.tarray->rank) { 961 stype_convert_failure(stype, src, dest); 962 return expr; 963 } 964 965 /* XXX Should we convert each element? */ 966 if (tdata_item_equal(src->u.tarray->base_ti, 967 dest->u.tarray->base_ti) != b_true) { 968 stype_convert_failure(stype, src, dest); 969 } 970 971 return expr; 972 } 973 974 /** Convert expression of delegate type to delegate type. 975 * 976 * @param stype Static typing object 977 * @param expr Expression 978 * @param dest Destination type 979 */ 980 static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr, 981 tdata_item_t *dest) 982 { 983 tdata_item_t *src; 984 tdata_deleg_t *sdeleg, *ddeleg; 985 986 #ifdef DEBUG_TYPE_TRACE 987 printf("Convert delegate type.\n"); 988 #endif 989 src = expr->titem; 990 assert(src->tic == tic_tdeleg); 991 assert(dest->tic == tic_tdeleg); 992 993 sdeleg = src->u.tdeleg; 994 ddeleg = dest->u.tdeleg; 995 996 /* 997 * XXX We need to redesign handling of generic types to handle 998 * delegates in generic CSIs properly. 999 */ 1000 1001 /* Destination should never be anonymous delegate. */ 1002 assert(ddeleg->deleg != NULL); 1003 1004 /* Both must be the same delegate. */ 1005 if (sdeleg->deleg != ddeleg->deleg) { 1006 stype_convert_failure(stype, src, dest); 1007 return expr; 1008 } 1009 1010 return expr; 1011 } 1012 1013 /** Convert expression of function type to delegate type. 1014 * 1015 * @param stype Static typing object 1016 * @param expr Expression 1017 * @param dest Destination type 1018 */ 1019 static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype, 1020 stree_expr_t *expr, tdata_item_t *dest) 1021 { 1022 tdata_item_t *src; 1023 tdata_fun_t *sfun; 1024 tdata_deleg_t *ddeleg; 1025 tdata_fun_sig_t *ssig, *dsig; 1026 1027 #ifdef DEBUG_TYPE_TRACE 1028 printf("Convert delegate type.\n"); 1029 #endif 1030 src = expr->titem; 1031 assert(src->tic == tic_tfun); 1032 assert(dest->tic == tic_tdeleg); 1033 1034 sfun = src->u.tfun; 1035 ddeleg = dest->u.tdeleg; 1036 1037 ssig = sfun->tsig; 1038 assert(ssig != NULL); 1039 dsig = stype_deleg_get_sig(stype, ddeleg); 1040 assert(dsig != NULL); 1041 1042 /* Signature type must match. */ 1043 1044 if (!stype_fun_sig_equal(stype, ssig, dsig)) { 1045 stype_convert_failure(stype, src, dest); 1046 return expr; 1047 } 1048 1049 /* 1050 * XXX We should also compare attributes. Either the 1051 * tdeleg should be extended or we should get them 1052 * from stree_deleg. 1053 */ 1054 1055 return expr; 1056 } 1057 1058 1059 /** Convert expression of variable type to variable type. 1060 * 1061 * @param stype Static typing object 1062 * @param expr Expression 1063 * @param dest Destination type 1064 */ 1065 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr, 1066 tdata_item_t *dest) 1067 { 1068 tdata_item_t *src; 1069 1070 #ifdef DEBUG_TYPE_TRACE 1071 printf("Convert variable type.\n"); 1072 #endif 1073 src = expr->titem; 1074 1075 /* Currently only allow if both types are the same. */ 1076 if (src->u.tvref->targ != dest->u.tvref->targ) { 1077 stype_convert_failure(stype, src, dest); 1078 return expr; 1079 } 1080 1081 return expr; 1082 } 1083 1084 /** Display conversion error message and note error. 1085 * 1086 * @param stype Static typing object 1087 * @param src Original type 1088 * @param dest Destination type 1089 */ 1090 static void stype_convert_failure(stype_t *stype, tdata_item_t *src, 1091 tdata_item_t *dest) 1092 { 555 556 failure: 1093 557 printf("Error: Cannot convert "); 1094 558 tdata_item_print(src); … … 1098 562 1099 563 stype_note_error(stype); 1100 } 1101 1102 /** Determine if two type signatures are equal. 1103 * 1104 * XXX This does not compare the attributes, which are missing from 1105 * @c tdata_fun_sig_t. 1106 * 1107 * @param stype Static typing object 1108 * @param asig First function signature type 1109 * @param bsig Second function signature type 1110 */ 1111 static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig, 1112 tdata_fun_sig_t *bsig) 1113 { 1114 list_node_t *aarg_n, *barg_n; 1115 tdata_item_t *aarg_ti, *barg_ti; 1116 1117 (void) stype; 1118 1119 /* Compare types of arguments */ 1120 aarg_n = list_first(&asig->arg_ti); 1121 barg_n = list_first(&bsig->arg_ti); 1122 1123 while (aarg_n != NULL && barg_n != NULL) { 1124 aarg_ti = list_node_data(aarg_n, tdata_item_t *); 1125 barg_ti = list_node_data(barg_n, tdata_item_t *); 1126 1127 if (!tdata_item_equal(aarg_ti, barg_ti)) 1128 return b_false; 1129 1130 aarg_n = list_next(&asig->arg_ti, aarg_n); 1131 barg_n = list_next(&bsig->arg_ti, barg_n); 1132 } 1133 1134 if (aarg_n != NULL || barg_n != NULL) 1135 return b_false; 1136 1137 /* Compare variadic argument */ 1138 1139 if (asig->varg_ti != NULL || bsig->varg_ti != NULL) { 1140 if (asig->varg_ti == NULL || 1141 bsig->varg_ti == NULL) { 1142 return b_false; 1143 } 1144 1145 if (!tdata_item_equal(asig->varg_ti, bsig->varg_ti)) { 1146 return b_false; 1147 } 1148 } 1149 1150 /* Compare return type */ 1151 if (!tdata_item_equal(asig->rtype, bsig->rtype)) 1152 return b_false; 1153 1154 return b_true; 1155 } 1156 1157 /** Get function signature from delegate. 1158 * 1159 * Function signature can be missing if the delegate type is incomplete. 1160 * This is used to break circular dependency when typing delegates. 1161 * If this happens, we type the delegate, which gives us the signature. 1162 */ 1163 tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg) 1164 { 1165 if (tdeleg->tsig == NULL) 1166 stype_deleg(stype, tdeleg->deleg); 1167 1168 /* Now we should have a signature. */ 1169 assert(tdeleg->tsig != NULL); 1170 return tdeleg->tsig; 1171 } 1172 1173 /** Convert tic_tobject type item to TVV, 1174 * 1175 * We split generic type application into two steps. In the first step 1176 * we match argument names of @a ti->csi to argument values in @a ti 1177 * to produce a TVV (name to value map for type arguments). That is the 1178 * purpose of this function. 1179 * 1180 * In the second step we substitute variables in another type item 1181 * with their values using the TVV. This is performed by tdata_item_subst(). 1182 * 1183 * @param stype Static typing object. 1184 * @param ti Type item of class tic_tobject. 1185 * @param rtvv Place to store pointer to new TVV. 1186 */ 1187 void stype_titem_to_tvv(stype_t *stype, tdata_item_t *ti, tdata_tvv_t **rtvv) 1188 { 1189 tdata_tvv_t *tvv; 1190 stree_csi_t *csi; 1191 1192 list_node_t *formal_n; 1193 list_node_t *real_n; 1194 1195 stree_targ_t *formal_arg; 1196 tdata_item_t *real_arg; 1197 1198 assert(ti->tic == tic_tobject); 1199 1200 tvv = tdata_tvv_new(); 1201 intmap_init(&tvv->tvv); 1202 1203 csi = ti->u.tobject->csi; 1204 formal_n = list_first(&csi->targ); 1205 real_n = list_first(&ti->u.tobject->targs); 1206 1207 while (formal_n != NULL && real_n != NULL) { 1208 formal_arg = list_node_data(formal_n, stree_targ_t *); 1209 real_arg = list_node_data(real_n, tdata_item_t *); 1210 1211 /* Store argument value into valuation. */ 1212 tdata_tvv_set_val(tvv, formal_arg->name->sid, real_arg); 1213 1214 formal_n = list_next(&csi->targ, formal_n); 1215 real_n = list_next(&ti->u.tobject->targs, real_n); 1216 } 1217 1218 if (formal_n != NULL || real_n != NULL) { 1219 printf("Error: Incorrect number of type arguments.\n"); 1220 stype_note_error(stype); 1221 1222 /* Fill missing arguments with recovery type items. */ 1223 while (formal_n != NULL) { 1224 formal_arg = list_node_data(formal_n, stree_targ_t *); 1225 /* Store recovery value into valuation. */ 1226 tdata_tvv_set_val(tvv, formal_arg->name->sid, 1227 stype_recovery_titem(stype)); 1228 1229 formal_n = list_next(&csi->targ, formal_n); 1230 } 1231 } 1232 1233 *rtvv = tvv; 1234 } 1235 1236 /** Return a boolean type item. 1237 * 1238 * @param stype Static typing object 1239 * @return New boolean type item. 1240 */ 564 return expr; 565 } 566 567 /** Return a boolean type item */ 1241 568 tdata_item_t *stype_boolean_titem(stype_t *stype) 1242 569 { … … 1253 580 } 1254 581 1255 /** Find a local variable in the current function. 1256 * 1257 * @param stype Static typing object 1258 * @param name Name of variable (SID). 1259 * @return Pointer to variable declaration or @c NULL if not 1260 * found. 1261 */ 582 /** Find a local variable in the current function. */ 1262 583 stree_vdecl_t *stype_local_vars_lookup(stype_t *stype, sid_t name) 1263 584 { … … 1284 605 } 1285 606 1286 /** Find argument of the current procedure. 1287 * 1288 * @param stype Static typing object 1289 * @param name Name of argument (SID). 1290 * @return Pointer to argument declaration or @c NULL if not 1291 * found. 1292 */ 607 /** Find argument of the current procedure. */ 1293 608 stree_proc_arg_t *stype_proc_args_lookup(stype_t *stype, sid_t name) 1294 609 { … … 1318 633 fun = symbol_to_fun(outer_sym); 1319 634 assert(fun != NULL); 1320 args = &fun-> sig->args;1321 varg = fun-> sig->varg;635 args = &fun->args; 636 varg = fun->varg; 1322 637 break; 1323 638 case sc_prop: … … 1373 688 } 1374 689 1375 /** Note a static typing error that has been immediately recovered. 1376 * 1377 * @param stype Static typing object 1378 */ 690 /** Note a static typing error that has been immediately recovered. */ 1379 691 void stype_note_error(stype_t *stype) 1380 692 { … … 1382 694 } 1383 695 1384 /** Construct a special type item for recovery. 1385 * 1386 * The recovery item is propagated towards the expression root and causes 1387 * any further typing errors in the expression to be supressed. 1388 * 1389 * @param stype Static typing object 1390 */ 696 /** Construct a special type item for recovery. */ 1391 697 tdata_item_t *stype_recovery_titem(stype_t *stype) 1392 698 { … … 1399 705 } 1400 706 1401 /** Get current block visit record. 1402 * 1403 * @param stype Static typing object 1404 */ 707 /** Get current block visit record. */ 1405 708 stype_block_vr_t *stype_get_current_block_vr(stype_t *stype) 1406 709 { … … 1411 714 } 1412 715 1413 /** Allocate new procedure visit record.1414 *1415 * @return New procedure VR1416 */1417 716 stype_proc_vr_t *stype_proc_vr_new(void) 1418 717 { … … 1428 727 } 1429 728 1430 /** Allocate new block visit record.1431 *1432 * @return New block VR1433 */1434 729 stype_block_vr_t *stype_block_vr_new(void) 1435 730 { -
uspace/app/sbi/src/stype.h
rf4f866c r80badbe 33 33 34 34 void stype_module(stype_t *stype, stree_module_t *module); 35 void stype_deleg(stype_t *stype, stree_deleg_t *deleg);36 void stype_fun_header(stype_t *stype, stree_fun_t *fun);37 35 void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value); 38 36 … … 42 40 stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr, 43 41 tdata_item_t *dest); 44 45 tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg);46 47 void stype_titem_to_tvv(stype_t *stype, tdata_item_t *ti, tdata_tvv_t **rtvv);48 42 49 43 tdata_item_t *stype_boolean_titem(stype_t *stype); -
uspace/app/sbi/src/stype_expr.c
rf4f866c r80badbe 27 27 */ 28 28 29 /** @file Typing of expressions. 30 * 31 * This module types (data) expressions -- not to be confused with evaluating 32 * type expressions! Thus the type of each (sub-)expression is determined 33 * and stored in its @c titem field. 34 * 35 * It can also happen that, due to implicit conversions, the expression 36 * needs to be patched to insert these conversions. 37 * 38 * If a type error occurs within an expression, @c stype->error is set 39 * and the type of the expression will be @c tic_ignore. This type item 40 * is propagated upwards and causes further typing errors to be ignored 41 * (this prevents a type error avalanche). Type checking is thus resumed 42 * at the next expression. 43 */ 29 /** @file Type expressions. */ 44 30 45 31 #include <stdio.h> … … 117 103 tdata_item_t **rtitem); 118 104 static void stype_as(stype_t *stype, stree_as_t *as_op, tdata_item_t **rtitem); 119 static void stype_box(stype_t *stype, stree_box_t *box, tdata_item_t **rtitem); 120 121 122 /** Type expression 123 * 124 * The type is stored in @a expr->titem. If the express contains a type error, 125 * @a stype->error will be set when this function returns. 126 * 127 * @param stype Static typing object 128 * @param expr Expression 129 */ 105 106 107 /** Type expression. */ 130 108 void stype_expr(stype_t *stype, stree_expr_t *expr) 131 109 { … … 150 128 case ec_assign: stype_assign(stype, expr->u.assign, &et); break; 151 129 case ec_as: stype_as(stype, expr->u.as_op, &et); break; 152 case ec_box: stype_box(stype, expr->u.box, &et); break;153 130 } 154 131 … … 162 139 } 163 140 164 /** Type name reference. 165 * 166 * @param stype Static typing object 167 * @param nameref Name reference 168 * @param rtitem Place to store result type 169 */ 141 /** Type name reference. */ 170 142 static void stype_nameref(stype_t *stype, stree_nameref_t *nameref, 171 143 tdata_item_t **rtitem) … … 177 149 tdata_object_t *tobject; 178 150 stree_csi_t *csi; 179 stree_deleg_t *deleg;180 151 stree_fun_t *fun; 181 152 … … 260 231 tobject->csi = csi; 261 232 break; 262 case sc_deleg:263 printf("referenced name is deleg\n");264 deleg = symbol_to_deleg(sym);265 assert(deleg != NULL);266 /* Type delegate if it has not been typed yet. */267 stype_deleg(stype, deleg);268 titem = deleg->titem;269 break;270 233 case sc_fun: 271 234 fun = symbol_to_fun(sym); 272 235 assert(fun != NULL); 273 /* Type function header if it has not been typed yet. */ 274 stype_fun_header(stype, fun); 275 titem = fun->titem; 236 237 titem = tdata_item_new(tic_tfun); 238 titem->u.tfun = tdata_fun_new(); 239 titem->u.tfun->fun = fun; 276 240 break; 277 241 } … … 280 244 } 281 245 282 /** Type a literal. 283 * 284 * @param stype Static typing object 285 * @param literal Literal 286 * @param rtitem Place to store result type 287 */ 246 /** Type a literal. */ 288 247 static void stype_literal(stype_t *stype, stree_literal_t *literal, 289 248 tdata_item_t **rtitem) … … 313 272 } 314 273 315 /** Type @c self reference. 316 * 317 * @param stype Static typing object 318 * @param self_ref @c self reference 319 * @param rtitem Place to store result type 320 */ 274 /** Type a self reference. */ 321 275 static void stype_self_ref(stype_t *stype, stree_self_ref_t *self_ref, 322 276 tdata_item_t **rtitem) … … 331 285 } 332 286 333 /** Type a binary operation. 334 * 335 * @param stype Static typing object 336 * @param binop Binary operation 337 * @param rtitem Place to store result type 338 */ 287 /** Type a binary operation. */ 339 288 static void stype_binop(stype_t *stype, stree_binop_t *binop, 340 289 tdata_item_t **rtitem) … … 396 345 } 397 346 398 /** Type a binary operation with arguments of primitive type. 399 * 400 * @param stype Static typing object 401 * @param binop Binary operation 402 * @param ta Type of first argument 403 * @param tb Type of second argument 404 * @param rtitem Place to store result type 405 */ 347 /** Type a binary operation with arguments of primitive type. */ 406 348 static void stype_binop_tprimitive(stype_t *stype, stree_binop_t *binop, 407 349 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem) … … 432 374 } 433 375 434 /** Type a binary operation with @c bool arguments. 435 * 436 * @param stype Static typing object 437 * @param binop Binary operation 438 * @param rtitem Place to store result type 439 */ 376 /** Type a binary operation with bool arguments. */ 440 377 static void stype_binop_bool(stype_t *stype, stree_binop_t *binop, 441 378 tdata_item_t **rtitem) … … 471 408 } 472 409 473 /** Type a binary operation with @c char arguments. 474 * 475 * @param stype Static typing object 476 * @param binop Binary operation 477 * @param rtitem Place to store result type 478 */ 410 /** Type a binary operation with char arguments. */ 479 411 static void stype_binop_char(stype_t *stype, stree_binop_t *binop, 480 412 tdata_item_t **rtitem) … … 512 444 } 513 445 514 /** Type a binary operation with @c int arguments. 515 * 516 * @param stype Static typing object 517 * @param binop Binary operation 518 * @param rtitem Place to store result type 519 */ 446 /** Type a binary operation with int arguments. */ 520 447 static void stype_binop_int(stype_t *stype, stree_binop_t *binop, 521 448 tdata_item_t **rtitem) … … 550 477 } 551 478 552 /** Type a binary operation with @c nil arguments. 553 * 554 * @param stype Static typing object 555 * @param binop Binary operation 556 * @param rtitem Place to store result type 557 */ 479 /** Type a binary operation with nil arguments. */ 558 480 static void stype_binop_nil(stype_t *stype, stree_binop_t *binop, 559 481 tdata_item_t **rtitem) … … 566 488 } 567 489 568 /** Type a binary operation with @c string arguments. 569 * 570 * @param stype Static typing object 571 * @param binop Binary operation 572 * @param rtitem Place to store result type 573 */ 490 /** Type a binary operation with string arguments. */ 574 491 static void stype_binop_string(stype_t *stype, stree_binop_t *binop, 575 492 tdata_item_t **rtitem) … … 594 511 } 595 512 596 /** Type a binary operation with resource arguments. 597 * 598 * @param stype Static typing object 599 * @param binop Binary operation 600 * @param rtitem Place to store result type 601 */ 513 /** Type a binary operation with resource arguments. */ 602 514 static void stype_binop_resource(stype_t *stype, stree_binop_t *binop, 603 515 tdata_item_t **rtitem) … … 618 530 } 619 531 620 /** Type a binary operation with arguments of an object type. 621 * 622 * @param stype Static typing object 623 * @param binop Binary operation 624 * @param ta Type of first argument 625 * @param tb Type of second argument 626 * @param rtitem Place to store result type 627 */ 532 /** Type a binary operation with arguments of an object type. */ 628 533 static void stype_binop_tobject(stype_t *stype, stree_binop_t *binop, 629 534 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem) … … 656 561 657 562 658 /** Type a unary operation. 659 * 660 * @param stype Static typing object 661 * @param unop Unary operation 662 * @param rtitem Place to store result type 663 */ 563 /** Type a unary operation. */ 664 564 static void stype_unop(stype_t *stype, stree_unop_t *unop, 665 565 tdata_item_t **rtitem) … … 694 594 } 695 595 696 /** Type a binary operation arguments of primitive type. 697 * 698 * @param stype Static typing object 699 * @param unop Binary operation 700 * @param ta Type of argument 701 * @param rtitem Place to store result type 702 */ 596 /** Type a binary operation arguments of primitive type. */ 703 597 static void stype_unop_tprimitive(stype_t *stype, stree_unop_t *unop, 704 598 tdata_item_t *ta, tdata_item_t **rtitem) … … 733 627 } 734 628 735 /** Type a @c new operation. 736 * 737 * @param stype Static typing object 738 * @param new_op @c new operation 739 * @param rtitem Place to store result type 740 */ 629 /** Type a @c new operation. */ 741 630 static void stype_new(stype_t *stype, stree_new_t *new_op, 742 631 tdata_item_t **rtitem) … … 757 646 } 758 647 759 /** Type a member access operation. 760 * 761 * @param stype Static typing object 762 * @param access Member access operation 763 * @param rtitem Place to store result type 764 */ 648 /** Type a field access operation */ 765 649 static void stype_access(stype_t *stype, stree_access_t *access, 766 650 tdata_item_t **rtitem) … … 791 675 stype_access_tarray(stype, access, arg_ti, rtitem); 792 676 break; 793 case tic_t deleg:677 case tic_tfun: 794 678 printf("Error: Using '.' operator on a function.\n"); 795 679 stype_note_error(stype); 796 680 *rtitem = stype_recovery_titem(stype); 797 681 break; 798 case tic_tfun:799 printf("Error: Using '.' operator on a delegate.\n");800 stype_note_error(stype);801 *rtitem = stype_recovery_titem(stype);802 break;803 case tic_tvref:804 /* Cannot allow this without some constraint. */805 printf("Error: Using '.' operator on generic data.\n");806 *rtitem = stype_recovery_titem(stype);807 break;808 682 case tic_ignore: 809 683 *rtitem = stype_recovery_titem(stype); … … 812 686 } 813 687 814 /** Type a primitive type access operation. 815 * 816 * @param stype Static typing object 817 * @param access Member access operation 818 * @param arg_ti Base type 819 * @param rtitem Place to store result type 820 */ 688 /** Type a primitive type access operation. */ 821 689 static void stype_access_tprimitive(stype_t *stype, stree_access_t *access, 822 690 tdata_item_t *arg_ti, tdata_item_t **rtitem) … … 833 701 } 834 702 835 /** Type an object access operation. 836 * 837 * @param stype Static typing object 838 * @param access Member access operation 839 * @param arg_ti Base type 840 * @param rtitem Place to store result type 841 */ 703 /** Type an object access operation. */ 842 704 static void stype_access_tobject(stype_t *stype, stree_access_t *access, 843 705 tdata_item_t *arg_ti, tdata_item_t **rtitem) … … 848 710 stree_prop_t *prop; 849 711 tdata_object_t *tobject; 850 tdata_item_t *mtitem;851 tdata_tvv_t *tvv;852 712 853 713 #ifdef DEBUG_TYPE_TRACE … … 883 743 stype_note_error(stype); 884 744 *rtitem = stype_recovery_titem(stype); 885 return; 886 case sc_deleg: 887 printf("Error: Accessing object member which is a " 888 "delegate.\n"); 889 stype_note_error(stype); 890 *rtitem = stype_recovery_titem(stype); 891 return; 745 break; 892 746 case sc_fun: 893 747 fun = symbol_to_fun(member_sym); 894 748 assert(fun != NULL); 895 /* Type function header now */896 stype_fun_header(stype, fun);897 mtitem = fun->titem;749 *rtitem = tdata_item_new(tic_tfun); 750 (*rtitem)->u.tfun = tdata_fun_new(); 751 (*rtitem)->u.tfun->fun = fun; 898 752 break; 899 753 case sc_var: 900 754 var = symbol_to_var(member_sym); 901 755 assert(var != NULL); 756 /* XXX Memoize to avoid recomputing every time. */ 902 757 run_texpr(stype->program, member_sym->outer_csi, 903 var->type, &mtitem);758 var->type, rtitem); 904 759 break; 905 760 case sc_prop: 906 761 prop = symbol_to_prop(member_sym); 907 762 assert(prop != NULL); 763 /* XXX Memoize to avoid recomputing every time. */ 908 764 run_texpr(stype->program, member_sym->outer_csi, 909 prop->type, &mtitem); 910 break; 911 } 912 913 /* 914 * Substitute type arguments in member titem. 915 * 916 * Since the CSI can be generic the actual type of the member 917 * is obtained by substituting our type arguments into the 918 * (generic) type of the member. 919 */ 920 921 stype_titem_to_tvv(stype, arg_ti, &tvv); 922 tdata_item_subst(mtitem, tvv, rtitem); 923 } 924 925 /** Type an array access operation. 926 * 927 * @param stype Static typing object 928 * @param access Member access operation 929 * @param arg_ti Base type 930 * @param rtitem Place to store result type 931 */ 765 prop->type, rtitem); 766 break; 767 } 768 } 769 770 /** Type an array access operation. */ 932 771 static void stype_access_tarray(stype_t *stype, stree_access_t *access, 933 772 tdata_item_t *arg_ti, tdata_item_t **rtitem) … … 944 783 } 945 784 946 /** Type a call operation. 947 * 948 * @param stype Static typing object 949 * @param call Call operation 950 * @param rtitem Place to store result type 951 */ 785 /** Type a call operation. */ 952 786 static void stype_call(stype_t *stype, stree_call_t *call, 953 787 tdata_item_t **rtitem) 954 788 { 955 list_node_t *fargt_n; 789 list_node_t *farg_n; 790 stree_proc_arg_t *farg; 956 791 tdata_item_t *farg_ti; 957 792 tdata_item_t *varg_ti; … … 962 797 963 798 tdata_item_t *fun_ti; 964 tdata_fun_sig_t *tsig; 965 966 int cnt; 799 stree_fun_t *fun; 800 stree_symbol_t *fun_sym; 967 801 968 802 #ifdef DEBUG_TYPE_TRACE … … 973 807 974 808 /* Check type item class */ 809 975 810 fun_ti = call->fun->titem; 976 811 switch (fun_ti->tic) { 977 case tic_tdeleg:978 tsig = stype_deleg_get_sig(stype, fun_ti->u.tdeleg);979 assert(tsig != NULL);980 break;981 812 case tic_tfun: 982 tsig = fun_ti->u.tfun->tsig;813 /* The expected case */ 983 814 break; 984 815 case tic_ignore: … … 995 826 } 996 827 828 fun = fun_ti->u.tfun->fun; 829 fun_sym = fun_to_symbol(fun); 830 997 831 /* Type and check the arguments. */ 998 farg t_n = list_first(&tsig->arg_ti);832 farg_n = list_first(&fun->args); 999 833 arg_n = list_first(&call->args); 1000 1001 cnt = 0; 1002 while (fargt_n != NULL && arg_n != NULL) { 1003 farg_ti = list_node_data(fargt_n, tdata_item_t *); 834 while (farg_n != NULL && arg_n != NULL) { 835 farg = list_node_data(farg_n, stree_proc_arg_t *); 1004 836 arg = list_node_data(arg_n, stree_expr_t *); 1005 837 stype_expr(stype, arg); 1006 838 1007 839 /* XXX Because of overloaded bultin WriteLine */ 1008 if (farg _ti== NULL) {840 if (farg->type == NULL) { 1009 841 /* Skip the check */ 1010 farg t_n = list_next(&tsig->arg_ti, fargt_n);842 farg_n = list_next(&fun->args, farg_n); 1011 843 arg_n = list_next(&call->args, arg_n); 1012 844 continue; 1013 845 } 1014 846 847 /* XXX Memoize to avoid recomputing every time. */ 848 run_texpr(stype->program, fun_sym->outer_csi, farg->type, 849 &farg_ti); 850 1015 851 /* Convert expression to type of formal argument. */ 1016 852 carg = stype_convert(stype, arg, farg_ti); … … 1019 855 list_node_setdata(arg_n, carg); 1020 856 1021 farg t_n = list_next(&tsig->arg_ti, fargt_n);857 farg_n = list_next(&fun->args, farg_n); 1022 858 arg_n = list_next(&call->args, arg_n); 1023 859 } 1024 860 1025 861 /* Type and check variadic arguments. */ 1026 if (tsig->varg_ti != NULL) { 1027 /* Obtain type of packed argument. */ 1028 farg_ti = tsig->varg_ti; 862 if (fun->varg != NULL) { 863 /* XXX Memoize to avoid recomputing every time. */ 864 run_texpr(stype->program, fun_sym->outer_csi, fun->varg->type, 865 &farg_ti); 1029 866 1030 867 /* Get array element type */ … … 1046 883 } 1047 884 1048 if (fargt_n != NULL) { 1049 printf("Error: Too few arguments to function.\n"); 885 if (farg_n != NULL) { 886 printf("Error: Too few arguments to function '"); 887 symbol_print_fqn(fun_to_symbol(fun)); 888 printf("'.\n"); 1050 889 stype_note_error(stype); 1051 890 } 1052 891 1053 892 if (arg_n != NULL) { 1054 printf("Error: Too many arguments to function.\n"); 1055 stype_note_error(stype); 1056 } 1057 1058 if (tsig->rtype != NULL) { 1059 /* XXX Might be better to clone here. */ 1060 *rtitem = tsig->rtype; 893 printf("Error: Too many arguments to function '"); 894 symbol_print_fqn(fun_to_symbol(fun)); 895 printf("'.\n"); 896 stype_note_error(stype); 897 } 898 899 if (fun->rtype != NULL) { 900 /* XXX Memoize to avoid recomputing every time. */ 901 run_texpr(stype->program, fun_sym->outer_csi, fun->rtype, 902 rtitem); 1061 903 } else { 1062 904 *rtitem = NULL; … … 1064 906 } 1065 907 1066 /** Type an indexing operation. 1067 * 1068 * @param stype Static typing object 1069 * @param index Indexing operation 1070 * @param rtitem Place to store result type 1071 */ 908 /** Type an indexing operation. */ 1072 909 static void stype_index(stype_t *stype, stree_index_t *index, 1073 910 tdata_item_t **rtitem) … … 1102 939 stype_index_tarray(stype, index, base_ti, rtitem); 1103 940 break; 1104 case tic_tdeleg:1105 printf("Error: Indexing a delegate.\n");1106 stype_note_error(stype);1107 *rtitem = stype_recovery_titem(stype);1108 break;1109 941 case tic_tfun: 1110 942 printf("Error: Indexing a function.\n"); … … 1112 944 *rtitem = stype_recovery_titem(stype); 1113 945 break; 1114 case tic_tvref:1115 /* Cannot allow this without some constraint. */1116 printf("Error: Indexing generic data.\n");1117 *rtitem = stype_recovery_titem(stype);1118 break;1119 946 case tic_ignore: 1120 947 *rtitem = stype_recovery_titem(stype); … … 1123 950 } 1124 951 1125 /** Type a primitive indexing operation. 1126 * 1127 * @param stype Static typing object 1128 * @param index Indexing operation 1129 * @param base_ti Base type (primitive being indexed) 1130 * @param rtitem Place to store result type 1131 */ 952 /** Type a primitive indexing operation. */ 1132 953 static void stype_index_tprimitive(stype_t *stype, stree_index_t *index, 1133 954 tdata_item_t *base_ti, tdata_item_t **rtitem) … … 1156 977 } 1157 978 1158 /** Type an object indexing operation. 1159 * 1160 * @param stype Static typing object 1161 * @param index Indexing operation 1162 * @param base_ti Base type (object being indexed) 1163 * @param rtitem Place to store result type 1164 */ 979 /** Type an object indexing operation. */ 1165 980 static void stype_index_tobject(stype_t *stype, stree_index_t *index, 1166 981 tdata_item_t *base_ti, tdata_item_t **rtitem) … … 1170 985 stree_prop_t *idx; 1171 986 stree_ident_t *idx_ident; 1172 tdata_item_t *mtitem;1173 tdata_tvv_t *tvv;1174 987 1175 988 (void) index; … … 1202 1015 1203 1016 /* XXX Memoize to avoid recomputing every time. */ 1204 run_texpr(stype->program, idx_sym->outer_csi, idx->type, &mtitem); 1205 1206 /* 1207 * Substitute type arguments in member titem. 1208 * 1209 * Since the CSI can be generic the actual type of the member 1210 * is obtained by substituting our type arguments into the 1211 * (generic) type of the member. 1212 */ 1213 1214 stype_titem_to_tvv(stype, base_ti, &tvv); 1215 tdata_item_subst(mtitem, tvv, rtitem); 1216 } 1217 1218 /** Type an array indexing operation. 1219 * 1220 * @param stype Static typing object 1221 * @param index Indexing operation 1222 * @param base_ti Base type (array being indexed) 1223 * @param rtitem Place to store result type 1224 */ 1017 run_texpr(stype->program, idx_sym->outer_csi, idx->type, rtitem); 1018 } 1019 1020 /** Type an array indexing operation. */ 1225 1021 static void stype_index_tarray(stype_t *stype, stree_index_t *index, 1226 1022 tdata_item_t *base_ti, tdata_item_t **rtitem) … … 1262 1058 } 1263 1059 1264 /** Type an assignment. 1265 * 1266 * @param stype Static typing object 1267 * @param assign Assignment operation 1268 * @param rtitem Place to store result type 1269 */ 1060 /** Type an assignment. */ 1270 1061 static void stype_assign(stype_t *stype, stree_assign_t *assign, 1271 1062 tdata_item_t **rtitem) … … 1286 1077 } 1287 1078 1288 /** Type @c as conversion. 1289 * 1290 * @param stype Static typing object 1291 * @param as_op @c as conversion operation 1292 * @param rtitem Place to store result type 1293 */ 1079 /** Type @c as conversion. */ 1294 1080 static void stype_as(stype_t *stype, stree_as_t *as_op, tdata_item_t **rtitem) 1295 1081 { … … 1314 1100 *rtitem = titem; 1315 1101 } 1316 1317 /** Type boxing operation.1318 *1319 * While there is no boxing operation on the first typing pass, we do want1320 * to allow potential re-evaluation (with same results).1321 *1322 * @param stype Static typing object1323 * @param box Boxing operation1324 * @param rtitem Place to store result type1325 */1326 static void stype_box(stype_t *stype, stree_box_t *box, tdata_item_t **rtitem)1327 {1328 tdata_item_t *ptitem, *btitem;1329 tdata_object_t *tobject;1330 stree_symbol_t *csi_sym;1331 builtin_t *bi;1332 1333 #ifdef DEBUG_TYPE_TRACE1334 printf("Evaluate type of boxing operation.\n");1335 #endif1336 bi = stype->program->builtin;1337 1338 stype_expr(stype, box->arg);1339 ptitem = box->arg->titem;1340 1341 /* Make compiler happy. */1342 csi_sym = NULL;1343 1344 assert(ptitem->tic == tic_tprimitive);1345 switch (ptitem->u.tprimitive->tpc) {1346 case tpc_bool: csi_sym = bi->boxed_bool; break;1347 case tpc_char: csi_sym = bi->boxed_char; break;1348 case tpc_int: csi_sym = bi->boxed_int; break;1349 case tpc_nil: assert(b_false);1350 case tpc_string: csi_sym = bi->boxed_string; break;1351 case tpc_resource: assert(b_false);1352 }1353 1354 btitem = tdata_item_new(tic_tobject);1355 tobject = tdata_object_new();1356 1357 btitem->u.tobject = tobject;1358 tobject->static_ref = b_false;1359 tobject->csi = symbol_to_csi(csi_sym);1360 assert(tobject->csi != NULL);1361 list_init(&tobject->targs);1362 1363 *rtitem = btitem;1364 } -
uspace/app/sbi/src/symbol.c
rf4f866c r80badbe 44 44 static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol); 45 45 46 /** Lookup symbol in CSI using a type expression. 47 * 48 * XXX This should be removed in favor of full type expression evaluation 49 * (run_texpr). This cannot work properly with generics. 50 * 51 * @param prog Program 52 * @param scope CSI used as base for relative references 53 * @param texpr Type expression 54 * 55 * @return Symbol referenced by type expression or @c NULL 56 * if not found 57 */ 46 /** Lookup symbol in CSI using a type expression. */ 58 47 stree_symbol_t *symbol_xlookup_in_csi(stree_program_t *prog, 59 48 stree_csi_t *scope, stree_texpr_t *texpr) … … 88 77 /** Lookup symbol reference in CSI. 89 78 * 90 * @param prog Program to look in 91 * @param scope CSI in @a prog which is the base for references 92 * @param name Identifier of the symbol 93 * 94 * @return Symbol or @c NULL if symbol not found 79 * @param prog Program to look in. 80 * @param scope CSI in @a prog which is the base for references. 81 * @param name Identifier of the symbol. 82 * 83 * @return Symbol or @c NULL if symbol not found. 95 84 */ 96 85 stree_symbol_t *symbol_lookup_in_csi(stree_program_t *prog, stree_csi_t *scope, … … 118 107 * Look for symbol in definition of a CSI and its ancestors. (But not 119 108 * in lexically enclosing CSI.) 120 *121 * @param prog Program to look in122 * @param scope CSI in which to look123 * @param name Identifier of the symbol124 *125 * @return Symbol or @c NULL if symbol not found.126 109 */ 127 110 stree_symbol_t *symbol_search_csi(stree_program_t *prog, … … 142 125 while (node != NULL) { 143 126 csimbr = list_node_data(node, stree_csimbr_t *); 144 145 /* Keep compiler happy. */146 mbr_name = NULL;147 148 127 switch (csimbr->cc) { 149 128 case csimbr_csi: mbr_name = csimbr->u.csi->name; break; 150 case csimbr_deleg: mbr_name = csimbr->u.deleg->name; break;151 129 case csimbr_fun: mbr_name = csimbr->u.fun->name; break; 152 130 case csimbr_var: mbr_name = csimbr->u.var->name; break; 153 131 case csimbr_prop: mbr_name = csimbr->u.prop->name; break; 132 default: assert(b_false); 154 133 } 155 134 … … 159 138 case csimbr_csi: 160 139 symbol = csi_to_symbol(csimbr->u.csi); 161 break;162 case csimbr_deleg:163 symbol = deleg_to_symbol(csimbr->u.deleg);164 140 break; 165 141 case csimbr_fun: … … 194 170 } 195 171 196 /** Look for symbol in global scope.197 *198 * @param prog Program to look in199 * @param name Identifier of the symbol200 *201 * @return Symbol or @c NULL if symbol not found.202 */203 172 static stree_symbol_t *symbol_search_global(stree_program_t *prog, 204 173 stree_ident_t *name) … … 228 197 } 229 198 230 /** Find entry point. 231 * 232 * Perform a walk of all CSIs and look for a function with the name @a name. 233 * 234 * @param prog Program to look in 235 * @param name Name of entry point 236 * 237 * @return Symbol or @c NULL if symbol not found. 238 */ 199 /** Find entry point. */ 239 200 stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name) 240 201 { … … 264 225 } 265 226 266 /** Find entry point under CSI.267 *268 * Internal part of symbol_find_epoint() that recursively walks CSIs.269 *270 * @param prog Program to look in271 * @param name Name of entry point272 *273 * @return Symbol or @c NULL if symbol not found.274 */275 227 static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog, 276 228 stree_ident_t *name, stree_csi_t *csi) … … 315 267 } 316 268 317 /*318 * The notion of symbol is designed as a common base class for several319 * types of declarations with global and CSI scope. Here we simulate320 * conversion from this base class (symbol) to derived classes (CSI,321 * fun, ..) and vice versa.322 */323 324 /** Convert symbol to delegate (base to derived).325 *326 * @param symbol Symbol327 * @return Delegate or @c NULL if symbol is not a delegate328 */329 stree_deleg_t *symbol_to_deleg(stree_symbol_t *symbol)330 {331 if (symbol->sc != sc_deleg)332 return NULL;333 334 return symbol->u.deleg;335 }336 337 /** Convert delegate to symbol (derived to base).338 *339 * @param deleg Delegate340 * @return Symbol341 */342 stree_symbol_t *deleg_to_symbol(stree_deleg_t *deleg)343 {344 assert(deleg->symbol);345 return deleg->symbol;346 }347 348 /** Convert symbol to CSI (base to derived).349 *350 * @param symbol Symbol351 * @return CSI or @c NULL if symbol is not a CSI352 */353 269 stree_csi_t *symbol_to_csi(stree_symbol_t *symbol) 354 270 { … … 359 275 } 360 276 361 /** Convert CSI to symbol (derived to base).362 *363 * @param csi CSI364 * @return Symbol365 */366 277 stree_symbol_t *csi_to_symbol(stree_csi_t *csi) 367 278 { … … 370 281 } 371 282 372 /** Convert symbol to function (base to derived).373 *374 * @param symbol Symbol375 * @return Function or @c NULL if symbol is not a function376 */377 283 stree_fun_t *symbol_to_fun(stree_symbol_t *symbol) 378 284 { … … 383 289 } 384 290 385 /** Convert function to symbol (derived to base).386 *387 * @param fun Function388 * @return Symbol389 */390 291 stree_symbol_t *fun_to_symbol(stree_fun_t *fun) 391 292 { … … 394 295 } 395 296 396 /** Convert symbol to member variable (base to derived).397 *398 * @param symbol Symbol399 * @return Variable or @c NULL if symbol is not a member variable400 */401 297 stree_var_t *symbol_to_var(stree_symbol_t *symbol) 402 298 { … … 407 303 } 408 304 409 /** Convert variable to symbol (derived to base).410 *411 * @param fun Variable412 * @return Symbol413 */414 305 stree_symbol_t *var_to_symbol(stree_var_t *var) 415 306 { … … 418 309 } 419 310 420 /** Convert symbol to property (base to derived).421 *422 * @param symbol Symbol423 * @return Property or @c NULL if symbol is not a property424 */425 311 stree_prop_t *symbol_to_prop(stree_symbol_t *symbol) 426 312 { … … 431 317 } 432 318 433 /** Convert property to symbol (derived to base).434 *435 * @param fun Property436 * @return Symbol437 */438 319 stree_symbol_t *prop_to_symbol(stree_prop_t *prop) 439 320 { … … 442 323 } 443 324 444 /** Print fully qualified name of symbol. 445 * 446 * @param symbol Symbol 447 */ 325 /** Print fully qualified name of symbol. */ 448 326 void symbol_print_fqn(stree_symbol_t *symbol) 449 327 { … … 461 339 } 462 340 463 /** Return symbol identifier.464 *465 * @param symbol Symbol466 * @return Symbol identifier467 */468 341 static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol) 469 342 { … … 472 345 switch (symbol->sc) { 473 346 case sc_csi: ident = symbol->u.csi->name; break; 474 case sc_deleg: ident = symbol->u.deleg->name; break;475 347 case sc_fun: ident = symbol->u.fun->name; break; 476 348 case sc_var: ident = symbol->u.var->name; break; -
uspace/app/sbi/src/symbol.h
rf4f866c r80badbe 40 40 stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name); 41 41 42 stree_deleg_t *symbol_to_deleg(stree_symbol_t *symbol);43 stree_symbol_t *deleg_to_symbol(stree_deleg_t *deleg);44 42 stree_csi_t *symbol_to_csi(stree_symbol_t *symbol); 45 43 stree_symbol_t *csi_to_symbol(stree_csi_t *csi); -
uspace/app/sbi/src/tdata.c
rf4f866c r80badbe 31 31 #include <stdlib.h> 32 32 #include <assert.h> 33 #include "intmap.h"34 33 #include "list.h" 35 34 #include "mytypes.h" 36 35 #include "stree.h" 37 #include "strtab.h"38 36 #include "symbol.h" 39 37 40 38 #include "tdata.h" 41 42 static void tdata_item_subst_tprimitive(tdata_primitive_t *torig,43 tdata_tvv_t *tvv, tdata_item_t **res);44 static void tdata_item_subst_tobject(tdata_object_t *torig, tdata_tvv_t *tvv,45 tdata_item_t **res);46 static void tdata_item_subst_tarray(tdata_array_t *torig, tdata_tvv_t *tvv,47 tdata_item_t **res);48 static void tdata_item_subst_tdeleg(tdata_deleg_t *torig,49 tdata_tvv_t *tvv, tdata_item_t **res);50 static void tdata_item_subst_tfun(tdata_fun_t *torig,51 tdata_tvv_t *tvv, tdata_item_t **res);52 static void tdata_item_subst_tvref(tdata_vref_t *tvref, tdata_tvv_t *tvv,53 tdata_item_t **res);54 55 static void tdata_item_subst_fun_sig(tdata_fun_sig_t *torig, tdata_tvv_t *tvv,56 tdata_fun_sig_t **res);57 39 58 40 static void tdata_tprimitive_print(tdata_primitive_t *tprimitive); 59 41 static void tdata_tobject_print(tdata_object_t *tobject); 60 42 static void tdata_tarray_print(tdata_array_t *tarray); 61 static void tdata_tdeleg_print(tdata_deleg_t *tdeleg);62 43 static void tdata_tfun_print(tdata_fun_t *tfun); 63 static void tdata_tvref_print(tdata_vref_t *tvref); 64 65 /** Determine if CSI @a a is derived from CSI described by type item @a tb. 66 * 67 * XXX This won't work with generics. 68 * 69 * @param a Potential derived CSI. 70 * @param tb Type of potentail base CSI. 71 */ 44 45 /** Determine if CSI @a a is derived from CSI described by type item @a tb. */ 72 46 bool_t tdata_is_csi_derived_from_ti(stree_csi_t *a, tdata_item_t *tb) 73 47 { … … 89 63 * Determine if CSI described by type item @a a is derived from CSI described 90 64 * by type item @a tb. 91 *92 * XXX This is somewhat complementary to stype_convert(). It is used for93 * the explicit @c as conversion. It should only work for objects and only94 * allow conversion from base to derived types. We might want to scrap this95 * for a version specific to @c as. The current code does not work with96 * generics.97 *98 * @param a Potential derived CSI.99 * @param tb Type of potentail base CSI.100 65 */ 101 66 bool_t tdata_is_ti_derived_from_ti(tdata_item_t *ta, tdata_item_t *tb) … … 115 80 } 116 81 117 /** Determine if two type items are equal (i.e. describe the same type). 118 * 119 * Needed to check compatibility of type arguments in which a parametrized 120 * type is not monotonous. 121 * 122 * @param a Type item 123 * @param b Type item 124 * @return @c b_true if equal, @c b_false if not. 125 */ 82 /** Determine if two type items are equal (i.e. describe the same type). */ 126 83 bool_t tdata_item_equal(tdata_item_t *a, tdata_item_t *b) 127 84 { … … 157 114 return tdata_item_equal(a->u.tarray->base_ti, 158 115 b->u.tarray->base_ti); 159 case tic_tvref:160 /* Check if both refer to the same type argument. */161 return (a->u.tvref->targ == b->u.tvref->targ);162 116 default: 163 117 printf("Warning: Unimplemented: Compare types '"); … … 170 124 } 171 125 172 /** Substitute type variables in a type item. 173 * 174 * This is the second part of generic type application. In the first part 175 * obtained a TVV using stype_titem_to_tvv() and in this second part we 176 * actually substitute type variables in a type item for their values. 177 * @a tvv must contain all variables referenced in @a ti. 178 * 179 * @param ti Type item to substitute into. 180 * @param tvv Type variable valuation (values of type variables). 181 * @param res Place to store pointer to new type item. 182 */ 183 void tdata_item_subst(tdata_item_t *ti, tdata_tvv_t *tvv, tdata_item_t **res) 184 { 185 switch (ti->tic) { 186 case tic_tprimitive: 187 tdata_item_subst_tprimitive(ti->u.tprimitive, tvv, res); 188 break; 189 case tic_tobject: 190 tdata_item_subst_tobject(ti->u.tobject, tvv, res); 191 break; 192 case tic_tarray: 193 tdata_item_subst_tarray(ti->u.tarray, tvv, res); 194 break; 195 case tic_tdeleg: 196 tdata_item_subst_tdeleg(ti->u.tdeleg, tvv, res); 197 break; 198 case tic_tfun: 199 tdata_item_subst_tfun(ti->u.tfun, tvv, res); 200 break; 201 case tic_tvref: 202 tdata_item_subst_tvref(ti->u.tvref, tvv, res); 203 break; 204 case tic_ignore: 205 *res = tdata_item_new(tic_ignore); 206 } 207 } 208 209 /** Substitute type variables in a primitive type item. 210 * 211 * @param torig Type item to substitute into. 212 * @param tvv Type variable valuation (values of type variables). 213 * @param res Place to store pointer to new type item. 214 */ 215 static void tdata_item_subst_tprimitive(tdata_primitive_t *torig, 216 tdata_tvv_t *tvv, tdata_item_t **res) 217 { 218 tdata_primitive_t *tnew; 219 220 (void) tvv; 221 222 /* Plain copy */ 223 tnew = tdata_primitive_new(torig->tpc); 224 *res = tdata_item_new(tic_tprimitive); 225 (*res)->u.tprimitive = tnew; 226 } 227 228 /** Substitute type variables in an object type item. 229 * 230 * @param torig Type item to substitute into. 231 * @param tvv Type variable valuation (values of type variables). 232 * @param res Place to store pointer to new type item. 233 */ 234 static void tdata_item_subst_tobject(tdata_object_t *torig, tdata_tvv_t *tvv, 235 tdata_item_t **res) 236 { 237 tdata_object_t *tnew; 238 list_node_t *targ_n; 239 tdata_item_t *targ; 240 tdata_item_t *new_targ; 241 242 /* Copy static ref flag and base CSI. */ 243 tnew = tdata_object_new(); 244 tnew->static_ref = torig->static_ref; 245 tnew->csi = torig->csi; 246 list_init(&tnew->targs); 247 248 /* Substitute arguments */ 249 targ_n = list_first(&torig->targs); 250 while (targ_n != NULL) { 251 targ = list_node_data(targ_n, tdata_item_t *); 252 tdata_item_subst(targ, tvv, &new_targ); 253 list_append(&tnew->targs, new_targ); 254 255 targ_n = list_next(&torig->targs, targ_n); 256 } 257 258 *res = tdata_item_new(tic_tobject); 259 (*res)->u.tobject = tnew; 260 } 261 262 /** Substitute type variables in an array type item. 263 * 264 * @param torig Type item to substitute into. 265 * @param tvv Type variable valuation (values of type variables). 266 * @param res Place to store pointer to new type item. 267 */ 268 static void tdata_item_subst_tarray(tdata_array_t *torig, tdata_tvv_t *tvv, 269 tdata_item_t **res) 270 { 271 tdata_array_t *tnew; 272 list_node_t *ext_n; 273 stree_expr_t *extent; 274 275 tnew = tdata_array_new(); 276 277 /* Substitute base type */ 278 tdata_item_subst(torig->base_ti, tvv, &tnew->base_ti); 279 280 /* Copy rank and extents */ 281 tnew->rank = torig->rank; 282 list_init(&tnew->extents); 283 284 ext_n = list_first(&torig->extents); 285 while (ext_n != NULL) { 286 extent = list_node_data(ext_n, stree_expr_t *); 287 list_append(&tnew->extents, extent); 288 289 ext_n = list_next(&tnew->extents, ext_n); 290 } 291 292 *res = tdata_item_new(tic_tarray); 293 (*res)->u.tarray = tnew; 294 } 295 296 /** Substitute type variables in a delegate type item. 297 * 298 * @param torig Type item to substitute into. 299 * @param tvv Type variable valuation (values of type variables). 300 * @param res Place to store pointer to new type item. 301 */ 302 static void tdata_item_subst_tdeleg(tdata_deleg_t *torig, tdata_tvv_t *tvv, 303 tdata_item_t **res) 304 { 305 tdata_deleg_t *tnew; 306 307 tnew = tdata_deleg_new(); 308 tnew->deleg = torig->deleg; 309 tdata_item_subst_fun_sig(torig->tsig, tvv, &tnew->tsig); 310 311 *res = tdata_item_new(tic_tdeleg); 312 (*res)->u.tdeleg = tnew; 313 } 314 315 /** Substitute type variables in a functional type item. 316 * 317 * @param torig Type item to substitute into. 318 * @param tvv Type variable valuation (values of type variables). 319 * @param res Place to store pointer to new type item. 320 */ 321 static void tdata_item_subst_tfun(tdata_fun_t *torig, tdata_tvv_t *tvv, 322 tdata_item_t **res) 323 { 324 tdata_fun_t *tnew; 325 326 tnew = tdata_fun_new(); 327 tdata_item_subst_fun_sig(torig->tsig, tvv, &tnew->tsig); 328 329 *res = tdata_item_new(tic_tfun); 330 (*res)->u.tfun = tnew; 331 } 332 333 /** Substitute type variables in a type-variable reference item. 334 * 335 * @param torig Type item to substitute into. 336 * @param tvv Type variable valuation (values of type variables). 337 * @param res Place to store pointer to new type item. 338 */ 339 static void tdata_item_subst_tvref(tdata_vref_t *tvref, tdata_tvv_t *tvv, 340 tdata_item_t **res) 341 { 342 tdata_item_t *ti_new; 343 344 ti_new = tdata_tvv_get_val(tvv, tvref->targ->name->sid); 345 assert(ti_new != NULL); 346 347 /* XXX Might be better to clone here. */ 348 *res = ti_new; 349 } 350 351 /** Substitute type variables in a function signature type fragment. 352 * 353 * @param torig Type item to substitute into. 354 * @param tvv Type variable valuation (values of type variables). 355 * @param res Place to store pointer to new type item. 356 */ 357 static void tdata_item_subst_fun_sig(tdata_fun_sig_t *torig, tdata_tvv_t *tvv, 358 tdata_fun_sig_t **res) 359 { 360 tdata_fun_sig_t *tnew; 361 list_node_t *arg_n; 362 tdata_item_t *arg_ti; 363 tdata_item_t *narg_ti; 364 365 tnew = tdata_fun_sig_new(); 366 367 /* Substitute type of each argument */ 368 list_init(&tnew->arg_ti); 369 arg_n = list_first(&torig->arg_ti); 370 while (arg_n != NULL) { 371 arg_ti = list_node_data(arg_n, tdata_item_t *); 372 373 /* XXX Because of overloaded Builtin.WriteLine */ 374 if (arg_ti == NULL) 375 narg_ti = NULL; 376 else 377 tdata_item_subst(arg_ti, tvv, &narg_ti); 378 379 list_append(&tnew->arg_ti, narg_ti); 380 381 arg_n = list_next(&torig->arg_ti, arg_n); 382 } 383 384 /* Substitute type of variadic argument */ 385 if (torig->varg_ti != NULL) 386 tdata_item_subst(torig->varg_ti, tvv, &tnew->varg_ti); 387 388 /* Substitute return type */ 389 if (torig->rtype != NULL) 390 tdata_item_subst(torig->rtype, tvv, &tnew->rtype); 391 392 *res = tnew; 393 } 394 395 396 /** Print type item. 397 * 398 * @param titem Type item 399 */ 126 /** Print type item. */ 400 127 void tdata_item_print(tdata_item_t *titem) 401 128 { … … 415 142 tdata_tarray_print(titem->u.tarray); 416 143 break; 417 case tic_tdeleg:418 tdata_tdeleg_print(titem->u.tdeleg);419 break;420 144 case tic_tfun: 421 145 tdata_tfun_print(titem->u.tfun); 422 146 break; 423 case tic_tvref:424 tdata_tvref_print(titem->u.tvref);425 break;426 147 case tic_ignore: 427 148 printf("ignore"); … … 430 151 } 431 152 432 /** Print primitive type item.433 *434 * @param tprimitive Primitive type item435 */436 153 static void tdata_tprimitive_print(tdata_primitive_t *tprimitive) 437 154 { … … 446 163 } 447 164 448 /** Print object type item.449 *450 * @param tobject Object type item451 */452 165 static void tdata_tobject_print(tdata_object_t *tobject) 453 166 { … … 469 182 } 470 183 471 /** Print array type item.472 *473 * @param tarray Array type item474 */475 184 static void tdata_tarray_print(tdata_array_t *tarray) 476 185 { … … 485 194 } 486 195 487 /** Print delegate type item.488 *489 * @param tdeleg Delegate type item490 */491 static void tdata_tdeleg_print(tdata_deleg_t *tdeleg)492 {493 stree_symbol_t *deleg_sym;494 495 deleg_sym = deleg_to_symbol(tdeleg->deleg);496 symbol_print_fqn(deleg_sym);497 }498 499 /** Print function type item.500 *501 * @param tfun Function type item502 */503 196 static void tdata_tfun_print(tdata_fun_t *tfun) 504 197 { 505 list_node_t *arg_n; 506 tdata_item_t *arg_ti; 507 bool_t first; 508 509 printf("fun("); 510 511 arg_n = list_first(&tfun->tsig->arg_ti); 512 first = b_true; 513 while (arg_n != NULL) { 514 if (first == b_false) 515 printf("; "); 516 else 517 first = b_false; 518 519 arg_ti = list_node_data(arg_n, tdata_item_t *); 520 tdata_item_print(arg_ti); 521 522 arg_n = list_next(&tfun->tsig->arg_ti, arg_n); 523 } 524 525 printf(") : "); 526 tdata_item_print(tfun->tsig->rtype); 527 } 528 529 /** Print type variable reference type item. 530 * 531 * @param tvref Type variable reference type item 532 */ 533 static void tdata_tvref_print(tdata_vref_t *tvref) 534 { 535 printf("%s", strtab_get_str(tvref->targ->name->sid)); 536 } 537 538 /** Allocate new type item. 539 * 540 * @param tic Type item class 541 * @return New type item 542 */ 198 (void) tfun; 199 printf("unimplemented(fun)"); 200 } 201 543 202 tdata_item_t *tdata_item_new(titem_class_t tic) 544 203 { … … 555 214 } 556 215 557 /** Allocate new array type item.558 *559 * @return New array type item560 */561 216 tdata_array_t *tdata_array_new(void) 562 217 { … … 572 227 } 573 228 574 /** Allocate new object type item.575 *576 * @return New object type item577 */578 229 tdata_object_t *tdata_object_new(void) 579 230 { … … 589 240 } 590 241 591 /** Allocate new primitive type item.592 *593 * @return New primitive type item594 */595 242 tdata_primitive_t *tdata_primitive_new(tprimitive_class_t tpc) 596 243 { … … 607 254 } 608 255 609 /** Allocate new delegate type item.610 *611 * @return New function type item612 */613 tdata_deleg_t *tdata_deleg_new(void)614 {615 tdata_deleg_t *tdeleg;616 617 tdeleg = calloc(1, sizeof(tdata_deleg_t));618 if (tdeleg == NULL) {619 printf("Memory allocation failed.\n");620 exit(1);621 }622 623 return tdeleg;624 }625 626 /** Allocate new functional type item.627 *628 * @return New function type item629 */630 256 tdata_fun_t *tdata_fun_new(void) 631 257 { … … 640 266 return tfun; 641 267 } 642 643 /** Allocate new type variable reference type item.644 *645 * @return New type variable reference type item646 */647 tdata_vref_t *tdata_vref_new(void)648 {649 tdata_vref_t *tvref;650 651 tvref = calloc(1, sizeof(tdata_vref_t));652 if (tvref == NULL) {653 printf("Memory allocation failed.\n");654 exit(1);655 }656 657 return tvref;658 }659 660 /** Allocate new function signature type fragment.661 *662 * @return New function signature type fragment663 */664 tdata_fun_sig_t *tdata_fun_sig_new(void)665 {666 tdata_fun_sig_t *tfun_sig;667 668 tfun_sig = calloc(1, sizeof(tdata_fun_sig_t));669 if (tfun_sig == NULL) {670 printf("Memory allocation failed.\n");671 exit(1);672 }673 674 return tfun_sig;675 }676 677 /** Create a new type variable valuation.678 *679 * @retrun New type variable valuation680 */681 tdata_tvv_t *tdata_tvv_new(void)682 {683 tdata_tvv_t *tvv;684 685 tvv = calloc(1, sizeof(tdata_tvv_t));686 if (tvv == NULL) {687 printf("Memory allocation failed.\n");688 exit(1);689 }690 691 return tvv;692 }693 694 /** Get type variable value.695 *696 * Looks up value of the variable with name SID @a name in type697 * variable valuation @a tvv.698 *699 * @param tvv Type variable valuation700 * @param name Name of the variable (SID)701 * @return Value of the type variable (type item) or @c NULL702 * if not defined in @a tvv703 */704 tdata_item_t *tdata_tvv_get_val(tdata_tvv_t *tvv, sid_t name)705 {706 return (tdata_item_t *)intmap_get(&tvv->tvv, name);707 }708 709 /** Set tyoe variable value.710 *711 * Sets the value of variable with name SID @a name in type variable712 * valuation @a tvv to the value @a tvalue.713 *714 * @param tvv Type variable valuation715 * @param name Name of the variable (SID)716 * @param tvalue Value to set (type item) or @c NULL to unset717 */718 void tdata_tvv_set_val(tdata_tvv_t *tvv, sid_t name, tdata_item_t *tvalue)719 {720 intmap_set(&tvv->tvv, name, tvalue);721 } -
uspace/app/sbi/src/tdata.h
rf4f866c r80badbe 36 36 tdata_object_t *tdata_object_new(void); 37 37 tdata_primitive_t *tdata_primitive_new(tprimitive_class_t tpc); 38 tdata_deleg_t *tdata_deleg_new(void);39 38 tdata_fun_t *tdata_fun_new(void); 40 tdata_vref_t *tdata_vref_new(void);41 42 tdata_fun_sig_t *tdata_fun_sig_new(void);43 44 tdata_tvv_t *tdata_tvv_new(void);45 tdata_item_t *tdata_tvv_get_val(tdata_tvv_t *tvv, sid_t name);46 void tdata_tvv_set_val(tdata_tvv_t *tvv, sid_t name, tdata_item_t *tvalue);47 39 48 40 bool_t tdata_is_csi_derived_from_ti(stree_csi_t *a, tdata_item_t *tb); 49 41 bool_t tdata_is_ti_derived_from_ti(tdata_item_t *ta, tdata_item_t *tb); 50 42 bool_t tdata_item_equal(tdata_item_t *a, tdata_item_t *b); 51 52 void tdata_item_subst(tdata_item_t *ti, tdata_tvv_t *tvv, tdata_item_t **res);53 43 void tdata_item_print(tdata_item_t *titem); 54 44 -
uspace/app/sbi/src/tdata_t.h
rf4f866c r80badbe 31 31 #ifndef TDATA_T_H_ 32 32 #define TDATA_T_H_ 33 34 #include "intmap_t.h"35 33 36 34 /** Class of primitive type. */ … … 80 78 } tdata_array_t; 81 79 82 /** Function signature type.83 *84 * This is a part of functional type or delegate type.85 */86 typedef struct {87 /** Types of fixed arguments. */88 list_t arg_ti; /* of tdata_item_t */89 90 /** Type of variadic argument */91 struct tdata_item *varg_ti;92 93 /** Return type */94 struct tdata_item *rtype;95 } tdata_fun_sig_t;96 97 /** Delegate type. */98 typedef struct {99 /** Delegate definition or @c NULL if anonymous delegate */100 struct stree_deleg *deleg;101 102 /** Delegate signature type */103 tdata_fun_sig_t *tsig;104 } tdata_deleg_t;105 106 80 /** Functional type. */ 107 81 typedef struct { 108 /** Delegate definition or @c NULL if anonymous delegate */ 109 struct stree_deleg *deleg; 110 111 /** Function signature type */ 112 tdata_fun_sig_t *tsig; 82 /** 83 * Function definition. We'll leave expansion to the call operation. 84 */ 85 struct stree_fun *fun; 113 86 } tdata_fun_t; 114 115 /** Type variable reference. */116 typedef struct {117 /** Definition of type argument this variable is referencing. */118 struct stree_targ *targ;119 } tdata_vref_t;120 87 121 88 typedef enum { … … 126 93 /** Array type item */ 127 94 tic_tarray, 128 /** Delegate type item */129 tic_tdeleg,130 95 /** Function type item */ 131 96 tic_tfun, 132 /** Type variable item */133 tic_tvref,134 97 /** Special error-recovery type item */ 135 98 tic_ignore … … 144 107 tdata_object_t *tobject; 145 108 tdata_array_t *tarray; 146 tdata_deleg_t *tdeleg;147 109 tdata_fun_t *tfun; 148 tdata_vref_t *tvref;149 110 } u; 150 111 } tdata_item_t; 151 112 152 /** Type variable valuation (mapping of type argument names to values). */153 typedef struct {154 /** Maps name SID to type item */155 intmap_t tvv; /* of tdata_item_t */156 } tdata_tvv_t;157 158 113 #endif -
uspace/dist/src/sysel/demos/arith.sy
rf4f866c r80badbe 30 30 fun Main() is 31 31 -- Test addition, multiplication and precedence. 32 Builtin.Write ("2*2 + 2*2 =");33 Builtin.Write (2*2 + 2*2);34 Builtin.WriteLine(" 32 Builtin.WriteLine("2*2 + 2*2 ="); 33 Builtin.WriteLine(2*2 + 2*2); 34 Builtin.WriteLine("(expected: 8)"); 35 35 36 36 -- Test subtraction, multiplication and precedence. 37 Builtin.Write ("1111 - 1 - 10 - 10*10 - 10*10*10 =");38 Builtin.Write (1111 - 1 - 10 - 10*10 - 10*10*10);39 Builtin.WriteLine(" 37 Builtin.WriteLine("1111 - 1 - 10 - 10*10 - 10*10*10 ="); 38 Builtin.WriteLine(1111 - 1 - 10 - 10*10 - 10*10*10); 39 Builtin.WriteLine("(expected: 0)"); 40 40 41 41 -- Test parenthesized sub-expressions. 42 Builtin.Write ("10 * (1 - 1) =");43 Builtin.Write (10 * (1 - 1));44 Builtin.WriteLine(" 42 Builtin.WriteLine("10 * (1 - 1) ="); 43 Builtin.WriteLine(10 * (1 - 1)); 44 Builtin.WriteLine("(expected: 0)"); 45 45 46 46 -- Test unary plus and minus. 47 Builtin.Write ("(+1) - (-1) - (+(+1)) + (+(-1)) = ");48 Builtin.Write ((+1) - (-1) - (+(+1)) + (+(-1)));49 Builtin.WriteLine(" 47 Builtin.WriteLine("(+1) - (-1) - (+(+1)) + (+(-1)) = "); 48 Builtin.WriteLine((+1) - (-1) - (+(+1)) + (+(-1))); 49 Builtin.WriteLine("(expected: 0)"); 50 50 51 51 -- Test signed multiplication. 52 Builtin.Write("+1 * +1 = "); 53 Builtin.Write(+1 * +1); 54 Builtin.WriteLine(" (expected: 1)"); 55 56 Builtin.Write("-1 * -1 = "); 57 Builtin.Write(-1 * -1); 58 Builtin.WriteLine(" (expected: 1)"); 59 60 Builtin.Write("+1 * -1 = "); 61 Builtin.Write(+1 * -1); 62 Builtin.WriteLine(" (expected: -1)"); 63 64 Builtin.Write("-1 * +1 = "); 65 Builtin.Write(-1 * +1); 66 Builtin.WriteLine(" (expected: -1)"); 52 Builtin.WriteLine("+1 * +1 = "); 53 Builtin.WriteLine(+1 * +1); 54 Builtin.WriteLine("(expected: 1)"); 55 Builtin.WriteLine("-1 * -1 = "); 56 Builtin.WriteLine(-1 * -1); 57 Builtin.WriteLine("(expected: 1)"); 58 Builtin.WriteLine("+1 * -1 = "); 59 Builtin.WriteLine(+1 * -1); 60 Builtin.WriteLine("(expected: -1)"); 61 Builtin.WriteLine("-1 * +1 = "); 62 Builtin.WriteLine(-1 * +1); 63 Builtin.WriteLine("(expected: -1)"); 67 64 68 65 -- Test multiplication with large result. 69 Builtin.Write ("1000000 * 1000000 * 1000000 * 1000000 =");70 Builtin.Write (1000000 * 1000000 * 1000000 * 1000000);71 Builtin.WriteLine(" 66 Builtin.WriteLine("1000000 * 1000000 * 1000000 * 1000000 ="); 67 Builtin.WriteLine(1000000 * 1000000 * 1000000 * 1000000); 68 Builtin.WriteLine("(expected: 1000000000000000000000000)"); 72 69 73 70 -- Test large literals. 74 Builtin.Write ("1000000000000000000000000 =");75 Builtin.Write (1000000000000000000000000);76 Builtin.WriteLine(" 71 Builtin.WriteLine("1000000000000000000000000 ="); 72 Builtin.WriteLine(1000000000000000000000000); 73 Builtin.WriteLine("(expected: 1000000000000000000000000)"); 77 74 78 75 -- Test large factorials. -
uspace/dist/src/sysel/demos/list.sy
rf4f866c r80badbe 30 30 class ListDemo is 31 31 fun Main() is 32 var list : List/int; 32 var list : List; 33 var i : Int; 33 34 34 list = new List /int();35 list = new List(); 35 36 list.Init(); 36 37 37 list.Append(5); 38 list.Append(6); 39 list.Append(7); 40 list.Append(8); 38 -- We need autoboxing or generics to get rid of this mess. 39 i = new Int(); i.Value = 5; list.Append(i); 40 i = new Int(); i.Value = 6; list.Append(i); 41 i = new Int(); i.Value = 7; list.Append(i); 42 i = new Int(); i.Value = 8; list.Append(i); 41 43 42 var n : ListNode /int;44 var n : ListNode; 43 45 44 46 n = list.First; 45 47 while n != nil do 46 Builtin.WriteLine( n.Value);48 Builtin.WriteLine((n.value as Int).Value); 47 49 n = n.Next; 48 50 end -
uspace/dist/src/sysel/demos/property.sy
rf4f866c r80badbe 33 33 prop X : int is 34 34 get is 35 Builtin.Write ("Getting value of X which is");35 Builtin.WriteLine("Getting value of X which is"); 36 36 Builtin.WriteLine(x); 37 37 return x; … … 39 39 40 40 set value is 41 Builtin.Write ("Setting value of X to");41 Builtin.WriteLine("Setting value of X to"); 42 42 Builtin.WriteLine(value); 43 43 x = value; … … 51 51 prop self[index : int] : int is 52 52 get is 53 Builtin.Write ("Getting property with index ");54 Builtin.Write (index);55 Builtin.Write (" which is");53 Builtin.WriteLine("Getting property with index "); 54 Builtin.WriteLine(index); 55 Builtin.WriteLine("which is"); 56 56 Builtin.WriteLine(iprops[index]); 57 57 … … 60 60 61 61 set value is 62 Builtin.Write ("Setting property with index ");63 Builtin.Write (index);64 Builtin.Write (" to");62 Builtin.WriteLine("Setting property with index "); 63 Builtin.WriteLine(index); 64 Builtin.WriteLine("to"); 65 65 Builtin.WriteLine(value); 66 66 … … 110 110 i = a.X; 111 111 112 Builtin.Write ("Main(): Got ");112 Builtin.WriteLine("Main(): Got "); 113 113 Builtin.WriteLine(i); 114 114 … … 121 121 i = a[1]; 122 122 123 Builtin.Write ("Main(): Got ");123 Builtin.WriteLine("Main(): Got "); 124 124 Builtin.WriteLine(i); 125 125 -
uspace/dist/src/sysel/lib/boxed.sy
rf4f866c r80badbe 28 28 29 29 -- 30 -- Declarations for boxed variants of primitive types. The interpreter 31 -- binds to these types internally. They must be declared. 30 -- Declarations for boxed variants of primitive types. 32 31 -- 33 32 -
uspace/dist/src/sysel/lib/list.sy
rf4f866c r80badbe 27 27 -- 28 28 29 -- Doubly-linked list.30 class List /tis31 var head : ListNode /t;29 -- Doubly-linked non-generic list. 30 class List is 31 var head : ListNode; 32 32 33 33 -- Initialize list. 34 34 fun Init() is 35 head = new ListNode /t();35 head = new ListNode(); 36 36 head.prev = head; 37 37 head.next = head; … … 39 39 40 40 -- Append new entry at the end of the list. 41 fun Append(data : t) is42 var n : ListNode /t;43 var ntl : ListNode /t;41 fun Append(data : Object) is 42 var n : ListNode; 43 var ntl : ListNode; 44 44 45 45 ntl = head.prev; 46 46 47 n = new ListNode /t();47 n = new ListNode(); 48 48 n.value = data; 49 49 … … 57 57 58 58 -- Return first node in the list or @c nil if there is none. 59 prop First : ListNode /tis59 prop First : ListNode is 60 60 get is 61 61 return get_first(); … … 64 64 65 65 -- Return first node in the list or @c nil if there is none. 66 fun get_first() : ListNode /tis66 fun get_first() : ListNode is 67 67 if head.next == head then 68 68 return nil; … … 73 73 end 74 74 75 class ListNode /tis76 var value : t;75 class ListNode is 76 var value : Object; 77 77 78 var prev : ListNode /t;79 var next : ListNode /t;80 var head : ListNode /t;78 var prev : ListNode; 79 var next : ListNode; 80 var head : ListNode; 81 81 82 82 -- Value stored in this node. 83 prop Value : t is83 prop Value : Object is 84 84 get is 85 85 return value; … … 88 88 89 89 -- Previous node in list. 90 prop Prev : ListNode /tis90 prop Prev : ListNode is 91 91 get is 92 92 return get_prev(); … … 95 95 96 96 -- Next node in list. 97 prop Next : ListNode /tis97 prop Next : ListNode is 98 98 get is 99 99 return get_next(); … … 102 102 103 103 -- Get next node. 104 fun get_next() : ListNode /tis104 fun get_next() : ListNode is 105 105 if next != head then 106 106 return next; … … 111 111 112 112 -- Get previous node. 113 fun get_prev() : ListNode /tis113 fun get_prev() : ListNode is 114 114 if prev != head then 115 115 return next;
Note:
See TracChangeset
for help on using the changeset viewer.