Changeset 640ffe6 in mainline
- Timestamp:
- 2010-05-08T08:15:57Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4039c77
- Parents:
- 1317380 (diff), 051bc69a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 9 added
- 45 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/Makefile
r1317380 r640ffe6 38 38 src/builtin/bi_fun.c \ 39 39 src/builtin/bi_textfile.c \ 40 src/builtin/bi_string.c \ 40 41 src/os/helenos.c \ 41 42 src/ancr.c \ 42 43 src/bigint.c \ 43 44 src/builtin.c \ 45 src/cspan.c \ 44 46 src/imode.c \ 45 47 src/input.c \ -
uspace/app/sbi/src/ancr.c
r1317380 r640ffe6 81 81 while (node != NULL) { 82 82 modm = list_node_data(node, stree_modm_t *); 83 assert(modm->mc == mc_csi); /* XXX */ 84 ancr_csi_dfs(prog, modm->u.csi); 83 84 switch (modm->mc) { 85 case mc_csi: 86 ancr_csi_dfs(prog, modm->u.csi); 87 break; 88 case mc_enum: 89 break; 90 } 85 91 86 92 node = list_next(&prog->module->members, node); -
uspace/app/sbi/src/builtin.c
r1317380 r640ffe6 44 44 #include "builtin/bi_fun.h" 45 45 #include "builtin/bi_textfile.h" 46 #include "builtin/bi_string.h" 46 47 #include "input.h" 47 48 #include "intmap.h" … … 90 91 bi_fun_declare(bi); 91 92 bi_textfile_declare(bi); 93 bi_string_declare(bi); 92 94 } 93 95 … … 105 107 bi_fun_bind(bi); 106 108 bi_textfile_bind(bi); 109 bi_string_bind(bi); 107 110 } 108 111 -
uspace/app/sbi/src/builtin/bi_textfile.c
r1317380 r640ffe6 71 71 "fun WriteLine(line : string), builtin;\n" 72 72 "\n" 73 "prop EOF : intis\n"73 "prop EOF : bool is\n" 74 74 "get is\n" 75 75 "return is_eof();\n" … … 77 77 "end\n" 78 78 "\n" 79 "fun is_eof() : int, builtin;\n"79 "fun is_eof() : bool, builtin;\n" 80 80 "end\n"); 81 81 … … 342 342 rdata_var_t *self_f_var; 343 343 344 int eof_flag;345 rdata_ int_t *eof_int;344 bool_t eof_flag; 345 rdata_bool_t *eof_bool; 346 346 rdata_var_t *eof_var; 347 347 rdata_value_t *eof_val; … … 362 362 /* Get status of EOF flag. */ 363 363 364 eof_flag = feof(file) ? 1 : 0;365 366 #ifdef DEBUG_RUN_TRACE 367 printf("Read EOF flag '% d'.\n", eof_flag);364 eof_flag = feof(file) ? b_true : b_false; 365 366 #ifdef DEBUG_RUN_TRACE 367 printf("Read EOF flag '%s'.\n", eof_flag ? "true" : "false"); 368 368 #endif 369 369 /* Construct return value. */ 370 eof_ int = rdata_int_new();371 bigint_init(&eof_int->value, eof_flag);372 373 eof_var = rdata_var_new(vc_ int);374 eof_var->u. int_v = eof_int;370 eof_bool = rdata_bool_new(); 371 eof_bool->value = eof_flag; 372 373 eof_var = rdata_var_new(vc_bool); 374 eof_var->u.bool_v = eof_bool; 375 375 eof_val = rdata_value_new(); 376 376 eof_val->var = eof_var; -
uspace/app/sbi/src/imode.c
r1317380 r640ffe6 116 116 fun->name = stree_ident_new(); 117 117 fun->name->sid = strtab_get_sid("$imode"); 118 fun->sig = stree_fun_sig_new(); 118 119 119 120 stype.proc_vr->proc = proc; -
uspace/app/sbi/src/input.c
r1317380 r640ffe6 118 118 } 119 119 120 input->name = os_str_dup(fname); 120 121 input->str = NULL; 121 122 input->line_no = 0; … … 136 137 } 137 138 139 input->name = "<user-input>"; 138 140 input->str = NULL; 139 141 input->line_no = 0; … … 154 156 } 155 157 158 input->name = "<builtin>"; 156 159 input->str = str; 157 160 input->line_no = 0; … … 226 229 /** Get number of the last provided line of input. 227 230 * 228 * @param input Input module.231 * @param input Input object. 229 232 * @return Line number of the last provided input line (counting 230 233 * from 1 up). -
uspace/app/sbi/src/input_t.h
r1317380 r640ffe6 34 34 /** Input state object */ 35 35 typedef struct input { 36 /** Input name (for error output) */ 37 const char *name; 38 36 39 /** Input file if reading from file. */ 37 40 FILE *fin; -
uspace/app/sbi/src/lex.c
r1317380 r640ffe6 35 35 #include <stdlib.h> 36 36 #include "bigint.h" 37 #include "cspan.h" 37 38 #include "mytypes.h" 38 39 #include "input.h" … … 74 75 /** Keyword names. Used both for printing and recognition. */ 75 76 static struct lc_name keywords[] = { 77 { lc_and, "and" }, 76 78 { lc_as, "as" }, 77 79 { lc_bool, "bool" }, 80 { lc_break, "break" }, 81 { lc_builtin, "builtin" }, 78 82 { lc_char, "char" }, 79 { lc_builtin, "builtin" },80 83 { lc_class, "class" }, 81 { lc_constructor, "constructor" },82 84 { lc_deleg, "deleg" }, 83 85 { lc_do, "do" }, 86 { lc_elif, "elif" }, 84 87 { lc_else, "else" }, 85 88 { lc_end, "end" }, 89 { lc_enum, "enum" }, 86 90 { lc_except, "except" }, 87 91 { lc_false, "false" }, … … 96 100 { lc_is, "is" }, 97 101 { lc_new, "new" }, 102 { lc_not, "not" }, 98 103 { lc_nil, "nil" }, 104 { lc_or, "or" }, 99 105 { lc_override, "override" }, 100 106 { lc_packed, "packed" }, … … 233 239 void lem_print_coords(lem_t *lem) 234 240 { 235 printf("%d:%d", lem->line_no, lem->col_0);241 cspan_print(lem->cspan); 236 242 } 237 243 … … 255 261 lex->ibp = lex->inbuf; 256 262 lex->col_adj = 0; 263 lex->prev_valid = b_false; 257 264 lex->current_valid = b_true; 258 265 } … … 279 286 * @param lex Lexer object. 280 287 * @return Pointer to current lem. Owned by @a lex and only valid 281 * until next call to lex_ next().288 * until next call to lex_xxx(). 282 289 */ 283 290 lem_t *lex_get_current(lex_t *lex) … … 287 294 } 288 295 296 /** Get previous lem if valid. 297 * 298 * The returned pointer is invalidated by next call to lex_next() 299 * 300 * @param lex Lexer object. 301 * @return Pointer to previous lem. Owned by @a lex and only valid 302 * until next call to lex_xxx(). 303 */ 304 lem_t *lex_peek_prev(lex_t *lex) 305 { 306 if (lex->current_valid == b_false) { 307 /* 308 * This means the head is advanced but next lem was not read. 309 * Thus the previous lem is still in @a current. 310 */ 311 return &lex->current; 312 } 313 314 if (lex->prev_valid != b_true) { 315 /* Looks like we are still at the first lem. */ 316 return NULL; 317 } 318 319 /* 320 * Current lem has been read in. Thus the previous lem was moved to 321 * @a previous. 322 */ 323 return &lex->prev; 324 } 325 289 326 /** Read in the current lexical element (unless already read in). 290 327 * … … 297 334 if (lex->current_valid == b_true) 298 335 return; 336 337 /* Copy previous lem */ 338 lex->prev = lex->current; 339 lex->prev_valid = b_true; 299 340 300 341 do { … … 318 359 static bool_t lex_read_try(lex_t *lex) 319 360 { 320 char *bp; 361 char *bp, *lsp; 362 int line0, col0; 321 363 322 364 lex_skip_ws(lex); … … 328 370 * separately using col_adj. 329 371 */ 330 lex->current.line_no = input_get_line_no(lex->input); 331 lex->current.col_0 = 1 + lex->col_adj + (lex->ibp - lex->inbuf); 332 372 line0 = input_get_line_no(lex->input); 373 col0 = 1 + lex->col_adj + (lex->ibp - lex->inbuf); 374 375 lex->current.cspan = cspan_new(lex->input, line0, col0, line0, col0); 376 377 lsp = lex->ibp; 333 378 bp = lex->ibp; 334 379 … … 336 381 /* End of input */ 337 382 lex->current.lclass = lc_eof; 338 return b_true;383 goto finish; 339 384 } 340 385 341 386 if (is_wstart(bp[0])) { 342 387 lex_word(lex); 343 return b_true;388 goto finish; 344 389 } 345 390 346 391 if (bp[0] == '\'') { 347 392 lex_char(lex); 348 return b_true;393 goto finish; 349 394 } 350 395 351 396 if (is_digit(bp[0])) { 352 397 lex_number(lex); 353 return b_true;398 goto finish; 354 399 } 355 400 356 401 if (bp[0] == '"') { 357 402 lex_string(lex); 358 return b_true;403 goto finish; 359 404 } 360 405 361 406 if (bp[0] == '-' && bp[1] == '-') { 362 407 lex_skip_comment(lex); 408 409 /* Compute ending column number */ 410 lex->current.cspan->col1 = col0 + (lex->ibp - lsp) - 1; 411 412 /* Try again */ 363 413 return b_false; 364 414 } … … 417 467 418 468 lex->ibp = bp; 469 470 finish: 471 /* Compute ending column number */ 472 lex->current.cspan->col1 = col0 + (lex->ibp - lsp) - 1; 419 473 return b_true; 420 474 -
uspace/app/sbi/src/lex.h
r1317380 r640ffe6 39 39 void lex_next(lex_t *lex); 40 40 lem_t *lex_get_current(lex_t *lex); 41 lem_t *lex_peek_prev(lex_t *lex); 41 42 42 43 #endif -
uspace/app/sbi/src/lex_t.h
r1317380 r640ffe6 43 43 44 44 /* Keywords */ 45 lc_and, 45 46 lc_as, 47 lc_break, 46 48 lc_bool, 47 49 lc_builtin, 48 50 lc_char, 49 51 lc_class, 50 lc_constructor,51 52 lc_deleg, 52 53 lc_do, 54 lc_elif, 53 55 lc_else, 54 56 lc_end, 57 lc_enum, 55 58 lc_except, 56 59 lc_false, … … 66 69 lc_is, 67 70 lc_nil, 71 lc_not, 72 lc_or, 68 73 lc_override, 69 74 lc_packed, … … 148 153 149 154 /** Coordinates of this lexical element */ 150 int line_no, col_0;155 struct cspan *cspan; 151 156 } lem_t; 152 157 … … 168 173 int col_adj; 169 174 170 /** @c b_true if we have the next lem in @c current */ 175 /** @c b_true if we have the previous lem in @c prev */ 176 bool_t prev_valid; 177 178 /** Previous lem (only valid if @c current_valid is true) */ 179 lem_t prev; 180 181 /** @c b_true if we have the current lem in @c current */ 171 182 bool_t current_valid; 172 183 -
uspace/app/sbi/src/mytypes.h
r1317380 r640ffe6 49 49 #include "bigint_t.h" 50 50 #include "builtin_t.h" 51 #include "cspan_t.h" 51 52 #include "input_t.h" 52 53 #include "intmap_t.h" -
uspace/app/sbi/src/os/helenos.c
r1317380 r640ffe6 29 29 /** @file HelenOS-specific code. */ 30 30 31 #include <assert.h> 31 32 #include <errno.h> 32 33 #include <stdio.h> … … 75 76 } 76 77 78 /** Return slice (substring) of a string. 79 * 80 * Copies the specified range of characters from @a str and returns it 81 * as a newly allocated string. @a start + @a length must be less than 82 * or equal to the length of @a str. 83 * 84 * @param str String 85 * @param start Index of first character (starting from zero). 86 * @param length Number of characters to copy. 87 * 88 * @return Newly allocated string holding the slice. 89 */ 90 char *os_str_aslice(const char *str, size_t start, size_t length) 91 { 92 char *slice; 93 size_t offset; 94 size_t i; 95 size_t size; 96 wchar_t c; 97 98 assert(start + length <= str_length(str)); 99 100 offset = 0; 101 for (i = 0; i < start; ++i) { 102 c = str_decode(str, &offset, STR_NO_LIMIT); 103 assert(c != '\0'); 104 assert(c != U_SPECIAL); 105 (void) c; 106 } 107 108 size = str_lsize(str, length); 109 slice = str_ndup(str + offset, size); 110 111 return slice; 112 } 113 77 114 /** Compare two strings. 78 115 * -
uspace/app/sbi/src/os/os.h
r1317380 r640ffe6 31 31 32 32 char *os_str_acat(const char *a, const char *b); 33 char *os_str_aslice(const char *str, size_t start, size_t length); 33 34 int os_str_cmp(const char *a, const char *b); 34 35 char *os_str_dup(const char *str); -
uspace/app/sbi/src/os/posix.c
r1317380 r640ffe6 29 29 /** @file POSIX-specific code. */ 30 30 31 #include <assert.h> 31 32 #include <libgen.h> 32 33 #include <stdio.h> … … 78 79 } 79 80 81 /** Return slice (substring) of a string. 82 * 83 * Copies the specified range of characters from @a str and returns it 84 * as a newly allocated string. @a start + @a length must be less than 85 * or equal to the length of @a str. 86 * 87 * @param str String 88 * @param start Index of first character (starting from zero). 89 * @param length Number of characters to copy. 90 * 91 * @return Newly allocated string holding the slice. 92 */ 93 char *os_str_aslice(const char *str, size_t start, size_t length) 94 { 95 char *slice; 96 97 assert(start + length <= strlen(str)); 98 slice = malloc(length + 1); 99 if (slice == NULL) { 100 printf("Memory allocation error.\n"); 101 exit(1); 102 } 103 104 strncpy(slice, str + start, length); 105 slice[length] = '\0'; 106 107 return slice; 108 } 109 80 110 /** Compare two strings. 81 111 * -
uspace/app/sbi/src/p_expr.c
r1317380 r640ffe6 32 32 #include <stdlib.h> 33 33 #include "bigint.h" 34 #include "cspan.h" 34 35 #include "debug.h" 35 36 #include "lex.h" … … 43 44 44 45 static stree_expr_t *parse_assign(parse_t *parse); 46 static stree_expr_t *parse_disjunctive(parse_t *parse); 47 static stree_expr_t *parse_conjunctive(parse_t *parse); 45 48 static stree_expr_t *parse_comparative(parse_t *parse); 46 49 static stree_expr_t *parse_additive(parse_t *parse); … … 95 98 stree_assign_t *assign; 96 99 97 a = parse_ comparative(parse);100 a = parse_disjunctive(parse); 98 101 99 102 switch (lcur_lc(parse)) { … … 109 112 110 113 lskip(parse); 111 b = parse_ comparative(parse);114 b = parse_disjunctive(parse); 112 115 113 116 assign->dest = a; … … 116 119 tmp = stree_expr_new(ec_assign); 117 120 tmp->u.assign = assign; 121 tmp->cspan = cspan_merge(a->cspan, b->cspan); 122 123 assign->expr = tmp; 124 118 125 return tmp; 126 } 127 128 /** Parse disjunctive expression. 129 * 130 * @param parse Parser object. 131 */ 132 static stree_expr_t *parse_disjunctive(parse_t *parse) 133 { 134 stree_expr_t *a, *b, *tmp; 135 stree_binop_t *binop; 136 cspan_t *cs; 137 138 a = parse_conjunctive(parse); 139 cs = a->cspan; 140 141 while (lcur_lc(parse) == lc_or) { 142 if (parse_is_error(parse)) 143 break; 144 145 lskip(parse); 146 b = parse_conjunctive(parse); 147 148 binop = stree_binop_new(bo_or); 149 binop->arg1 = a; 150 binop->arg2 = b; 151 152 tmp = stree_expr_new(ec_binop); 153 tmp->u.binop = binop; 154 tmp->cspan = cspan_merge(cs, b->cspan); 155 binop->expr = tmp; 156 157 a = tmp; 158 cs = tmp->cspan; 159 } 160 161 return a; 162 } 163 164 /** Parse conjunctive expression. 165 * 166 * @param parse Parser object. 167 */ 168 static stree_expr_t *parse_conjunctive(parse_t *parse) 169 { 170 stree_expr_t *a, *b, *tmp; 171 stree_binop_t *binop; 172 cspan_t *cs; 173 174 a = parse_comparative(parse); 175 cs = a->cspan; 176 177 while (lcur_lc(parse) == lc_and) { 178 if (parse_is_error(parse)) 179 break; 180 181 lskip(parse); 182 b = parse_comparative(parse); 183 184 binop = stree_binop_new(bo_and); 185 binop->arg1 = a; 186 binop->arg2 = b; 187 188 tmp = stree_expr_new(ec_binop); 189 tmp->u.binop = binop; 190 tmp->cspan = cspan_merge(cs, b->cspan); 191 binop->expr = tmp; 192 193 a = tmp; 194 cs = tmp->cspan; 195 } 196 197 return a; 119 198 } 120 199 … … 128 207 stree_binop_t *binop; 129 208 binop_class_t bc; 209 cspan_t *cs; 130 210 131 211 a = parse_additive(parse); 212 cs = a->cspan; 132 213 133 214 while (lcur_lc(parse) == lc_equal || lcur_lc(parse) == lc_notequal || … … 157 238 tmp = stree_expr_new(ec_binop); 158 239 tmp->u.binop = binop; 240 tmp->cspan = cspan_merge(cs, b->cspan); 241 binop->expr = tmp; 242 159 243 a = tmp; 244 cs = tmp->cspan; 160 245 } 161 246 … … 172 257 stree_binop_t *binop; 173 258 binop_class_t bc; 259 cspan_t *cs; 174 260 175 261 a = parse_multip(parse); 262 cs = a->cspan; 263 176 264 while (lcur_lc(parse) == lc_plus || lcur_lc(parse) == lc_minus) { 177 265 if (parse_is_error(parse)) … … 193 281 tmp = stree_expr_new(ec_binop); 194 282 tmp->u.binop = binop; 283 tmp->cspan = cspan_merge(cs, b->cspan); 284 binop->expr = tmp; 285 195 286 a = tmp; 287 cs = tmp->cspan; 196 288 } 197 289 … … 208 300 stree_binop_t *binop; 209 301 binop_class_t bc; 302 cspan_t *cs; 210 303 211 304 a = parse_prefix(parse); 305 cs = a->cspan; 306 212 307 while (lcur_lc(parse) == lc_mult) { 213 308 if (parse_is_error(parse)) … … 228 323 tmp = stree_expr_new(ec_binop); 229 324 tmp->u.binop = binop; 325 tmp->cspan = cspan_merge(cs, b->cspan); 326 binop->expr = tmp; 327 230 328 a = tmp; 329 cs = tmp->cspan; 231 330 } 232 331 … … 244 343 stree_unop_t *unop; 245 344 unop_class_t uc; 345 cspan_t *cs0; 246 346 247 347 switch (lcur_lc(parse)) { 248 348 case lc_plus: 249 349 case lc_minus: 350 case lc_not: 250 351 if (parse_is_error(parse)) 251 352 return parse_recovery_expr(parse); … … 254 355 case lc_plus: uc = uo_plus; break; 255 356 case lc_minus: uc = uo_minus; break; 357 case lc_not: uc = uo_not; break; 256 358 default: assert(b_false); 257 359 } 258 360 361 cs0 = lcur_span(parse); 259 362 lskip(parse); 260 363 a = parse_postfix(parse); … … 265 368 tmp = stree_expr_new(ec_unop); 266 369 tmp->u.unop = unop; 370 tmp->cspan = cspan_merge(cs0, a->cspan); 371 unop->expr = tmp; 267 372 a = tmp; 268 373 break; … … 287 392 stree_new_t *new_op; 288 393 stree_expr_t *expr; 289 394 stree_expr_t *arg; 395 cspan_t *cs0, *cs1; 396 397 cs0 = lcur_span(parse); 290 398 lmatch(parse, lc_new); 291 399 texpr = parse_texpr(parse); 292 400 293 /* Parenthesis should be present except for arrays. */ 294 if (texpr->tc != tc_tindex) { 295 lmatch(parse, lc_lparen); 296 lmatch(parse, lc_rparen); 297 } 401 /* XXX Take span from texpr */ 402 cs1 = lprev_span(parse); 298 403 299 404 new_op = stree_new_new(); … … 302 407 expr->u.new_op = new_op; 303 408 409 list_init(&new_op->ctor_args); 410 411 /* Parenthesized arguments should be present except for arrays. */ 412 if (texpr->tc != tc_tindex) { 413 lmatch(parse, lc_lparen); 414 415 /* Parse constructor arguments */ 416 417 if (lcur_lc(parse) != lc_rparen) { 418 while (!parse_is_error(parse)) { 419 arg = parse_expr(parse); 420 list_append(&new_op->ctor_args, arg); 421 422 if (lcur_lc(parse) == lc_rparen) 423 break; 424 lmatch(parse, lc_comma); 425 } 426 } 427 428 lmatch(parse, lc_rparen); 429 cs1 = cspan_merge(cs0, lprev_span(parse)); 430 } 431 432 expr->cspan = cspan_merge(cs0, cs1); 433 new_op->expr = expr; 434 304 435 return expr; 305 436 } … … 354 485 stree_expr_t *expr; 355 486 stree_access_t *access; 487 cspan_t *cs1; 356 488 357 489 lmatch(parse, lc_period); 358 490 ident = parse_ident(parse); 491 492 /* XXX Take span from ident */ 493 cs1 = lprev_span(parse); 359 494 360 495 access = stree_access_new(); … … 364 499 expr = stree_expr_new(ec_access); 365 500 expr->u.access = access; 501 expr->cspan = cspan_merge(a->cspan, cs1); 502 503 access->expr = expr; 366 504 367 505 return expr; … … 377 515 stree_call_t *call; 378 516 stree_expr_t *arg; 517 cspan_t *cs1; 379 518 380 519 lmatch(parse, lc_lparen); … … 398 537 399 538 lmatch(parse, lc_rparen); 539 cs1 = lprev_span(parse); 400 540 401 541 expr = stree_expr_new(ec_call); 402 542 expr->u.call = call; 543 expr->cspan = cspan_merge(a->cspan, cs1); 544 call->expr = expr; 403 545 404 546 return expr; … … 414 556 stree_index_t *index; 415 557 stree_expr_t *arg; 558 cspan_t *cs1; 416 559 417 560 lmatch(parse, lc_lsbr); … … 435 578 436 579 lmatch(parse, lc_rsbr); 580 cs1 = lprev_span(parse); 437 581 438 582 expr = stree_expr_new(ec_index); 439 583 expr->u.index = index; 584 expr->cspan = cspan_merge(a->cspan, cs1); 585 index->expr = expr; 440 586 441 587 return expr; … … 451 597 stree_texpr_t *texpr; 452 598 stree_as_t *as_op; 599 cspan_t *cs1; 453 600 454 601 lmatch(parse, lc_as); 455 602 texpr = parse_texpr(parse); 603 604 /* XXX Take span from texpr */ 605 cs1 = lprev_span(parse); 456 606 457 607 as_op = stree_as_new(); 458 608 as_op->arg = a; 459 609 as_op->dtype = texpr; 610 460 611 expr = stree_expr_new(ec_as); 461 612 expr->u.as_op = as_op; 613 expr->cspan = cspan_merge(a->cspan, cs1); 614 615 as_op->expr = expr; 462 616 463 617 return expr; … … 471 625 { 472 626 stree_expr_t *expr; 627 cspan_t *cs0, *cs1; 473 628 474 629 if (lcur_lc(parse) == lc_lparen) { 630 cs0 = lcur_span(parse); 475 631 lskip(parse); 476 632 expr = parse_expr(parse); 477 633 lmatch(parse, lc_rparen); 634 cs1 = lprev_span(parse); 635 636 expr->cspan = cspan_merge(cs0, cs1); 478 637 } else { 479 638 expr = parse_primitive(parse); … … 482 641 return expr; 483 642 } 484 485 643 486 644 /** Parse primitive expression. … … 536 694 expr = stree_expr_new(ec_nameref); 537 695 expr->u.nameref = nameref; 696 expr->cspan = lprev_span(parse); 697 nameref->expr = expr; 538 698 539 699 return expr; … … 563 723 expr = stree_expr_new(ec_literal); 564 724 expr->u.literal = literal; 725 expr->cspan = lprev_span(parse); 726 literal->expr = expr; 565 727 566 728 return expr; … … 586 748 expr = stree_expr_new(ec_literal); 587 749 expr->u.literal = literal; 750 expr->cspan = lprev_span(parse); 751 literal->expr = expr; 588 752 589 753 return expr; … … 609 773 expr = stree_expr_new(ec_literal); 610 774 expr->u.literal = literal; 775 expr->cspan = lprev_span(parse); 776 literal->expr = expr; 611 777 612 778 return expr; … … 628 794 expr = stree_expr_new(ec_literal); 629 795 expr->u.literal = literal; 796 expr->cspan = lprev_span(parse); 797 literal->expr = expr; 630 798 631 799 return expr; … … 650 818 expr = stree_expr_new(ec_literal); 651 819 expr->u.literal = literal; 820 expr->cspan = lprev_span(parse); 821 literal->expr = expr; 652 822 653 823 return expr; … … 669 839 expr = stree_expr_new(ec_self_ref); 670 840 expr->u.self_ref = self_ref; 841 expr->cspan = lprev_span(parse); 842 self_ref->expr = expr; 671 843 672 844 return expr; … … 688 860 expr = stree_expr_new(ec_literal); 689 861 expr->u.literal = literal; 690 691 return expr; 692 } 862 literal->expr = expr; 863 864 return expr; 865 } -
uspace/app/sbi/src/p_type.c
r1317380 r640ffe6 31 31 #include <assert.h> 32 32 #include <stdlib.h> 33 #include "cspan.h" 33 34 #include "debug.h" 34 35 #include "lex.h" … … 45 46 static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a); 46 47 static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a); 48 static stree_texpr_t *parse_tparen(parse_t *parse); 47 49 static stree_texpr_t *parse_tprimitive(parse_t *parse); 48 static stree_t literal_t *parse_tliteral(parse_t *parse);49 static stree_t nameref_t *parse_tnameref(parse_t *parse);50 static stree_texpr_t *parse_tliteral(parse_t *parse); 51 static stree_texpr_t *parse_tnameref(parse_t *parse); 50 52 51 53 static stree_texpr_t *parse_recovery_texpr(parse_t *parse); … … 91 93 list_init(&tapply->targs); 92 94 95 targ = NULL; 96 93 97 while (lcur_lc(parse) == lc_slash) { 94 98 … … 104 108 aexpr = stree_texpr_new(tc_tapply); 105 109 aexpr->u.tapply = tapply; 110 tapply->texpr = aexpr; 111 112 if (targ != NULL) 113 aexpr->cspan = cspan_merge(gtype->cspan, targ->cspan); 114 else 115 aexpr->cspan = gtype->cspan; 116 106 117 return aexpr; 107 118 } … … 116 127 stree_texpr_t *tmp; 117 128 118 a = parse_tp rimitive(parse);129 a = parse_tparen(parse); 119 130 120 131 while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lsbr) { … … 162 173 texpr = stree_texpr_new(tc_taccess); 163 174 texpr->u.taccess = taccess; 175 taccess->texpr = texpr; 176 texpr->cspan = cspan_merge(a->cspan, ident->cspan); 164 177 165 178 return texpr; … … 176 189 stree_tindex_t *tindex; 177 190 stree_expr_t *expr; 191 cspan_t *cs1; 178 192 179 193 tindex = stree_tindex_new(); … … 209 223 210 224 lmatch(parse, lc_rsbr); 225 cs1 = lprev_span(parse); 211 226 212 227 texpr = stree_texpr_new(tc_tindex); 213 228 texpr->u.tindex = tindex; 214 215 return texpr; 216 } 229 tindex->texpr = texpr; 230 texpr->cspan = cspan_merge(a->cspan, cs1); 231 232 return texpr; 233 } 234 235 /** Parse possibly partenthesized type expression. 236 * 237 * @param parse Parser object. 238 */ 239 static stree_texpr_t *parse_tparen(parse_t *parse) 240 { 241 stree_texpr_t *texpr; 242 cspan_t *cs0, *cs1; 243 244 if (lcur_lc(parse) == lc_lparen) { 245 cs0 = lcur_span(parse); 246 lskip(parse); 247 texpr = parse_texpr(parse); 248 lmatch(parse, lc_rparen); 249 cs1 = lprev_span(parse); 250 texpr->cspan = cspan_merge(cs0, cs1); 251 } else { 252 texpr = parse_tprimitive(parse); 253 } 254 255 return texpr; 256 } 257 217 258 218 259 /** Parse primitive type expression. … … 226 267 switch (lcur_lc(parse)) { 227 268 case lc_ident: 228 texpr = stree_texpr_new(tc_tnameref); 229 texpr->u.tnameref = parse_tnameref(parse); 269 texpr = parse_tnameref(parse); 230 270 break; 231 271 case lc_bool: … … 234 274 case lc_string: 235 275 case lc_resource: 236 texpr = stree_texpr_new(tc_tliteral); 237 texpr->u.tliteral = parse_tliteral(parse); 276 texpr = parse_tliteral(parse); 238 277 break; 239 278 default: … … 250 289 * @param parse Parser object. 251 290 */ 252 static stree_t literal_t *parse_tliteral(parse_t *parse)291 static stree_texpr_t *parse_tliteral(parse_t *parse) 253 292 { 254 293 stree_tliteral_t *tliteral; 255 294 tliteral_class_t tlc; 295 stree_texpr_t *texpr; 256 296 257 297 switch (lcur_lc(parse)) { … … 278 318 279 319 tliteral = stree_tliteral_new(tlc); 280 return tliteral; 320 texpr = stree_texpr_new(tc_tliteral); 321 texpr->u.tliteral = tliteral; 322 tliteral->texpr = texpr; 323 texpr->cspan = lprev_span(parse); 324 325 return texpr; 281 326 } 282 327 … … 285 330 * @param parse Parser object. 286 331 */ 287 static stree_t nameref_t *parse_tnameref(parse_t *parse)332 static stree_texpr_t *parse_tnameref(parse_t *parse) 288 333 { 289 334 stree_tnameref_t *tnameref; 335 stree_texpr_t *texpr; 290 336 291 337 tnameref = stree_tnameref_new(); 292 338 tnameref->name = parse_ident(parse); 293 339 294 return tnameref; 340 texpr = stree_texpr_new(tc_tnameref); 341 texpr->u.tnameref = tnameref; 342 tnameref->texpr = texpr; 343 texpr->cspan = tnameref->name->cspan; 344 345 return texpr; 295 346 } 296 347 … … 310 361 texpr = stree_texpr_new(tc_tliteral); 311 362 texpr->u.tliteral = tliteral; 312 313 return texpr; 314 } 363 tliteral->texpr = texpr; 364 365 return texpr; 366 } -
uspace/app/sbi/src/parse.c
r1317380 r640ffe6 48 48 49 49 /* 50 * Module members50 * Module and CSI members 51 51 */ 52 52 static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass, 53 53 stree_csi_t *outer_csi); 54 54 static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi); 55 56 static stree_ctor_t *parse_ctor(parse_t *parse, stree_csi_t *outer_csi); 57 58 static stree_enum_t *parse_enum(parse_t *parse, stree_csi_t *outer_csi); 59 static stree_embr_t *parse_embr(parse_t *parse, stree_enum_t *outer_enum); 55 60 56 61 static stree_deleg_t *parse_deleg(parse_t *parse, stree_csi_t *outer_csi); … … 76 81 static stree_for_t *parse_for(parse_t *parse); 77 82 static stree_raise_t *parse_raise(parse_t *parse); 83 static stree_break_t *parse_break(parse_t *parse); 78 84 static stree_return_t *parse_return(parse_t *parse); 79 85 static stree_wef_t *parse_wef(parse_t *parse); … … 123 129 { 124 130 stree_csi_t *csi; 131 stree_enum_t *enum_d; 125 132 stree_modm_t *modm; 126 133 … … 136 143 list_append(&parse->cur_mod->members, modm); 137 144 break; 145 case lc_enum: 146 enum_d = parse_enum(parse, NULL); 147 modm = stree_modm_new(mc_enum); 148 modm->u.enum_d = enum_d; 149 150 list_append(&parse->cur_mod->members, modm); 151 break; 138 152 default: 139 153 lunexpected_error(parse); … … 223 237 * 224 238 * @param parse Parser object. 225 * @param outer_csi CSI containing this declaration or @c NULL if global.239 * @param outer_csi CSI containing this declaration. 226 240 * @return New syntax tree node. In case of parse error, 227 241 * @c NULL may (but need not) be returned. … … 232 246 233 247 stree_csi_t *csi; 248 stree_ctor_t *ctor; 234 249 stree_deleg_t *deleg; 250 stree_enum_t *enum_d; 235 251 stree_fun_t *fun; 236 252 stree_var_t *var; … … 245 261 csimbr->u.csi = csi; 246 262 break; 263 case lc_new: 264 ctor = parse_ctor(parse, outer_csi); 265 csimbr = stree_csimbr_new(csimbr_ctor); 266 csimbr->u.ctor = ctor; 267 break; 247 268 case lc_deleg: 248 269 deleg = parse_deleg(parse, outer_csi); … … 250 271 csimbr->u.deleg = deleg; 251 272 break; 273 case lc_enum: 274 enum_d = parse_enum(parse, outer_csi); 275 csimbr = stree_csimbr_new(csimbr_enum); 276 csimbr->u.enum_d = enum_d; 277 break; 252 278 case lc_fun: 253 279 fun = parse_fun(parse, outer_csi); … … 273 299 274 300 return csimbr; 301 } 302 303 /** Parse constructor. 304 * 305 * @param parse Parser object. 306 * @param outer_csi CSI containing this declaration or @c NULL if global. 307 * @return New syntax tree node. 308 */ 309 static stree_ctor_t *parse_ctor(parse_t *parse, stree_csi_t *outer_csi) 310 { 311 stree_ctor_t *ctor; 312 stree_symbol_t *symbol; 313 stree_symbol_attr_t *attr; 314 315 ctor = stree_ctor_new(); 316 symbol = stree_symbol_new(sc_ctor); 317 318 symbol->u.ctor = ctor; 319 symbol->outer_csi = outer_csi; 320 ctor->symbol = symbol; 321 322 lmatch(parse, lc_new); 323 324 /* Fake identifier. */ 325 ctor->name = stree_ident_new(); 326 ctor->name->sid = strtab_get_sid(CTOR_IDENT); 327 ctor->name->cspan = lprev_span(parse); 328 329 #ifdef DEBUG_PARSE_TRACE 330 printf("Parsing constructor of CSI '"); 331 symbol_print_fqn(csi_to_symbol(outer_csi)); 332 printf("'.\n"); 333 #endif 334 ctor->sig = parse_fun_sig(parse); 335 if (ctor->sig->rtype != NULL) { 336 printf("Error: Constructor of CSI '"); 337 symbol_print_fqn(csi_to_symbol(outer_csi)); 338 printf("' has a return type.\n"); 339 parse_note_error(parse); 340 } 341 342 list_init(&symbol->attr); 343 344 /* Parse attributes. */ 345 while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) { 346 lskip(parse); 347 attr = parse_symbol_attr(parse); 348 list_append(&symbol->attr, attr); 349 } 350 351 ctor->proc = stree_proc_new(); 352 ctor->proc->outer_symbol = symbol; 353 354 if (lcur_lc(parse) == lc_scolon) { 355 lskip(parse); 356 357 /* This constructor has no body. */ 358 printf("Error: Constructor of CSI '"); 359 symbol_print_fqn(csi_to_symbol(outer_csi)); 360 printf("' has no body.\n"); 361 parse_note_error(parse); 362 363 ctor->proc->body = NULL; 364 } else { 365 lmatch(parse, lc_is); 366 ctor->proc->body = parse_block(parse); 367 lmatch(parse, lc_end); 368 } 369 370 return ctor; 371 } 372 373 /** Parse @c enum declaration. 374 * 375 * @param parse Parser object. 376 * @param outer_csi CSI containing this declaration or @c NULL if global. 377 * @return New syntax tree node. 378 */ 379 static stree_enum_t *parse_enum(parse_t *parse, stree_csi_t *outer_csi) 380 { 381 stree_enum_t *enum_d; 382 stree_symbol_t *symbol; 383 stree_embr_t *embr; 384 385 enum_d = stree_enum_new(); 386 symbol = stree_symbol_new(sc_enum); 387 388 symbol->u.enum_d = enum_d; 389 symbol->outer_csi = outer_csi; 390 enum_d->symbol = symbol; 391 392 lmatch(parse, lc_enum); 393 enum_d->name = parse_ident(parse); 394 list_init(&enum_d->members); 395 396 #ifdef DEBUG_PARSE_TRACE 397 printf("Parse enum '%s'.\n", strtab_get_str(enum_d->name->sid)); 398 #endif 399 lmatch(parse, lc_is); 400 401 /* Parse enum members. */ 402 while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) { 403 embr = parse_embr(parse, enum_d); 404 if (embr == NULL) 405 break; 406 407 list_append(&enum_d->members, embr); 408 } 409 410 if (list_is_empty(&enum_d->members)) { 411 printf("Error: Enum type '%s' has no members.\n", 412 strtab_get_str(enum_d->name->sid)); 413 parse_note_error(parse); 414 } 415 416 lmatch(parse, lc_end); 417 418 return enum_d; 419 } 420 421 /** Parse enum member. 422 * 423 * @param parse Parser object. 424 * @param outer_enum Enum containing this declaration. 425 * @return New syntax tree node. In case of parse error, 426 * @c NULL may (but need not) be returned. 427 */ 428 static stree_embr_t *parse_embr(parse_t *parse, stree_enum_t *outer_enum) 429 { 430 stree_embr_t *embr; 431 432 embr = stree_embr_new(); 433 embr->outer_enum = outer_enum; 434 embr->name = parse_ident(parse); 435 436 lmatch(parse, lc_scolon); 437 438 return embr; 275 439 } 276 440 … … 681 845 stree_for_t *for_s; 682 846 stree_raise_t *raise_s; 847 stree_break_t *break_s; 683 848 stree_return_t *return_s; 684 849 stree_wef_t *wef_s; … … 714 879 stat->u.raise_s = raise_s; 715 880 break; 881 case lc_break: 882 break_s = parse_break(parse); 883 stat = stree_stat_new(st_break); 884 stat->u.break_s = break_s; 885 break; 716 886 case lc_return: 717 887 return_s = parse_return(parse); … … 777 947 { 778 948 stree_if_t *if_s; 949 stree_if_clause_t *if_c; 779 950 780 951 #ifdef DEBUG_PARSE_TRACE … … 782 953 #endif 783 954 if_s = stree_if_new(); 784 955 list_init(&if_s->if_clauses); 956 957 /* Parse @c if clause. */ 785 958 lmatch(parse, lc_if); 786 if_s->cond = parse_expr(parse); 959 960 if_c = stree_if_clause_new(); 961 if_c->cond = parse_expr(parse); 787 962 lmatch(parse, lc_then); 788 if_s->if_block = parse_block(parse); 789 963 if_c->block = parse_block(parse); 964 965 list_append(&if_s->if_clauses, if_c); 966 967 /* Parse @c elif clauses. */ 968 while (lcur_lc(parse) == lc_elif) { 969 lskip(parse); 970 if_c = stree_if_clause_new(); 971 if_c->cond = parse_expr(parse); 972 lmatch(parse, lc_then); 973 if_c->block = parse_block(parse); 974 975 list_append(&if_s->if_clauses, if_c); 976 } 977 978 /* Parse @c else clause. */ 790 979 if (lcur_lc(parse) == lc_else) { 791 980 lskip(parse); … … 867 1056 } 868 1057 1058 /** Parse @c break statement. 1059 * 1060 * @param parse Parser object. 1061 * @return New syntax tree node. 1062 */ 1063 static stree_break_t *parse_break(parse_t *parse) 1064 { 1065 stree_break_t *break_s; 1066 1067 #ifdef DEBUG_PARSE_TRACE 1068 printf("Parse 'break' statement.\n"); 1069 #endif 1070 break_s = stree_break_new(); 1071 1072 lmatch(parse, lc_break); 1073 lmatch(parse, lc_scolon); 1074 1075 return break_s; 1076 } 1077 869 1078 /** Parse @c return statement. 870 1079 * … … 882 1091 883 1092 lmatch(parse, lc_return); 884 return_s->expr = parse_expr(parse); 1093 1094 if (lcur_lc(parse) != lc_scolon) 1095 return_s->expr = parse_expr(parse); 1096 885 1097 lmatch(parse, lc_scolon); 886 1098 … … 996 1208 ident = stree_ident_new(); 997 1209 ident->sid = lcur(parse)->u.ident.sid; 1210 ident->cspan = lcur_span(parse); 998 1211 lskip(parse); 999 1212 … … 1059 1272 /** Return current lem lclass. 1060 1273 * 1061 * @param parse Parser object .1062 * @return Lclass of the current lem .1274 * @param parse Parser object 1275 * @return Lclass of the current lem 1063 1276 */ 1064 1277 lclass_t lcur_lc(parse_t *parse) … … 1081 1294 } 1082 1295 1296 /** Return coordinate span of current lem. 1297 * 1298 * @param parse Parser object 1299 * @return Coordinate span of current lem or @c NULL if a 1300 * parse error is active 1301 */ 1302 cspan_t *lcur_span(parse_t *parse) 1303 { 1304 lem_t *lem; 1305 1306 if (parse_is_error(parse)) 1307 return NULL; 1308 1309 lem = lcur(parse); 1310 return lem->cspan; 1311 } 1312 1313 /** Return coordinate span of previous lem. 1314 * 1315 * @param parse Parser object 1316 * @return Coordinate span of previous lem or @c NULL if 1317 * parse error is active or previous lem is not 1318 * available. 1319 */ 1320 cspan_t *lprev_span(parse_t *parse) 1321 { 1322 lem_t *lem; 1323 1324 if (parse_is_error(parse)) 1325 return NULL; 1326 1327 lem = lex_peek_prev(parse->lex); 1328 if (lem == NULL) 1329 return NULL; 1330 1331 return lem->cspan; 1332 } 1333 1083 1334 /** Skip to next lem. 1084 1335 * … … 1170 1421 { 1171 1422 switch (lclass) { 1423 case lc_elif: 1172 1424 case lc_else: 1173 1425 case lc_end: -
uspace/app/sbi/src/parse.h
r1317380 r640ffe6 48 48 lem_t *lcur(parse_t *parse); 49 49 lclass_t lcur_lc(parse_t *parse); 50 cspan_t *lcur_span(parse_t *parse); 51 cspan_t *lprev_span(parse_t *parse); 52 50 53 void lskip(parse_t *parse); 51 54 void lcheck(parse_t *parse, lclass_t lc); -
uspace/app/sbi/src/rdata.c
r1317380 r640ffe6 52 52 #include "stree.h" 53 53 #include "symbol.h" 54 #include "strtab.h" 54 55 55 56 #include "rdata.h" … … 61 62 static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest); 62 63 static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest); 64 static void rdata_enum_copy(rdata_enum_t *src, rdata_enum_t **dest); 63 65 static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest); 64 66 static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest); 65 67 static void rdata_resource_copy(rdata_resource_t *src, 66 68 rdata_resource_t **dest); 69 static void rdata_symbol_copy(rdata_symbol_t *src, rdata_symbol_t **dest); 67 70 68 71 static int rdata_array_get_dim(rdata_array_t *array); … … 247 250 248 251 return deleg; 252 } 253 254 /** Allocate new enum value. 255 * 256 * @return New enum value. 257 */ 258 rdata_enum_t *rdata_enum_new(void) 259 { 260 rdata_enum_t *enum_v; 261 262 enum_v = calloc(1, sizeof(rdata_enum_t)); 263 if (enum_v == NULL) { 264 printf("Memory allocation failed.\n"); 265 exit(1); 266 } 267 268 return enum_v; 249 269 } 250 270 … … 373 393 374 394 return resource_v; 395 } 396 397 /** Allocate new symbol reference. 398 * 399 * @return New symbol reference. 400 */ 401 rdata_symbol_t *rdata_symbol_new(void) 402 { 403 rdata_symbol_t *symbol_v; 404 405 symbol_v = calloc(1, sizeof(rdata_symbol_t)); 406 if (symbol_v == NULL) { 407 printf("Memory allocation failed.\n"); 408 exit(1); 409 } 410 411 return symbol_v; 375 412 } 376 413 … … 453 490 rdata_deleg_copy(src->u.deleg_v, &nvar->u.deleg_v); 454 491 break; 492 case vc_enum: 493 rdata_enum_copy(src->u.enum_v, &nvar->u.enum_v); 494 break; 455 495 case vc_array: 456 496 rdata_array_copy(src->u.array_v, &nvar->u.array_v); … … 461 501 case vc_resource: 462 502 rdata_resource_copy(src->u.resource_v, &nvar->u.resource_v); 503 break; 504 case vc_symbol: 505 rdata_symbol_copy(src->u.symbol_v, &nvar->u.symbol_v); 463 506 break; 464 507 } … … 534 577 } 535 578 579 /** Copy enum value. 580 * 581 * @param src Source enum value. 582 * @param dest Place to store pointer to new enum value. 583 */ 584 static void rdata_enum_copy(rdata_enum_t *src, rdata_enum_t **dest) 585 { 586 *dest = rdata_enum_new(); 587 (*dest)->value = src->value; 588 } 589 536 590 /** Copy array. 537 591 * … … 567 621 *dest = rdata_resource_new(); 568 622 (*dest)->data = src->data; 623 } 624 625 /** Copy symbol. 626 * 627 * @param src Source symbol. 628 * @param dest Place to store pointer to new symbol. 629 */ 630 static void rdata_symbol_copy(rdata_symbol_t *src, rdata_symbol_t **dest) 631 { 632 *dest = rdata_symbol_new(); 633 (*dest)->sym = src->sym; 569 634 } 570 635 … … 621 686 case vc_ref: var->u.ref_v = nvar->u.ref_v; break; 622 687 case vc_deleg: var->u.deleg_v = nvar->u.deleg_v; break; 688 case vc_enum: var->u.enum_v = nvar->u.enum_v; break; 623 689 case vc_array: var->u.array_v = nvar->u.array_v; break; 624 690 case vc_object: var->u.object_v = nvar->u.object_v; break; 625 691 case vc_resource: var->u.resource_v = nvar->u.resource_v; break; 692 case vc_symbol: var->u.symbol_v = nvar->u.symbol_v; break; 626 693 } 627 694 … … 732 799 printf(")"); 733 800 break; 801 case vc_enum: 802 symbol_print_fqn( 803 enum_to_symbol(var->u.enum_v->value->outer_enum)); 804 printf(".%s", 805 strtab_get_str(var->u.enum_v->value->name->sid)); 806 break; 734 807 case vc_array: 735 808 printf("array"); … … 741 814 printf("resource(%p)", var->u.resource_v->data); 742 815 break; 743 } 744 } 816 case vc_symbol: 817 printf("symbol("); 818 if (var->u.symbol_v->sym != NULL) { 819 symbol_print_fqn(var->u.symbol_v->sym); 820 } else { 821 printf("nil"); 822 } 823 printf(")"); 824 break; 825 } 826 } -
uspace/app/sbi/src/rdata.h
r1317380 r640ffe6 43 43 rdata_ref_t *rdata_ref_new(void); 44 44 rdata_deleg_t *rdata_deleg_new(void); 45 rdata_enum_t *rdata_enum_new(void); 45 46 rdata_array_t *rdata_array_new(int rank); 46 47 rdata_object_t *rdata_object_new(void); … … 50 51 rdata_string_t *rdata_string_new(void); 51 52 rdata_resource_t *rdata_resource_new(void); 53 rdata_symbol_t *rdata_symbol_new(void); 52 54 53 55 void rdata_array_alloc_element(rdata_array_t *array); -
uspace/app/sbi/src/rdata_t.h
r1317380 r640ffe6 82 82 } rdata_deleg_t; 83 83 84 /** Enumerated type value. */ 85 typedef struct { 86 /** Enum member declaration */ 87 struct stree_embr *value; 88 } rdata_enum_t; 89 84 90 /** Array variable */ 85 91 typedef struct { … … 116 122 } rdata_resource_t; 117 123 124 /** Symbol reference variable 125 * 126 * A symbol reference points to a program symbol. 127 */ 128 typedef struct { 129 /** Program symbol. */ 130 struct stree_symbol *sym; 131 } rdata_symbol_t; 132 118 133 typedef enum var_class { 119 134 /** Boolean */ … … 135 150 vc_deleg, 136 151 152 /** Enumerated type value */ 153 vc_enum, 154 137 155 /** Array */ 138 156 vc_array, … … 142 160 143 161 /** Interpreter builtin resource */ 144 vc_resource 162 vc_resource, 163 164 /** Symbol reference */ 165 vc_symbol 145 166 } var_class_t; 146 167 … … 161 182 rdata_ref_t *ref_v; 162 183 rdata_deleg_t *deleg_v; 184 rdata_enum_t *enum_v; 163 185 rdata_array_t *array_v; 164 186 rdata_object_t *object_v; 165 187 rdata_resource_t *resource_v; 188 rdata_symbol_t *symbol_v; 166 189 } u; 167 190 } rdata_var_t; -
uspace/app/sbi/src/run.c
r1317380 r640ffe6 34 34 #include "bigint.h" 35 35 #include "builtin.h" 36 #include "cspan.h" 36 37 #include "debug.h" 37 38 #include "intmap.h" … … 54 55 static void run_while(run_t *run, stree_while_t *while_s); 55 56 static void run_raise(run_t *run, stree_raise_t *raise_s); 57 static void run_break(run_t *run, stree_break_t *break_s); 56 58 static void run_return(run_t *run, stree_return_t *return_s); 57 59 static void run_wef(run_t *run, stree_wef_t *wef_s); … … 71 73 static void run_var_new_null_ref(run_t *run, rdata_var_t **rvar); 72 74 static void run_var_new_deleg(run_t *run, rdata_var_t **rvar); 73 75 static void run_var_new_enum(run_t *run, tdata_enum_t *tenum, 76 rdata_var_t **rvar); 74 77 75 78 /** Initialize runner instance. … … 177 180 switch (run->thread_ar->bo_mode) { 178 181 case bm_stat: 179 printf("Error: Misplaced 'break' statement.\n");180 exit(1);182 /* Break bailout was not caught. */ 183 assert(b_false); 181 184 case bm_proc: 182 185 run->thread_ar->bo_mode = bm_none; … … 283 286 run_raise(run, stat->u.raise_s); 284 287 break; 288 case st_break: 289 run_break(run, stat->u.break_s); 290 break; 285 291 case st_return: 286 292 run_return(run, stat->u.return_s); … … 292 298 printf("Ignoring unimplemented statement type %d.\n", stat->sc); 293 299 break; 294 default:295 assert(b_false);296 300 } 297 301 } … … 364 368 { 365 369 rdata_item_t *rcond; 370 list_node_t *ifc_node; 371 stree_if_clause_t *ifc; 372 bool_t clause_fired; 366 373 367 374 #ifdef DEBUG_RUN_TRACE 368 375 printf("Executing if statement.\n"); 369 376 #endif 370 run_expr(run, if_s->cond, &rcond); 371 if (run_is_bo(run)) 372 return; 373 374 if (run_item_boolean_value(run, rcond) == b_true) { 375 #ifdef DEBUG_RUN_TRACE 376 printf("Taking true path.\n"); 377 #endif 378 run_block(run, if_s->if_block); 379 } else { 380 #ifdef DEBUG_RUN_TRACE 381 printf("Taking false path.\n"); 382 #endif 383 if (if_s->else_block != NULL) 384 run_block(run, if_s->else_block); 377 clause_fired = b_false; 378 ifc_node = list_first(&if_s->if_clauses); 379 380 /* Walk through all if/elif clauses and see if they fire. */ 381 382 while (ifc_node != NULL) { 383 /* Get if/elif clause */ 384 ifc = list_node_data(ifc_node, stree_if_clause_t *); 385 386 run_expr(run, ifc->cond, &rcond); 387 if (run_is_bo(run)) 388 return; 389 390 if (run_item_boolean_value(run, rcond) == b_true) { 391 #ifdef DEBUG_RUN_TRACE 392 printf("Taking non-default path.\n"); 393 #endif 394 run_block(run, ifc->block); 395 clause_fired = b_true; 396 break; 397 } 398 399 ifc_node = list_next(&if_s->if_clauses, ifc_node); 400 } 401 402 /* If no if/elif clause fired, invoke the else clause. */ 403 if (clause_fired == b_false && if_s->else_block != NULL) { 404 #ifdef DEBUG_RUN_TRACE 405 printf("Taking default path.\n"); 406 #endif 407 run_block(run, if_s->else_block); 385 408 } 386 409 … … 410 433 run_expr(run, while_s->cond, &rcond); 411 434 if (run_is_bo(run)) 412 return;413 414 if (run->thread_ar->bo_mode != bm_none)415 435 break; 436 } 437 438 if (run->thread_ar->bo_mode == bm_stat) { 439 /* Bailout due to break statement */ 440 run->thread_ar->bo_mode = bm_none; 416 441 } 417 442 … … 440 465 run_cvt_value_item(run, rexpr, &rexpr_vi); 441 466 467 /* Store expression cspan in thread AR. */ 468 run->thread_ar->exc_cspan = raise_s->expr->cspan; 469 442 470 /* Store expression result in thread AR. */ 443 471 run->thread_ar->exc_payload = rexpr_vi->u.value; … … 447 475 } 448 476 477 /** Run @c break statement. 478 * 479 * Forces control to return from the active breakable statement by setting 480 * bailout mode to @c bm_stat. 481 * 482 * @param run Runner object 483 * @param break_s Break statement to run 484 */ 485 static void run_break(run_t *run, stree_break_t *break_s) 486 { 487 #ifdef DEBUG_RUN_TRACE 488 printf("Executing 'break' statement.\n"); 489 #endif 490 (void) break_s; 491 492 /* Force control to ascend and leave the procedure. */ 493 if (run->thread_ar->bo_mode == bm_none) 494 run->thread_ar->bo_mode = bm_stat; 495 } 496 449 497 /** Run @c return statement. 450 498 * … … 453 501 * 454 502 * @param run Runner object 455 * @param r aise_s Return statement to run503 * @param return_s Return statement to run 456 504 */ 457 505 static void run_return(run_t *run, stree_return_t *return_s) … … 464 512 printf("Executing return statement.\n"); 465 513 #endif 466 run_expr(run, return_s->expr, &rexpr); 467 if (run_is_bo(run)) 468 return; 469 470 run_cvt_value_item(run, rexpr, &rexpr_vi); 471 472 /* Store expression result in procedure AR. */ 473 proc_ar = run_get_current_proc_ar(run); 474 proc_ar->retval = rexpr_vi; 514 if (return_s->expr != NULL) { 515 run_expr(run, return_s->expr, &rexpr); 516 if (run_is_bo(run)) 517 return; 518 519 run_cvt_value_item(run, rexpr, &rexpr_vi); 520 521 /* Store expression result in procedure AR. */ 522 proc_ar = run_get_current_proc_ar(run); 523 proc_ar->retval = rexpr_vi; 524 } 475 525 476 526 /* Force control to ascend and leave the procedure. */ … … 632 682 exc_csi = run_exc_payload_get_csi(run); 633 683 684 if (run->thread_ar->exc_cspan != NULL) { 685 cspan_print(run->thread_ar->exc_cspan); 686 putchar(' '); 687 } 688 634 689 printf("Error: Unhandled exception '"); 635 690 symbol_print_fqn(csi_to_symbol(exc_csi)); … … 749 804 rdata_char_t *char_v; 750 805 rdata_deleg_t *deleg_v; 806 rdata_enum_t *enum_v; 751 807 rdata_int_t *int_v; 752 808 rdata_string_t *string_v; … … 780 836 deleg_v->obj = item->u.value->var->u.deleg_v->obj; 781 837 deleg_v->sym = item->u.value->var->u.deleg_v->sym; 838 break; 839 case vc_enum: 840 *var = rdata_var_new(vc_enum); 841 enum_v = rdata_enum_new(); 842 843 (*var)->u.enum_v = enum_v; 844 enum_v->value = item->u.value->var->u.enum_v->value; 782 845 break; 783 846 case vc_int: … … 854 917 void run_proc_ar_set_args(run_t *run, run_proc_ar_t *proc_ar, list_t *arg_vals) 855 918 { 919 stree_ctor_t *ctor; 856 920 stree_fun_t *fun; 857 921 stree_prop_t *prop; … … 878 942 outer_symbol = proc_ar->proc->outer_symbol; 879 943 944 /* Make compiler happy. */ 945 args = NULL; 946 varg = NULL; 947 880 948 /* 881 949 * The procedure being activated should belong to a member function or … … 883 951 */ 884 952 switch (outer_symbol->sc) { 953 case sc_ctor: 954 ctor = symbol_to_ctor(outer_symbol); 955 args = &ctor->sig->args; 956 varg = ctor->sig->varg; 957 break; 885 958 case sc_fun: 886 959 fun = symbol_to_fun(outer_symbol); … … 893 966 varg = prop->varg; 894 967 break; 895 default: 968 case sc_csi: 969 case sc_deleg: 970 case sc_enum: 971 case sc_var: 896 972 assert(b_false); 897 973 } … … 1377 1453 * @param run Runner object 1378 1454 * @param ref Reference 1455 * @param cspan Cspan to put into exception if reference is nil 1456 * or @c NULL if no cspan is provided. 1379 1457 * @param rtitem Place to store pointer to the resulting address. 1380 1458 */ 1381 void run_dereference(run_t *run, rdata_item_t *ref, rdata_item_t **ritem) 1459 void run_dereference(run_t *run, rdata_item_t *ref, cspan_t *cspan, 1460 rdata_item_t **ritem) 1382 1461 { 1383 1462 rdata_item_t *ref_val; … … 1404 1483 #endif 1405 1484 /* Raise Error.NilReference */ 1406 run_raise_exc(run, run->program->builtin->error_nilreference); 1485 run_raise_exc(run, run->program->builtin->error_nilreference, 1486 cspan); 1407 1487 *ritem = run_recovery_item(run); 1408 1488 return; … … 1422 1502 * @param run Runner object 1423 1503 * @param csi Exception class 1424 */ 1425 void run_raise_exc(run_t *run, stree_csi_t *csi) 1504 * @param cspan Cspan of code that caused exception (for debugging) 1505 */ 1506 void run_raise_exc(run_t *run, stree_csi_t *csi, cspan_t *cspan) 1426 1507 { 1427 1508 rdata_item_t *exc_vi; 1509 1510 /* Store exception cspan in thread AR. */ 1511 run->thread_ar->exc_cspan = cspan; 1428 1512 1429 1513 /* Create exception object. */ … … 1472 1556 break; 1473 1557 case tic_tdeleg: 1558 run_var_new_deleg(run, rvar); 1559 break; 1560 case tic_tebase: 1561 /* 1562 * One cannot declare variable of ebase type. It is just 1563 * type of expressions referring to enum types. 1564 */ 1565 assert(b_false); 1566 case tic_tenum: 1567 run_var_new_enum(run, ti->u.tenum, rvar); 1568 break; 1474 1569 case tic_tfun: 1475 1570 run_var_new_deleg(run, rvar); … … 1578 1673 } 1579 1674 1675 /** Construct a new variable containing default value of an enum type. 1676 * 1677 * @param run Runner object 1678 * @param rvar Place to store pointer to new variable 1679 */ 1680 static void run_var_new_enum(run_t *run, tdata_enum_t *tenum, 1681 rdata_var_t **rvar) 1682 { 1683 rdata_var_t *var; 1684 list_node_t *embr_n; 1685 stree_embr_t *embr; 1686 1687 (void) run; 1688 1689 /* Get first member of enum which will serve as default value. */ 1690 embr_n = list_first(&tenum->enum_d->members); 1691 assert(embr_n != NULL); 1692 1693 embr = list_node_data(embr_n, stree_embr_t *); 1694 1695 /* Return null reference. */ 1696 var = rdata_var_new(vc_enum); 1697 var->u.enum_v = rdata_enum_new(); 1698 var->u.enum_v->value = embr; 1699 1700 *rvar = var; 1701 } 1702 1580 1703 /** Construct a new thread activation record. 1581 1704 * -
uspace/app/sbi/src/run.h
r1317380 r640ffe6 63 63 rdata_value_t *value); 64 64 void run_reference(run_t *run, rdata_var_t *var, rdata_item_t **res); 65 void run_dereference(run_t *run, rdata_item_t *ref, rdata_item_t **ritem); 65 void run_dereference(run_t *run, rdata_item_t *ref, cspan_t *cspan, 66 rdata_item_t **ritem); 66 67 67 void run_raise_exc(run_t *run, stree_csi_t *csi );68 void run_raise_exc(run_t *run, stree_csi_t *csi, cspan_t *cspan); 68 69 bool_t run_is_bo(run_t *run); 69 70 -
uspace/app/sbi/src/run_expr.c
r1317380 r640ffe6 78 78 static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 79 79 rdata_value_t *v2, rdata_item_t **res); 80 static void run_binop_enum(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 81 rdata_value_t *v2, rdata_item_t **res); 80 82 81 83 static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res); 84 static void run_unop_bool(run_t *run, stree_unop_t *unop, rdata_value_t *val, 85 rdata_item_t **res); 82 86 static void run_unop_int(run_t *run, stree_unop_t *unop, rdata_value_t *val, 83 87 rdata_item_t **res); … … 88 92 static void run_new_object(run_t *run, stree_new_t *new_op, 89 93 tdata_item_t *titem, rdata_item_t **res); 94 95 static void run_object_ctor(run_t *run, rdata_var_t *obj, list_t *arg_vals); 90 96 91 97 static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res); … … 98 104 static void run_access_object(run_t *run, stree_access_t *access, 99 105 rdata_item_t *arg, rdata_item_t **res); 106 static void run_access_symbol(run_t *run, stree_access_t *access, 107 rdata_item_t *arg, rdata_item_t **res); 100 108 101 109 static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res); 110 static void run_call_args(run_t *run, list_t *args, list_t *arg_vals); 111 102 112 static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res); 103 113 static void run_index_array(run_t *run, stree_index_t *index, … … 189 199 rdata_var_t *var; 190 200 rdata_deleg_t *deleg_v; 201 rdata_symbol_t *symbol_v; 191 202 192 203 run_proc_ar_t *proc_ar; … … 246 257 case sc_csi: 247 258 #ifdef DEBUG_RUN_TRACE 248 printf("Referencing class.\n");259 printf("Referencing CSI.\n"); 249 260 #endif 250 261 item = rdata_item_new(ic_value); … … 260 271 deleg_v->sym = sym; 261 272 *res = item; 273 break; 274 case sc_ctor: 275 /* It is not possible to reference a constructor explicitly. */ 276 assert(b_false); 277 case sc_enum: 278 #ifdef DEBUG_RUN_TRACE 279 printf("Referencing enum.\n"); 280 #endif 281 item = rdata_item_new(ic_value); 282 value = rdata_value_new(); 283 var = rdata_var_new(vc_symbol); 284 symbol_v = rdata_symbol_new(); 285 286 item->u.value = value; 287 value->var = var; 288 var->u.symbol_v = symbol_v; 289 290 symbol_v->sym = sym; 291 *res = item; 292 break; 293 case sc_deleg: 294 /* XXX TODO */ 295 printf("Unimplemented: Delegate name reference.\n"); 296 abort(); 262 297 break; 263 298 case sc_fun: … … 329 364 *res = item; 330 365 break; 331 default: 332 printf("Referencing symbol class %d unimplemented.\n", sym->sc); 333 *res = NULL; 366 case sc_prop: 367 /* XXX TODO */ 368 printf("Unimplemented: Property name reference.\n"); 369 abort(); 334 370 break; 335 371 } … … 571 607 } 572 608 573 switch (binop->bc) {574 case bo_plus:575 case bo_minus:576 case bo_mult:577 case bo_equal:578 case bo_notequal:579 case bo_lt:580 case bo_gt:581 case bo_lt_equal:582 case bo_gt_equal:583 /* These are implemented so far. */584 break;585 default:586 printf("Unimplemented: Binary operation type %d.\n",587 binop->bc);588 exit(1);589 }590 591 609 #ifdef DEBUG_RUN_TRACE 592 610 printf("Check binop argument results.\n"); … … 621 639 run_binop_ref(run, binop, v1, v2, res); 622 640 break; 641 case vc_enum: 642 run_binop_enum(run, binop, v1, v2, res); 643 break; 623 644 case vc_deleg: 624 645 case vc_array: 625 646 case vc_object: 626 647 case vc_resource: 648 case vc_symbol: 627 649 assert(b_false); 628 650 } … … 685 707 bool_v->value = (b1 == b_true) || (b2 == b_false); 686 708 break; 709 710 case bo_and: 711 bool_v->value = (b1 == b_true) && (b2 == b_true); 712 break; 713 case bo_or: 714 bool_v->value = (b1 == b_true) || (b2 == b_true); 715 break; 687 716 } 688 717 … … 753 782 bool_v->value = !nf; 754 783 break; 755 default: 784 785 case bo_and: 786 case bo_or: 756 787 assert(b_false); 757 788 } … … 832 863 833 864 switch (binop->bc) { 865 case bo_plus: 866 case bo_minus: 867 case bo_mult: 868 assert(b_false); 869 834 870 case bo_equal: 835 871 bool_v->value = zf; … … 850 886 bool_v->value = !nf; 851 887 break; 852 default: 888 case bo_and: 889 case bo_or: 853 890 assert(b_false); 854 891 } … … 872 909 rdata_var_t *var; 873 910 rdata_string_t *string_v; 911 rdata_bool_t *bool_v; 912 bool_t done; 913 bool_t zf; 874 914 875 915 const char *s1, *s2; … … 879 919 item = rdata_item_new(ic_value); 880 920 value = rdata_value_new(); 881 var = rdata_var_new(vc_string);882 string_v = rdata_string_new();883 921 884 922 item->u.value = value; 885 value->var = var;886 var->u.string_v = string_v;887 923 888 924 s1 = v1->var->u.string_v->value; 889 925 s2 = v2->var->u.string_v->value; 926 927 done = b_true; 890 928 891 929 switch (binop->bc) { 892 930 case bo_plus: 893 931 /* Concatenate strings. */ 932 string_v = rdata_string_new(); 894 933 string_v->value = os_str_acat(s1, s2); 934 break; 935 default: 936 done = b_false; 937 break; 938 } 939 940 if (done) { 941 var = rdata_var_new(vc_string); 942 var->u.string_v = string_v; 943 value->var = var; 944 *res = item; 945 return; 946 } 947 948 var = rdata_var_new(vc_bool); 949 bool_v = rdata_bool_new(); 950 var->u.bool_v = bool_v; 951 value->var = var; 952 953 /* Relational operation. */ 954 955 zf = os_str_cmp(s1, s2) == 0; 956 957 switch (binop->bc) { 958 case bo_equal: 959 bool_v->value = zf; 960 break; 961 case bo_notequal: 962 bool_v->value = !zf; 895 963 break; 896 964 default: … … 951 1019 } 952 1020 1021 /** Evaluate binary operation on enum arguments. 1022 * 1023 * @param run Runner object 1024 * @param binop Binary operation 1025 * @param v1 Value of first argument 1026 * @param v2 Value of second argument 1027 * @param res Place to store result 1028 */ 1029 static void run_binop_enum(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 1030 rdata_value_t *v2, rdata_item_t **res) 1031 { 1032 rdata_item_t *item; 1033 rdata_value_t *value; 1034 rdata_var_t *var; 1035 rdata_bool_t *bool_v; 1036 1037 rdata_var_t *ref1, *ref2; 1038 1039 (void) run; 1040 1041 item = rdata_item_new(ic_value); 1042 value = rdata_value_new(); 1043 var = rdata_var_new(vc_bool); 1044 bool_v = rdata_bool_new(); 1045 1046 item->u.value = value; 1047 value->var = var; 1048 var->u.bool_v = bool_v; 1049 1050 ref1 = v1->var->u.ref_v->vref; 1051 ref2 = v2->var->u.ref_v->vref; 1052 1053 switch (binop->bc) { 1054 case bo_equal: 1055 bool_v->value = (ref1 == ref2); 1056 break; 1057 case bo_notequal: 1058 bool_v->value = (ref1 != ref2); 1059 break; 1060 default: 1061 /* Should have been caught by static typing. */ 1062 assert(b_false); 1063 } 1064 1065 *res = item; 1066 } 953 1067 954 1068 /** Evaluate unary operation. … … 981 1095 982 1096 switch (val->var->vc) { 1097 case vc_bool: 1098 run_unop_bool(run, unop, val, res); 1099 break; 983 1100 case vc_int: 984 1101 run_unop_int(run, unop, val, res); … … 993 1110 } 994 1111 1112 /** Evaluate unary operation on bool argument. 1113 * 1114 * @param run Runner object 1115 * @param unop Unary operation 1116 * @param val Value of argument 1117 * @param res Place to store result 1118 */ 1119 static void run_unop_bool(run_t *run, stree_unop_t *unop, rdata_value_t *val, 1120 rdata_item_t **res) 1121 { 1122 rdata_item_t *item; 1123 rdata_value_t *value; 1124 rdata_var_t *var; 1125 rdata_bool_t *bool_v; 1126 1127 (void) run; 1128 1129 item = rdata_item_new(ic_value); 1130 value = rdata_value_new(); 1131 var = rdata_var_new(vc_bool); 1132 bool_v = rdata_bool_new(); 1133 1134 item->u.value = value; 1135 value->var = var; 1136 var->u.bool_v = bool_v; 1137 1138 switch (unop->uc) { 1139 case uo_plus: 1140 case uo_minus: 1141 assert(b_false); 1142 1143 case uo_not: 1144 bool_v->value = !val->var->u.bool_v->value; 1145 break; 1146 } 1147 1148 *res = item; 1149 } 1150 995 1151 /** Evaluate unary operation on int argument. 996 1152 * … … 1027 1183 &int_v->value); 1028 1184 break; 1185 case uo_not: 1186 assert(b_false); 1029 1187 } 1030 1188 1031 1189 *res = item; 1032 1190 } 1033 1034 1191 1035 1192 /** Evaluate @c new operation. … … 1186 1343 { 1187 1344 stree_csi_t *csi; 1345 rdata_item_t *obj_i; 1346 list_t arg_vals; 1188 1347 1189 1348 #ifdef DEBUG_RUN_TRACE 1190 1349 printf("Create new object.\n"); 1191 1350 #endif 1192 (void) new_op;1193 1194 1351 /* Lookup object CSI. */ 1195 1352 assert(titem->tic == tic_tobject); 1196 1353 csi = titem->u.tobject->csi; 1197 1354 1355 /* Evaluate constructor arguments. */ 1356 run_call_args(run, &new_op->ctor_args, &arg_vals); 1357 if (run_is_bo(run)) { 1358 *res = NULL; 1359 return; 1360 } 1361 1198 1362 /* Create CSI instance. */ 1199 1363 run_new_csi_inst(run, csi, res); 1364 1365 /* Run the constructor. */ 1366 run_dereference(run, *res, NULL, &obj_i); 1367 assert(obj_i->ic == ic_address); 1368 assert(obj_i->u.address->ac == ac_var); 1369 run_object_ctor(run, obj_i->u.address->u.var_a->vref, &arg_vals); 1200 1370 } 1201 1371 … … 1256 1426 run_access_object(run, access, arg, res); 1257 1427 break; 1258 default: 1428 case vc_symbol: 1429 run_access_symbol(run, access, arg, res); 1430 break; 1431 1432 case vc_bool: 1433 case vc_char: 1434 case vc_enum: 1435 case vc_int: 1436 case vc_string: 1437 case vc_array: 1438 case vc_resource: 1259 1439 printf("Unimplemented: Using access operator ('.') " 1260 1440 "with unsupported data type (value/%d).\n", vc); … … 1276 1456 1277 1457 /* Implicitly dereference. */ 1278 run_dereference(run, arg, &darg);1458 run_dereference(run, arg, access->arg->cspan, &darg); 1279 1459 1280 1460 if (run->thread_ar->bo_mode != bm_none) { … … 1396 1576 printf("Error: Accessing object member which is a delegate.\n"); 1397 1577 exit(1); 1578 case sc_enum: 1579 printf("Error: Accessing object member which is an enum.\n"); 1580 exit(1); 1581 case sc_ctor: 1582 /* It is not possible to reference a constructor explicitly. */ 1583 assert(b_false); 1398 1584 case sc_fun: 1399 1585 /* Construct anonymous delegate. */ … … 1442 1628 } 1443 1629 1630 /** Evaluate symbol member acccess. 1631 * 1632 * @param run Runner object 1633 * @param access Access operation 1634 * @param arg Evaluated base expression 1635 * @param res Place to store result 1636 */ 1637 static void run_access_symbol(run_t *run, stree_access_t *access, 1638 rdata_item_t *arg, rdata_item_t **res) 1639 { 1640 rdata_item_t *arg_vi; 1641 rdata_value_t *arg_val; 1642 rdata_symbol_t *symbol_v; 1643 stree_embr_t *embr; 1644 1645 rdata_item_t *ritem; 1646 rdata_value_t *rvalue; 1647 rdata_var_t *rvar; 1648 rdata_enum_t *enum_v; 1649 1650 #ifdef DEBUG_RUN_TRACE 1651 printf("Run symbol access operation.\n"); 1652 #endif 1653 run_cvt_value_item(run, arg, &arg_vi); 1654 arg_val = arg_vi->u.value; 1655 assert(arg_val->var->vc == vc_symbol); 1656 1657 symbol_v = arg_val->var->u.symbol_v; 1658 1659 /* XXX Port CSI symbol reference to using vc_symbol */ 1660 assert(symbol_v->sym->sc == sc_enum); 1661 1662 embr = stree_enum_find_mbr(symbol_v->sym->u.enum_d, 1663 access->member_name); 1664 1665 /* Member existence should be ensured by static type checking. */ 1666 assert(embr != NULL); 1667 1668 #ifdef DEBUG_RUN_TRACE 1669 printf("Found enum member '%s'.\n", 1670 strtab_get_str(access->member_name->sid)); 1671 #endif 1672 ritem = rdata_item_new(ic_value); 1673 rvalue = rdata_value_new(); 1674 rvar = rdata_var_new(vc_enum); 1675 enum_v = rdata_enum_new(); 1676 1677 ritem->u.value = rvalue; 1678 rvalue->var = rvar; 1679 rvar->u.enum_v = enum_v; 1680 enum_v->value = embr; 1681 1682 *res = ritem; 1683 } 1684 1444 1685 /** Call a function. 1445 1686 * … … 1455 1696 rdata_deleg_t *deleg_v; 1456 1697 list_t arg_vals; 1457 list_node_t *node;1458 stree_expr_t *arg;1459 rdata_item_t *rarg_i, *rarg_vi;1460 1698 1461 1699 stree_fun_t *fun; … … 1499 1737 #endif 1500 1738 /* Evaluate function arguments. */ 1739 run_call_args(run, &call->args, &arg_vals); 1740 if (run_is_bo(run)) { 1741 *res = NULL; 1742 return; 1743 } 1744 1745 fun = symbol_to_fun(deleg_v->sym); 1746 assert(fun != NULL); 1747 1748 /* Create procedure activation record. */ 1749 run_proc_ar_create(run, deleg_v->obj, fun->proc, &proc_ar); 1750 1751 /* Fill in argument values. */ 1752 run_proc_ar_set_args(run, proc_ar, &arg_vals); 1753 1754 /* Run the function. */ 1755 run_proc(run, proc_ar, res); 1756 1757 if (!run_is_bo(run) && fun->sig->rtype != NULL && *res == NULL) { 1758 printf("Error: Function '"); 1759 symbol_print_fqn(deleg_v->sym); 1760 printf("' did not return a value.\n"); 1761 exit(1); 1762 } 1763 1764 #ifdef DEBUG_RUN_TRACE 1765 printf("Returned from function call.\n"); 1766 #endif 1767 } 1768 1769 /** Evaluate call arguments. 1770 * 1771 * Evaluate arguments to function or constructor. 1772 * 1773 * @param run Runner object 1774 * @param args Real arguments (list of stree_expr_t) 1775 * @param arg_vals Address of uninitialized list to store argument values 1776 * (list of rdata_item_t). 1777 */ 1778 static void run_call_args(run_t *run, list_t *args, list_t *arg_vals) 1779 { 1780 list_node_t *arg_n; 1781 stree_expr_t *arg; 1782 rdata_item_t *rarg_i, *rarg_vi; 1783 1784 /* Evaluate function arguments. */ 1785 list_init(arg_vals); 1786 arg_n = list_first(args); 1787 1788 while (arg_n != NULL) { 1789 arg = list_node_data(arg_n, stree_expr_t *); 1790 run_expr(run, arg, &rarg_i); 1791 if (run_is_bo(run)) 1792 return; 1793 1794 run_cvt_value_item(run, rarg_i, &rarg_vi); 1795 1796 list_append(arg_vals, rarg_vi); 1797 arg_n = list_next(args, arg_n); 1798 } 1799 } 1800 1801 /** Run index operation. 1802 * 1803 * Evaluate operation per the indexing ('[', ']') operator. 1804 * 1805 * @param run Runner object 1806 * @param index Index operation 1807 * @param res Place to store result 1808 */ 1809 static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res) 1810 { 1811 rdata_item_t *rbase; 1812 rdata_item_t *base_i; 1813 list_node_t *node; 1814 stree_expr_t *arg; 1815 rdata_item_t *rarg_i, *rarg_vi; 1816 var_class_t vc; 1817 list_t arg_vals; 1818 1819 #ifdef DEBUG_RUN_TRACE 1820 printf("Run index operation.\n"); 1821 #endif 1822 run_expr(run, index->base, &rbase); 1823 if (run_is_bo(run)) { 1824 *res = NULL; 1825 return; 1826 } 1827 1828 vc = run_item_get_vc(run, rbase); 1829 1830 /* Implicitly dereference. */ 1831 if (vc == vc_ref) { 1832 run_dereference(run, rbase, index->base->cspan, &base_i); 1833 if (run_is_bo(run)) { 1834 *res = NULL; 1835 return; 1836 } 1837 } else { 1838 base_i = rbase; 1839 } 1840 1841 vc = run_item_get_vc(run, base_i); 1842 1843 /* Evaluate arguments (indices). */ 1844 node = list_first(&index->args); 1501 1845 list_init(&arg_vals); 1502 node = list_first(&call->args);1503 1846 1504 1847 while (node != NULL) { … … 1513 1856 1514 1857 list_append(&arg_vals, rarg_vi); 1515 node = list_next(&call->args, node);1516 }1517 1518 fun = symbol_to_fun(deleg_v->sym);1519 assert(fun != NULL);1520 1521 /* Create procedure activation record. */1522 run_proc_ar_create(run, deleg_v->obj, fun->proc, &proc_ar);1523 1524 /* Fill in argument values. */1525 run_proc_ar_set_args(run, proc_ar, &arg_vals);1526 1527 /* Run the function. */1528 run_proc(run, proc_ar, res);1529 1530 #ifdef DEBUG_RUN_TRACE1531 printf("Returned from function call.\n");1532 #endif1533 }1534 1535 /** Run index operation.1536 *1537 * Evaluate operation per the indexing ('[', ']') operator.1538 *1539 * @param run Runner object1540 * @param index Index operation1541 * @param res Place to store result1542 */1543 static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res)1544 {1545 rdata_item_t *rbase;1546 rdata_item_t *base_i;1547 list_node_t *node;1548 stree_expr_t *arg;1549 rdata_item_t *rarg_i, *rarg_vi;1550 var_class_t vc;1551 list_t arg_vals;1552 1553 #ifdef DEBUG_RUN_TRACE1554 printf("Run index operation.\n");1555 #endif1556 run_expr(run, index->base, &rbase);1557 if (run_is_bo(run)) {1558 *res = NULL;1559 return;1560 }1561 1562 vc = run_item_get_vc(run, rbase);1563 1564 /* Implicitly dereference. */1565 if (vc == vc_ref) {1566 run_dereference(run, rbase, &base_i);1567 } else {1568 base_i = rbase;1569 }1570 1571 vc = run_item_get_vc(run, base_i);1572 1573 /* Evaluate arguments (indices). */1574 node = list_first(&index->args);1575 list_init(&arg_vals);1576 1577 while (node != NULL) {1578 arg = list_node_data(node, stree_expr_t *);1579 run_expr(run, arg, &rarg_i);1580 if (run_is_bo(run)) {1581 *res = NULL;1582 return;1583 }1584 1585 run_cvt_value_item(run, rarg_i, &rarg_vi);1586 1587 list_append(&arg_vals, rarg_vi);1588 1858 1589 1859 node = list_next(&index->args, node); … … 1634 1904 #endif 1635 1905 (void) run; 1636 (void) index;1637 1906 1638 1907 assert(base->ic == ic_address); … … 1676 1945 /* Raise Error.OutOfBounds */ 1677 1946 run_raise_exc(run, 1678 run->program->builtin->error_outofbounds); 1947 run->program->builtin->error_outofbounds, 1948 index->expr->cspan); 1949 /* XXX It should be cspan of the argument. */ 1679 1950 *res = run_recovery_item(run); 1680 1951 return; … … 1814 2085 #endif 1815 2086 (void) run; 1816 (void) index;1817 2087 1818 2088 run_cvt_value_item(run, base, &base_vi); … … 1866 2136 #endif 1867 2137 /* Raise Error.OutOfBounds */ 1868 run_raise_exc(run, run->program->builtin->error_outofbounds); 2138 run_raise_exc(run, run->program->builtin->error_outofbounds, 2139 index->expr->cspan); 1869 2140 *res = run_recovery_item(run); 1870 2141 return; … … 1970 2241 } 1971 2242 1972 run_dereference(run, rarg_vi, &rarg_di);2243 run_dereference(run, rarg_vi, NULL, &rarg_di); 1973 2244 1974 2245 /* Now we should have a variable address. */ … … 2048 2319 case vc_ref: 2049 2320 case vc_deleg: 2321 case vc_enum: 2050 2322 case vc_array: 2051 2323 case vc_object: 2052 2324 case vc_resource: 2325 case vc_symbol: 2053 2326 assert(b_false); 2054 2327 } … … 2147 2420 } 2148 2421 2422 /** Run constructor on an object. 2423 * 2424 * @param run Runner object 2425 * @param obj Object to run constructor on 2426 * @param arg_vals Argument values (list of rdata_item_t) 2427 */ 2428 static void run_object_ctor(run_t *run, rdata_var_t *obj, list_t *arg_vals) 2429 { 2430 stree_ident_t *ctor_ident; 2431 stree_symbol_t *csi_sym; 2432 stree_csi_t *csi; 2433 stree_symbol_t *ctor_sym; 2434 stree_ctor_t *ctor; 2435 run_proc_ar_t *proc_ar; 2436 rdata_item_t *res; 2437 2438 csi_sym = obj->u.object_v->class_sym; 2439 csi = symbol_to_csi(csi_sym); 2440 assert(csi != NULL); 2441 2442 #ifdef DEBUG_RUN_TRACE 2443 printf("Run object constructor from CSI '"); 2444 symbol_print_fqn(csi_sym); 2445 printf("'.\n"); 2446 #endif 2447 ctor_ident = stree_ident_new(); 2448 ctor_ident->sid = strtab_get_sid(CTOR_IDENT); 2449 2450 /* Find constructor. */ 2451 ctor_sym = symbol_search_csi_no_base(run->program, csi, ctor_ident); 2452 if (ctor_sym == NULL) { 2453 #ifdef DEBUG_RUN_TRACE 2454 printf("No constructor found.\n"); 2455 #endif 2456 return; 2457 } 2458 2459 ctor = symbol_to_ctor(ctor_sym); 2460 assert(ctor != NULL); 2461 2462 /* Create procedure activation record. */ 2463 run_proc_ar_create(run, obj, ctor->proc, &proc_ar); 2464 2465 /* Fill in argument values. */ 2466 run_proc_ar_set_args(run, proc_ar, arg_vals); 2467 2468 /* Run the procedure. */ 2469 run_proc(run, proc_ar, &res); 2470 2471 /* Constructor does not return a value. */ 2472 assert(res == NULL); 2473 2474 #ifdef DEBUG_RUN_TRACE 2475 printf("Returned from constructor..\n"); 2476 #endif 2477 } 2478 2149 2479 /** Return boolean value of an item. 2150 2480 * -
uspace/app/sbi/src/run_t.h
r1317380 r640ffe6 97 97 run_bailout_mode_t bo_mode; 98 98 99 /** Exception cspan */ 100 struct cspan *exc_cspan; 101 99 102 /** Exception payload */ 100 103 struct rdata_value *exc_payload; -
uspace/app/sbi/src/run_texpr.c
r1317380 r640ffe6 31 31 #include <assert.h> 32 32 #include <stdlib.h> 33 #include "cspan.h" 33 34 #include "debug.h" 34 35 #include "list.h" … … 102 103 tdata_deleg_t *tdeleg; 103 104 stree_csi_t *base_csi; 105 stree_deleg_t *deleg; 106 stree_enum_t *enum_d; 107 tdata_enum_t *tenum; 104 108 105 109 #ifdef DEBUG_RUN_TRACE … … 115 119 116 120 if (targ_i->tic != tic_tobject) { 117 printf("Error: Using '.' with type which is not an object.\n"); 121 cspan_print(taccess->texpr->cspan); 122 printf(" Error: Using '.' with type which is not an " 123 "object.\n"); 118 124 *res = tdata_item_new(tic_ignore); 119 125 return; … … 125 131 sym = symbol_lookup_in_csi(prog, base_csi, taccess->member_name); 126 132 if (sym == NULL) { 127 printf("Error: CSI '"); 133 cspan_print(taccess->member_name->cspan); 134 printf(" Error: CSI '"); 128 135 symbol_print_fqn(csi_to_symbol(base_csi)); 129 136 printf("' has no member named '%s'.\n", … … 142 149 tobject->static_ref = b_false; 143 150 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: 157 printf("Error: Symbol '"); 158 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 */ 178 static void run_tindex(stree_program_t *prog, stree_csi_t *ctx, 179 stree_tindex_t *tindex, tdata_item_t **res) 180 { 181 tdata_item_t *base_ti; 182 tdata_item_t *titem; 183 tdata_array_t *tarray; 184 stree_expr_t *arg_expr; 185 list_node_t *arg_node; 186 187 #ifdef DEBUG_RUN_TRACE 188 printf("Evaluating type index operation.\n"); 189 #endif 190 /* Evaluate base type. */ 191 run_texpr(prog, ctx, tindex->base_type, &base_ti); 192 193 if (base_ti->tic == tic_ignore) { 194 *res = tdata_item_new(tic_ignore); 195 return; 196 } 197 198 /* Construct type item. */ 199 titem = tdata_item_new(tic_tarray); 200 tarray = tdata_array_new(); 201 titem->u.tarray = tarray; 202 203 tarray->base_ti = base_ti; 204 tarray->rank = tindex->n_args; 205 206 /* Copy extents. */ 207 list_init(&tarray->extents); 208 arg_node = list_first(&tindex->args); 209 210 while (arg_node != NULL) { 211 arg_expr = list_node_data(arg_node, stree_expr_t *); 212 list_append(&tarray->extents, arg_expr); 213 arg_node = list_next(&tindex->args, arg_node); 214 } 215 216 *res = titem; 217 } 218 219 /** Evaluate type literal expression. 220 * 221 * @param prog Program 222 * @param ctx Current CSI (context) 223 * @param tliteral Type literal 224 * @param res Place to store type result 225 */ 226 static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx, 227 stree_tliteral_t *tliteral, tdata_item_t **res) 228 { 229 tdata_item_t *titem; 230 tdata_primitive_t *tprimitive; 231 tprimitive_class_t tpc; 232 233 #ifdef DEBUG_RUN_TRACE 234 printf("Evaluating type literal.\n"); 235 #endif 236 (void) prog; 237 (void) ctx; 238 (void) tliteral; 239 240 switch (tliteral->tlc) { 241 case tlc_bool: tpc = tpc_bool; break; 242 case tlc_char: tpc = tpc_char; break; 243 case tlc_int: tpc = tpc_int; break; 244 case tlc_string: tpc = tpc_string; break; 245 case tlc_resource: tpc = tpc_resource; break; 246 } 247 248 /* Construct type item. */ 249 titem = tdata_item_new(tic_tprimitive); 250 tprimitive = tdata_primitive_new(tpc); 251 titem->u.tprimitive = tprimitive; 252 253 *res = titem; 254 } 255 256 static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx, 257 stree_tnameref_t *tnameref, tdata_item_t **res) 258 { 259 stree_symbol_t *sym; 260 tdata_item_t *titem; 261 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 267 #ifdef DEBUG_RUN_TRACE 268 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 */ 293 sym = symbol_lookup_in_csi(prog, ctx, tnameref->name); 294 if (sym == NULL) { 295 printf("Error: Symbol '%s' not found.\n", 296 strtab_get_str(tnameref->name->sid)); 297 *res = tdata_item_new(tic_ignore); 298 return; 299 } 300 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; 151 list_init(&tobject->targs); 152 break; 153 case sc_ctor: 154 /* It is not possible to reference a constructor explicitly. */ 155 assert(b_false); 312 156 case sc_deleg: 313 157 /* Fetch stored delegate type. */ … … 330 174 } 331 175 break; 176 case sc_enum: 177 /* Fetch stored enum type. */ 178 enum_d = symbol_to_enum(sym); 179 assert(enum_d != NULL); 180 if (enum_d->titem == NULL) { 181 /* 182 * Prepare a partial enum whic will be completed 183 * later. 184 */ 185 titem = tdata_item_new(tic_tenum); 186 tenum = tdata_enum_new(); 187 titem->u.tenum = tenum; 188 tenum->enum_d = enum_d; 189 } else { 190 titem = enum_d->titem; 191 } 192 break; 332 193 case sc_fun: 333 194 case sc_var: 334 195 case sc_prop: 335 printf("Error: Symbol '"); 196 cspan_print(taccess->member_name->cspan); 197 printf(" Error: Symbol '"); 198 symbol_print_fqn(sym); 199 printf("' is not a type.\n"); 200 titem = tdata_item_new(tic_ignore); 201 break; 202 } 203 204 *res = titem; 205 } 206 207 /** Evaluate type indexing expression. 208 * 209 * Evaluate operation per the type indexing ('[', ']') operator. 210 * A type indexing operation may have extents specified or only rank 211 * specified. 212 * 213 * @param prog Program 214 * @param ctx Current CSI (context) 215 * @param tindex Type indexing expression to evaluate 216 * @param res Place to store type result 217 */ 218 static void run_tindex(stree_program_t *prog, stree_csi_t *ctx, 219 stree_tindex_t *tindex, tdata_item_t **res) 220 { 221 tdata_item_t *base_ti; 222 tdata_item_t *titem; 223 tdata_array_t *tarray; 224 stree_expr_t *arg_expr; 225 list_node_t *arg_node; 226 227 #ifdef DEBUG_RUN_TRACE 228 printf("Evaluating type index operation.\n"); 229 #endif 230 /* Evaluate base type. */ 231 run_texpr(prog, ctx, tindex->base_type, &base_ti); 232 233 if (base_ti->tic == tic_ignore) { 234 *res = tdata_item_new(tic_ignore); 235 return; 236 } 237 238 /* Construct type item. */ 239 titem = tdata_item_new(tic_tarray); 240 tarray = tdata_array_new(); 241 titem->u.tarray = tarray; 242 243 tarray->base_ti = base_ti; 244 tarray->rank = tindex->n_args; 245 246 /* Copy extents. */ 247 list_init(&tarray->extents); 248 arg_node = list_first(&tindex->args); 249 250 while (arg_node != NULL) { 251 arg_expr = list_node_data(arg_node, stree_expr_t *); 252 list_append(&tarray->extents, arg_expr); 253 arg_node = list_next(&tindex->args, arg_node); 254 } 255 256 *res = titem; 257 } 258 259 /** Evaluate type literal expression. 260 * 261 * @param prog Program 262 * @param ctx Current CSI (context) 263 * @param tliteral Type literal 264 * @param res Place to store type result 265 */ 266 static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx, 267 stree_tliteral_t *tliteral, tdata_item_t **res) 268 { 269 tdata_item_t *titem; 270 tdata_primitive_t *tprimitive; 271 tprimitive_class_t tpc; 272 273 #ifdef DEBUG_RUN_TRACE 274 printf("Evaluating type literal.\n"); 275 #endif 276 (void) prog; 277 (void) ctx; 278 (void) tliteral; 279 280 switch (tliteral->tlc) { 281 case tlc_bool: tpc = tpc_bool; break; 282 case tlc_char: tpc = tpc_char; break; 283 case tlc_int: tpc = tpc_int; break; 284 case tlc_string: tpc = tpc_string; break; 285 case tlc_resource: tpc = tpc_resource; break; 286 } 287 288 /* Construct type item. */ 289 titem = tdata_item_new(tic_tprimitive); 290 tprimitive = tdata_primitive_new(tpc); 291 titem->u.tprimitive = tprimitive; 292 293 *res = titem; 294 } 295 296 static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx, 297 stree_tnameref_t *tnameref, tdata_item_t **res) 298 { 299 stree_symbol_t *sym; 300 tdata_item_t *titem; 301 tdata_object_t *tobject; 302 stree_targ_t *targ; 303 tdata_vref_t *tvref; 304 stree_deleg_t *deleg; 305 tdata_deleg_t *tdeleg; 306 stree_enum_t *enum_d; 307 tdata_enum_t *tenum; 308 309 #ifdef DEBUG_RUN_TRACE 310 printf("Evaluating type name reference.\n"); 311 printf("'%s'\n", strtab_get_str(tnameref->name->sid)); 312 #endif 313 /* In interactive mode we are not in a class */ 314 if (ctx != NULL) { 315 /* Look for type argument */ 316 targ = stree_csi_find_targ(ctx, tnameref->name); 317 318 if (targ != NULL) { 319 /* Found type argument */ 320 #ifdef DEBUG_RUN_TRACE 321 printf("Found type argument '%s'.\n", 322 strtab_get_str(tnameref->name->sid)); 323 #endif 324 titem = tdata_item_new(tic_tvref); 325 tvref = tdata_vref_new(); 326 titem->u.tvref = tvref; 327 tvref->targ = targ; 328 329 *res = titem; 330 return; 331 } 332 } 333 334 /* Look for symbol */ 335 sym = symbol_lookup_in_csi(prog, ctx, tnameref->name); 336 if (sym == NULL) { 337 cspan_print(tnameref->texpr->cspan); 338 printf(" Error: Symbol '%s' not found.\n", 339 strtab_get_str(tnameref->name->sid)); 340 *res = tdata_item_new(tic_ignore); 341 return; 342 } 343 344 switch (sym->sc) { 345 case sc_csi: 346 /* Construct type item. */ 347 titem = tdata_item_new(tic_tobject); 348 tobject = tdata_object_new(); 349 titem->u.tobject = tobject; 350 351 tobject->static_ref = b_false; 352 tobject->csi = sym->u.csi; 353 list_init(&tobject->targs); 354 break; 355 case sc_ctor: 356 /* It is not possible to reference a constructor explicitly. */ 357 assert(b_false); 358 case sc_deleg: 359 /* Fetch stored delegate type. */ 360 deleg = symbol_to_deleg(sym); 361 assert(deleg != NULL); 362 if (deleg->titem == NULL) { 363 /* 364 * Prepare a partial delegate which will be completed 365 * later. 366 */ 367 titem = tdata_item_new(tic_tdeleg); 368 tdeleg = tdata_deleg_new(); 369 titem->u.tdeleg = tdeleg; 370 tdeleg->deleg = deleg; 371 tdeleg->tsig = NULL; 372 373 deleg->titem = titem; 374 } else { 375 titem = deleg->titem; 376 } 377 break; 378 case sc_enum: 379 /* Fetch stored enum type. */ 380 enum_d = symbol_to_enum(sym); 381 assert(enum_d != NULL); 382 if (enum_d->titem == NULL) { 383 /* 384 * Prepare a partial enum whic will be completed 385 * later. 386 */ 387 titem = tdata_item_new(tic_tenum); 388 tenum = tdata_enum_new(); 389 titem->u.tenum = tenum; 390 tenum->enum_d = enum_d; 391 } else { 392 titem = enum_d->titem; 393 } 394 break; 395 case sc_fun: 396 case sc_var: 397 case sc_prop: 398 cspan_print(tnameref->texpr->cspan); 399 printf(" Error: Symbol '"); 336 400 symbol_print_fqn(sym); 337 401 printf("' is not a type.\n"); … … 379 443 380 444 if (base_ti->tic != tic_tobject) { 381 printf("Error: Base type of generic application is not " 445 cspan_print(tapply->gtype->cspan); 446 printf(" Error: Base type of generic application is not " 382 447 "a CSI.\n"); 383 448 *res = tdata_item_new(tic_ignore); … … 410 475 411 476 if (farg_n != NULL || arg_n != NULL) { 412 printf("Error: Incorrect number of type arguments.\n"); 477 cspan_print(tapply->texpr->cspan); 478 printf(" Error: Incorrect number of type arguments.\n"); 413 479 *res = tdata_item_new(tic_ignore); 414 480 return; -
uspace/app/sbi/src/stree.c
r1317380 r640ffe6 116 116 } 117 117 118 /** Allocate new constructor. 119 * 120 * @return New constructor 121 */ 122 stree_ctor_t *stree_ctor_new(void) 123 { 124 stree_ctor_t *ctor; 125 126 ctor = calloc(1, sizeof(stree_ctor_t)); 127 if (ctor == NULL) { 128 printf("Memory allocation failed.\n"); 129 exit(1); 130 } 131 132 return ctor; 133 } 134 118 135 /** Allocate new member delegate. 119 136 * … … 133 150 } 134 151 152 /** Allocate new enum. 153 * 154 * @return New enum 155 */ 156 stree_enum_t *stree_enum_new(void) 157 { 158 stree_enum_t *enum_d; 159 160 enum_d = calloc(1, sizeof(stree_enum_t)); 161 if (enum_d == NULL) { 162 printf("Memory allocation failed.\n"); 163 exit(1); 164 } 165 166 return enum_d; 167 } 168 169 /** Allocate new enum member. 170 * 171 * @return New enum member 172 */ 173 stree_embr_t *stree_embr_new(void) 174 { 175 stree_embr_t *embr; 176 177 embr = calloc(1, sizeof(stree_embr_t)); 178 if (embr == NULL) { 179 printf("Memory allocation failed.\n"); 180 exit(1); 181 } 182 183 return embr; 184 } 185 135 186 /** Allocate new member function. 136 187 * … … 394 445 } 395 446 447 /** Allocate new @c break statement. 448 * 449 * @return New @c break statement 450 */ 451 stree_break_t *stree_break_new(void) 452 { 453 stree_break_t *break_s; 454 455 break_s = calloc(1, sizeof(stree_break_t)); 456 if (break_s == NULL) { 457 printf("Memory allocation failed.\n"); 458 exit(1); 459 } 460 461 return break_s; 462 } 463 396 464 /** Allocate new @c return statement. 397 465 * … … 462 530 } 463 531 532 /** Allocate new @c if/elif clause. 533 * 534 * @return New @c if/elif clause 535 */ 536 stree_if_clause_t *stree_if_clause_new(void) 537 { 538 stree_if_clause_t *if_clause; 539 540 if_clause = calloc(1, sizeof(stree_if_clause_t)); 541 if (if_clause == NULL) { 542 printf("Memory allocation failed.\n"); 543 exit(1); 544 } 545 546 return if_clause; 547 } 548 464 549 /** Allocate new statement block. 465 550 * … … 869 954 * @param symbol Symbol 870 955 * @param sac Symbol attribute class 871 * @return @c b_true if yes, @c b_false if no .956 * @return @c b_true if yes, @c b_false if no 872 957 */ 873 958 bool_t stree_symbol_has_attr(stree_symbol_t *symbol, symbol_attr_class_t sac) … … 938 1023 /** Search for CSI type argument of the given name. 939 1024 * 940 * @param csi CSI to look in .941 * @param ident Identifier of the type argument .942 * @return Type argument de finition or @c NULL if not found.1025 * @param csi CSI to look in 1026 * @param ident Identifier of the type argument 1027 * @return Type argument declaration or @c NULL if not found 943 1028 */ 944 1029 stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident) … … 959 1044 return NULL; 960 1045 } 1046 1047 /** Search for enum member of the given name. 1048 * 1049 * @param enum_d Enum to look in 1050 * @param ident Identifier of the enum member 1051 * @return Enum member declaration or @c NULL if not found 1052 */ 1053 stree_embr_t *stree_enum_find_mbr(stree_enum_t *enum_d, stree_ident_t *ident) 1054 { 1055 list_node_t *embr_n; 1056 stree_embr_t *embr; 1057 1058 embr_n = list_first(&enum_d->members); 1059 while (embr_n != NULL) { 1060 embr = list_node_data(embr_n, stree_embr_t *); 1061 if (embr->name->sid == ident->sid) 1062 return embr; 1063 1064 embr_n = list_next(&enum_d->members, embr_n); 1065 } 1066 1067 /* No match */ 1068 return NULL; 1069 } 1070 1071 /** Get CSI member name. 1072 * 1073 * @param csimbr CSI member 1074 * @return Member name 1075 */ 1076 stree_ident_t *stree_csimbr_get_name(stree_csimbr_t *csimbr) 1077 { 1078 stree_ident_t *mbr_name; 1079 1080 /* Keep compiler happy. */ 1081 mbr_name = NULL; 1082 1083 switch (csimbr->cc) { 1084 case csimbr_csi: mbr_name = csimbr->u.csi->name; break; 1085 case csimbr_ctor: mbr_name = csimbr->u.ctor->name; break; 1086 case csimbr_deleg: mbr_name = csimbr->u.deleg->name; break; 1087 case csimbr_enum: mbr_name = csimbr->u.enum_d->name; break; 1088 case csimbr_fun: mbr_name = csimbr->u.fun->name; break; 1089 case csimbr_var: mbr_name = csimbr->u.var->name; break; 1090 case csimbr_prop: mbr_name = csimbr->u.prop->name; break; 1091 } 1092 1093 return mbr_name; 1094 } -
uspace/app/sbi/src/stree.h
r1317380 r640ffe6 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_ctor_t *stree_ctor_new(void); 38 39 stree_deleg_t *stree_deleg_new(void); 40 stree_enum_t *stree_enum_new(void); 41 stree_embr_t *stree_embr_new(void); 39 42 stree_fun_t *stree_fun_new(void); 40 43 stree_var_t *stree_var_new(void); … … 55 58 stree_for_t *stree_for_new(void); 56 59 stree_raise_t *stree_raise_new(void); 60 stree_break_t *stree_break_new(void); 57 61 stree_return_t *stree_return_new(void); 58 62 stree_wef_t *stree_wef_new(void); … … 60 64 61 65 stree_except_t *stree_except_new(void); 66 stree_if_clause_t *stree_if_clause_new(void); 62 67 stree_block_t *stree_block_new(void); 63 68 … … 92 97 bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b); 93 98 stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident); 99 stree_embr_t *stree_enum_find_mbr(stree_enum_t *enum_d, stree_ident_t *ident); 100 stree_ident_t *stree_csimbr_get_name(stree_csimbr_t *csimbr); 94 101 95 102 #endif -
uspace/app/sbi/src/stree_t.h
r1317380 r640ffe6 43 43 typedef struct { 44 44 int sid; 45 struct cspan *cspan; 45 46 } stree_ident_t; 46 47 47 48 /** Name reference */ 48 49 typedef struct { 50 /** Expression backlink */ 51 struct stree_expr *expr; 52 49 53 stree_ident_t *name; 50 54 } stree_nameref_t; 51 52 /** Reference to currently active object. */53 typedef struct {54 } stree_self_ref_t;55 55 56 56 /** Boolean literal */ … … 88 88 /** Literal */ 89 89 typedef struct { 90 /** Expression backlink */ 91 struct stree_expr *expr; 92 90 93 literal_class_t ltc; 91 94 union { … … 98 101 } stree_literal_t; 99 102 103 /** Reference to currently active object. */ 104 typedef struct { 105 /** Expression backlink */ 106 struct stree_expr *expr; 107 } stree_self_ref_t; 108 100 109 /** Binary operation class */ 101 110 typedef enum { … … 108 117 bo_plus, 109 118 bo_minus, 110 bo_mult 119 bo_mult, 120 bo_and, 121 bo_or 111 122 } binop_class_t; 112 123 … … 115 126 uo_plus, 116 127 uo_minus, 128 uo_not 117 129 } unop_class_t; 118 130 119 131 /** Binary operation */ 120 132 typedef struct { 133 /** Expression backlink */ 134 struct stree_expr *expr; 135 121 136 /** Binary operation class */ 122 137 binop_class_t bc; … … 128 143 /** Unary operation */ 129 144 typedef struct { 145 /** Expression backlink */ 146 struct stree_expr *expr; 147 130 148 /** Operation class */ 131 149 unop_class_t uc; … … 137 155 /** New operation */ 138 156 typedef struct { 157 /** Expression backlink */ 158 struct stree_expr *expr; 159 139 160 /** Type of object to construct. */ 140 161 struct stree_texpr *texpr; 162 163 /** Constructor arguments */ 164 list_t ctor_args; /* of stree_expr_t */ 141 165 } stree_new_t; 142 166 143 167 /** Member access operation */ 144 168 typedef struct { 169 /** Expression backlink */ 170 struct stree_expr *expr; 171 145 172 /** Argument */ 146 173 struct stree_expr *arg; … … 151 178 /** Function call operation */ 152 179 typedef struct { 180 /** Expression backlink */ 181 struct stree_expr *expr; 182 153 183 /** Function */ 154 184 struct stree_expr *fun; … … 165 195 /** Assignment */ 166 196 typedef struct { 197 /** Expression backlink */ 198 struct stree_expr *expr; 199 167 200 assign_class_t ac; 168 201 struct stree_expr *dest, *src; … … 171 204 /** Indexing operation */ 172 205 typedef struct { 206 /** Expression backlink */ 207 struct stree_expr *expr; 208 173 209 /** Base */ 174 210 struct stree_expr *base; … … 180 216 /** @c as conversion operation */ 181 217 typedef struct { 218 /** Expression backlink */ 219 struct stree_expr *expr; 220 182 221 /** Expression to convert */ 183 222 struct stree_expr *arg; 223 184 224 /** Destination type of conversion. */ 185 225 struct stree_texpr *dtype; … … 193 233 */ 194 234 typedef struct { 235 /** Expression backlink */ 236 struct stree_expr *expr; 237 195 238 /* Primitive type expression */ 196 239 struct stree_expr *arg; … … 217 260 expr_class_t ec; 218 261 262 /** Type of this expression or @c NULL if not typed yet */ 219 263 struct tdata_item *titem; 264 265 /** Coordinate span */ 266 struct cspan *cspan; 220 267 221 268 union { … … 252 299 /** Type literal */ 253 300 typedef struct { 301 /** Type expression backlink */ 302 struct stree_texpr *texpr; 303 254 304 tliteral_class_t tlc; 255 305 } stree_tliteral_t; … … 257 307 /** Type name reference */ 258 308 typedef struct { 309 /** Type expression backlink */ 310 struct stree_texpr *texpr; 311 259 312 stree_ident_t *name; 260 313 } stree_tnameref_t; … … 262 315 /** Type member access operation */ 263 316 typedef struct { 317 /** Type expression backlink */ 318 struct stree_texpr *texpr; 319 264 320 /** Argument */ 265 321 struct stree_texpr *arg; 322 266 323 /** Name of member being accessed. */ 267 324 stree_ident_t *member_name; … … 270 327 /** Type application operation */ 271 328 typedef struct { 329 /** Type expression backlink */ 330 struct stree_texpr *texpr; 331 272 332 /* Base type */ 273 333 struct stree_texpr *gtype; … … 279 339 /** Type index operation */ 280 340 typedef struct { 341 /** Type expression backlink */ 342 struct stree_texpr *texpr; 343 281 344 /** Base type */ 282 345 struct stree_texpr *base_type; … … 304 367 typedef struct stree_texpr { 305 368 texpr_class_t tc; 369 370 /** Coordinate span */ 371 struct cspan *cspan; 306 372 307 373 union { … … 337 403 } stree_except_t; 338 404 405 /** @c if or @c elif clause */ 406 typedef struct { 407 stree_expr_t *cond; 408 stree_block_t *block; 409 } stree_if_clause_t; 410 339 411 /** If statement */ 340 412 typedef struct { 341 stree_expr_t *cond; 342 stree_block_t *if_block; 413 /** If and elif clauses */ 414 list_t if_clauses; /* of stree_if_clause_t */ 415 416 /** Else block */ 343 417 stree_block_t *else_block; 344 418 } stree_if_t; … … 359 433 stree_expr_t *expr; 360 434 } stree_raise_t; 435 436 /** Break statement */ 437 typedef struct { 438 } stree_break_t; 361 439 362 440 /** Return statement */ … … 384 462 st_for, 385 463 st_raise, 464 st_break, 386 465 st_return, 387 466 st_exps, … … 399 478 stree_for_t *for_s; 400 479 stree_raise_t *raise_s; 480 stree_break_t *break_s; 401 481 stree_return_t *return_s; 402 482 stree_exps_t *exp_s; … … 461 541 } stree_proc_t; 462 542 543 /** Constructor declaration */ 544 typedef struct stree_ctor { 545 /** Constructor 'name'. Points to the @c new keyword. */ 546 stree_ident_t *name; 547 548 /** Symbol */ 549 struct stree_symbol *symbol; 550 551 /** Signature (arguments, return type is always none) */ 552 stree_fun_sig_t *sig; 553 554 /** Constructor implementation */ 555 stree_proc_t *proc; 556 557 /** Type item describing the constructor */ 558 struct tdata_item *titem; 559 } stree_ctor_t; 560 463 561 /** Delegate declaration */ 464 562 typedef struct stree_deleg { … … 476 574 } stree_deleg_t; 477 575 576 /** Enum member */ 577 typedef struct stree_embr { 578 /** Enum containing this declaration */ 579 struct stree_enum *outer_enum; 580 581 /** Enum member name */ 582 stree_ident_t *name; 583 } stree_embr_t; 584 585 /** Enum declaration */ 586 typedef struct stree_enum { 587 /** Enum name */ 588 stree_ident_t *name; 589 590 /** Symbol */ 591 struct stree_symbol *symbol; 592 593 /** List of enum members */ 594 list_t members; /* of stree_embr_t */ 595 596 /** Type item describing the enum */ 597 struct tdata_item *titem; 598 } stree_enum_t; 599 478 600 /** Member function declaration */ 479 601 typedef struct stree_fun { … … 521 643 /** 522 644 * Fake identifiers used with symbols that do not really have one. 523 * (Mostly for error messages.)524 645 */ 646 #define CTOR_IDENT "$ctor" 525 647 #define INDEXER_IDENT "$indexer" 526 648 527 649 typedef enum { 528 650 csimbr_csi, 651 csimbr_ctor, 529 652 csimbr_deleg, 653 csimbr_enum, 530 654 csimbr_fun, 531 655 csimbr_var, … … 539 663 union { 540 664 struct stree_csi *csi; 665 stree_ctor_t *ctor; 541 666 stree_deleg_t *deleg; 667 stree_enum_t *enum_d; 542 668 stree_fun_t *fun; 543 669 stree_var_t *var; … … 587 713 typedef enum { 588 714 /* Class, struct or interface declaration */ 589 mc_csi 715 mc_csi, 716 /* Enum declaration */ 717 mc_enum 590 718 } modm_class_t; 591 719 … … 595 723 union { 596 724 stree_csi_t *csi; 725 stree_enum_t *enum_d; 597 726 } u; 598 727 } stree_modm_t; … … 618 747 /** CSI (class, struct or interface) */ 619 748 sc_csi, 749 /** Constructor */ 750 sc_ctor, 620 751 /** Member delegate */ 621 752 sc_deleg, 753 /** Enum */ 754 sc_enum, 622 755 /** Member function */ 623 756 sc_fun, … … 638 771 union { 639 772 struct stree_csi *csi; 773 stree_ctor_t *ctor; 640 774 stree_deleg_t *deleg; 775 stree_enum_t *enum_d; 641 776 stree_fun_t *fun; 642 777 stree_var_t *var; -
uspace/app/sbi/src/stype.c
r1317380 r640ffe6 38 38 #include <stdlib.h> 39 39 #include <assert.h> 40 #include "cspan.h" 40 41 #include "debug.h" 41 42 #include "intmap.h" … … 52 53 53 54 static void stype_csi(stype_t *stype, stree_csi_t *csi); 55 static void stype_ctor(stype_t *stype, stree_ctor_t *ctor); 56 static void stype_ctor_body(stype_t *stype, stree_ctor_t *ctor); 54 57 static void stype_fun(stype_t *stype, stree_fun_t *fun); 55 58 static void stype_var(stype_t *stype, stree_var_t *var); … … 66 69 static void stype_for(stype_t *stype, stree_for_t *for_s); 67 70 static void stype_raise(stype_t *stype, stree_raise_t *raise_s); 71 static void stype_break(stype_t *stype, stree_break_t *break_s); 68 72 static void stype_return(stype_t *stype, stree_return_t *return_s); 69 73 static void stype_exps(stype_t *stype, stree_exps_t *exp_s, bool_t want_value); … … 80 84 static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr, 81 85 tdata_item_t *dest); 86 static stree_expr_t *stype_convert_tenum(stype_t *stype, stree_expr_t *expr, 87 tdata_item_t *dest); 82 88 static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype, 83 89 stree_expr_t *expr, tdata_item_t *dest); 84 90 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr, 85 91 tdata_item_t *dest); 86 static void stype_convert_failure(stype_t *stype, tdata_item_t *src,92 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr, 87 93 tdata_item_t *dest); 88 94 … … 112 118 while (mbr_n != NULL) { 113 119 mbr = list_node_data(mbr_n, stree_modm_t *); 114 assert(mbr->mc == mc_csi); 115 116 stype_csi(stype, mbr->u.csi); 120 121 switch (mbr->mc) { 122 case mc_csi: 123 stype_csi(stype, mbr->u.csi); 124 break; 125 case mc_enum: 126 stype_enum(stype, mbr->u.enum_d); 127 break; 128 } 117 129 118 130 mbr_n = list_next(&module->members, mbr_n); … … 145 157 switch (csimbr->cc) { 146 158 case csimbr_csi: stype_csi(stype, csimbr->u.csi); break; 159 case csimbr_ctor: stype_ctor(stype, csimbr->u.ctor); break; 147 160 case csimbr_deleg: stype_deleg(stype, csimbr->u.deleg); break; 161 case csimbr_enum: stype_enum(stype, csimbr->u.enum_d); break; 148 162 case csimbr_fun: stype_fun(stype, csimbr->u.fun); break; 149 163 case csimbr_var: stype_var(stype, csimbr->u.var); break; … … 155 169 156 170 stype->current_csi = prev_ctx; 171 } 172 173 /** Type a constructor. 174 * 175 * @param stype Static typing object. 176 * @param ctor Constructor to type. 177 */ 178 static void stype_ctor(stype_t *stype, stree_ctor_t *ctor) 179 { 180 #ifdef DEBUG_TYPE_TRACE 181 printf("Type constructor '"); 182 symbol_print_fqn(ctor_to_symbol(ctor)); 183 printf("'.\n"); 184 #endif 185 if (ctor->titem == NULL) 186 stype_ctor_header(stype, ctor); 187 188 stype_ctor_body(stype, ctor); 189 } 190 191 /** Type constructor header. 192 * 193 * @param stype Static typing object. 194 * @param ctor Constructor to type. 195 */ 196 void stype_ctor_header(stype_t *stype, stree_ctor_t *ctor) 197 { 198 stree_symbol_t *ctor_sym; 199 tdata_item_t *ctor_ti; 200 tdata_fun_t *tfun; 201 tdata_fun_sig_t *tsig; 202 203 #ifdef DEBUG_TYPE_TRACE 204 printf("Type constructor '"); 205 symbol_print_fqn(ctor_to_symbol(ctor)); 206 printf("' header.\n"); 207 #endif 208 if (ctor->titem != NULL) 209 return; /* Constructor header has already been typed. */ 210 211 ctor_sym = ctor_to_symbol(ctor); 212 213 /* Type function signature. */ 214 stype_fun_sig(stype, ctor_sym->outer_csi, ctor->sig, &tsig); 215 216 ctor_ti = tdata_item_new(tic_tfun); 217 tfun = tdata_fun_new(); 218 ctor_ti->u.tfun = tfun; 219 tfun->tsig = tsig; 220 221 ctor->titem = ctor_ti; 222 } 223 224 /** Type constructor body. 225 * 226 * @param stype Static typing object 227 * @param ctor Constructor 228 */ 229 static void stype_ctor_body(stype_t *stype, stree_ctor_t *ctor) 230 { 231 #ifdef DEBUG_TYPE_TRACE 232 printf("Type constructor '"); 233 symbol_print_fqn(ctor_to_symbol(ctor)); 234 printf("' body.\n"); 235 #endif 236 assert(stype->proc_vr == NULL); 237 238 stype->proc_vr = stype_proc_vr_new(); 239 stype->proc_vr->proc = ctor->proc; 240 list_init(&stype->proc_vr->block_vr); 241 242 stype_block(stype, ctor->proc->body); 243 244 free(stype->proc_vr); 245 stype->proc_vr = NULL; 157 246 } 158 247 … … 197 286 } 198 287 288 /** Type enum. 289 * 290 * @param stype Static typing object 291 * @param enum_d Enum to type 292 */ 293 void stype_enum(stype_t *stype, stree_enum_t *enum_d) 294 { 295 tdata_item_t *titem; 296 tdata_enum_t *tenum; 297 298 (void) stype; 299 300 #ifdef DEBUG_TYPE_TRACE 301 printf("Type enum '"); 302 symbol_print_fqn(enum_to_symbol(enum_d)); 303 printf("'.\n"); 304 #endif 305 if (enum_d->titem == NULL) { 306 titem = tdata_item_new(tic_tenum); 307 tenum = tdata_enum_new(); 308 titem->u.tenum = tenum; 309 tenum->enum_d = enum_d; 310 311 enum_d->titem = titem; 312 } else { 313 titem = enum_d->titem; 314 } 315 } 316 199 317 /** Type function. 200 318 * … … 457 575 case st_for: stype_for(stype, stat->u.for_s); break; 458 576 case st_raise: stype_raise(stype, stat->u.raise_s); break; 577 case st_break: stype_break(stype, stat->u.break_s); break; 459 578 case st_return: stype_return(stype, stat->u.return_s); break; 460 579 case st_exps: stype_exps(stype, stat->u.exp_s, want_value); break; … … 506 625 { 507 626 stree_expr_t *ccond; 627 list_node_t *ifc_node; 628 stree_if_clause_t *ifc; 508 629 509 630 #ifdef DEBUG_TYPE_TRACE 510 631 printf("Type 'if' statement.\n"); 511 632 #endif 512 /* Convert condition to boolean type. */ 513 stype_expr(stype, if_s->cond); 514 ccond = stype_convert(stype, if_s->cond, stype_boolean_titem(stype)); 515 516 /* Patch code with augmented expression. */ 517 if_s->cond = ccond; 518 519 /* Type the @c if block */ 520 stype_block(stype, if_s->if_block); 633 ifc_node = list_first(&if_s->if_clauses); 634 635 /* Walk through all if/elif clauses. */ 636 637 while (ifc_node != NULL) { 638 /* Get if/elif clause */ 639 ifc = list_node_data(ifc_node, stree_if_clause_t *); 640 641 /* Convert condition to boolean type. */ 642 stype_expr(stype, ifc->cond); 643 ccond = stype_convert(stype, ifc->cond, 644 stype_boolean_titem(stype)); 645 646 /* Patch code with augmented expression. */ 647 ifc->cond = ccond; 648 649 /* Type the @c if/elif block */ 650 stype_block(stype, ifc->block); 651 652 ifc_node = list_next(&if_s->if_clauses, ifc_node); 653 } 521 654 522 655 /* Type the @c else block */ … … 545 678 while_s->cond = ccond; 546 679 680 /* While is a breakable statement. Increment counter. */ 681 stype->proc_vr->bstat_cnt += 1; 682 547 683 /* Type the body of the loop */ 548 684 stype_block(stype, while_s->body); 685 686 stype->proc_vr->bstat_cnt -= 1; 549 687 } 550 688 … … 559 697 printf("Type 'for' statement.\n"); 560 698 #endif 699 /* For is a breakable statement. Increment counter. */ 700 stype->proc_vr->bstat_cnt += 1; 701 561 702 stype_block(stype, for_s->body); 703 704 stype->proc_vr->bstat_cnt -= 1; 562 705 } 563 706 … … 573 716 #endif 574 717 stype_expr(stype, raise_s->expr); 718 } 719 720 /** Type @c break statement */ 721 static void stype_break(stype_t *stype, stree_break_t *break_s) 722 { 723 #ifdef DEBUG_TYPE_TRACE 724 printf("Type 'break' statement.\n"); 725 #endif 726 (void) break_s; 727 728 /* Check whether there is an active statement to break from. */ 729 if (stype->proc_vr->bstat_cnt == 0) { 730 printf("Error: Break statement outside of while or for.\n"); 731 stype_note_error(stype); 732 } 575 733 } 576 734 … … 588 746 printf("Type 'return' statement.\n"); 589 747 #endif 590 stype_expr(stype, return_s->expr); 748 if (return_s->expr != NULL) 749 stype_expr(stype, return_s->expr); 591 750 592 751 /* Determine the type we need to return. */ … … 599 758 600 759 /* XXX Memoize to avoid recomputing. */ 601 run_texpr(stype->program, outer_sym->outer_csi, 602 fun->sig->rtype, &dtype); 760 if (fun->sig->rtype != NULL) { 761 run_texpr(stype->program, outer_sym->outer_csi, 762 fun->sig->rtype, &dtype); 763 764 if (return_s->expr == NULL) { 765 printf("Error: Return without a value in " 766 "function returning value.\n"); 767 stype_note_error(stype); 768 } 769 } else { 770 dtype = NULL; 771 772 if (return_s->expr != NULL) { 773 printf("Error: Return with a value in " 774 "value-less function.\n"); 775 stype_note_error(stype); 776 } 777 } 603 778 break; 604 779 case sc_prop: … … 606 781 assert(prop != NULL); 607 782 608 if (stype->proc_vr->proc != prop->getter) { 609 printf("Error: Return statement in " 610 "setter.\n"); 611 stype_note_error(stype); 783 if (stype->proc_vr->proc == prop->getter) { 784 if (return_s->expr == NULL) { 785 printf("Error: Return without a value in " 786 "getter.\n"); 787 stype_note_error(stype); 788 } 789 } else { 790 if (return_s->expr == NULL) { 791 printf("Error: Return with a value in " 792 "setter.\n"); 793 stype_note_error(stype); 794 } 612 795 } 613 796 … … 620 803 } 621 804 622 /* Convert to the return type. */ 623 cexpr = stype_convert(stype, return_s->expr, dtype); 624 625 /* Patch code with the augmented expression. */ 626 return_s->expr = cexpr; 805 if (dtype != NULL && return_s->expr != NULL) { 806 /* Convert to the return type. */ 807 cexpr = stype_convert(stype, return_s->expr, dtype); 808 809 /* Patch code with the augmented expression. */ 810 return_s->expr = cexpr; 811 } 627 812 } 628 813 … … 714 899 715 900 if (src == NULL) { 716 printf("Error: Conversion source is not valid.\n"); 901 cspan_print(expr->cspan); 902 printf(" Error: Conversion source is not valid.\n"); 717 903 stype_note_error(stype); 718 904 return expr; … … 738 924 } 739 925 926 if (src->tic == tic_tebase) { 927 stype_convert_failure(stype, expr, dest); 928 printf("Invalid use of reference to enum type in " 929 "expression.\n"); 930 return expr; 931 } 932 740 933 if (src->tic != dest->tic) { 741 stype_convert_failure(stype, src, dest);934 stype_convert_failure(stype, expr, dest); 742 935 return expr; 743 936 } … … 756 949 expr = stype_convert_tdeleg(stype, expr, dest); 757 950 break; 951 case tic_tebase: 952 /* Conversion destination should never be enum-base */ 953 assert(b_false); 954 case tic_tenum: 955 expr = stype_convert_tenum(stype, expr, dest); 956 break; 758 957 case tic_tfun: 759 958 assert(b_false); … … 788 987 /* Check if both have the same tprimitive class. */ 789 988 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc) 790 stype_convert_failure(stype, src, dest);989 stype_convert_failure(stype, expr, dest); 791 990 792 991 return expr; … … 795 994 /** Convert expression of primitive type to object type. 796 995 * 797 * This function implements autoboxing. It modified the code. 996 * This function implements autoboxing. It modifies the code by inserting 997 * the boxing operation. 798 998 * 799 999 * @param stype Static typing object … … 828 1028 case tpc_string: bp_sym = bi->boxed_string; break; 829 1029 case tpc_resource: 830 stype_convert_failure(stype, src, dest);1030 stype_convert_failure(stype, expr, dest); 831 1031 return expr; 832 1032 } … … 834 1034 /* Target type must be boxed @a src or Object */ 835 1035 if (csi_sym != bp_sym && csi_sym != bi->gf_class) 836 stype_convert_failure(stype, src, dest);1036 stype_convert_failure(stype, expr, dest); 837 1037 838 1038 /* Patch the code to box the primitive value */ … … 841 1041 bexpr = stree_expr_new(ec_box); 842 1042 bexpr->u.box = box; 1043 bexpr->titem = dest; 843 1044 844 1045 /* No action needed to optionally convert boxed type to Object */ … … 901 1102 } else { 902 1103 /* No match */ 903 stype_convert_failure(stype, src, dest);1104 stype_convert_failure(stype, expr, dest); 904 1105 return expr; 905 1106 } … … 916 1117 if (tdata_item_equal(carg, darg) != b_true) { 917 1118 /* Diferent argument type */ 918 stype_convert_failure(stype, src, dest);1119 stype_convert_failure(stype, expr, dest); 919 1120 printf("Different argument type '"); 920 1121 tdata_item_print(carg); … … 931 1132 if (ca_n != NULL || da_n != NULL) { 932 1133 /* Diferent number of arguments */ 933 stype_convert_failure(stype, src, dest);1134 stype_convert_failure(stype, expr, dest); 934 1135 printf("Different number of arguments.\n"); 935 1136 return expr; … … 959 1160 /* Compare rank and base type. */ 960 1161 if (src->u.tarray->rank != dest->u.tarray->rank) { 961 stype_convert_failure(stype, src, dest);1162 stype_convert_failure(stype, expr, dest); 962 1163 return expr; 963 1164 } … … 966 1167 if (tdata_item_equal(src->u.tarray->base_ti, 967 1168 dest->u.tarray->base_ti) != b_true) { 968 stype_convert_failure(stype, src, dest);1169 stype_convert_failure(stype, expr, dest); 969 1170 } 970 1171 … … 1004 1205 /* Both must be the same delegate. */ 1005 1206 if (sdeleg->deleg != ddeleg->deleg) { 1006 stype_convert_failure(stype, src, dest); 1207 stype_convert_failure(stype, expr, dest); 1208 return expr; 1209 } 1210 1211 return expr; 1212 } 1213 1214 /** Convert expression of enum type to enum type. 1215 * 1216 * @param stype Static typing object 1217 * @param expr Expression 1218 * @param dest Destination type 1219 */ 1220 static stree_expr_t *stype_convert_tenum(stype_t *stype, stree_expr_t *expr, 1221 tdata_item_t *dest) 1222 { 1223 tdata_item_t *src; 1224 tdata_enum_t *senum, *denum; 1225 1226 #ifdef DEBUG_TYPE_TRACE 1227 printf("Convert enum type.\n"); 1228 #endif 1229 src = expr->titem; 1230 assert(src->tic == tic_tenum); 1231 assert(dest->tic == tic_tenum); 1232 1233 senum = src->u.tenum; 1234 denum = dest->u.tenum; 1235 1236 /* 1237 * XXX How should enum types interact with generics? 1238 */ 1239 1240 /* Both must be of the same enum type (with the same declaration). */ 1241 if (senum->enum_d != denum->enum_d) { 1242 stype_convert_failure(stype, expr, dest); 1007 1243 return expr; 1008 1244 } … … 1043 1279 1044 1280 if (!stype_fun_sig_equal(stype, ssig, dsig)) { 1045 stype_convert_failure(stype, src, dest);1281 stype_convert_failure(stype, expr, dest); 1046 1282 return expr; 1047 1283 } … … 1075 1311 /* Currently only allow if both types are the same. */ 1076 1312 if (src->u.tvref->targ != dest->u.tvref->targ) { 1077 stype_convert_failure(stype, src, dest);1313 stype_convert_failure(stype, expr, dest); 1078 1314 return expr; 1079 1315 } … … 1085 1321 * 1086 1322 * @param stype Static typing object 1087 * @param src Original type1323 * @param expr Original expression 1088 1324 * @param dest Destination type 1089 1325 */ 1090 static void stype_convert_failure(stype_t *stype, tdata_item_t *src,1326 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr, 1091 1327 tdata_item_t *dest) 1092 1328 { 1093 printf("Error: Cannot convert "); 1094 tdata_item_print(src); 1329 cspan_print(expr->cspan); 1330 printf(" Error: Cannot convert "); 1331 tdata_item_print(expr->titem); 1095 1332 printf(" to "); 1096 1333 tdata_item_print(dest); … … 1099 1336 stype_note_error(stype); 1100 1337 } 1338 1339 /** Box value. 1340 * 1341 * This function implements implicit boxing. It modifies the code by inserting 1342 * the boxing operation. 1343 * 1344 * @param stype Static typing object 1345 * @param expr Expression 1346 * @return Modified expression. 1347 */ 1348 stree_expr_t *stype_box_expr(stype_t *stype, stree_expr_t *expr) 1349 { 1350 tdata_item_t *src; 1351 builtin_t *bi; 1352 stree_symbol_t *bp_sym; 1353 stree_box_t *box; 1354 stree_expr_t *bexpr; 1355 tdata_object_t *tobject; 1356 1357 #ifdef DEBUG_TYPE_TRACE 1358 printf("Boxing.\n"); 1359 #endif 1360 src = expr->titem; 1361 assert(src->tic == tic_tprimitive); 1362 1363 bi = stype->program->builtin; 1364 1365 /* Make compiler happy. */ 1366 bp_sym = NULL; 1367 1368 switch (src->u.tprimitive->tpc) { 1369 case tpc_bool: bp_sym = bi->boxed_bool; break; 1370 case tpc_char: bp_sym = bi->boxed_char; break; 1371 case tpc_int: bp_sym = bi->boxed_int; break; 1372 case tpc_nil: assert(b_false); 1373 case tpc_string: bp_sym = bi->boxed_string; break; 1374 case tpc_resource: 1375 cspan_print(expr->cspan); 1376 printf(" Error: Cannot use "); 1377 tdata_item_print(expr->titem); 1378 printf(" as an object.\n"); 1379 1380 stype_note_error(stype); 1381 return expr; 1382 } 1383 1384 /* Patch the code to box the primitive value */ 1385 box = stree_box_new(); 1386 box->arg = expr; 1387 bexpr = stree_expr_new(ec_box); 1388 bexpr->u.box = box; 1389 bexpr->titem = tdata_item_new(tic_tobject); 1390 tobject = tdata_object_new(); 1391 bexpr->titem->u.tobject = tobject; 1392 1393 tobject->csi = symbol_to_csi(bp_sym); 1394 assert(tobject->csi != NULL); 1395 1396 return bexpr; 1397 } 1398 1399 1101 1400 1102 1401 /** Determine if two type signatures are equal. … … 1296 1595 1297 1596 stree_symbol_t *outer_sym; 1597 stree_ctor_t *ctor; 1298 1598 stree_fun_t *fun; 1299 1599 stree_prop_t *prop; … … 1314 1614 #endif 1315 1615 1616 /* Make compiler happy. */ 1617 args = NULL; 1618 varg = NULL; 1619 1316 1620 switch (outer_sym->sc) { 1621 case sc_ctor: 1622 ctor = symbol_to_ctor(outer_sym); 1623 assert(ctor != NULL); 1624 args = &ctor->sig->args; 1625 varg = ctor->sig->varg; 1626 break; 1317 1627 case sc_fun: 1318 1628 fun = symbol_to_fun(outer_sym); … … 1331 1641 setter_arg = prop->setter_arg; 1332 1642 break; 1333 default: 1643 case sc_csi: 1644 case sc_deleg: 1645 case sc_enum: 1646 case sc_var: 1334 1647 assert(b_false); 1335 1648 } -
uspace/app/sbi/src/stype.h
r1317380 r640ffe6 33 33 34 34 void stype_module(stype_t *stype, stree_module_t *module); 35 void stype_ctor_header(stype_t *stype, stree_ctor_t *ctor); 35 36 void stype_deleg(stype_t *stype, stree_deleg_t *deleg); 37 void stype_enum(stype_t *stype, stree_enum_t *enum_d); 36 38 void stype_fun_header(stype_t *stype, stree_fun_t *fun); 37 39 void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value); … … 42 44 stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr, 43 45 tdata_item_t *dest); 46 stree_expr_t *stype_box_expr(stype_t *stype, stree_expr_t *expr); 44 47 45 48 tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg); -
uspace/app/sbi/src/stype_expr.c
r1317380 r640ffe6 46 46 #include <stdlib.h> 47 47 #include <assert.h> 48 #include "cspan.h" 48 49 #include "debug.h" 49 50 #include "list.h" … … 85 86 static void stype_binop_tobject(stype_t *stype, stree_binop_t *binop, 86 87 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem); 88 static void stype_binop_tenum(stype_t *stype, stree_binop_t *binop, 89 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem); 90 static void stype_binop_tvref(stype_t *stype, stree_binop_t *binop, 91 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem); 87 92 88 93 static void stype_unop(stype_t *stype, stree_unop_t *unop, … … 92 97 static void stype_new(stype_t *stype, stree_new_t *new, 93 98 tdata_item_t **rtitem); 99 static void stype_new_object_args(stype_t *stype, stree_new_t *new_op, 100 tdata_item_t *obj_ti); 94 101 95 102 static void stype_access(stype_t *stype, stree_access_t *access, … … 101 108 static void stype_access_tarray(stype_t *stype, stree_access_t *access, 102 109 tdata_item_t *arg_ti, tdata_item_t **rtitem); 110 static void stype_access_tebase(stype_t *stype, stree_access_t *access, 111 tdata_item_t *arg_ti, tdata_item_t **rtitem); 103 112 104 113 static void stype_call(stype_t *stype, stree_call_t *call, 105 114 tdata_item_t **rtitem); 115 static void stype_call_args(stype_t *stype, cspan_t *cspan, list_t *farg_tis, 116 tdata_item_t *fvarg_ti, list_t *args); 106 117 107 118 static void stype_index(stype_t *stype, stree_index_t *index, … … 133 144 134 145 #ifdef DEBUG_TYPE_TRACE 135 printf("Type expression.\n"); 146 cspan_print(expr->cspan); 147 printf(" Type expression.\n"); 136 148 #endif 137 149 /* Silence warning. */ … … 156 168 157 169 #ifdef DEBUG_TYPE_TRACE 158 printf("Expression type is '"); 170 cspan_print(expr->cspan); 171 printf(" Expression type is '"); 159 172 tdata_item_print(et); 160 173 printf("'.\n"); … … 178 191 stree_csi_t *csi; 179 192 stree_deleg_t *deleg; 193 stree_enum_t *enum_d; 194 tdata_ebase_t *tebase; 180 195 stree_fun_t *fun; 181 196 182 197 #ifdef DEBUG_TYPE_TRACE 183 printf("Evaluate type of name reference '%s'.\n", 198 cspan_print(nameref->expr->cspan); 199 printf(" Evaluate type of name reference '%s'.\n", 184 200 strtab_get_str(nameref->name->sid)); 185 201 #endif … … 226 242 /* Not found. */ 227 243 if (stype->current_csi != NULL) { 228 printf("Error: Symbol '%s' not found in '", 244 cspan_print(nameref->expr->cspan); 245 printf(" Error: Symbol '%s' not found in '", 229 246 strtab_get_str(nameref->name->sid)); 230 247 symbol_print_fqn(csi_to_symbol(stype->current_csi)); 231 248 printf("'.\n"); 232 249 } else { 233 printf("Error: Symbol '%s' not found.\n", 250 cspan_print(nameref->expr->cspan); 251 printf(" Error: Symbol '%s' not found.\n", 234 252 strtab_get_str(nameref->name->sid)); 235 253 } … … 260 278 tobject->csi = csi; 261 279 break; 280 case sc_ctor: 281 /* It is not possible to reference a constructor explicitly. */ 282 assert(b_false); 262 283 case sc_deleg: 263 printf("referenced name is deleg\n");264 284 deleg = symbol_to_deleg(sym); 265 285 assert(deleg != NULL); … … 267 287 stype_deleg(stype, deleg); 268 288 titem = deleg->titem; 289 break; 290 case sc_enum: 291 enum_d = symbol_to_enum(sym); 292 assert(enum_d != NULL); 293 294 titem = tdata_item_new(tic_tebase); 295 tebase = tdata_ebase_new(); 296 titem->u.tebase = tebase; 297 298 /* This is an enum base reference. */ 299 tebase->enum_d = enum_d; 269 300 break; 270 301 case sc_fun: … … 294 325 295 326 #ifdef DEBUG_TYPE_TRACE 296 printf("Evaluate type of literal.\n"); 327 cspan_print(literal->expr->cspan); 328 printf(" Evaluate type of literal.\n"); 297 329 #endif 298 330 (void) stype; … … 322 354 tdata_item_t **rtitem) 323 355 { 356 stree_csi_t *cur_csi; 357 tdata_item_t *titem; 358 tdata_object_t *tobject; 359 324 360 #ifdef DEBUG_TYPE_TRACE 325 printf("Evaluate type of self reference.\n"); 361 cspan_print(self_ref->expr->cspan); 362 printf(" Evaluate type of self reference.\n"); 326 363 #endif 327 364 (void) stype; 328 365 (void) self_ref; 329 366 330 *rtitem = NULL; 367 cur_csi = stype->proc_vr->proc->outer_symbol->outer_csi; 368 369 /* No global symbols should have procedures. */ 370 assert(cur_csi != NULL); 371 372 /* Construct type item. */ 373 titem = tdata_item_new(tic_tobject); 374 tobject = tdata_object_new(); 375 titem->u.tobject = tobject; 376 377 tobject->static_ref = b_false; 378 tobject->csi = cur_csi; 379 list_init(&tobject->targs); 380 381 *rtitem = titem; 331 382 } 332 383 … … 344 395 345 396 #ifdef DEBUG_TYPE_TRACE 346 printf("Evaluate type of binary operation.\n"); 397 cspan_print(binop->expr->cspan); 398 printf(" Evaluate type of binary operation.\n"); 347 399 #endif 348 400 stype_expr(stype, binop->arg1); … … 352 404 titem2 = binop->arg2->titem; 353 405 354 if (titem1 == NULL || titem2 == NULL) { 355 printf("Error: Binary operand has no value.\n"); 406 if (titem1 == NULL) { 407 cspan_print(binop->arg1->cspan); 408 printf(" Error: Binary operand has no value.\n"); 409 stype_note_error(stype); 410 *rtitem = stype_recovery_titem(stype); 411 return; 412 } 413 414 if (titem2 == NULL) { 415 cspan_print(binop->arg2->cspan); 416 printf(" Error: Binary operand has no value.\n"); 356 417 stype_note_error(stype); 357 418 *rtitem = stype_recovery_titem(stype); … … 366 427 equal = tdata_item_equal(titem1, titem2); 367 428 if (equal != b_true) { 368 printf("Error: Binary operation arguments " 429 cspan_print(binop->expr->cspan); 430 printf(" Error: Binary operation arguments " 369 431 "have different types ('"); 370 432 tdata_item_print(titem1); … … 384 446 stype_binop_tobject(stype, binop, titem1, titem2, rtitem); 385 447 break; 448 case tic_tenum: 449 stype_binop_tenum(stype, binop, titem1, titem2, rtitem); 450 break; 451 case tic_tvref: 452 stype_binop_tvref(stype, binop, titem1, titem2, rtitem); 453 break; 386 454 default: 387 printf("Error: Binary operation on value which is not of a " 455 cspan_print(binop->expr->cspan); 456 printf(" Error: Binary operation on value which is not of a " 388 457 "supported type (found '"); 389 458 tdata_item_print(titem1); … … 458 527 case bo_mult: 459 528 /* Arithmetic -> error */ 460 printf("Error: Binary operation (%d) on booleans.\n", 529 cspan_print(binop->expr->cspan); 530 printf(" Error: Binary operation (%d) on booleans.\n", 461 531 binop->bc); 462 532 stype_note_error(stype); 463 533 *rtitem = stype_recovery_titem(stype); 464 534 return; 535 case bo_and: 536 case bo_or: 537 /* Boolean -> boolean type */ 538 rtpc = tpc_bool; 539 break; 465 540 } 466 541 … … 498 573 case bo_minus: 499 574 case bo_mult: 500 /* Arithmetic -> error */ 501 printf("Error: Binary operation (%d) on characters.\n", 575 case bo_and: 576 case bo_or: 577 /* Arithmetic, boolean -> error */ 578 cspan_print(binop->expr->cspan); 579 printf(" Error: Binary operation (%d) on characters.\n", 502 580 binop->bc); 503 581 stype_note_error(stype); … … 542 620 rtpc = tpc_int; 543 621 break; 622 case bo_and: 623 case bo_or: 624 /* Boolean -> error */ 625 cspan_print(binop->expr->cspan); 626 printf(" Error: Binary operation (%d) on integers.\n", 627 binop->bc); 628 stype_note_error(stype); 629 rtpc = tpc_char; 630 break; 544 631 } 545 632 … … 561 648 (void) binop; 562 649 563 printf("Unimplemented; Binary operation on nil.\n"); 650 cspan_print(binop->expr->cspan); 651 printf(" Unimplemented: Binary operation on nil.\n"); 564 652 stype_note_error(stype); 565 653 *rtitem = stype_recovery_titem(stype); … … 578 666 tdata_item_t *res_ti; 579 667 580 if (binop->bc != bo_plus) { 581 printf("Unimplemented: Binary operation(%d) " 582 "on strings.\n", binop->bc); 583 stype_note_error(stype); 584 *rtitem = stype_recovery_titem(stype); 585 return; 586 } 587 588 rtpc = tpc_string; 668 switch (binop->bc) { 669 case bo_equal: 670 case bo_notequal: 671 /* Comparison -> boolean type */ 672 rtpc = tpc_bool; 673 break; 674 case bo_plus: 675 /* Concatenation -> string type */ 676 rtpc = tpc_string; 677 break; 678 679 case bo_lt: 680 case bo_gt: 681 case bo_lt_equal: 682 case bo_gt_equal: 683 684 case bo_minus: 685 case bo_mult: 686 case bo_and: 687 case bo_or: 688 /* Ordering, arithmetic, boolean -> error */ 689 cspan_print(binop->expr->cspan); 690 printf(" Error: Binary operation (%d) on strings.\n", 691 binop->bc); 692 stype_note_error(stype); 693 rtpc = tpc_char; 694 break; 695 } 589 696 590 697 res_ti = tdata_item_new(tic_tprimitive); … … 608 715 (void) binop; 609 716 610 printf("Error: Cannot apply operator to resource type.\n"); 717 cspan_print(binop->expr->cspan); 718 printf(" Error: Cannot apply operator to resource type.\n"); 611 719 stype_note_error(stype); 612 720 rtpc = tpc_resource; … … 645 753 break; 646 754 default: 647 printf("Error: Binary operation (%d) on objects.\n", 755 cspan_print(binop->expr->cspan); 756 printf(" Error: Binary operation (%d) on objects.\n", 648 757 binop->bc); 649 758 stype_note_error(stype); … … 655 764 } 656 765 766 /** Type a binary operation with arguments of an enum type. 767 * 768 * @param stype Static typing object 769 * @param binop Binary operation 770 * @param ta Type of first argument 771 * @param tb Type of second argument 772 * @param rtitem Place to store result type 773 */ 774 static void stype_binop_tenum(stype_t *stype, stree_binop_t *binop, 775 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem) 776 { 777 tdata_item_t *res_ti; 778 779 assert(ta->tic == tic_tenum); 780 assert(tb->tic == tic_tenum); 781 782 switch (binop->bc) { 783 case bo_equal: 784 case bo_notequal: 785 /* Comparison -> boolean type */ 786 res_ti = stype_boolean_titem(stype); 787 break; 788 default: 789 cspan_print(binop->expr->cspan); 790 printf(" Error: Binary operation (%d) on values of enum " 791 "type.\n", binop->bc); 792 stype_note_error(stype); 793 *rtitem = stype_recovery_titem(stype); 794 return; 795 } 796 797 *rtitem = res_ti; 798 } 799 800 /** Type a binary operation with arguments of a variable type. 801 * 802 * @param stype Static typing object 803 * @param binop Binary operation 804 * @param ta Type of first argument 805 * @param tb Type of second argument 806 * @param rtitem Place to store result type 807 */ 808 static void stype_binop_tvref(stype_t *stype, stree_binop_t *binop, 809 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem) 810 { 811 tdata_item_t *res_ti; 812 813 assert(ta->tic == tic_tvref || (ta->tic == tic_tprimitive && 814 ta->u.tprimitive->tpc == tpc_nil)); 815 assert(tb->tic == tic_tvref || (tb->tic == tic_tprimitive && 816 tb->u.tprimitive->tpc == tpc_nil)); 817 818 switch (binop->bc) { 819 case bo_equal: 820 case bo_notequal: 821 /* Comparison -> boolean type */ 822 res_ti = stype_boolean_titem(stype); 823 break; 824 default: 825 cspan_print(binop->expr->cspan); 826 printf(" Error: Binary operation (%d) on variable types.\n", 827 binop->bc); 828 stype_note_error(stype); 829 *rtitem = stype_recovery_titem(stype); 830 return; 831 } 832 833 *rtitem = res_ti; 834 } 657 835 658 836 /** Type a unary operation. … … 668 846 669 847 #ifdef DEBUG_TYPE_TRACE 670 printf("Evaluate type of unary operation.\n"); 848 cspan_print(unop->expr->cspan); 849 printf(" Evaluate type of unary operation.\n"); 671 850 #endif 672 851 stype_expr(stype, unop->arg); … … 684 863 break; 685 864 default: 686 printf("Error: Unary operation on value which is not of a " 865 cspan_print(unop->arg->cspan); 866 printf(" Error: Unary operation on value which is not of a " 687 867 "supported type (found '"); 688 868 tdata_item_print(titem); … … 720 900 break; 721 901 default: 722 printf("Error: Unary operator applied on unsupported " 902 cspan_print(unop->arg->cspan); 903 printf(" Error: Unary operator applied on unsupported " 723 904 "primitive type %d.\n", ta->u.tprimitive->tpc); 724 905 stype_note_error(stype); … … 743 924 { 744 925 #ifdef DEBUG_TYPE_TRACE 926 cspan_print(new_op->expr->cspan); 745 927 printf("Evaluate type of 'new' operation.\n"); 746 928 #endif … … 754 936 /* An error occured when evaluating the type expression. */ 755 937 stype_note_error(stype); 756 } 938 *rtitem = stype_recovery_titem(stype); 939 return; 940 } 941 942 if ((*rtitem)->tic == tic_tobject) 943 stype_new_object_args(stype, new_op, *rtitem); 944 } 945 946 /** Type a new object operation arguments. 947 * 948 * @param stype Static typing object 949 * @param new_op @c new operation 950 */ 951 static void stype_new_object_args(stype_t *stype, stree_new_t *new_op, 952 tdata_item_t *obj_ti) 953 { 954 stree_csi_t *csi; 955 stree_ctor_t *ctor; 956 stree_symbol_t *ctor_sym; 957 stree_ident_t *ctor_ident; 958 tdata_fun_sig_t *tsig; 959 960 assert(obj_ti->tic == tic_tobject); 961 csi = obj_ti->u.tobject->csi; 962 ctor_ident = stree_ident_new(); 963 ctor_ident->sid = strtab_get_sid(CTOR_IDENT); 964 965 /* Find constructor. */ 966 ctor_sym = symbol_search_csi_no_base(stype->program, csi, 967 ctor_ident); 968 969 if (ctor_sym == NULL && !list_is_empty(&new_op->ctor_args)) { 970 cspan_print(new_op->expr->cspan); 971 printf(" Error: Passing arguments to 'new' but no " 972 "constructor found.\n"); 973 stype_note_error(stype); 974 return; 975 } 976 977 if (ctor_sym == NULL) 978 return; 979 980 ctor = symbol_to_ctor(ctor_sym); 981 assert(ctor != NULL); 982 983 /* Type constructor header if it has not been typed yet. */ 984 stype_ctor_header(stype, ctor); 985 if (ctor->titem->tic == tic_ignore) 986 return; 987 988 assert(ctor->titem->tic == tic_tfun); 989 tsig = ctor->titem->u.tfun->tsig; 990 991 stype_call_args(stype, new_op->expr->cspan, &tsig->arg_ti, 992 tsig->varg_ti, &new_op->ctor_args); 757 993 } 758 994 … … 769 1005 770 1006 #ifdef DEBUG_TYPE_TRACE 771 printf("Evaluate type of access operation.\n"); 1007 cspan_print(access->expr->cspan); 1008 printf(" Evaluate type of access operation.\n"); 772 1009 #endif 773 1010 stype_expr(stype, access->arg); … … 775 1012 776 1013 if (arg_ti == NULL) { 777 printf("Error: Argument of access has no value.\n"); 1014 cspan_print(access->arg->cspan); 1015 printf(" Error: Argument of access operation has no value.\n"); 778 1016 stype_note_error(stype); 779 1017 *rtitem = stype_recovery_titem(stype); … … 792 1030 break; 793 1031 case tic_tdeleg: 794 printf("Error: Using '.' operator on a function.\n"); 1032 cspan_print(access->arg->cspan); 1033 printf(" Error: Using '.' operator on a delegate.\n"); 1034 stype_note_error(stype); 1035 *rtitem = stype_recovery_titem(stype); 1036 break; 1037 case tic_tebase: 1038 stype_access_tebase(stype, access, arg_ti, rtitem); 1039 break; 1040 case tic_tenum: 1041 cspan_print(access->arg->cspan); 1042 printf(" Error: Using '.' operator on expression of enum " 1043 "type.\n"); 795 1044 stype_note_error(stype); 796 1045 *rtitem = stype_recovery_titem(stype); 797 1046 break; 798 1047 case tic_tfun: 799 printf("Error: Using '.' operator on a delegate.\n"); 1048 cspan_print(access->arg->cspan); 1049 printf(" Error: Using '.' operator on a function.\n"); 800 1050 stype_note_error(stype); 801 1051 *rtitem = stype_recovery_titem(stype); … … 803 1053 case tic_tvref: 804 1054 /* Cannot allow this without some constraint. */ 805 printf("Error: Using '.' operator on generic data.\n"); 1055 cspan_print(access->arg->cspan); 1056 printf(" Error: Using '.' operator on generic data.\n"); 806 1057 *rtitem = stype_recovery_titem(stype); 807 1058 break; … … 822 1073 tdata_item_t *arg_ti, tdata_item_t **rtitem) 823 1074 { 824 (void) stype; 825 (void) access; 826 (void) rtitem; 827 828 printf("Error: Unimplemented: Accessing primitive type '"); 829 tdata_item_print(arg_ti); 830 printf("'.\n"); 831 stype_note_error(stype); 832 *rtitem = stype_recovery_titem(stype); 1075 (void) arg_ti; 1076 1077 /* Box the value. */ 1078 access->arg = stype_box_expr(stype, access->arg); 1079 if (access->arg->titem->tic == tic_ignore) { 1080 *rtitem = stype_recovery_titem(stype); 1081 return; 1082 } 1083 1084 /* Access the boxed object. */ 1085 stype_access_tobject(stype, access, access->arg->titem, rtitem); 833 1086 } 834 1087 … … 845 1098 stree_symbol_t *member_sym; 846 1099 stree_var_t *var; 1100 stree_enum_t *enum_d; 847 1101 stree_fun_t *fun; 848 1102 stree_prop_t *prop; … … 863 1117 if (member_sym == NULL) { 864 1118 /* No such member found. */ 865 printf("Error: CSI '"); 1119 cspan_print(access->member_name->cspan); 1120 printf(" Error: CSI '"); 866 1121 symbol_print_fqn(csi_to_symbol(tobject->csi)); 867 1122 printf("' has no member named '%s'.\n", … … 879 1134 switch (member_sym->sc) { 880 1135 case sc_csi: 881 printf("Error: Accessing object member which is nested " 1136 cspan_print(access->member_name->cspan); 1137 printf(" Error: Accessing object member which is nested " 882 1138 "CSI.\n"); 883 1139 stype_note_error(stype); 884 1140 *rtitem = stype_recovery_titem(stype); 885 1141 return; 1142 case sc_ctor: 1143 /* It is not possible to reference a constructor explicitly. */ 1144 assert(b_false); 886 1145 case sc_deleg: 887 printf("Error: Accessing object member which is a " 1146 cspan_print(access->member_name->cspan); 1147 printf(" Error: Accessing object member which is a " 888 1148 "delegate.\n"); 889 1149 stype_note_error(stype); 890 1150 *rtitem = stype_recovery_titem(stype); 891 1151 return; 1152 case sc_enum: 1153 enum_d = symbol_to_enum(member_sym); 1154 assert(enum_d != NULL); 1155 /* Type enum if it has not been typed yet. */ 1156 stype_enum(stype, enum_d); 1157 mtitem = enum_d->titem; 1158 break; 892 1159 case sc_fun: 893 1160 fun = symbol_to_fun(member_sym); … … 937 1204 (void) rtitem; 938 1205 939 printf("Error: Unimplemented: Accessing array type '"); 1206 cspan_print(access->arg->cspan); 1207 printf(" Error: Unimplemented: Accessing array type '"); 940 1208 tdata_item_print(arg_ti); 941 1209 printf("'.\n"); … … 944 1212 } 945 1213 1214 /** Type an enum access operation. 1215 * 1216 * @param stype Static typing object 1217 * @param access Member access operation 1218 * @param arg_ti Base type 1219 * @param rtitem Place to store result type 1220 */ 1221 static void stype_access_tebase(stype_t *stype, stree_access_t *access, 1222 tdata_item_t *arg_ti, tdata_item_t **rtitem) 1223 { 1224 tdata_ebase_t *tebase; 1225 tdata_enum_t *tenum; 1226 tdata_item_t *mtitem; 1227 stree_embr_t *embr; 1228 1229 #ifdef DEBUG_TYPE_TRACE 1230 printf("Type an ebase access operation.\n"); 1231 #endif 1232 assert(arg_ti->tic == tic_tebase); 1233 tebase = arg_ti->u.tebase; 1234 1235 /* Look for a member with the specified name. */ 1236 embr = stree_enum_find_mbr(tebase->enum_d, access->member_name); 1237 1238 if (embr == NULL) { 1239 /* No such member found. */ 1240 cspan_print(access->member_name->cspan); 1241 printf(" Error: Enum type '"); 1242 symbol_print_fqn(enum_to_symbol(tebase->enum_d)); 1243 printf("' has no member named '%s'.\n", 1244 strtab_get_str(access->member_name->sid)); 1245 stype_note_error(stype); 1246 *rtitem = stype_recovery_titem(stype); 1247 return; 1248 } 1249 1250 #ifdef DEBUG_RUN_TRACE 1251 printf("Found member '%s'.\n", 1252 strtab_get_str(access->member_name->sid)); 1253 #endif 1254 1255 mtitem = tdata_item_new(tic_tenum); 1256 tenum = tdata_enum_new(); 1257 mtitem->u.tenum = tenum; 1258 tenum->enum_d = tebase->enum_d; 1259 1260 *rtitem = mtitem; 1261 } 1262 1263 946 1264 /** Type a call operation. 947 1265 * … … 953 1271 tdata_item_t **rtitem) 954 1272 { 955 list_node_t *fargt_n;956 tdata_item_t *farg_ti;957 tdata_item_t *varg_ti;958 959 list_node_t *arg_n;960 stree_expr_t *arg;961 stree_expr_t *carg;962 963 1273 tdata_item_t *fun_ti; 964 1274 tdata_fun_sig_t *tsig; 965 1275 966 int cnt;967 968 1276 #ifdef DEBUG_TYPE_TRACE 969 printf("Evaluate type of call operation.\n"); 1277 cspan_print(call->expr->cspan); 1278 printf(" Evaluate type of call operation.\n"); 970 1279 #endif 971 1280 /* Type the function */ … … 986 1295 return; 987 1296 default: 988 printf("Error: Calling something which is not a function "); 1297 cspan_print(call->fun->cspan); 1298 printf(" Error: Calling something which is not a function "); 989 1299 printf("(found '"); 990 1300 tdata_item_print(fun_ti); … … 995 1305 } 996 1306 997 /* Type and check the arguments. */ 998 fargt_n = list_first(&tsig->arg_ti); 999 arg_n = list_first(&call->args); 1307 /* Type call arguments. */ 1308 stype_call_args(stype, call->expr->cspan, &tsig->arg_ti, tsig->varg_ti, 1309 &call->args); 1310 1311 if (tsig->rtype != NULL) { 1312 /* XXX Might be better to clone here. */ 1313 *rtitem = tsig->rtype; 1314 } else { 1315 *rtitem = NULL; 1316 } 1317 } 1318 1319 /** Type call arguments. 1320 * 1321 * Type arguments in call to a function or constructor. 1322 * 1323 * @param stype Static typing object 1324 * @param cpsan Cspan to print in case of error. 1325 * @param farg_tis Formal argument types (list of tdata_item_t) 1326 * @param args Real arguments (list of stree_expr_t) 1327 */ 1328 static void stype_call_args(stype_t *stype, cspan_t *cspan, list_t *farg_tis, 1329 tdata_item_t *fvarg_ti, list_t *args) 1330 { 1331 list_node_t *fargt_n; 1332 tdata_item_t *farg_ti; 1333 tdata_item_t *varg_ti; 1334 1335 list_node_t *arg_n; 1336 stree_expr_t *arg; 1337 stree_expr_t *carg; 1338 1339 int cnt; 1340 1341 /* Type and check regular arguments. */ 1342 fargt_n = list_first(farg_tis); 1343 arg_n = list_first(args); 1000 1344 1001 1345 cnt = 0; … … 1008 1352 if (farg_ti == NULL) { 1009 1353 /* Skip the check */ 1010 fargt_n = list_next( &tsig->arg_ti, fargt_n);1011 arg_n = list_next( &call->args, arg_n);1354 fargt_n = list_next(farg_tis, fargt_n); 1355 arg_n = list_next(args, arg_n); 1012 1356 continue; 1013 1357 } … … 1019 1363 list_node_setdata(arg_n, carg); 1020 1364 1021 fargt_n = list_next( &tsig->arg_ti, fargt_n);1022 arg_n = list_next( &call->args, arg_n);1365 fargt_n = list_next(farg_tis, fargt_n); 1366 arg_n = list_next(args, arg_n); 1023 1367 } 1024 1368 1025 1369 /* Type and check variadic arguments. */ 1026 if ( tsig->varg_ti != NULL) {1370 if (fvarg_ti != NULL) { 1027 1371 /* Obtain type of packed argument. */ 1028 farg_ti = tsig->varg_ti;1372 farg_ti = fvarg_ti; 1029 1373 1030 1374 /* Get array element type */ … … 1042 1386 list_node_setdata(arg_n, carg); 1043 1387 1044 arg_n = list_next( &call->args, arg_n);1388 arg_n = list_next(args, arg_n); 1045 1389 } 1046 1390 } 1047 1391 1048 1392 if (fargt_n != NULL) { 1049 printf("Error: Too few arguments to function.\n"); 1393 cspan_print(cspan); 1394 printf(" Error: Too few arguments.\n"); 1050 1395 stype_note_error(stype); 1051 1396 } 1052 1397 1053 1398 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; 1061 } else { 1062 *rtitem = NULL; 1399 cspan_print(cspan); 1400 printf(" Error: Too many arguments.\n"); 1401 stype_note_error(stype); 1063 1402 } 1064 1403 } … … 1078 1417 1079 1418 #ifdef DEBUG_TYPE_TRACE 1080 printf("Evaluate type of index operation.\n"); 1419 cspan_print(index->expr->cspan); 1420 printf(" Evaluate type of index operation.\n"); 1081 1421 #endif 1082 1422 stype_expr(stype, index->base); … … 1103 1443 break; 1104 1444 case tic_tdeleg: 1105 printf("Error: Indexing a delegate.\n"); 1445 cspan_print(index->base->cspan); 1446 printf(" Error: Indexing a delegate.\n"); 1447 stype_note_error(stype); 1448 *rtitem = stype_recovery_titem(stype); 1449 break; 1450 case tic_tebase: 1451 cspan_print(index->base->cspan); 1452 printf(" Error: Indexing an enum declaration.\n"); 1453 stype_note_error(stype); 1454 *rtitem = stype_recovery_titem(stype); 1455 break; 1456 case tic_tenum: 1457 cspan_print(index->base->cspan); 1458 printf(" Error: Indexing an enum value.\n"); 1106 1459 stype_note_error(stype); 1107 1460 *rtitem = stype_recovery_titem(stype); 1108 1461 break; 1109 1462 case tic_tfun: 1110 printf("Error: Indexing a function.\n"); 1463 cspan_print(index->base->cspan); 1464 printf(" Error: Indexing a function.\n"); 1111 1465 stype_note_error(stype); 1112 1466 *rtitem = stype_recovery_titem(stype); … … 1114 1468 case tic_tvref: 1115 1469 /* Cannot allow this without some constraint. */ 1116 printf("Error: Indexing generic data.\n"); 1470 cspan_print(index->base->cspan); 1471 printf(" Error: Indexing generic data.\n"); 1117 1472 *rtitem = stype_recovery_titem(stype); 1118 1473 break; … … 1149 1504 } 1150 1505 1151 printf("Error: Indexing primitive type '"); 1506 cspan_print(index->base->cspan); 1507 printf(" Error: Indexing primitive type '"); 1152 1508 tdata_item_print(base_ti); 1153 1509 printf("'.\n"); … … 1176 1532 1177 1533 #ifdef DEBUG_TYPE_TRACE 1178 printf("Indexing object type '"); 1534 cspan_print(index->expr->cspan); 1535 printf(" Indexing object type '"); 1179 1536 tdata_item_print(base_ti); 1180 1537 printf("'.\n"); … … 1190 1547 1191 1548 if (idx_sym == NULL) { 1192 printf("Error: Indexing object of type '"); 1549 cspan_print(index->base->cspan); 1550 printf(" Error: Indexing object of type '"); 1193 1551 tdata_item_print(base_ti); 1194 1552 printf("' which does not have an indexer.\n"); … … 1246 1604 arg->titem->u.tprimitive->tpc != tpc_int) { 1247 1605 1248 printf("Error: Array index is not an integer.\n"); 1606 cspan_print(arg->cspan); 1607 printf(" Error: Array index is not an integer.\n"); 1249 1608 stype_note_error(stype); 1250 1609 } … … 1254 1613 1255 1614 if (arg_count != base_ti->u.tarray->rank) { 1256 printf("Error: Using %d indices with array of rank %d.\n", 1615 cspan_print(index->expr->cspan); 1616 printf(" Error: Using %d indices with array of rank %d.\n", 1257 1617 arg_count, base_ti->u.tarray->rank); 1258 1618 stype_note_error(stype); … … 1274 1634 1275 1635 #ifdef DEBUG_TYPE_TRACE 1276 printf("Evaluate type of assignment.\n"); 1636 cspan_print(assign->expr->cspan); 1637 printf(" Evaluate type of assignment.\n"); 1277 1638 #endif 1278 1639 stype_expr(stype, assign->dest); … … 1297 1658 1298 1659 #ifdef DEBUG_TYPE_TRACE 1299 printf("Evaluate type of @c as conversion.\n"); 1660 cspan_print(as_op->expr->cspan); 1661 printf(" Evaluate type of @c as conversion.\n"); 1300 1662 #endif 1301 1663 stype_expr(stype, as_op->arg); … … 1304 1666 /* Check that target type is derived from argument type. */ 1305 1667 if (tdata_is_ti_derived_from_ti(titem, as_op->arg->titem) != b_true) { 1306 printf("Error: Target of 'as' operator '"); 1668 cspan_print(as_op->dtype->cspan); 1669 printf(" Error: Target of 'as' operator '"); 1307 1670 tdata_item_print(titem); 1308 1671 printf("' is not derived from '"); … … 1332 1695 1333 1696 #ifdef DEBUG_TYPE_TRACE 1334 printf("Evaluate type of boxing operation.\n"); 1697 cspan_print(box->expr->cspan); 1698 printf(" Evaluate type of boxing operation.\n"); 1335 1699 #endif 1336 1700 bi = stype->program->builtin; -
uspace/app/sbi/src/stype_t.h
r1317380 r640ffe6 54 54 /** Block activation records */ 55 55 list_t block_vr; /* of run_block_ar_t */ 56 57 /** Number of active breakable statements (for break checking). */ 58 int bstat_cnt; 56 59 } stype_proc_vr_t; 57 60 -
uspace/app/sbi/src/symbol.c
r1317380 r640ffe6 42 42 static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog, 43 43 stree_ident_t *name, stree_csi_t *csi); 44 static stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr); 44 45 static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol); 45 46 … … 88 89 /** Lookup symbol reference in CSI. 89 90 * 91 * XXX These functions should take just an sid, not a full identifier. 92 * Sometimes we search for a name which has no associated cspan. 93 * 90 94 * @param prog Program to look in 91 95 * @param scope CSI in @a prog which is the base for references … … 128 132 stree_csi_t *scope, stree_ident_t *name) 129 133 { 130 list_node_t *node;131 stree_csimbr_t *csimbr;132 stree_symbol_t *symbol;133 stree_ident_t *mbr_name;134 134 stree_symbol_t *base_csi_sym; 135 135 stree_csi_t *base_csi; 136 137 (void) prog; 136 stree_symbol_t *symbol; 138 137 139 138 /* Look in new members in this class. */ 140 141 node = list_first(&scope->members); 142 while (node != NULL) { 143 csimbr = list_node_data(node, stree_csimbr_t *); 144 145 /* Keep compiler happy. */ 146 mbr_name = NULL; 147 148 switch (csimbr->cc) { 149 case csimbr_csi: mbr_name = csimbr->u.csi->name; break; 150 case csimbr_deleg: mbr_name = csimbr->u.deleg->name; break; 151 case csimbr_fun: mbr_name = csimbr->u.fun->name; break; 152 case csimbr_var: mbr_name = csimbr->u.var->name; break; 153 case csimbr_prop: mbr_name = csimbr->u.prop->name; break; 154 } 155 156 if (name->sid == mbr_name->sid) { 157 /* Match */ 158 switch (csimbr->cc) { 159 case csimbr_csi: 160 symbol = csi_to_symbol(csimbr->u.csi); 161 break; 162 case csimbr_deleg: 163 symbol = deleg_to_symbol(csimbr->u.deleg); 164 break; 165 case csimbr_fun: 166 symbol = fun_to_symbol(csimbr->u.fun); 167 break; 168 case csimbr_var: 169 symbol = var_to_symbol(csimbr->u.var); 170 break; 171 case csimbr_prop: 172 symbol = prop_to_symbol(csimbr->u.prop); 173 break; 174 default: 175 assert(b_false); 176 } 177 return symbol; 178 } 179 node = list_next(&scope->members, node); 180 } 139 symbol = symbol_search_csi_no_base(prog, scope, name); 140 if (symbol != NULL) 141 return symbol; 181 142 182 143 /* Try inherited members. */ … … 194 155 } 195 156 157 /** Look for symbol strictly in CSI. 158 * 159 * Look for symbol in definition of a CSI and its ancestors. (But not 160 * in lexically enclosing CSI or in base CSI.) 161 * 162 * @param prog Program to look in 163 * @param scope CSI in which to look 164 * @param name Identifier of the symbol 165 * 166 * @return Symbol or @c NULL if symbol not found. 167 */ 168 stree_symbol_t *symbol_search_csi_no_base(stree_program_t *prog, 169 stree_csi_t *scope, stree_ident_t *name) 170 { 171 list_node_t *node; 172 stree_csimbr_t *csimbr; 173 stree_ident_t *mbr_name; 174 175 (void) prog; 176 177 /* Look in new members in this class. */ 178 179 node = list_first(&scope->members); 180 while (node != NULL) { 181 csimbr = list_node_data(node, stree_csimbr_t *); 182 mbr_name = stree_csimbr_get_name(csimbr); 183 184 if (name->sid == mbr_name->sid) { 185 /* Match */ 186 return csimbr_to_symbol(csimbr); 187 } 188 189 node = list_next(&scope->members, node); 190 } 191 /* No match */ 192 return NULL; 193 } 194 196 195 /** Look for symbol in global scope. 197 196 * … … 207 206 stree_modm_t *modm; 208 207 stree_symbol_t *symbol; 208 stree_ident_t *mbr_name; 209 209 210 210 node = list_first(&prog->module->members); 211 211 while (node != NULL) { 212 212 modm = list_node_data(node, stree_modm_t *); 213 if (name->sid == modm->u.csi->name->sid) { 213 214 switch (modm->mc) { 215 case mc_csi: mbr_name = modm->u.csi->name; break; 216 case mc_enum: mbr_name = modm->u.enum_d->name; break; 217 } 218 219 if (name->sid == mbr_name->sid) { 214 220 /* Match */ 215 221 switch (modm->mc) { … … 217 223 symbol = csi_to_symbol(modm->u.csi); 218 224 break; 219 default: 220 assert(b_false); 225 case mc_enum: 226 symbol = enum_to_symbol(modm->u.enum_d); 227 break; 221 228 } 222 229 return symbol; … … 346 353 } 347 354 355 /** Convert symbol to enum (base to derived).