Changeset 1113c9e in mainline for uspace/app
- Timestamp:
- 2010-06-09T19:03:24Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8eec3c8
- Parents:
- 8f80c77 (diff), c5cb943d (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/app/sbi
- Files:
-
- 4 added
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/Makefile
r8f80c77 r1113c9e 35 35 SOURCES = \ 36 36 src/builtin/bi_boxed.c \ 37 src/builtin/bi_char.c \ 37 38 src/builtin/bi_error.c \ 38 39 src/builtin/bi_fun.c \ 40 src/builtin/bi_int.c \ 39 41 src/builtin/bi_textfile.c \ 40 42 src/builtin/bi_string.c \ -
uspace/app/sbi/src/ancr.c
r8f80c77 r1113c9e 51 51 #include <assert.h> 52 52 #include "builtin.h" 53 #include "cspan.h" 53 54 #include "list.h" 54 55 #include "mytypes.h" … … 61 62 static void ancr_csi_dfs(stree_program_t *prog, stree_csi_t *csi); 62 63 static void ancr_csi_process(stree_program_t *prog, stree_csi_t *node); 64 static stree_csi_t *ancr_csi_get_pred(stree_program_t *prog, stree_csi_t *csi, 65 stree_texpr_t *pred_ref); 63 66 static void ancr_csi_print_cycle(stree_program_t *prog, stree_csi_t *node); 64 67 … … 128 131 * 129 132 * @param prog Program being processed. 130 * @param node CSI node to process. 131 */ 132 static void ancr_csi_process(stree_program_t *prog, stree_csi_t *node) 133 { 134 stree_symbol_t *base_sym; 133 * @param csi CSI node to process. 134 */ 135 static void ancr_csi_process(stree_program_t *prog, stree_csi_t *csi) 136 { 135 137 stree_csi_t *base_csi, *outer_csi; 136 138 stree_csi_t *gf_class; 137 139 138 if (node->ancr_state == ws_visited) { 140 list_node_t *pred_n; 141 stree_texpr_t *pred; 142 stree_csi_t *pred_csi; 143 144 if (csi->ancr_state == ws_visited) { 139 145 /* Node already processed */ 140 146 return; 141 147 } 142 148 143 if ( node->ancr_state == ws_active) {149 if (csi->ancr_state == ws_active) { 144 150 /* Error, closed reference loop. */ 145 151 printf("Error: Circular class, struct or interface chain: "); 146 ancr_csi_print_cycle(prog, node);152 ancr_csi_print_cycle(prog, csi); 147 153 printf(".\n"); 148 154 exit(1); 149 155 } 150 156 151 node->ancr_state = ws_active;152 153 outer_csi = csi_to_symbol( node)->outer_csi;157 csi->ancr_state = ws_active; 158 159 outer_csi = csi_to_symbol(csi)->outer_csi; 154 160 gf_class = builtin_get_gf_class(prog->builtin); 155 161 156 /* Process outer CSI */ 157 if (outer_csi != NULL) 158 ancr_csi_process(prog, outer_csi); 159 160 if (node->base_csi_ref != NULL) { 161 /* Resolve base CSI. */ 162 base_sym = symbol_xlookup_in_csi(prog, outer_csi, 163 node->base_csi_ref); 164 base_csi = symbol_to_csi(base_sym); 165 assert(base_csi != NULL); 166 167 /* Process base CSI. */ 168 ancr_csi_process(prog, base_csi); 169 } else if (node != gf_class) { 162 if (csi != gf_class){ 170 163 /* Implicit inheritance from grandfather class. */ 171 164 base_csi = gf_class; … … 175 168 } 176 169 170 /* Process outer CSI */ 171 if (outer_csi != NULL) 172 ancr_csi_process(prog, outer_csi); 173 174 /* 175 * Process inheritance list. 176 */ 177 pred_n = list_first(&csi->inherit); 178 179 /* For a class node, the first entry can be a class. */ 180 if (csi->cc == csi_class && pred_n != NULL) { 181 pred = list_node_data(pred_n, stree_texpr_t *); 182 pred_csi = ancr_csi_get_pred(prog, csi, pred); 183 assert(pred_csi != NULL); 184 185 if (pred_csi->cc == csi_class) { 186 /* Process base class */ 187 base_csi = pred_csi; 188 ancr_csi_process(prog, pred_csi); 189 190 pred_n = list_next(&csi->inherit, pred_n); 191 } 192 } 193 194 /* Following entires can only be interfaces. */ 195 while (pred_n != NULL) { 196 pred = list_node_data(pred_n, stree_texpr_t *); 197 pred_csi = ancr_csi_get_pred(prog, csi, pred); 198 assert(pred_csi != NULL); 199 200 /* Process implemented or accumulated interface. */ 201 ancr_csi_process(prog, pred_csi); 202 203 switch (pred_csi->cc) { 204 case csi_class: 205 switch (csi->cc) { 206 case csi_class: 207 cspan_print(csi->name->cspan); 208 printf(" Error: Only the first predecessor " 209 "can be a class. ('"); 210 symbol_print_fqn(csi_to_symbol(csi)); 211 printf("' deriving from '"); 212 symbol_print_fqn(csi_to_symbol(pred_csi)); 213 printf("').\n"); 214 exit(1); 215 break; 216 case csi_struct: 217 assert(b_false); /* XXX */ 218 case csi_interface: 219 cspan_print(csi->name->cspan); 220 printf(" Error: Interface predecessor must be " 221 "an interface ('"); 222 symbol_print_fqn(csi_to_symbol(csi)); 223 printf("' deriving from '"); 224 symbol_print_fqn(csi_to_symbol(pred_csi)); 225 printf("').\n"); 226 exit(1); 227 break; 228 } 229 case csi_struct: 230 assert(b_false); /* XXX */ 231 case csi_interface: 232 break; 233 } 234 235 pred_n = list_next(&csi->inherit, pred_n); 236 } 237 177 238 /* Store base CSI and update node state. */ 178 node->ancr_state = ws_visited; 179 node->base_csi = base_csi; 239 csi->ancr_state = ws_visited; 240 csi->base_csi = base_csi; 241 } 242 243 /** Resolve CSI predecessor reference. 244 * 245 * Returns the CSI predecessor referenced by @a pred_ref. 246 * If the referenced CSI does not exist, an error is generated. 247 * 248 * @param prog Program being processed. 249 * @param csi CSI node to process. 250 * @param pred_ref Type expression referencing the predecessor. 251 * @return Predecessor CSI. 252 */ 253 static stree_csi_t *ancr_csi_get_pred(stree_program_t *prog, stree_csi_t *csi, 254 stree_texpr_t *pred_ref) 255 { 256 stree_csi_t *outer_csi; 257 stree_symbol_t *pred_sym; 258 stree_csi_t *pred_csi; 259 260 outer_csi = csi_to_symbol(csi)->outer_csi; 261 pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred_ref); 262 pred_csi = symbol_to_csi(pred_sym); 263 assert(pred_csi != NULL); /* XXX */ 264 265 return pred_csi; 180 266 } 181 267 … … 191 277 { 192 278 stree_csi_t *n; 193 stree_symbol_t *base_sym, *node_sym; 194 stree_csi_t *base_csi, *outer_csi; 279 stree_symbol_t *pred_sym, *node_sym; 280 stree_csi_t *pred_csi, *outer_csi; 281 stree_texpr_t *pred; 282 list_node_t *pred_n; 195 283 196 284 n = node; … … 204 292 if (outer_csi != NULL && outer_csi->ancr_state == ws_active) { 205 293 node = outer_csi; 206 } else if (node->base_csi_ref != NULL) {207 /* Resolve base CSI. */208 base_sym = symbol_xlookup_in_csi(prog, outer_csi,209 node->base_csi_ref);210 base_csi = symbol_to_csi(base_sym);211 assert(base_csi != NULL);212 213 assert(base_csi->ancr_state == ws_active);214 node = base_csi;215 294 } else { 216 assert(b_false); 295 node = NULL; 296 297 pred_n = list_first(&node->inherit); 298 while (pred_n != NULL) { 299 pred = list_node_data(pred_n, stree_texpr_t *); 300 pred_sym = symbol_xlookup_in_csi(prog, 301 outer_csi, pred); 302 pred_csi = symbol_to_csi(pred_sym); 303 assert(pred_csi != NULL); 304 305 if (pred_csi->ancr_state == ws_active) { 306 node = pred_csi; 307 break; 308 } 309 } 310 311 assert(node != NULL); 217 312 } 218 313 } while (n != node); -
uspace/app/sbi/src/bigint.c
r8f80c77 r1113c9e 360 360 } 361 361 362 /** Print bigint to standard output. */ 363 void bigint_print(bigint_t *bigint) 364 { 362 /** Convert bigint to string. 363 * 364 * @param bigint Bigint to convert. 365 * @param dptr Place to store pointer to new string. 366 */ 367 void bigint_get_as_string(bigint_t *bigint, char **dptr) 368 { 369 static const char digits[] = { '0', '1', '2', '3', '4', '5', '6', 370 '7', '8', '9' }; 371 365 372 bigint_t val, tmp; 366 373 bigint_word_t rem; 367 size_t n digits;368 int *digits;369 size_t idx; 370 371 #ifdef DEBUG_BIGINT_TRACE 372 printf(" Print bigint.\n");374 size_t nchars; 375 char *str; 376 size_t idx; 377 378 #ifdef DEBUG_BIGINT_TRACE 379 printf("Convert bigint to string.\n"); 373 380 #endif 374 381 assert(BIGINT_BASE >= 10); 375 382 376 if (bigint_is_zero(bigint)) { 377 putchar('0'); 378 return; 379 } 380 381 if (bigint->negative) 382 putchar('-'); 383 384 /* Compute number of digits. */ 385 ndigits = 0; 383 /* Compute number of characters. */ 384 nchars = 0; 385 386 if (bigint_is_zero(bigint) || bigint->negative) 387 nchars += 1; /* '0' or '-' */ 388 386 389 bigint_clone(bigint, &val); 387 390 while (bigint_is_zero(&val) != b_true) { … … 390 393 bigint_shallow_copy(&tmp, &val); 391 394 392 n digits += 1;395 nchars += 1; 393 396 } 394 397 bigint_destroy(&val); 395 398 396 /* Store digits to array. */397 398 digits = malloc(ndigits * sizeof(int));399 if ( digits== NULL) {399 /* Store characters to array. */ 400 401 str = malloc(nchars * sizeof(char) + 1); 402 if (str == NULL) { 400 403 printf("Memory allocation failed.\n"); 401 404 exit(1); 402 405 } 403 406 404 idx = 0; 407 if (bigint_is_zero(bigint)) { 408 str[0] = '0'; 409 } else if (bigint->negative) { 410 str[0] = '-'; 411 } 412 413 idx = 1; 405 414 bigint_clone(bigint, &val); 406 415 while (bigint_is_zero(&val) != b_true) { … … 409 418 bigint_shallow_copy(&tmp, &val); 410 419 411 digits[idx++] = (int) rem; 412 } 420 str[nchars - idx] = digits[(int) rem]; 421 ++idx; 422 } 423 413 424 bigint_destroy(&val); 414 415 for (idx = 0; idx < ndigits; ++idx) 416 printf("%u", digits[ndigits - 1 - idx]); 417 418 free(digits); 425 str[nchars] = '\0'; 426 *dptr = str; 427 } 428 429 /** Print bigint to standard output. 430 * 431 * @param bigint Bigint to print. 432 */ 433 void bigint_print(bigint_t *bigint) 434 { 435 char *str; 436 437 #ifdef DEBUG_BIGINT_TRACE 438 printf("Print bigint.\n"); 439 #endif 440 bigint_get_as_string(bigint, &str); 441 printf("%s", str); 442 free(str); 419 443 } 420 444 -
uspace/app/sbi/src/bigint.h
r8f80c77 r1113c9e 48 48 void bigint_sub(bigint_t *a, bigint_t *b, bigint_t *dest); 49 49 void bigint_mul(bigint_t *a, bigint_t *b, bigint_t *dest); 50 51 void bigint_get_as_string(bigint_t *bigint, char **dptr); 50 52 void bigint_print(bigint_t *bigint); 51 53 -
uspace/app/sbi/src/builtin.c
r8f80c77 r1113c9e 42 42 #include "builtin/bi_boxed.h" 43 43 #include "builtin/bi_error.h" 44 #include "builtin/bi_char.h" 44 45 #include "builtin/bi_fun.h" 46 #include "builtin/bi_int.h" 45 47 #include "builtin/bi_textfile.h" 46 48 #include "builtin/bi_string.h" … … 52 54 #include "os/os.h" 53 55 #include "parse.h" 56 #include "rdata.h" 54 57 #include "run.h" 55 58 #include "stree.h" … … 89 92 90 93 bi_error_declare(bi); 94 bi_char_declare(bi); 91 95 bi_fun_declare(bi); 96 bi_int_declare(bi); 92 97 bi_textfile_declare(bi); 93 98 bi_string_declare(bi); … … 105 110 bi_boxed_bind(bi); 106 111 bi_error_bind(bi); 112 bi_char_bind(bi); 107 113 bi_fun_bind(bi); 114 bi_int_bind(bi); 108 115 bi_textfile_bind(bi); 109 116 bi_string_bind(bi); … … 250 257 { 251 258 stree_symbol_t *fun_sym; 252 builtin_t *bi;253 259 builtin_proc_t bproc; 254 260 … … 257 263 #endif 258 264 fun_sym = proc->outer_symbol; 259 bi = run->program->builtin;260 265 261 266 bproc = proc->bi_handler; … … 298 303 } 299 304 300 /** Declare a builtin function in @a csi. 305 /** Return string value from builtin procedure. 306 * 307 * Makes it easy for a builtin procedure to return value of type @c string. 308 * 309 * @param run Runner object 310 * @param str String value. Must be allocated from heap and its 311 * ownership is hereby given up. 312 */ 313 void builtin_return_string(run_t *run, const char *astr) 314 { 315 rdata_string_t *rstring; 316 rdata_var_t *rvar; 317 rdata_value_t *rval; 318 rdata_item_t *ritem; 319 320 run_proc_ar_t *proc_ar; 321 322 #ifdef DEBUG_RUN_TRACE 323 printf("Return string '%s' from builtin function.\n", astr); 324 #endif 325 rstring = rdata_string_new(); 326 rstring->value = astr; 327 328 rvar = rdata_var_new(vc_string); 329 rvar->u.string_v = rstring; 330 rval = rdata_value_new(); 331 rval->var = rvar; 332 333 ritem = rdata_item_new(ic_value); 334 ritem->u.value = rval; 335 336 proc_ar = run_get_current_proc_ar(run); 337 proc_ar->retval = ritem; 338 } 339 340 /** Declare a static builtin function in @a csi. 301 341 * 302 342 * Declare a builtin function member of CSI @a csi. Deprecated in favor … … 314 354 stree_csimbr_t *csimbr; 315 355 stree_symbol_t *fun_sym; 356 stree_symbol_attr_t *sym_attr; 316 357 317 358 ident = stree_ident_new(); … … 333 374 fun_sym->u.fun = fun; 334 375 fun_sym->outer_csi = csi; 376 377 sym_attr = stree_symbol_attr_new(sac_static); 378 list_append(&fun_sym->attr, sym_attr); 379 335 380 fun->symbol = fun_sym; 336 381 fun->proc->outer_symbol = fun_sym; -
uspace/app/sbi/src/builtin.h
r8f80c77 r1113c9e 40 40 41 41 rdata_var_t *builtin_get_self_mbr_var(run_t *run, const char *mbr_name); 42 void builtin_return_string(run_t *run, const char *str); 42 43 43 44 stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name); -
uspace/app/sbi/src/builtin/bi_fun.c
r8f80c77 r1113c9e 94 94 builtin_code_snippet(bi, 95 95 "class Task is\n" 96 "fun Exec(args : string[], packed), builtin;\n"96 "fun Exec(args : string[], packed), static, builtin;\n" 97 97 "end\n"); 98 98 } -
uspace/app/sbi/src/builtin/bi_string.c
r8f80c77 r1113c9e 116 116 rdata_var_t *self_value_var; 117 117 const char *str; 118 const char *slice; 118 119 size_t str_l; 119 120 … … 125 126 126 127 int rc; 127 128 rdata_string_t *rstring;129 rdata_var_t *rvar;130 rdata_value_t *rval;131 rdata_item_t *ritem;132 133 run_proc_ar_t *proc_ar;134 128 135 129 /* Extract self.Value */ … … 165 159 start, length, str); 166 160 #endif 167 /* Construct return value. */ 168 rstring = rdata_string_new(); 169 rstring->value = os_str_aslice(str, start, length); 161 slice = os_str_aslice(str, start, length); 170 162 171 rvar = rdata_var_new(vc_string); 172 rvar->u.string_v = rstring; 173 rval = rdata_value_new(); 174 rval->var = rvar; 175 176 ritem = rdata_item_new(ic_value); 177 ritem->u.value = rval; 178 179 proc_ar = run_get_current_proc_ar(run); 180 proc_ar->retval = ritem; 163 /* Ownership of slice is transferred. */ 164 builtin_return_string(run, slice); 181 165 } -
uspace/app/sbi/src/imode.c
r8f80c77 r1113c9e 130 130 131 131 /* Construct run context. */ 132 run_gdata_init(&run); 133 132 134 run.thread_ar = run_thread_ar_new(); 133 135 list_init(&run.thread_ar->proc_ar); 134 run_proc_ar_create(&run, NULL, proc, &proc_ar);136 run_proc_ar_create(&run, run.gdata, proc, &proc_ar); 135 137 list_append(&run.thread_ar->proc_ar, proc_ar); 136 138 -
uspace/app/sbi/src/input.c
r8f80c77 r1113c9e 206 206 *dp++ = *sp++; 207 207 208 *dp ++= '\0';208 *dp = '\0'; 209 209 input->str = sp; 210 210 *line = input->buffer; -
uspace/app/sbi/src/mytypes.h
r8f80c77 r1113c9e 43 43 } walk_state_t; 44 44 45 /** Static vs. nonstatic */ 46 typedef enum { 47 sn_nonstatic, 48 sn_static 49 } statns_t; 50 45 51 /** Error return codes. */ 46 52 #include <errno.h> -
uspace/app/sbi/src/os/helenos.c
r8f80c77 r1113c9e 173 173 } 174 174 175 /** Convert character to new string. 176 * 177 * @param chr Character 178 * @return Newly allocated string. 179 */ 180 char *os_chr_to_astr(wchar_t chr) 181 { 182 char *str; 183 size_t offset; 184 185 str = malloc(STR_BOUNDS(1) + 1); 186 if (str == NULL) { 187 printf("Memory allocation error.\n"); 188 exit(1); 189 } 190 191 offset = 0; 192 if (chr_encode(chr, str, &offset, STR_BOUNDS(1)) != EOK) { 193 /* XXX Should handle gracefully */ 194 printf("String conversion error.\n"); 195 exit(1); 196 } 197 198 str[offset] = '\0'; 199 return str; 200 } 201 175 202 /** Display survival help message. */ 176 203 void os_input_disp_help(void) -
uspace/app/sbi/src/os/os.h
r8f80c77 r1113c9e 36 36 size_t os_str_length(const char *str); 37 37 int os_str_get_char(const char *str, int index, int *out_char); 38 char *os_chr_to_astr(wchar_t chr); 38 39 void os_input_disp_help(void); 39 40 int os_input_line(char **ptr); -
uspace/app/sbi/src/os/posix.c
r8f80c77 r1113c9e 159 159 } 160 160 161 /** Convert character to new string. 162 * 163 * @param chr Character 164 * @return Newly allocated string. 165 */ 166 char *os_chr_to_astr(wchar_t chr) 167 { 168 char *str; 169 170 str = malloc(2); 171 if (str == NULL) { 172 printf("Memory allocation error.\n"); 173 exit(1); 174 } 175 176 str[0] = (char) chr; 177 str[1] = '\0'; 178 179 return str; 180 } 181 161 182 #define OS_INPUT_BUFFER_SIZE 256 162 183 static char os_input_buffer[OS_INPUT_BUFFER_SIZE]; -
uspace/app/sbi/src/parse.c
r8f80c77 r1113c9e 35 35 #include <assert.h> 36 36 #include <stdlib.h> 37 #include "cspan.h" 37 38 #include "debug.h" 38 39 #include "lex.h" … … 64 65 static stree_prop_t *parse_prop(parse_t *parse, stree_csi_t *outer_csi); 65 66 67 static void parse_symbol_attrs(parse_t *parse, stree_symbol_t *symbol); 66 68 static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse); 67 69 … … 70 72 static stree_fun_sig_t *parse_fun_sig(parse_t *parse); 71 73 74 static void parse_prop_get(parse_t *parse, stree_prop_t *prop); 75 static void parse_prop_set(parse_t *parse, stree_prop_t *prop); 72 76 73 77 /* … … 175 179 stree_ident_t *targ_name; 176 180 stree_targ_t *targ; 181 stree_texpr_t *pref; 177 182 178 183 switch (dclass) { … … 212 217 /* Inheritance list */ 213 218 lskip(parse); 214 csi->base_csi_ref = parse_texpr(parse); 215 } else { 216 csi->base_csi_ref = NULL; 219 220 while (b_true) { 221 pref = parse_texpr(parse); 222 if (parse_is_error(parse)) 223 break; 224 225 list_append(&csi->inherit, pref); 226 if (lcur_lc(parse) != lc_plus) 227 break; 228 229 lskip(parse); 230 } 217 231 } 218 232 … … 224 238 csimbr = parse_csimbr(parse, csi); 225 239 if (csimbr == NULL) 240 continue; 241 242 list_append(&csi->members, csimbr); 243 } 244 245 lmatch(parse, lc_end); 246 247 if (outer_csi != NULL) { 248 switch (outer_csi->cc) { 249 case csi_class: 250 case csi_struct: 226 251 break; 227 228 list_append(&csi->members, csimbr); 229 } 230 231 lmatch(parse, lc_end); 252 case csi_interface: 253 cspan_print(csi->name->cspan); 254 printf(" Error: CSI declared inside interface.\n"); 255 parse_note_error(parse); 256 /* XXX Free csi */ 257 return NULL; 258 } 259 } 232 260 233 261 return csi; … … 253 281 stree_prop_t *prop; 254 282 283 csimbr = NULL; 284 255 285 switch (lcur_lc(parse)) { 256 286 case lc_class: … … 258 288 case lc_interface: 259 289 csi = parse_csi(parse, lcur_lc(parse), outer_csi); 260 csimbr = stree_csimbr_new(csimbr_csi); 261 csimbr->u.csi = csi; 290 if (csi != NULL) { 291 csimbr = stree_csimbr_new(csimbr_csi); 292 csimbr->u.csi = csi; 293 } 262 294 break; 263 295 case lc_new: 264 296 ctor = parse_ctor(parse, outer_csi); 265 csimbr = stree_csimbr_new(csimbr_ctor); 266 csimbr->u.ctor = ctor; 297 if (ctor != NULL) { 298 csimbr = stree_csimbr_new(csimbr_ctor); 299 csimbr->u.ctor = ctor; 300 } 267 301 break; 268 302 case lc_deleg: 269 303 deleg = parse_deleg(parse, outer_csi); 270 csimbr = stree_csimbr_new(csimbr_deleg); 271 csimbr->u.deleg = deleg; 304 if (deleg != NULL) { 305 csimbr = stree_csimbr_new(csimbr_deleg); 306 csimbr->u.deleg = deleg; 307 } 272 308 break; 273 309 case lc_enum: 274 310 enum_d = parse_enum(parse, outer_csi); 275 csimbr = stree_csimbr_new(csimbr_enum); 276 csimbr->u.enum_d = enum_d; 311 if (enum_d != NULL) { 312 csimbr = stree_csimbr_new(csimbr_enum); 313 csimbr->u.enum_d = enum_d; 314 } 277 315 break; 278 316 case lc_fun: … … 283 321 case lc_var: 284 322 var = parse_var(parse, outer_csi); 285 csimbr = stree_csimbr_new(csimbr_var); 286 csimbr->u.var = var; 323 if (var != NULL) { 324 csimbr = stree_csimbr_new(csimbr_var); 325 csimbr->u.var = var; 326 } 287 327 break; 288 328 case lc_prop: … … 294 334 lunexpected_error(parse); 295 335 lex_next(parse->lex); 296 csimbr = NULL;297 336 break; 298 337 } … … 311 350 stree_ctor_t *ctor; 312 351 stree_symbol_t *symbol; 313 stree_symbol_attr_t *attr;352 cspan_t *cspan; 314 353 315 354 ctor = stree_ctor_new(); … … 321 360 322 361 lmatch(parse, lc_new); 362 cspan = lprev_span(parse); 323 363 324 364 /* Fake identifier. */ … … 334 374 ctor->sig = parse_fun_sig(parse); 335 375 if (ctor->sig->rtype != NULL) { 336 printf("Error: Constructor of CSI '"); 376 cspan_print(cspan); 377 printf(" Error: Constructor of CSI '"); 337 378 symbol_print_fqn(csi_to_symbol(outer_csi)); 338 379 printf("' has a return type.\n"); … … 340 381 } 341 382 342 list_init(&symbol->attr);343 344 383 /* 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 } 384 parse_symbol_attrs(parse, symbol); 350 385 351 386 ctor->proc = stree_proc_new(); … … 356 391 357 392 /* This constructor has no body. */ 358 printf("Error: Constructor of CSI '"); 393 cspan_print(cspan); 394 printf(" Error: Constructor of CSI '"); 359 395 symbol_print_fqn(csi_to_symbol(outer_csi)); 360 396 printf("' has no body.\n"); … … 368 404 } 369 405 406 switch (outer_csi->cc) { 407 case csi_class: 408 case csi_struct: 409 break; 410 case csi_interface: 411 cspan_print(ctor->name->cspan); 412 printf(" Error: Constructor declared inside interface.\n"); 413 parse_note_error(parse); 414 /* XXX Free ctor */ 415 return NULL; 416 } 417 370 418 return ctor; 371 419 } … … 409 457 410 458 if (list_is_empty(&enum_d->members)) { 459 cspan_print(enum_d->name->cspan); 411 460 printf("Error: Enum type '%s' has no members.\n", 412 461 strtab_get_str(enum_d->name->sid)); … … 416 465 lmatch(parse, lc_end); 417 466 467 if (outer_csi != NULL) { 468 switch (outer_csi->cc) { 469 case csi_class: 470 case csi_struct: 471 break; 472 case csi_interface: 473 cspan_print(enum_d->name->cspan); 474 printf(" Error: Enum declared inside interface.\n"); 475 parse_note_error(parse); 476 /* XXX Free enum */ 477 return NULL; 478 } 479 } 480 418 481 return enum_d; 419 482 } … … 449 512 stree_deleg_t *deleg; 450 513 stree_symbol_t *symbol; 451 stree_symbol_attr_t *attr;452 514 453 515 deleg = stree_deleg_new(); … … 467 529 deleg->sig = parse_fun_sig(parse); 468 530 469 list_init(&symbol->attr);470 471 531 /* Parse attributes. */ 472 while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) { 473 lskip(parse); 474 attr = parse_symbol_attr(parse); 475 list_append(&symbol->attr, attr); 476 } 532 parse_symbol_attrs(parse, symbol); 477 533 478 534 lmatch(parse, lc_scolon); 535 536 switch (outer_csi->cc) { 537 case csi_class: 538 case csi_struct: 539 break; 540 case csi_interface: 541 cspan_print(deleg->name->cspan); 542 printf(" Error: Delegate declared inside interface.\n"); 543 parse_note_error(parse); 544 /* XXX Free deleg */ 545 return NULL; 546 } 479 547 480 548 return deleg; … … 491 559 stree_fun_t *fun; 492 560 stree_symbol_t *symbol; 493 stree_symbol_attr_t *attr;561 bool_t body_expected; 494 562 495 563 fun = stree_fun_new(); … … 508 576 fun->sig = parse_fun_sig(parse); 509 577 510 list_init(&symbol->attr);511 512 578 /* Parse attributes. */ 513 while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) { 514 lskip(parse); 515 attr = parse_symbol_attr(parse); 516 list_append(&symbol->attr, attr); 517 } 579 parse_symbol_attrs(parse, symbol); 580 581 body_expected = !stree_symbol_has_attr(symbol, sac_builtin) && 582 (outer_csi->cc != csi_interface); 518 583 519 584 fun->proc = stree_proc_new(); … … 523 588 lskip(parse); 524 589 525 /* This function has no body. */ 526 if (!stree_symbol_has_attr(symbol, sac_builtin)) { 527 printf("Error: Function '"); 590 /* Body not present */ 591 if (body_expected) { 592 cspan_print(fun->name->cspan); 593 printf(" Error: Function '"); 528 594 symbol_print_fqn(symbol); 529 printf("' has nobody.\n");595 printf("' should have a body.\n"); 530 596 parse_note_error(parse); 531 597 } 598 532 599 fun->proc->body = NULL; 533 600 } else { … … 535 602 fun->proc->body = parse_block(parse); 536 603 lmatch(parse, lc_end); 604 605 /* Body present */ 606 if (!body_expected) { 607 cspan_print(fun->name->cspan); 608 printf(" Error: Function declaration '"); 609 symbol_print_fqn(symbol); 610 printf("' should not have a body.\n"); 611 parse_note_error(parse); 612 } 537 613 } 538 614 … … 561 637 lmatch(parse, lc_colon); 562 638 var->type = parse_texpr(parse); 639 640 parse_symbol_attrs(parse, symbol); 641 563 642 lmatch(parse, lc_scolon); 643 644 switch (outer_csi->cc) { 645 case csi_class: 646 case csi_struct: 647 break; 648 case csi_interface: 649 cspan_print(var->name->cspan); 650 printf(" Error: Variable declared inside interface.\n"); 651 parse_note_error(parse); 652 /* XXX Free var */ 653 return NULL; 654 } 564 655 565 656 return var; … … 576 667 stree_prop_t *prop; 577 668 stree_symbol_t *symbol; 669 bool_t body_expected; 578 670 579 671 stree_ident_t *ident; … … 625 717 lmatch(parse, lc_colon); 626 718 prop->type = parse_texpr(parse); 719 720 /* Parse attributes. */ 721 parse_symbol_attrs(parse, symbol); 722 723 body_expected = (outer_csi->cc != csi_interface); 724 627 725 lmatch(parse, lc_is); 628 726 … … 630 728 switch (lcur_lc(parse)) { 631 729 case lc_get: 632 lskip(parse); 633 lmatch(parse, lc_is); 634 if (prop->getter != NULL) { 635 printf("Error: Duplicate getter.\n"); 636 (void) parse_block(parse); /* XXX Free */ 637 lmatch(parse, lc_end); 638 parse_note_error(parse); 639 break; 640 } 641 642 /* Create setter procedure */ 643 prop->getter = stree_proc_new(); 644 prop->getter->body = parse_block(parse); 645 prop->getter->outer_symbol = symbol; 646 647 lmatch(parse, lc_end); 730 parse_prop_get(parse, prop); 648 731 break; 649 732 case lc_set: 650 lskip(parse); 651 prop->setter_arg = stree_proc_arg_new(); 652 prop->setter_arg->name = parse_ident(parse); 653 prop->setter_arg->type = prop->type; 654 lmatch(parse, lc_is); 655 if (prop->setter != NULL) { 656 printf("Error: Duplicate setter.\n"); 657 (void) parse_block(parse); /* XXX Free */ 658 lmatch(parse, lc_end); 659 parse_note_error(parse); 660 } 661 662 /* Create setter procedure */ 663 prop->setter = stree_proc_new(); 664 prop->setter->body = parse_block(parse); 665 prop->setter->outer_symbol = symbol; 666 667 lmatch(parse, lc_end); 733 parse_prop_set(parse, prop); 668 734 break; 669 735 default: … … 677 743 } 678 744 745 /** Parse symbol attributes. 746 * 747 * Parse list of attributes and add them to @a symbol. 748 * 749 * @param parse Parser object 750 * @param symbol Symbol to add these attributes to 751 */ 752 static void parse_symbol_attrs(parse_t *parse, stree_symbol_t *symbol) 753 { 754 stree_symbol_attr_t *attr; 755 756 /* Parse attributes. */ 757 while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) { 758 lskip(parse); 759 attr = parse_symbol_attr(parse); 760 list_append(&symbol->attr, attr); 761 } 762 } 763 679 764 /** Parse symbol attribute. 680 765 * 681 * @param parse Parser object. 682 * @param outer_csi CSI containing this declaration or @c NULL if global. 683 * @return New syntax tree node. 766 * @param parse Parser object 767 * @return New syntax tree node 684 768 */ 685 769 static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse) 686 770 { 687 771 stree_symbol_attr_t *attr; 688 689 if (lcur_lc(parse) != lc_builtin) { 690 printf("Error: Unexpected attribute '"); 772 symbol_attr_class_t sac; 773 774 /* Make compiler happy. */ 775 sac = 0; 776 777 switch (lcur_lc(parse)) { 778 case lc_builtin: sac = sac_builtin; break; 779 case lc_static: sac = sac_static; break; 780 default: 781 cspan_print(lcur_span(parse)); 782 printf(" Error: Unexpected attribute '"); 691 783 lem_print(lcur(parse)); 692 784 printf("'.\n"); 693 785 parse_note_error(parse); 786 break; 694 787 } 695 788 696 789 lskip(parse); 697 790 698 attr = stree_symbol_attr_new(sac _builtin);791 attr = stree_symbol_attr_new(sac); 699 792 return attr; 700 793 } … … 718 811 printf("Parse procedure argument.\n"); 719 812 #endif 720 813 list_init(&arg->attr); 721 814 722 815 /* Parse attributes. */ … … 740 833 741 834 if (lcur_lc(parse) != lc_packed) { 742 printf("Error: Unexpected attribute '"); 835 cspan_print(lcur_span(parse)); 836 printf(" Error: Unexpected attribute '"); 743 837 lem_print(lcur(parse)); 744 838 printf("'.\n"); … … 802 896 803 897 return sig; 898 } 899 900 /** Parse member property getter. 901 * 902 * @param parse Parser object. 903 * @param prop Property containing this declaration. 904 */ 905 static void parse_prop_get(parse_t *parse, stree_prop_t *prop) 906 { 907 cspan_t *cspan; 908 stree_block_t *block; 909 stree_proc_t *getter; 910 bool_t body_expected; 911 912 body_expected = (prop->symbol->outer_csi->cc != csi_interface); 913 914 lskip(parse); 915 cspan = lprev_span(parse); 916 917 if (prop->getter != NULL) { 918 cspan_print(cspan); 919 printf(" Error: Duplicate getter.\n"); 920 parse_note_error(parse); 921 return; 922 } 923 924 if (lcur_lc(parse) == lc_scolon) { 925 /* Body not present */ 926 lskip(parse); 927 block = NULL; 928 929 if (body_expected) { 930 cspan_print(prop->name->cspan); 931 printf(" Error: Property '"); 932 symbol_print_fqn(prop->symbol); 933 printf("' getter should have " 934 "a body.\n"); 935 parse_note_error(parse); 936 } 937 } else { 938 /* Body present */ 939 lmatch(parse, lc_is); 940 block = parse_block(parse); 941 lmatch(parse, lc_end); 942 943 if (!body_expected) { 944 cspan_print(prop->name->cspan); 945 printf(" Error: Property '"); 946 symbol_print_fqn(prop->symbol); 947 printf("' getter declaration should " 948 "not have a body.\n"); 949 parse_note_error(parse); 950 951 /* XXX Free block */ 952 block = NULL; 953 } 954 } 955 956 /* Create getter procedure */ 957 getter = stree_proc_new(); 958 getter->body = block; 959 getter->outer_symbol = prop->symbol; 960 961 /* Store getter in property. */ 962 prop->getter = getter; 963 } 964 965 966 /** Parse member property setter. 967 * 968 * @param parse Parser object. 969 * @param prop Property containing this declaration. 970 */ 971 static void parse_prop_set(parse_t *parse, stree_prop_t *prop) 972 { 973 cspan_t *cspan; 974 stree_block_t *block; 975 stree_proc_t *setter; 976 bool_t body_expected; 977 978 body_expected = (prop->symbol->outer_csi->cc != csi_interface); 979 980 lskip(parse); 981 cspan = lprev_span(parse); 982 983 if (prop->setter != NULL) { 984 cspan_print(cspan); 985 printf(" Error: Duplicate setter.\n"); 986 parse_note_error(parse); 987 return; 988 } 989 990 prop->setter_arg = stree_proc_arg_new(); 991 prop->setter_arg->name = parse_ident(parse); 992 prop->setter_arg->type = prop->type; 993 994 if (lcur_lc(parse) == lc_scolon) { 995 /* Body not present */ 996 lskip(parse); 997 998 block = NULL; 999 1000 if (body_expected) { 1001 cspan_print(prop->name->cspan); 1002 printf(" Error: Property '"); 1003 symbol_print_fqn(prop->symbol); 1004 printf("' setter should have " 1005 "a body.\n"); 1006 parse_note_error(parse); 1007 } 1008 } else { 1009 /* Body present */ 1010 lmatch(parse, lc_is); 1011 block = parse_block(parse); 1012 lmatch(parse, lc_end); 1013 1014 if (!body_expected) { 1015 cspan_print(prop->name->cspan); 1016 printf(" Error: Property '"); 1017 symbol_print_fqn(prop->symbol); 1018 printf("' setter declaration should " 1019 "not have a body.\n"); 1020 parse_note_error(parse); 1021 } 1022 } 1023 1024 1025 /* Create setter procedure */ 1026 setter = stree_proc_new(); 1027 setter->body = block; 1028 setter->outer_symbol = prop->symbol; 1029 1030 /* Store setter in property. */ 1031 prop->setter = setter; 804 1032 } 805 1033 -
uspace/app/sbi/src/program.c
r8f80c77 r1113c9e 85 85 * is read from '<libdir>/libflist'. Each line of the file contains one file 86 86 * name relative to <libdir>. 87 * 88 * @param program The program to which the parsed code is added. 89 * @return EOK on success, EIO if some file comprising the 90 * library is not found, EINVAL if the library 91 * has syntax errors. 87 92 */ 88 93 int program_lib_process(stree_program_t *program) … … 147 152 fclose(f); 148 153 149 return rc;154 return EOK; 150 155 } -
uspace/app/sbi/src/rdata.c
r8f80c77 r1113c9e 609 609 (void) src; (void) dest; 610 610 printf("Unimplemented: Copy object.\n"); 611 exit(1);611 abort(); 612 612 } 613 613 -
uspace/app/sbi/src/rdata_t.h
r8f80c77 r1113c9e 71 71 * 72 72 * A delegate variable points to a static or non-static symbol. If the 73 * symbol is non static, @c obj points to the object the symbol instance73 * symbol is non static, @c obj points to the object the symbol 74 74 * belongs to. 75 75 */ 76 76 typedef struct { 77 /** Object or @c NULL if deleg. points to a CSI or static member. */77 /** Object or @c NULL if deleg. points to a static function. */ 78 78 struct rdata_var *obj; 79 79 … … 107 107 /** Class of this object (symbol) */ 108 108 struct stree_symbol *class_sym; 109 110 /** @c sn_static if this is a static object (i.e. class object) */ 111 statns_t static_obj; 109 112 110 113 /** Map field name SID to field data */ -
uspace/app/sbi/src/run.c
r8f80c77 r1113c9e 99 99 stree_symbol_t *main_fun_sym; 100 100 stree_fun_t *main_fun; 101 rdata_var_t *main_obj; 101 102 stree_ident_t *fake_ident; 102 103 list_t main_args; … … 111 112 list_init(&run->thread_ar->proc_ar); 112 113 run->thread_ar->bo_mode = bm_none; 114 115 /* Initialize global data structure. */ 116 run_gdata_init(run); 113 117 114 118 /* … … 126 130 assert(main_fun != NULL); 127 131 132 main_obj = run_fun_sobject_find(run, main_fun); 133 128 134 #ifdef DEBUG_RUN_TRACE 129 135 printf("Found function '"); symbol_print_fqn(main_fun_sym); … … 133 139 /* Run function @c main. */ 134 140 list_init(&main_args); 135 run_proc_ar_create(run, NULL, main_fun->proc, &proc_ar);141 run_proc_ar_create(run, main_obj, main_fun->proc, &proc_ar); 136 142 run_proc_ar_set_args(run, proc_ar, &main_args); 137 143 run_proc(run, proc_ar, &res); 138 144 139 145 run_exc_check_unhandled(run); 146 } 147 148 /** Initialize global data. 149 * 150 * @param run Runner object 151 */ 152 void run_gdata_init(run_t *run) 153 { 154 rdata_object_t *gobject; 155 156 run->gdata = rdata_var_new(vc_object); 157 gobject = rdata_object_new(); 158 run->gdata->u.object_v = gobject; 159 160 gobject->class_sym = NULL; 161 gobject->static_obj = sn_static; 162 intmap_init(&gobject->fields); 140 163 } 141 164 … … 787 810 proc_ar = run_get_current_proc_ar(run); 788 811 return proc_ar->proc->outer_symbol->outer_csi; 812 } 813 814 /** Get static object (i.e. class object). 815 * 816 * Looks for a child static object named @a name in static object @a pobject. 817 * If the child does not exist yet, it is created. 818 * 819 * @param run Runner object 820 * @param csi CSI of the static object named @a name 821 * @param pobject Parent static object 822 * @param name Static object name 823 * 824 * @return Static (class) object of the given name 825 */ 826 rdata_var_t *run_sobject_get(run_t *run, stree_csi_t *csi, 827 rdata_var_t *pobj_var, sid_t name) 828 { 829 rdata_object_t *pobject; 830 rdata_var_t *mbr_var; 831 rdata_var_t *rvar; 832 stree_ident_t *ident; 833 834 assert(pobj_var->vc == vc_object); 835 pobject = pobj_var->u.object_v; 836 #ifdef DEBUG_RUN_TRACE 837 printf("Get static object '%s' in '", strtab_get_str(name)); 838 if (pobject->class_sym != NULL) 839 symbol_print_fqn(pobject->class_sym); 840 else 841 printf("global"); 842 #endif 843 844 assert(pobject->static_obj == sn_static); 845 846 mbr_var = intmap_get(&pobject->fields, name); 847 if (mbr_var != NULL) { 848 #ifdef DEBUG_RUN_TRACE 849 printf("Return exising static object (mbr_var=%p).\n", mbr_var); 850 #endif 851 /* Return existing object. */ 852 return mbr_var; 853 } 854 855 /* Construct new object. */ 856 #ifdef DEBUG_RUN_TRACE 857 printf("Construct new static object.\n"); 858 #endif 859 ident = stree_ident_new(); 860 ident->sid = name; 861 862 run_new_csi_inst(run, csi, sn_static, &rvar); 863 864 /* Store static object reference for future use. */ 865 intmap_set(&pobject->fields, name, rvar); 866 867 return rvar; 868 } 869 870 /** Get static object for CSI. 871 * 872 * In situations where we do not have the parent static object and need 873 * to find static object for a CSI from the gdata root we use this. 874 * 875 * This is only used in special cases such as when invoking the entry 876 * point. This is too slow to use during normal execution. 877 * 878 * @param run Runner object 879 * @param csi CSI to get static object of 880 * 881 * @return Static (class) object 882 */ 883 rdata_var_t *run_sobject_find(run_t *run, stree_csi_t *csi) 884 { 885 rdata_var_t *pobj_var; 886 887 if (csi == NULL) 888 return run->gdata; 889 890 assert(csi->ancr_state == ws_visited); 891 pobj_var = run_sobject_find(run, csi_to_symbol(csi)->outer_csi); 892 893 return run_sobject_get(run, csi, pobj_var, csi->name->sid); 894 } 895 896 /** Get static object for CSI containing function. 897 * 898 * This is used to obtain active object for invoking static function 899 * @a fun. Only used in cases where we don't already have the object such 900 * as when running the entry point. Otherwise this would be slow. 901 * 902 * @param run Runner object 903 * @param fun Function to get static class object of 904 * 905 * @return Static (class) object 906 */ 907 rdata_var_t *run_fun_sobject_find(run_t *run, stree_fun_t *fun) 908 { 909 return run_sobject_find(run, fun_to_symbol(fun)->outer_csi); 789 910 } 790 911 … … 1512 1633 1513 1634 /* Create exception object. */ 1514 run_new_csi_inst (run, csi, &exc_vi);1635 run_new_csi_inst_ref(run, csi, sn_nonstatic, &exc_vi); 1515 1636 assert(exc_vi->ic == ic_value); 1516 1637 -
uspace/app/sbi/src/run.h
r8f80c77 r1113c9e 33 33 34 34 void run_init(run_t *run); 35 void run_gdata_init(run_t *run); 35 36 void run_program(run_t *run, stree_program_t *prog); 36 37 void run_proc(run_t *run, run_proc_ar_t *proc_ar, rdata_item_t **res); … … 47 48 run_block_ar_t *run_get_current_block_ar(run_t *run); 48 49 stree_csi_t *run_get_current_csi(run_t *run); 50 51 rdata_var_t *run_sobject_get(run_t *run, stree_csi_t *pcsi, 52 rdata_var_t *pobj_var, sid_t name); 53 rdata_var_t *run_sobject_find(run_t *run, stree_csi_t *csi); 54 rdata_var_t *run_fun_sobject_find(run_t *run, stree_fun_t *fun); 49 55 50 56 void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var); -
uspace/app/sbi/src/run_expr.c
r8f80c77 r1113c9e 104 104 static void run_access_object(run_t *run, stree_access_t *access, 105 105 rdata_item_t *arg, rdata_item_t **res); 106 static void run_access_object_static(run_t *run, stree_access_t *access, 107 rdata_var_t *obj_var, rdata_item_t **res); 108 static void run_access_object_nonstatic(run_t *run, stree_access_t *access, 109 rdata_var_t *obj_var, rdata_item_t **res); 106 110 static void run_access_symbol(run_t *run, stree_access_t *access, 107 111 rdata_item_t *arg, rdata_item_t **res); … … 207 211 rdata_var_t *member_var; 208 212 213 rdata_var_t *psobj; 214 rdata_var_t *sobj; 215 rdata_object_t *aobj; 216 209 217 #ifdef DEBUG_RUN_TRACE 210 218 printf("Run nameref.\n"); … … 238 246 /* Determine currently active object or CSI. */ 239 247 proc_ar = run_get_current_proc_ar(run); 240 if (proc_ar->obj != NULL) { 241 assert(proc_ar->obj->vc == vc_object); 242 obj = proc_ar->obj->u.object_v; 243 csi_sym = obj->class_sym; 248 249 assert (proc_ar->obj != NULL); 250 assert(proc_ar->obj->vc == vc_object); 251 obj = proc_ar->obj->u.object_v; 252 csi_sym = obj->class_sym; 253 254 if (csi_sym != NULL) { 244 255 csi = symbol_to_csi(csi_sym); 245 256 assert(csi != NULL); 246 257 } else { 247 csi = proc_ar->proc->outer_symbol->outer_csi;248 obj= NULL;258 /* This happens in interactive mode. */ 259 csi = NULL; 249 260 } 250 261 … … 259 270 printf("Referencing CSI.\n"); 260 271 #endif 261 item = rdata_item_new(ic_value); 262 value = rdata_value_new(); 263 var = rdata_var_new(vc_deleg); 264 deleg_v = rdata_deleg_new(); 265 266 item->u.value = value; 267 value->var = var; 268 var->u.deleg_v = deleg_v; 269 270 deleg_v->obj = NULL; 271 deleg_v->sym = sym; 272 *res = item; 272 /* Obtain static object for the referenced CSI. */ 273 psobj = run->gdata; /* XXX */ 274 sobj = run_sobject_get(run, sym->u.csi, psobj, 275 nameref->name->sid); 276 277 /* Return reference to the object. */ 278 run_reference(run, sobj, res); 273 279 break; 274 280 case sc_ctor: … … 334 340 assert(csi != NULL); 335 341 336 /* XXX Assume variable is not static for now. */337 assert(obj != NULL);338 339 342 if (symbol_search_csi(run->program, csi, nameref->name) 340 == NULL ) {343 == NULL && !stree_symbol_is_static(sym)) { 341 344 /* Variable is not in the current object. */ 342 345 printf("Error: Cannot access non-static member " … … 349 352 } 350 353 354 if (stree_symbol_is_static(sym)) { 355 /* 356 * XXX This is too slow! 357 * 358 * However fixing this is non-trivial. We would 359 * have to have pointer to static object available 360 * for each object (therefore also for each object 361 * type). 362 */ 363 sobj = run_sobject_find(run, sym->outer_csi); 364 assert(sobj->vc == vc_object); 365 aobj = sobj->u.object_v; 366 } else { 367 aobj = obj; 368 } 369 351 370 /* Find member variable in object. */ 352 member_var = intmap_get(& obj->fields, nameref->name->sid);371 member_var = intmap_get(&aobj->fields, nameref->name->sid); 353 372 assert(member_var != NULL); 354 373 … … 1361 1380 1362 1381 /* Create CSI instance. */ 1363 run_new_csi_inst (run, csi, res);1382 run_new_csi_inst_ref(run, csi, sn_nonstatic, res); 1364 1383 1365 1384 /* Run the constructor. */ … … 1467 1486 } 1468 1487 1469 /** Evaluate delegate -member acccess.1488 /** Evaluate delegate member acccess. 1470 1489 * 1471 1490 * @param run Runner object … … 1477 1496 rdata_item_t *arg, rdata_item_t **res) 1478 1497 { 1479 rdata_item_t *arg_vi; 1480 rdata_value_t *arg_val; 1481 rdata_deleg_t *deleg_v; 1482 stree_symbol_t *member; 1483 1484 #ifdef DEBUG_RUN_TRACE 1485 printf("Run delegate access operation.\n"); 1486 #endif 1487 run_cvt_value_item(run, arg, &arg_vi); 1488 arg_val = arg_vi->u.value; 1489 assert(arg_val->var->vc == vc_deleg); 1490 1491 deleg_v = arg_val->var->u.deleg_v; 1492 if (deleg_v->obj != NULL || deleg_v->sym->sc != sc_csi) { 1493 printf("Error: Using '.' with delegate to different object " 1494 "than a CSI (%d).\n", deleg_v->sym->sc); 1495 exit(1); 1496 } 1497 1498 member = symbol_search_csi(run->program, deleg_v->sym->u.csi, 1499 access->member_name); 1500 1501 /* Member existence should be ensured by static type checking. */ 1502 assert(member != NULL); 1503 1504 #ifdef DEBUG_RUN_TRACE 1505 printf("Found member '%s'.\n", 1506 strtab_get_str(access->member_name->sid)); 1507 #endif 1508 1509 /* 1510 * Reuse existing item, value, var, deleg. 1511 * XXX This is maybe not a good idea because it complicates memory 1512 * management as there is not a single owner 1513 */ 1514 deleg_v->sym = member; 1515 *res = arg; 1498 (void) run; 1499 (void) access; 1500 (void) arg; 1501 (void) res; 1502 1503 printf("Error: Using '.' with delegate.\n"); 1504 exit(1); 1516 1505 } 1517 1506 … … 1526 1515 rdata_item_t *arg, rdata_item_t **res) 1527 1516 { 1517 rdata_var_t *obj_var; 1518 rdata_object_t *object; 1519 1520 #ifdef DEBUG_RUN_TRACE 1521 printf("Run object access operation.\n"); 1522 #endif 1523 assert(arg->ic == ic_address); 1524 assert(arg->u.address->ac == ac_var); 1525 1526 obj_var = arg->u.address->u.var_a->vref; 1527 assert(obj_var->vc == vc_object); 1528 1529 object = obj_var->u.object_v; 1530 1531 if (object->static_obj == sn_static) 1532 run_access_object_static(run, access, obj_var, res); 1533 else 1534 run_access_object_nonstatic(run, access, obj_var, res); 1535 } 1536 1537 /** Evaluate static object member acccess. 1538 * 1539 * @param run Runner object 1540 * @param access Access operation 1541 * @param arg Evaluated base expression 1542 * @param res Place to store result 1543 */ 1544 static void run_access_object_static(run_t *run, stree_access_t *access, 1545 rdata_var_t *obj_var, rdata_item_t **res) 1546 { 1547 rdata_object_t *object; 1528 1548 stree_symbol_t *member; 1529 rdata_var_t *object_var; 1530 rdata_object_t *object; 1549 stree_csi_t *member_csi; 1550 1551 rdata_deleg_t *deleg_v; 1531 1552 rdata_item_t *ritem; 1553 rdata_value_t *rvalue; 1554 rdata_var_t *rvar; 1532 1555 rdata_address_t *address; 1533 1556 rdata_addr_var_t *addr_var; … … 1535 1558 rdata_aprop_named_t *aprop_named; 1536 1559 rdata_deleg_t *deleg_p; 1537 1538 rdata_value_t *value; 1539 rdata_deleg_t *deleg_v; 1540 rdata_var_t *var; 1541 1542 #ifdef DEBUG_RUN_TRACE 1543 printf("Run object access operation.\n"); 1544 #endif 1545 assert(arg->ic == ic_address); 1546 assert(arg->u.address->ac == ac_var); 1547 assert(arg->u.address->u.var_a->vref->vc == vc_object); 1548 1549 object_var = arg->u.address->u.var_a->vref; 1550 object = object_var->u.object_v; 1560 rdata_var_t *mvar; 1561 1562 #ifdef DEBUG_RUN_TRACE 1563 printf("Run static object access operation.\n"); 1564 #endif 1565 assert(obj_var->vc == vc_object); 1566 object = obj_var->u.object_v; 1567 1568 assert(object->static_obj == sn_static); 1551 1569 1552 1570 member = symbol_search_csi(run->program, object->class_sym->u.csi, 1553 1571 access->member_name); 1554 1572 1555 if (member == NULL) { 1556 printf("Error: Object of class '"); 1557 symbol_print_fqn(object->class_sym); 1558 printf("' has no member named '%s'.\n", 1559 strtab_get_str(access->member_name->sid)); 1560 exit(1); 1561 } 1573 /* Member existence should be ensured by static type checking. */ 1574 assert(member != NULL); 1562 1575 1563 1576 #ifdef DEBUG_RUN_TRACE … … 1566 1579 #endif 1567 1580 1568 /* Make compiler happy. */1569 ritem = NULL;1570 1571 1581 switch (member->sc) { 1572 1582 case sc_csi: 1573 printf("Error: Accessing object member which is nested CSI.\n"); 1574 exit(1); 1583 /* Get child static object. */ 1584 member_csi = symbol_to_csi(member); 1585 assert(member_csi != NULL); 1586 1587 mvar = run_sobject_get(run, member_csi, obj_var, 1588 access->member_name->sid); 1589 1590 ritem = rdata_item_new(ic_address); 1591 address = rdata_address_new(ac_var); 1592 ritem->u.address = address; 1593 1594 addr_var = rdata_addr_var_new(); 1595 address->u.var_a = addr_var; 1596 addr_var->vref = mvar; 1597 1598 *res = ritem; 1599 break; 1600 case sc_ctor: 1601 /* It is not possible to reference a constructor explicitly. */ 1602 assert(b_false); 1575 1603 case sc_deleg: 1576 1604 printf("Error: Accessing object member which is a delegate.\n"); … … 1579 1607 printf("Error: Accessing object member which is an enum.\n"); 1580 1608 exit(1); 1581 case sc_ctor:1582 /* It is not possible to reference a constructor explicitly. */1583 assert(b_false);1584 1609 case sc_fun: 1585 1610 /* Construct anonymous delegate. */ 1586 1611 ritem = rdata_item_new(ic_value); 1587 value = rdata_value_new(); 1588 ritem->u.value = value; 1589 1590 var = rdata_var_new(vc_deleg); 1591 value->var = var; 1612 rvalue = rdata_value_new(); 1613 ritem->u.value = rvalue; 1614 1615 rvar = rdata_var_new(vc_deleg); 1616 rvalue->var = rvar; 1617 1592 1618 deleg_v = rdata_deleg_new(); 1593 var->u.deleg_v = deleg_v;1594 1595 deleg_v->obj = arg->u.address->u.var_a->vref;1619 rvar->u.deleg_v = deleg_v; 1620 1621 deleg_v->obj = obj_var; 1596 1622 deleg_v->sym = member; 1623 *res = ritem; 1597 1624 break; 1598 1625 case sc_var: 1599 /* Construct variable address item. */ 1626 /* Get static object member variable. */ 1627 mvar = intmap_get(&object->fields, access->member_name->sid); 1628 1600 1629 ritem = rdata_item_new(ic_address); 1601 1630 address = rdata_address_new(ac_var); 1631 ritem->u.address = address; 1632 1602 1633 addr_var = rdata_addr_var_new(); 1603 ritem->u.address = address;1604 1634 address->u.var_a = addr_var; 1605 1606 addr_var->vref = intmap_get(&object->fields, 1607 access->member_name->sid); 1608 assert(addr_var->vref != NULL); 1635 addr_var->vref = mvar; 1636 1637 *res = ritem; 1609 1638 break; 1610 1639 case sc_prop: … … 1619 1648 1620 1649 deleg_p = rdata_deleg_new(); 1621 deleg_p->obj = object_var; 1650 deleg_p->obj = obj_var; 1651 deleg_p->sym = member; 1652 addr_prop->u.named->prop_d = deleg_p; 1653 1654 *res = ritem; 1655 break; 1656 } 1657 } 1658 1659 /** Evaluate object member acccess. 1660 * 1661 * @param run Runner object 1662 * @param access Access operation 1663 * @param arg Evaluated base expression 1664 * @param res Place to store result 1665 */ 1666 static void run_access_object_nonstatic(run_t *run, stree_access_t *access, 1667 rdata_var_t *obj_var, rdata_item_t **res) 1668 { 1669 rdata_object_t *object; 1670 stree_symbol_t *member; 1671 rdata_item_t *ritem; 1672 rdata_address_t *address; 1673 rdata_addr_var_t *addr_var; 1674 rdata_addr_prop_t *addr_prop; 1675 rdata_aprop_named_t *aprop_named; 1676 rdata_deleg_t *deleg_p; 1677 1678 rdata_value_t *value; 1679 rdata_deleg_t *deleg_v; 1680 rdata_var_t *var; 1681 1682 #ifdef DEBUG_RUN_TRACE 1683 printf("Run nonstatic object access operation.\n"); 1684 #endif 1685 assert(obj_var->vc == vc_object); 1686 object = obj_var->u.object_v; 1687 1688 assert(object->static_obj == sn_nonstatic); 1689 1690 member = symbol_search_csi(run->program, object->class_sym->u.csi, 1691 access->member_name); 1692 1693 if (member == NULL) { 1694 printf("Error: Object of class '"); 1695 symbol_print_fqn(object->class_sym); 1696 printf("' has no member named '%s'.\n", 1697 strtab_get_str(access->member_name->sid)); 1698 exit(1); 1699 } 1700 1701 #ifdef DEBUG_RUN_TRACE 1702 printf("Found member '%s'.\n", 1703 strtab_get_str(access->member_name->sid)); 1704 #endif 1705 1706 /* Make compiler happy. */ 1707 ritem = NULL; 1708 1709 switch (member->sc) { 1710 case sc_csi: 1711 printf("Error: Accessing object member which is nested CSI.\n"); 1712 exit(1); 1713 case sc_ctor: 1714 /* It is not possible to reference a constructor explicitly. */ 1715 assert(b_false); 1716 case sc_deleg: 1717 printf("Error: Accessing object member which is a delegate.\n"); 1718 exit(1); 1719 case sc_enum: 1720 printf("Error: Accessing object member which is an enum.\n"); 1721 exit(1); 1722 case sc_fun: 1723 /* Construct anonymous delegate. */ 1724 ritem = rdata_item_new(ic_value); 1725 value = rdata_value_new(); 1726 ritem->u.value = value; 1727 1728 var = rdata_var_new(vc_deleg); 1729 value->var = var; 1730 deleg_v = rdata_deleg_new(); 1731 var->u.deleg_v = deleg_v; 1732 1733 deleg_v->obj = obj_var; 1734 deleg_v->sym = member; 1735 break; 1736 case sc_var: 1737 /* Construct variable address item. */ 1738 ritem = rdata_item_new(ic_address); 1739 address = rdata_address_new(ac_var); 1740 addr_var = rdata_addr_var_new(); 1741 ritem->u.address = address; 1742 address->u.var_a = addr_var; 1743 1744 addr_var->vref = intmap_get(&object->fields, 1745 access->member_name->sid); 1746 assert(addr_var->vref != NULL); 1747 break; 1748 case sc_prop: 1749 /* Construct named property address. */ 1750 ritem = rdata_item_new(ic_address); 1751 address = rdata_address_new(ac_prop); 1752 addr_prop = rdata_addr_prop_new(apc_named); 1753 aprop_named = rdata_aprop_named_new(); 1754 ritem->u.address = address; 1755 address->u.prop_a = addr_prop; 1756 addr_prop->u.named = aprop_named; 1757 1758 deleg_p = rdata_deleg_new(); 1759 deleg_p->obj = obj_var; 1622 1760 deleg_p->sym = member; 1623 1761 addr_prop->u.named->prop_d = deleg_p; … … 2168 2306 rdata_item_t *rdest_i, *rsrc_i; 2169 2307 rdata_item_t *rsrc_vi; 2170 rdata_value_t *src_val;2171 2308 2172 2309 #ifdef DEBUG_RUN_TRACE … … 2187 2324 run_cvt_value_item(run, rsrc_i, &rsrc_vi); 2188 2325 assert(rsrc_vi->ic == ic_value); 2189 src_val = rsrc_vi->u.value;2190 2326 2191 2327 if (rdest_i->ic != ic_address) { … … 2331 2467 2332 2468 /* Construct object of the relevant boxed type. */ 2333 run_new_csi_inst (run, csi, res);2469 run_new_csi_inst_ref(run, csi, sn_nonstatic, res); 2334 2470 2335 2471 /* Set the 'Value' field */ … … 2348 2484 } 2349 2485 2350 /** Create new CSI instance .2486 /** Create new CSI instance and return reference to it. 2351 2487 * 2352 2488 * Create a new object, instance of @a csi. … … 2357 2493 * run any constructor. 2358 2494 * 2359 * @param run Runner object 2360 * @param as_op @c as conversion expression 2361 * @param res Place to store result 2362 */ 2363 void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res) 2495 * If @a sn is @c sn_nonstatic a regular object is created, containing all 2496 * non-static member variables. If @a sn is @c sn_static a static object 2497 * is created, containing all static member variables. 2498 * 2499 * @param run Runner object 2500 * @param csi CSI to create instance of 2501 * @param sn @c sn_static to create a static (class) object, 2502 * @c sn_nonstatic to create a regular object 2503 * @param res Place to store result 2504 */ 2505 void run_new_csi_inst_ref(run_t *run, stree_csi_t *csi, statns_t sn, 2506 rdata_item_t **res) 2507 { 2508 rdata_var_t *obj_var; 2509 2510 /* Create object. */ 2511 run_new_csi_inst(run, csi, sn, &obj_var); 2512 2513 /* Create reference to the new object. */ 2514 run_reference(run, obj_var, res); 2515 } 2516 2517 /** Create new CSI instance. 2518 * 2519 * Create a new object, instance of @a csi. 2520 * XXX This does not work with generics as @a csi cannot specify a generic 2521 * type. 2522 * 2523 * Initialize the fields with default values of their types, but do not 2524 * run any constructor. 2525 * 2526 * If @a sn is @c sn_nonstatic a regular object is created, containing all 2527 * non-static member variables. If @a sn is @c sn_static a static object 2528 * is created, containing all static member variables. 2529 * 2530 * @param run Runner object 2531 * @param csi CSI to create instance of 2532 * @param sn @c sn_static to create a static (class) object, 2533 * @c sn_nonstatic to create a regular object 2534 * @param res Place to store result 2535 */ 2536 void run_new_csi_inst(run_t *run, stree_csi_t *csi, statns_t sn, 2537 rdata_var_t **res) 2364 2538 { 2365 2539 rdata_object_t *obj; … … 2368 2542 stree_symbol_t *csi_sym; 2369 2543 stree_csimbr_t *csimbr; 2544 stree_var_t *var; 2545 statns_t var_sn; 2370 2546 2371 2547 rdata_var_t *mbr_var; … … 2384 2560 obj = rdata_object_new(); 2385 2561 obj->class_sym = csi_sym; 2562 obj->static_obj = sn; 2386 2563 intmap_init(&obj->fields); 2387 2564 … … 2389 2566 obj_var->u.object_v = obj; 2390 2567 2391 /* Create object fields.*/2568 /* For this CSI and all base CSIs */ 2392 2569 while (csi != NULL) { 2570 2571 /* For all members */ 2393 2572 node = list_first(&csi->members); 2394 2573 while (node != NULL) { 2395 2574 csimbr = list_node_data(node, stree_csimbr_t *); 2575 2576 /* Is it a member variable? */ 2396 2577 if (csimbr->cc == csimbr_var) { 2397 /* Compute field type. XXX Memoize. */ 2398 run_texpr(run->program, csi, 2399 csimbr->u.var->type, 2400 &field_ti); 2401 2402 /* Create and initialize field. */ 2403 run_var_new(run, field_ti, &mbr_var); 2404 2405 /* Add to field map. */ 2406 intmap_set(&obj->fields, 2407 csimbr->u.var->name->sid, 2408 mbr_var); 2578 var = csimbr->u.var; 2579 2580 /* Is it static/nonstatic? */ 2581 var_sn = stree_symbol_has_attr( 2582 var_to_symbol(var), sac_static); 2583 if (var_sn == sn) { 2584 /* Compute field type. XXX Memoize. */ 2585 run_texpr(run->program, csi, var->type, 2586 &field_ti); 2587 2588 /* Create and initialize field. */ 2589 run_var_new(run, field_ti, &mbr_var); 2590 2591 /* Add to field map. */ 2592 intmap_set(&obj->fields, var->name->sid, 2593 mbr_var); 2594 } 2409 2595 } 2410 2596 … … 2416 2602 } 2417 2603 2418 /* Create reference to the new object. */ 2419 run_reference(run, obj_var, res); 2604 *res = obj_var; 2420 2605 } 2421 2606 -
uspace/app/sbi/src/run_expr.h
r8f80c77 r1113c9e 34 34 void run_expr(run_t *run, stree_expr_t *expr, rdata_item_t **res); 35 35 36 void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res); 36 void run_new_csi_inst_ref(run_t *run, stree_csi_t *csi, statns_t sn, 37 rdata_item_t **res); 38 void run_new_csi_inst(run_t *run, stree_csi_t *csi, statns_t sn, 39 rdata_var_t **res); 40 37 41 bool_t run_item_boolean_value(run_t *run, rdata_item_t *item); 38 42 -
uspace/app/sbi/src/run_t.h
r8f80c77 r1113c9e 114 114 /** Thread-private state */ 115 115 run_thread_ar_t *thread_ar; 116 117 /** Global state */ 118 struct rdata_var *gdata; 116 119 } run_t; 117 120 -
uspace/app/sbi/src/run_texpr.c
r8f80c77 r1113c9e 140 140 } 141 141 142 /* Make compiler happy. */ 143 titem = NULL; 144 142 145 switch (sym->sc) { 143 146 case sc_csi: … … 147 150 titem->u.tobject = tobject; 148 151 149 tobject->static_ref = b_false;152 tobject->static_ref = sn_nonstatic; 150 153 tobject->csi = sym->u.csi; 151 154 list_init(&tobject->targs); … … 278 281 (void) tliteral; 279 282 283 /* Make compiler happy. */ 284 tpc = 0; 285 280 286 switch (tliteral->tlc) { 281 287 case tlc_bool: tpc = tpc_bool; break; … … 342 348 } 343 349 350 /* Make compiler happy. */ 351 titem = NULL; 352 344 353 switch (sym->sc) { 345 354 case sc_csi: … … 349 358 titem->u.tobject = tobject; 350 359 351 tobject->static_ref = b_false;360 tobject->static_ref = sn_nonstatic; 352 361 tobject->csi = sym->u.csi; 353 362 list_init(&tobject->targs); … … 429 438 430 439 list_node_t *farg_n; 431 stree_targ_t *farg;432 440 433 441 #ifdef DEBUG_RUN_TRACE … … 450 458 } 451 459 452 tobject->static_ref = b_false;460 tobject->static_ref = sn_nonstatic; 453 461 tobject->csi = base_ti->u.tobject->csi; 454 462 list_init(&tobject->targs); … … 458 466 arg_n = list_first(&tapply->targs); 459 467 while (farg_n != NULL && arg_n != NULL) { 460 farg = list_node_data(farg_n, stree_targ_t *);461 468 arg = list_node_data(arg_n, stree_texpr_t *); 462 469 -
uspace/app/sbi/src/stree.c
r8f80c77 r1113c9e 92 92 csi->ancr_state = ws_unvisited; 93 93 csi->name = NULL; 94 csi->base_csi_ref = NULL; 94 csi->base_csi = NULL; 95 list_init(&csi->inherit); 96 list_init(&csi->impl_if_ti); 95 97 list_init(&csi->members); 98 96 99 return csi; 97 100 } … … 930 933 931 934 symbol->sc = sc; 935 list_init(&symbol->attr); 936 932 937 return symbol; 933 938 } … … 1018 1023 1019 1024 /* We went all the way to the root and did not find b. */ 1025 return b_false; 1026 } 1027 1028 /** Determine if @a symbol is static. 1029 * 1030 * @param symbol Symbol 1031 * @return @c b_true if symbol is static, @c b_false otherwise 1032 */ 1033 bool_t stree_symbol_is_static(stree_symbol_t *symbol) 1034 { 1035 /* Module-wide symbols are static. */ 1036 if (symbol->outer_csi == NULL) 1037 return b_true; 1038 1039 /* Symbols with @c static attribute are static. */ 1040 if (stree_symbol_has_attr(symbol, sac_static)) 1041 return b_true; 1042 1043 switch (symbol->sc) { 1044 case sc_csi: 1045 case sc_deleg: 1046 case sc_enum: 1047 return b_true; 1048 case sc_ctor: 1049 case sc_fun: 1050 case sc_var: 1051 case sc_prop: 1052 break; 1053 } 1054 1020 1055 return b_false; 1021 1056 } -
uspace/app/sbi/src/stree.h
r8f80c77 r1113c9e 96 96 bool_t stree_arg_has_attr(stree_proc_arg_t *arg, arg_attr_class_t aac); 97 97 bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b); 98 bool_t stree_symbol_is_static(stree_symbol_t *symbol); 98 99 stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident); 99 100 stree_embr_t *stree_enum_find_mbr(stree_enum_t *enum_d, stree_ident_t *ident); -
uspace/app/sbi/src/stree_t.h
r8f80c77 r1113c9e 639 639 /** Variadic argument or @c NULL if none. */ 640 640 stree_proc_arg_t *varg; 641 642 /** Type of the property */ 643 struct tdata_item *titem; 641 644 } stree_prop_t; 642 645 … … 698 701 struct stree_symbol *symbol; 699 702 700 /** Type expression referencing base CSI. */701 stree_texpr_t *base_csi_ref;703 /** Type expressions referencing inherited CSIs. */ 704 list_t inherit; /* of stree_texpr_t */ 702 705 703 706 /** Base CSI. Only available when ancr_state == ws_visited. */ 704 707 struct stree_csi *base_csi; 708 709 /** Types of implemented or accumulated interfaces. */ 710 list_t impl_if_ti; /* of tdata_item_t */ 705 711 706 712 /** Node state for ancr walks. */ … … 736 742 typedef enum { 737 743 /** Builtin symbol (interpreter hook) */ 738 sac_builtin 744 sac_builtin, 745 746 /** Static symbol */ 747 sac_static 739 748 } symbol_attr_class_t; 740 749 -
uspace/app/sbi/src/stype.c
r8f80c77 r1113c9e 63 63 static void stype_fun_body(stype_t *stype, stree_fun_t *fun); 64 64 static void stype_block(stype_t *stype, stree_block_t *block); 65 66 static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi); 67 static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi, 68 tdata_item_t *iface_ti); 69 static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi, 70 tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr); 71 static void stype_class_impl_check_fun(stype_t *stype, 72 stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym); 73 static void stype_class_impl_check_prop(stype_t *stype, 74 stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym); 65 75 66 76 static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s); … … 90 100 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr, 91 101 tdata_item_t *dest); 92 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,93 tdata_item_t *dest);94 102 95 103 static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig, … … 168 176 } 169 177 178 if (csi->cc == csi_class) 179 stype_class_impl_check(stype, csi); 180 170 181 stype->current_csi = prev_ctx; 171 182 } … … 310 321 311 322 enum_d->titem = titem; 312 } else {313 titem = enum_d->titem;314 323 } 315 324 } … … 453 462 assert(stype->proc_vr == NULL); 454 463 455 /* Builtin functions do not have a body. */464 /* Declarations and builtin functions do not have a body. */ 456 465 if (fun->proc->body == NULL) 457 466 return; … … 475 484 { 476 485 tdata_item_t *titem; 477 478 (void) stype;479 (void) var;480 486 481 487 run_texpr(stype->program, stype->current_csi, var->type, … … 484 490 /* An error occured. */ 485 491 stype_note_error(stype); 486 return;487 492 } 488 493 } … … 500 505 printf("'.\n"); 501 506 #endif 507 if (prop->titem == NULL) 508 stype_prop_header(stype, prop); 509 502 510 stype->proc_vr = stype_proc_vr_new(); 503 511 list_init(&stype->proc_vr->block_vr); 504 512 505 if (prop->getter != NULL) { 513 /* Property declarations do not have a getter body. */ 514 if (prop->getter != NULL && prop->getter->body != NULL) { 506 515 stype->proc_vr->proc = prop->getter; 507 516 stype_block(stype, prop->getter->body); 508 517 } 509 518 510 if (prop->setter != NULL) { 519 /* Property declarations do not have a setter body. */ 520 if (prop->setter != NULL && prop->setter->body != NULL) { 511 521 stype->proc_vr->proc = prop->setter; 512 522 stype_block(stype, prop->setter->body); … … 515 525 free(stype->proc_vr); 516 526 stype->proc_vr = NULL; 527 } 528 529 /** Type property header. 530 * 531 * @param stype Static typing object 532 * @param prop Property 533 */ 534 void stype_prop_header(stype_t *stype, stree_prop_t *prop) 535 { 536 tdata_item_t *titem; 537 538 #ifdef DEBUG_TYPE_TRACE 539 printf("Type property '"); 540 symbol_print_fqn(prop_to_symbol(prop)); 541 printf("' header.\n"); 542 #endif 543 run_texpr(stype->program, stype->current_csi, prop->type, 544 &titem); 545 if (titem->tic == tic_ignore) { 546 /* An error occured. */ 547 stype_note_error(stype); 548 return; 549 } 550 551 prop->titem = titem; 517 552 } 518 553 … … 552 587 assert(list_node_data(bvr_n, stype_block_vr_t *) == block_vr); 553 588 list_remove(&stype->proc_vr->block_vr, bvr_n); 589 } 590 591 /** Verify that class fully implements all interfaces as it claims. 592 * 593 * @param stype Static typing object 594 * @param csi CSI to check 595 */ 596 static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi) 597 { 598 list_node_t *pred_n; 599 stree_texpr_t *pred_te; 600 tdata_item_t *pred_ti; 601 602 #ifdef DEBUG_TYPE_TRACE 603 printf("Verify that class implements all interfaces.\n"); 604 #endif 605 assert(csi->cc == csi_class); 606 607 pred_n = list_first(&csi->inherit); 608 while (pred_n != NULL) { 609 pred_te = list_node_data(pred_n, stree_texpr_t *); 610 run_texpr(stype->program, csi, pred_te, &pred_ti); 611 612 assert(pred_ti->tic == tic_tobject); 613 switch (pred_ti->u.tobject->csi->cc) { 614 case csi_class: 615 break; 616 case csi_struct: 617 assert(b_false); 618 case csi_interface: 619 /* Store to impl_if_ti for later use. */ 620 list_append(&csi->impl_if_ti, pred_ti); 621 622 /* Check implementation of this interface. */ 623 stype_class_impl_check_if(stype, csi, pred_ti); 624 break; 625 } 626 627 pred_n = list_next(&csi->inherit, pred_n); 628 } 629 } 630 631 /** Verify that class fully implements an interface. 632 * 633 * @param stype Static typing object 634 * @param csi CSI to check 635 * @param iface Interface that must be fully implemented 636 */ 637 static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi, 638 tdata_item_t *iface_ti) 639 { 640 tdata_tvv_t *iface_tvv; 641 list_node_t *pred_n; 642 tdata_item_t *pred_ti; 643 tdata_item_t *pred_sti; 644 645 stree_csi_t *iface; 646 list_node_t *ifmbr_n; 647 stree_csimbr_t *ifmbr; 648 649 assert(csi->cc == csi_class); 650 651 assert(iface_ti->tic == tic_tobject); 652 iface = iface_ti->u.tobject->csi; 653 assert(iface->cc = csi_interface); 654 655 #ifdef DEBUG_TYPE_TRACE 656 printf("Verify that class fully implements interface.\n"); 657 #endif 658 /* Compute TVV for this interface reference. */ 659 stype_titem_to_tvv(stype, iface_ti, &iface_tvv); 660 661 /* 662 * Recurse to accumulated interfaces. 663 */ 664 pred_n = list_first(&iface->impl_if_ti); 665 while (pred_n != NULL) { 666 pred_ti = list_node_data(pred_n, tdata_item_t *); 667 assert(pred_ti->tic == tic_tobject); 668 assert(pred_ti->u.tobject->csi->cc == csi_interface); 669 670 /* Substitute real type parameters to predecessor reference. */ 671 tdata_item_subst(pred_ti, iface_tvv, &pred_sti); 672 673 /* Check accumulated interface. */ 674 stype_class_impl_check_if(stype, csi, pred_sti); 675 676 pred_n = list_next(&iface->impl_if_ti, pred_n); 677 } 678 679 /* 680 * Check all interface members. 681 */ 682 ifmbr_n = list_first(&iface->members); 683 while (ifmbr_n != NULL) { 684 ifmbr = list_node_data(ifmbr_n, stree_csimbr_t *); 685 stype_class_impl_check_mbr(stype, csi, iface_tvv, ifmbr); 686 687 ifmbr_n = list_next(&iface->members, ifmbr_n); 688 } 689 } 690 691 /** Verify that class fully implements an interface member. 692 * 693 * @param stype Static typing object 694 * @param csi CSI to check 695 * @param if_tvv TVV for @a ifmbr 696 * @param ifmbr Interface that must be fully implemented 697 */ 698 static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi, 699 tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr) 700 { 701 stree_symbol_t *cmbr_sym; 702 stree_symbol_t *ifmbr_sym; 703 stree_ident_t *ifmbr_name; 704 705 assert(csi->cc == csi_class); 706 707 #ifdef DEBUG_TYPE_TRACE 708 printf("Verify that class implements interface member.\n"); 709 #endif 710 ifmbr_name = stree_csimbr_get_name(ifmbr); 711 712 cmbr_sym = symbol_search_csi(stype->program, csi, ifmbr_name); 713 if (cmbr_sym == NULL) { 714 printf("Error: CSI '"); 715 symbol_print_fqn(csi_to_symbol(csi)); 716 printf("' should implement '"); 717 symbol_print_fqn(csimbr_to_symbol(ifmbr)); 718 printf("' but it does not.\n"); 719 stype_note_error(stype); 720 return; 721 } 722 723 ifmbr_sym = csimbr_to_symbol(ifmbr); 724 if (cmbr_sym->sc != ifmbr_sym->sc) { 725 printf("Error: CSI '"); 726 symbol_print_fqn(csi_to_symbol(csi)); 727 printf("' implements '"); 728 symbol_print_fqn(csimbr_to_symbol(ifmbr)); 729 printf("' as a different kind of symbol.\n"); 730 stype_note_error(stype); 731 } 732 733 switch (cmbr_sym->sc) { 734 case sc_csi: 735 case sc_ctor: 736 case sc_deleg: 737 case sc_enum: 738 /* 739 * Checked at parse time. Interface should not have these 740 * member types. 741 */ 742 assert(b_false); 743 case sc_fun: 744 stype_class_impl_check_fun(stype, cmbr_sym, if_tvv, ifmbr_sym); 745 break; 746 case sc_var: 747 /* 748 * Checked at parse time. Interface should not have these 749 * member types. 750 */ 751 assert(b_false); 752 case sc_prop: 753 stype_class_impl_check_prop(stype, cmbr_sym, if_tvv, ifmbr_sym); 754 break; 755 } 756 } 757 758 /** Verify that class properly implements a function from an interface. 759 * 760 * @param stype Static typing object 761 * @param cfun_sym Function symbol in class 762 * @param if_tvv TVV for @a ifun_sym 763 * @param ifun_sym Function declaration symbol in interface 764 */ 765 static void stype_class_impl_check_fun(stype_t *stype, 766 stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym) 767 { 768 stree_fun_t *cfun; 769 tdata_fun_t *tcfun; 770 stree_fun_t *ifun; 771 tdata_item_t *sifun_ti; 772 tdata_fun_t *tifun; 773 774 #ifdef DEBUG_TYPE_TRACE 775 printf("Verify that class '"); 776 symbol_print_fqn(csi_to_symbol(cfun_sym->outer_csi)); 777 printf("' implements function '"); 778 symbol_print_fqn(ifun_sym); 779 printf("' properly.\n"); 780 #endif 781 assert(cfun_sym->sc == sc_fun); 782 cfun = cfun_sym->u.fun; 783 784 assert(ifun_sym->sc == sc_fun); 785 ifun = ifun_sym->u.fun; 786 787 assert(cfun->titem->tic == tic_tfun); 788 tcfun = cfun->titem->u.tfun; 789 790 tdata_item_subst(ifun->titem, if_tvv, &sifun_ti); 791 assert(sifun_ti->tic == tic_tfun); 792 tifun = sifun_ti->u.tfun; 793 794 if (!stype_fun_sig_equal(stype, tcfun->tsig, tifun->tsig)) { 795 cspan_print(cfun->name->cspan); 796 printf(" Error: Type of function '"); 797 symbol_print_fqn(cfun_sym); 798 printf("' ("); 799 tdata_item_print(cfun->titem); 800 printf(") does not match type of '"); 801 symbol_print_fqn(ifun_sym); 802 printf("' ("); 803 tdata_item_print(sifun_ti); 804 printf(") which it should implement.\n"); 805 stype_note_error(stype); 806 } 807 } 808 809 /** Verify that class properly implements a function from an interface. 810 * 811 * @param stype Static typing object 812 * @param cprop_sym Property symbol in class 813 * @param if_tvv TVV for @a ifun_sym 814 * @param iprop_sym Property declaration symbol in interface 815 */ 816 static void stype_class_impl_check_prop(stype_t *stype, 817 stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym) 818 { 819 stree_prop_t *cprop; 820 stree_prop_t *iprop; 821 tdata_item_t *siprop_ti; 822 823 #ifdef DEBUG_TYPE_TRACE 824 printf("Verify that class '"); 825 symbol_print_fqn(csi_to_symbol(cprop_sym->outer_csi)); 826 printf("' implements property '"); 827 symbol_print_fqn(iprop_sym); 828 printf("' properly.\n"); 829 #endif 830 assert(cprop_sym->sc == sc_prop); 831 cprop = cprop_sym->u.prop; 832 833 assert(iprop_sym->sc == sc_prop); 834 iprop = iprop_sym->u.prop; 835 836 tdata_item_subst(iprop->titem, if_tvv, &siprop_ti); 837 838 if (!tdata_item_equal(cprop->titem, siprop_ti)) { 839 cspan_print(cprop->name->cspan); 840 printf(" Error: Type of property '"); 841 symbol_print_fqn(cprop_sym); 842 printf("' ("); 843 tdata_item_print(cprop->titem); 844 printf(") does not match type of '"); 845 symbol_print_fqn(iprop_sym); 846 printf("' ("); 847 tdata_item_print(siprop_ti); 848 printf(") which it should implement.\n"); 849 stype_note_error(stype); 850 } 851 852 if (iprop->getter != NULL && cprop->getter == NULL) { 853 cspan_print(cprop->name->cspan); 854 printf(" Error: Property '"); 855 symbol_print_fqn(cprop_sym); 856 printf("' is missing a getter, which is required by '"); 857 symbol_print_fqn(iprop_sym); 858 printf("'.\n"); 859 stype_note_error(stype); 860 } 861 862 if (iprop->setter != NULL && cprop->setter == NULL) { 863 cspan_print(cprop->name->cspan); 864 printf(" Error: Property '"); 865 symbol_print_fqn(cprop_sym); 866 printf("' is missing a setter, which is required by '"); 867 symbol_print_fqn(iprop_sym); 868 printf("'.\n"); 869 stype_note_error(stype); 870 } 554 871 } 555 872 … … 824 1141 stype_expr(stype, exp_s->expr); 825 1142 826 if (want_value == b_false && exp_s->expr->titem != NULL) 827 printf("Warning: Expression value ignored.\n"); 1143 if (want_value == b_false && exp_s->expr->titem != NULL) { 1144 cspan_print(exp_s->expr->cspan); 1145 printf(" Warning: Expression value ignored.\n"); 1146 } 828 1147 } 829 1148 … … 925 1244 926 1245 if (src->tic == tic_tebase) { 927 stype_convert_failure(stype, expr, dest);1246 stype_convert_failure(stype, convc_implicit, expr, dest); 928 1247 printf("Invalid use of reference to enum type in " 929 1248 "expression.\n"); … … 932 1251 933 1252 if (src->tic != dest->tic) { 934 stype_convert_failure(stype, expr, dest);1253 stype_convert_failure(stype, convc_implicit, expr, dest); 935 1254 return expr; 936 1255 } … … 987 1306 /* Check if both have the same tprimitive class. */ 988 1307 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc) 989 stype_convert_failure(stype, expr, dest);1308 stype_convert_failure(stype, convc_implicit, expr, dest); 990 1309 991 1310 return expr; … … 1020 1339 bi = stype->program->builtin; 1021 1340 csi_sym = csi_to_symbol(dest->u.tobject->csi); 1341 1342 /* Make compiler happy. */ 1343 bp_sym = NULL; 1022 1344 1023 1345 switch (src->u.tprimitive->tpc) { … … 1028 1350 case tpc_string: bp_sym = bi->boxed_string; break; 1029 1351 case tpc_resource: 1030 stype_convert_failure(stype, expr, dest);1352 stype_convert_failure(stype, convc_implicit, expr, dest); 1031 1353 return expr; 1032 1354 } … … 1034 1356 /* Target type must be boxed @a src or Object */ 1035 1357 if (csi_sym != bp_sym && csi_sym != bi->gf_class) 1036 stype_convert_failure(stype, expr, dest);1358 stype_convert_failure(stype, convc_implicit, expr, dest); 1037 1359 1038 1360 /* Patch the code to box the primitive value */ … … 1058 1380 { 1059 1381 tdata_item_t *src; 1060 tdata_item_t *cur; 1061 stree_csi_t *cur_csi; 1062 tdata_tvv_t *tvv; 1063 tdata_item_t *b_ti, *bs_ti; 1382 tdata_item_t *pred_ti; 1064 1383 1065 1384 #ifdef DEBUG_TYPE_TRACE 1066 1385 printf("Convert object type.\n"); 1067 1386 #endif 1068 list_node_t *ca_n, *da_n;1069 tdata_item_t *carg, *darg;1070 1071 1387 src = expr->titem; 1072 1388 assert(src->tic == tic_tobject); 1073 1389 assert(dest->tic == tic_tobject); 1074 1390 1075 cur = src; 1076 1077 while (cur->u.tobject->csi != dest->u.tobject->csi) { 1078 1079 cur_csi = cur->u.tobject->csi; 1080 stype_titem_to_tvv(stype, cur, &tvv); 1081 1082 if (cur_csi->base_csi_ref != NULL) { 1083 run_texpr(stype->program, cur_csi, cur_csi->base_csi_ref, &b_ti); 1084 if (b_ti->tic == tic_ignore) { 1085 /* An error occured. */ 1086 stype_note_error(stype); 1087 return expr; 1088 } 1089 1090 tdata_item_subst(b_ti, tvv, &bs_ti); 1091 cur = bs_ti; 1092 assert(cur->tic == tic_tobject); 1093 1094 } else if (cur_csi->base_csi != NULL) { 1095 /* No explicit reference. Use grandfather class. */ 1096 cur = tdata_item_new(tic_tobject); 1097 cur->u.tobject = tdata_object_new(); 1098 cur->u.tobject->csi = cur_csi->base_csi; 1099 cur->u.tobject->static_ref = b_false; 1100 1101 list_init(&cur->u.tobject->targs); 1102 } else { 1103 /* No match */ 1104 stype_convert_failure(stype, expr, dest); 1105 return expr; 1106 } 1107 } 1108 1109 /* Verify that type arguments match */ 1110 ca_n = list_first(&cur->u.tobject->targs); 1111 da_n = list_first(&dest->u.tobject->targs); 1112 1113 while (ca_n != NULL && da_n != NULL) { 1114 carg = list_node_data(ca_n, tdata_item_t *); 1115 darg = list_node_data(da_n, tdata_item_t *); 1116 1117 if (tdata_item_equal(carg, darg) != b_true) { 1118 /* Diferent argument type */ 1119 stype_convert_failure(stype, expr, dest); 1120 printf("Different argument type '"); 1121 tdata_item_print(carg); 1122 printf("' vs. '"); 1123 tdata_item_print(darg); 1124 printf("'.\n"); 1125 return expr; 1126 } 1127 1128 ca_n = list_next(&cur->u.tobject->targs, ca_n); 1129 da_n = list_next(&dest->u.tobject->targs, da_n); 1130 } 1131 1132 if (ca_n != NULL || da_n != NULL) { 1133 /* Diferent number of arguments */ 1134 stype_convert_failure(stype, expr, dest); 1135 printf("Different number of arguments.\n"); 1391 /* 1392 * Find predecessor of the right type. This determines the 1393 * type arguments that the destination type should have. 1394 */ 1395 pred_ti = stype_tobject_find_pred(stype, src, dest); 1396 if (pred_ti == NULL) { 1397 stype_convert_failure(stype, convc_implicit, expr, dest); 1398 printf("Not a base class or implemented or accumulated " 1399 "interface.\n"); 1400 return expr; 1401 } 1402 1403 /* 1404 * Verify that type arguments match with those specified for 1405 * conversion destination. 1406 */ 1407 if (stype_targs_check_equal(stype, pred_ti, dest) != EOK) { 1408 stype_convert_failure(stype, convc_implicit, expr, dest); 1136 1409 return expr; 1137 1410 } … … 1160 1433 /* Compare rank and base type. */ 1161 1434 if (src->u.tarray->rank != dest->u.tarray->rank) { 1162 stype_convert_failure(stype, expr, dest);1435 stype_convert_failure(stype, convc_implicit, expr, dest); 1163 1436 return expr; 1164 1437 } … … 1167 1440 if (tdata_item_equal(src->u.tarray->base_ti, 1168 1441 dest->u.tarray->base_ti) != b_true) { 1169 stype_convert_failure(stype, expr, dest);1442 stype_convert_failure(stype, convc_implicit, expr, dest); 1170 1443 } 1171 1444 … … 1205 1478 /* Both must be the same delegate. */ 1206 1479 if (sdeleg->deleg != ddeleg->deleg) { 1207 stype_convert_failure(stype, expr, dest);1480 stype_convert_failure(stype, convc_implicit, expr, dest); 1208 1481 return expr; 1209 1482 } … … 1240 1513 /* Both must be of the same enum type (with the same declaration). */ 1241 1514 if (senum->enum_d != denum->enum_d) { 1242 stype_convert_failure(stype, expr, dest);1515 stype_convert_failure(stype, convc_implicit, expr, dest); 1243 1516 return expr; 1244 1517 } … … 1279 1552 1280 1553 if (!stype_fun_sig_equal(stype, ssig, dsig)) { 1281 stype_convert_failure(stype, expr, dest);1554 stype_convert_failure(stype, convc_implicit, expr, dest); 1282 1555 return expr; 1283 1556 } … … 1311 1584 /* Currently only allow if both types are the same. */ 1312 1585 if (src->u.tvref->targ != dest->u.tvref->targ) { 1313 stype_convert_failure(stype, expr, dest);1586 stype_convert_failure(stype, convc_implicit, expr, dest); 1314 1587 return expr; 1315 1588 } … … 1324 1597 * @param dest Destination type 1325 1598 */ 1326 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,1327 tdata_item_t *dest)1599 void stype_convert_failure(stype_t *stype, stype_conv_class_t convc, 1600 stree_expr_t *expr, tdata_item_t *dest) 1328 1601 { 1329 1602 cspan_print(expr->cspan); 1330 printf(" Error: Cannot convert "); 1603 printf(" Error: "); 1604 switch (convc) { 1605 case convc_implicit: printf("Cannot implicitly convert '"); break; 1606 case convc_as: printf("Cannot use 'as' to convert '"); break; 1607 } 1608 1331 1609 tdata_item_print(expr->titem); 1332 1610 printf(" to "); … … 1397 1675 } 1398 1676 1677 /** Find predecessor CSI and return its type item. 1678 * 1679 * Looks for predecessor of CSI type @a src that matches @a dest. 1680 * The type maches if they use the same generic CSI definition, type 1681 * arguments are ignored. If found, returns the type arguments that 1682 * @a dest should have in order to be a true predecessor of @a src. 1683 * 1684 * @param stype Static typing object 1685 * @param src Source type 1686 * @param dest Destination type 1687 * @return Type matching @a dest with correct type arguments 1688 */ 1689 tdata_item_t *stype_tobject_find_pred(stype_t *stype, tdata_item_t *src, 1690 tdata_item_t *dest) 1691 { 1692 stree_csi_t *src_csi; 1693 tdata_tvv_t *tvv; 1694 tdata_item_t *b_ti, *bs_ti; 1695 1696 list_node_t *pred_n; 1697 stree_texpr_t *pred_te; 1698 1699 tdata_item_t *res_ti; 1700 1701 #ifdef DEBUG_TYPE_TRACE 1702 printf("Find CSI predecessor.\n"); 1703 #endif 1704 assert(src->tic == tic_tobject); 1705 assert(dest->tic == tic_tobject); 1706 1707 if (src->u.tobject->csi == dest->u.tobject->csi) 1708 return src; 1709 1710 src_csi = src->u.tobject->csi; 1711 stype_titem_to_tvv(stype, src, &tvv); 1712 1713 res_ti = NULL; 1714 1715 switch (dest->u.tobject->csi->cc) { 1716 case csi_class: 1717 /* Destination is a class. Look at base class. */ 1718 pred_te = symbol_get_base_class_ref(stype->program, 1719 src_csi); 1720 if (pred_te != NULL) { 1721 run_texpr(stype->program, src_csi, pred_te, 1722 &b_ti); 1723 } else if (src_csi->base_csi != NULL && 1724 src->u.tobject->csi->cc == csi_class) { 1725 /* No explicit reference. Use grandfather class. */ 1726 b_ti = tdata_item_new(tic_tobject); 1727 b_ti->u.tobject = tdata_object_new(); 1728 b_ti->u.tobject->csi = src_csi->base_csi; 1729 b_ti->u.tobject->static_ref = sn_nonstatic; 1730 1731 list_init(&b_ti->u.tobject->targs); 1732 } else { 1733 /* No match */ 1734 return NULL; 1735 } 1736 1737 /* Substitute type variables to get predecessor type. */ 1738 tdata_item_subst(b_ti, tvv, &bs_ti); 1739 assert(bs_ti->tic == tic_tobject); 1740 1741 /* Recurse to compute the rest of the path. */ 1742 res_ti = stype_tobject_find_pred(stype, bs_ti, dest); 1743 if (b_ti->tic == tic_ignore) { 1744 /* An error occured. */ 1745 return NULL; 1746 } 1747 break; 1748 case csi_struct: 1749 assert(b_false); 1750 case csi_interface: 1751 /* 1752 * Destination is an interface. Look at implemented 1753 * or accumulated interfaces. 1754 */ 1755 pred_n = list_first(&src_csi->inherit); 1756 while (pred_n != NULL) { 1757 pred_te = list_node_data(pred_n, stree_texpr_t *); 1758 run_texpr(stype->program, src_csi, pred_te, 1759 &b_ti); 1760 1761 /* Substitute type variables to get predecessor type. */ 1762 tdata_item_subst(b_ti, tvv, &bs_ti); 1763 assert(bs_ti->tic == tic_tobject); 1764 1765 /* Recurse to compute the rest of the path. */ 1766 res_ti = stype_tobject_find_pred(stype, bs_ti, dest); 1767 if (res_ti != NULL) 1768 break; 1769 1770 pred_n = list_next(&src_csi->inherit, pred_n); 1771 } 1772 break; 1773 } 1774 1775 return res_ti; 1776 } 1777 1778 /** Check whether type arguments of expression type and another type are equal. 1779 * 1780 * Compare type arguments of the type of @a expr and of type @a b_ti. 1781 * @a convc denotes the type of conversion for which we perform this check 1782 * (for sake of error reporting). 1783 * 1784 * If the type arguments are not equal a typing error and a conversion error 1785 * message is generated. 1786 * 1787 * @param stype Static typing object 1788 * @param expr Expression 1789 * @param b_ti b_tiination type 1790 * @return EOK if equal, EINVAL if not. 1791 */ 1792 int stype_targs_check_equal(stype_t *stype, tdata_item_t *a_ti, 1793 tdata_item_t *b_ti) 1794 { 1795 list_node_t *arg_a_n, *arg_b_n; 1796 tdata_item_t *arg_a, *arg_b; 1797 1798 (void) stype; 1799 1800 #ifdef DEBUG_TYPE_TRACE 1801 printf("Check if type arguments match.\n"); 1802 #endif 1803 assert(a_ti->tic == tic_tobject); 1804 assert(b_ti->tic == tic_tobject); 1805 1806 /* 1807 * Verify that type arguments match with those specified for 1808 * conversion b_tiination. 1809 */ 1810 arg_a_n = list_first(&a_ti->u.tobject->targs); 1811 arg_b_n = list_first(&b_ti->u.tobject->targs); 1812 1813 while (arg_a_n != NULL && arg_b_n != NULL) { 1814 arg_a = list_node_data(arg_a_n, tdata_item_t *); 1815 arg_b = list_node_data(arg_b_n, tdata_item_t *); 1816 1817 if (tdata_item_equal(arg_a, arg_b) != b_true) { 1818 /* Diferent argument type */ 1819 printf("Different argument type '"); 1820 tdata_item_print(arg_a); 1821 printf("' vs. '"); 1822 tdata_item_print(arg_b); 1823 printf("'.\n"); 1824 return EINVAL; 1825 } 1826 1827 arg_a_n = list_next(&a_ti->u.tobject->targs, arg_a_n); 1828 arg_b_n = list_next(&b_ti->u.tobject->targs, arg_b_n); 1829 } 1830 1831 if (arg_a_n != NULL || arg_b_n != NULL) { 1832 /* Diferent number of arguments */ 1833 printf("Different number of arguments.\n"); 1834 return EINVAL; 1835 } 1836 1837 return EOK; 1838 } 1399 1839 1400 1840 … … 1448 1888 1449 1889 /* Compare return type */ 1450 if (!tdata_item_equal(asig->rtype, bsig->rtype)) 1451 return b_false; 1890 1891 if (asig->rtype != NULL || bsig->rtype != NULL) { 1892 if (asig->rtype == NULL || 1893 bsig->rtype == NULL) { 1894 return b_false; 1895 } 1896 1897 if (!tdata_item_equal(asig->rtype, bsig->rtype)) { 1898 return b_false; 1899 } 1900 } 1452 1901 1453 1902 return b_true; -
uspace/app/sbi/src/stype.h
r8f80c77 r1113c9e 37 37 void stype_enum(stype_t *stype, stree_enum_t *enum_d); 38 38 void stype_fun_header(stype_t *stype, stree_fun_t *fun); 39 void stype_prop_header(stype_t *stype, stree_prop_t *prop); 39 40 void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value); 40 41 … … 44 45 stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr, 45 46 tdata_item_t *dest); 47 void stype_convert_failure(stype_t *stype, stype_conv_class_t convc, 48 stree_expr_t *expr, tdata_item_t *dest); 46 49 stree_expr_t *stype_box_expr(stype_t *stype, stree_expr_t *expr); 50 tdata_item_t *stype_tobject_find_pred(stype_t *stype, tdata_item_t *src, 51 tdata_item_t *dest); 52 int stype_targs_check_equal(stype_t *stype, tdata_item_t *a_ti, 53 tdata_item_t *b_ti); 47 54 48 55 tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg); -
uspace/app/sbi/src/stype_expr.c
r8f80c77 r1113c9e 97 97 static void stype_new(stype_t *stype, stree_new_t *new, 98 98 tdata_item_t **rtitem); 99 static void stype_new_object _args(stype_t *stype, stree_new_t *new_op,99 static void stype_new_object(stype_t *stype, stree_new_t *new_op, 100 100 tdata_item_t *obj_ti); 101 101 … … 194 194 tdata_ebase_t *tebase; 195 195 stree_fun_t *fun; 196 bool_t static_ctx; 196 197 197 198 #ifdef DEBUG_TYPE_TRACE … … 257 258 } 258 259 260 /* Determine if current procedure is static. */ 261 static_ctx = stree_symbol_is_static(stype->proc_vr->proc->outer_symbol); 262 263 /* 264 * If the symbol is not found in current CSI, then we access it 265 * in a static context. (Context of current object cannot be used.) 266 */ 267 if (sym->outer_csi != stype->current_csi) 268 static_ctx = b_true; 269 270 /* Check for referencing non-static symbol in static context. */ 271 if (static_ctx && !stree_symbol_is_static(sym)) { 272 cspan_print(nameref->expr->cspan); 273 printf(" Error: Referencing non-static symbol '"); 274 symbol_print_fqn(sym); 275 printf("' in static context.\n"); 276 stype_note_error(stype); 277 *rtitem = stype_recovery_titem(stype); 278 return; 279 } 280 281 /* Referencing static member in non-static context is allowed. */ 282 283 /* Make compiler happy. */ 284 titem = NULL; 285 259 286 switch (sym->sc) { 260 287 case sc_var: … … 263 290 break; 264 291 case sc_prop: 265 run_texpr(stype->program, stype->current_csi, 266 sym->u.prop->type, &titem); 292 /* Type property header if it has not been typed yet. */ 293 stype_prop_header(stype, sym->u.prop); 294 titem = sym->u.prop->titem; 267 295 break; 268 296 case sc_csi: … … 274 302 titem->u.tobject = tobject; 275 303 276 /* This is a static CSI reference. */ 277 tobject->static_ref = b_true; 304 tobject->static_ref = sn_static; 278 305 tobject->csi = csi; 279 306 break; … … 330 357 (void) stype; 331 358 359 /* Make compiler happy. */ 360 tpc = 0; 361 332 362 switch (literal->ltc) { 333 363 case ltc_bool: tpc = tpc_bool; break; … … 375 405 titem->u.tobject = tobject; 376 406 377 tobject->static_ref = b_false;407 tobject->static_ref = sn_nonstatic; 378 408 tobject->csi = cur_csi; 379 409 list_init(&tobject->targs); … … 513 543 tdata_item_t *res_ti; 514 544 545 /* Make compiler happy. */ 546 rtpc = 0; 547 515 548 switch (binop->bc) { 516 549 case bo_equal: … … 560 593 (void) stype; 561 594 595 /* Make compiler happy. */ 596 rtpc = 0; 597 562 598 switch (binop->bc) { 563 599 case bo_equal: … … 604 640 (void) stype; 605 641 642 /* Make compiler happy. */ 643 rtpc = 0; 644 606 645 switch (binop->bc) { 607 646 case bo_equal: … … 666 705 tdata_item_t *res_ti; 667 706 707 /* Make compiler happy. */ 708 rtpc = 0; 709 668 710 switch (binop->bc) { 669 711 case bo_equal: … … 941 983 942 984 if ((*rtitem)->tic == tic_tobject) 943 stype_new_object _args(stype, new_op, *rtitem);985 stype_new_object(stype, new_op, *rtitem); 944 986 } 945 987 … … 949 991 * @param new_op @c new operation 950 992 */ 951 static void stype_new_object _args(stype_t *stype, stree_new_t *new_op,993 static void stype_new_object(stype_t *stype, stree_new_t *new_op, 952 994 tdata_item_t *obj_ti) 953 995 { … … 957 999 stree_ident_t *ctor_ident; 958 1000 tdata_fun_sig_t *tsig; 1001 tdata_tvv_t *obj_tvv; 1002 tdata_item_t *ctor_sti; 959 1003 960 1004 assert(obj_ti->tic == tic_tobject); 961 1005 csi = obj_ti->u.tobject->csi; 1006 1007 if (csi->cc == csi_interface) { 1008 cspan_print(new_op->expr->cspan); 1009 printf(" Error: Cannot instantiate an interface.\n"); 1010 stype_note_error(stype); 1011 return; 1012 } 1013 962 1014 ctor_ident = stree_ident_new(); 963 1015 ctor_ident->sid = strtab_get_sid(CTOR_IDENT); … … 986 1038 return; 987 1039 988 assert(ctor->titem->tic == tic_tfun); 989 tsig = ctor->titem->u.tfun->tsig; 1040 /* Substitute type arguments in constructor type. */ 1041 stype_titem_to_tvv(stype, obj_ti, &obj_tvv); 1042 tdata_item_subst(ctor->titem, obj_tvv, &ctor_sti); 1043 /* XXX Free obj_tvv */ 1044 1045 assert(ctor_sti->tic == tic_tfun); 1046 tsig = ctor_sti->u.tfun->tsig; 990 1047 991 1048 stype_call_args(stype, new_op->expr->cspan, &tsig->arg_ti, … … 1104 1161 tdata_item_t *mtitem; 1105 1162 tdata_tvv_t *tvv; 1163 stree_csi_t *member_csi; 1106 1164 1107 1165 #ifdef DEBUG_TYPE_TRACE … … 1131 1189 strtab_get_str(access->member_name->sid)); 1132 1190 #endif 1191 /* Check for accessing non-static member in static context. */ 1192 if (tobject->static_ref == sn_static && 1193 !stree_symbol_is_static(member_sym)) { 1194 cspan_print(access->member_name->cspan); 1195 printf(" Error: Accessing non-static member '"); 1196 symbol_print_fqn(member_sym); 1197 printf("' in static context.\n"); 1198 stype_note_error(stype); 1199 *rtitem = stype_recovery_titem(stype); 1200 return; 1201 } 1202 1203 /* Check for accessing static member in non-static context. */ 1204 if (tobject->static_ref != sn_static && 1205 stree_symbol_is_static(member_sym)) { 1206 cspan_print(access->member_name->cspan); 1207 printf(" Error: Accessing static member '"); 1208 symbol_print_fqn(member_sym); 1209 printf("' in non-static context.\n"); 1210 stype_note_error(stype); 1211 *rtitem = stype_recovery_titem(stype); 1212 return; 1213 } 1214 1215 /* Make compiler happy. */ 1216 mtitem = NULL; 1133 1217 1134 1218 switch (member_sym->sc) { 1135 1219 case sc_csi: 1136 cspan_print(access->member_name->cspan); 1137 printf(" Error: Accessing object member which is nested " 1138 "CSI.\n"); 1139 stype_note_error(stype); 1140 *rtitem = stype_recovery_titem(stype); 1141 return; 1220 member_csi = symbol_to_csi(member_sym); 1221 assert(member_csi != NULL); 1222 1223 mtitem = tdata_item_new(tic_tobject); 1224 tobject = tdata_object_new(); 1225 mtitem->u.tobject = tobject; 1226 1227 tobject->static_ref = sn_static; 1228 tobject->csi = member_csi; 1229 break; 1142 1230 case sc_ctor: 1143 1231 /* It is not possible to reference a constructor explicitly. */ … … 1337 1425 stree_expr_t *carg; 1338 1426 1339 int cnt;1340 1341 1427 /* Type and check regular arguments. */ 1342 1428 fargt_n = list_first(farg_tis); 1343 1429 arg_n = list_first(args); 1344 1430 1345 cnt = 0;1346 1431 while (fargt_n != NULL && arg_n != NULL) { 1347 1432 farg_ti = list_node_data(fargt_n, tdata_item_t *); … … 1656 1741 { 1657 1742 tdata_item_t *titem; 1743 tdata_item_t *pred_ti; 1658 1744 1659 1745 #ifdef DEBUG_TYPE_TRACE … … 1664 1750 run_texpr(stype->program, stype->current_csi, as_op->dtype, &titem); 1665 1751 1666 /* Check that target type is derived from argument type. */ 1667 if (tdata_is_ti_derived_from_ti(titem, as_op->arg->titem) != b_true) { 1668 cspan_print(as_op->dtype->cspan); 1669 printf(" Error: Target of 'as' operator '"); 1670 tdata_item_print(titem); 1671 printf("' is not derived from '"); 1672 tdata_item_print(as_op->arg->titem); 1673 printf("'.\n"); 1674 stype_note_error(stype); 1752 pred_ti = stype_tobject_find_pred(stype, titem, as_op->arg->titem); 1753 if (pred_ti == NULL) { 1754 /* No CSI match. */ 1755 stype_convert_failure(stype, convc_as, as_op->arg, titem); 1756 *rtitem = titem; 1757 return; 1758 } 1759 1760 /* 1761 * Verify that type arguments match with those specified for 1762 * conversion destination. 1763 */ 1764 if (stype_targs_check_equal(stype, pred_ti, as_op->arg->titem) 1765 != EOK) { 1766 stype_convert_failure(stype, convc_as, as_op->arg, titem); 1767 *rtitem = titem; 1768 return; 1675 1769 } 1676 1770 … … 1720 1814 1721 1815 btitem->u.tobject = tobject; 1722 tobject->static_ref = b_false;1816 tobject->static_ref = sn_nonstatic; 1723 1817 tobject->csi = symbol_to_csi(csi_sym); 1724 1818 assert(tobject->csi != NULL); -
uspace/app/sbi/src/stype_t.h
r8f80c77 r1113c9e 59 59 } stype_proc_vr_t; 60 60 61 /** Conversion class */ 62 typedef enum { 63 /** Implicit conversion */ 64 convc_implicit, 65 /** 'as' conversion */ 66 convc_as 67 } stype_conv_class_t; 68 61 69 /** Static typer state object */ 62 70 typedef struct stype { -
uspace/app/sbi/src/symbol.c
r8f80c77 r1113c9e 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);45 44 static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol); 46 45 … … 132 131 stree_csi_t *scope, stree_ident_t *name) 133 132 { 134 stree_symbol_t *base_csi_sym;135 133 stree_csi_t *base_csi; 136 134 stree_symbol_t *symbol; … … 142 140 143 141 /* Try inherited members. */ 144 if (scope->base_csi_ref != NULL) { 145 base_csi_sym = symbol_xlookup_in_csi(prog, 146 csi_to_symbol(scope)->outer_csi, scope->base_csi_ref); 147 base_csi = symbol_to_csi(base_csi_sym); 148 assert(base_csi != NULL); 149 142 base_csi = symbol_get_base_class(prog, scope); 143 if (base_csi != NULL) 150 144 return symbol_search_csi(prog, base_csi, name); 151 }152 145 153 146 /* No match */ … … 212 205 modm = list_node_data(node, stree_modm_t *); 213 206 207 /* Make compiler happy. */ 208 mbr_name = NULL; 209 214 210 switch (modm->mc) { 215 211 case mc_csi: mbr_name = modm->u.csi->name; break; … … 217 213 } 218 214 215 /* The Clang static analyzer is just too picky. */ 216 assert(mbr_name != NULL); 217 219 218 if (name->sid == mbr_name->sid) { 219 /* Make compiler happy. */ 220 symbol = NULL; 221 220 222 /* Match */ 221 223 switch (modm->mc) { … … 231 233 node = list_next(&prog->module->members, node); 232 234 } 235 236 return NULL; 237 } 238 239 /** Get explicit base class for a CSI. 240 * 241 * Note that if there is no explicit base class (class is derived implicitly 242 * from @c object, then @c NULL is returned. 243 * 244 * @param prog Program to look in 245 * @param csi CSI 246 * 247 * @return Base class (CSI) or @c NULL if no explicit base class. 248 */ 249 stree_csi_t *symbol_get_base_class(stree_program_t *prog, stree_csi_t *csi) 250 { 251 list_node_t *pred_n; 252 stree_texpr_t *pred; 253 stree_symbol_t *pred_sym; 254 stree_csi_t *pred_csi; 255 stree_csi_t *outer_csi; 256 257 outer_csi = csi_to_symbol(csi)->outer_csi; 258 259 pred_n = list_first(&csi->inherit); 260 if (pred_n == NULL) 261 return NULL; 262 263 pred = list_node_data(pred_n, stree_texpr_t *); 264 pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred); 265 pred_csi = symbol_to_csi(pred_sym); 266 assert(pred_csi != NULL); /* XXX! */ 267 268 if (pred_csi->cc == csi_class) 269 return pred_csi; 270 271 return NULL; 272 } 273 274 /** Get type expression referencing base class for a CSI. 275 * 276 * Note that if there is no explicit base class (class is derived implicitly 277 * from @c object, then @c NULL is returned. 278 * 279 * @param prog Program to look in 280 * @param csi CSI 281 * 282 * @return Type expression or @c NULL if no explicit base class. 283 */ 284 stree_texpr_t *symbol_get_base_class_ref(stree_program_t *prog, 285 stree_csi_t *csi) 286 { 287 list_node_t *pred_n; 288 stree_texpr_t *pred; 289 stree_symbol_t *pred_sym; 290 stree_csi_t *pred_csi; 291 stree_csi_t *outer_csi; 292 293 outer_csi = csi_to_symbol(csi)->outer_csi; 294 295 pred_n = list_first(&csi->inherit); 296 if (pred_n == NULL) 297 return NULL; 298 299 pred = list_node_data(pred_n, stree_texpr_t *); 300 pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred); 301 pred_csi = symbol_to_csi(pred_sym); 302 assert(pred_csi != NULL); /* XXX! */ 303 304 if (pred_csi->cc == csi_class) 305 return pred; 233 306 234 307 return NULL; … … 286 359 stree_csimbr_t *csimbr; 287 360 stree_symbol_t *entry, *etmp; 361 stree_symbol_t *fun_sym; 288 362 289 363 entry = NULL; … … 305 379 break; 306 380 case csimbr_fun: 307 if (csimbr->u.fun->name->sid == name->sid) { 381 fun_sym = fun_to_symbol(csimbr->u.fun); 382 383 if (csimbr->u.fun->name->sid == name->sid && 384 stree_symbol_has_attr(fun_sym, sac_static)) { 308 385 if (entry != NULL) { 309 386 printf("Error: Duplicate entry point.\n"); 310 387 exit(1); 311 388 } 312 entry = fun_ to_symbol(csimbr->u.fun);389 entry = fun_sym; 313 390 } 314 391 default: … … 494 571 * @return Symbol 495 572 */ 496 st atic stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr)573 stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr) 497 574 { 498 575 stree_symbol_t *symbol; … … 569 646 stree_ident_t *ident; 570 647 648 /* Make compiler happy. */ 649 ident = NULL; 650 571 651 switch (symbol->sc) { 572 652 case sc_csi: ident = symbol->u.csi->name; break; -
uspace/app/sbi/src/symbol.h
r8f80c77 r1113c9e 40 40 stree_symbol_t *symbol_search_csi_no_base(stree_program_t *prog, 41 41 stree_csi_t *scope, stree_ident_t *name); 42 stree_csi_t *symbol_get_base_class(stree_program_t *prog, stree_csi_t *csi); 43 stree_texpr_t *symbol_get_base_class_ref(stree_program_t *prog, 44 stree_csi_t *csi); 42 45 stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name); 43 46 … … 57 60 stree_symbol_t *prop_to_symbol(stree_prop_t *prop); 58 61 62 stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr); 63 59 64 void symbol_print_fqn(stree_symbol_t *symbol); 60 65 -
uspace/app/sbi/src/tdata.c
r8f80c77 r1113c9e 343 343 /* Plain copy */ 344 344 tnew = tdata_ebase_new(); 345 tnew->enum_d = tebase->enum_d; 346 345 347 *res = tdata_item_new(tic_tebase); 346 (*res)->u.tebase = t ebase;348 (*res)->u.tebase = tnew; 347 349 } 348 350 … … 362 364 /* Plain copy */ 363 365 tnew = tdata_enum_new(); 366 tnew->enum_d = tenum->enum_d; 367 364 368 *res = tdata_item_new(tic_tenum); 365 (*res)->u.tenum = t enum;369 (*res)->u.tenum = tnew; 366 370 } 367 371 -
uspace/app/sbi/src/tdata_t.h
r8f80c77 r1113c9e 58 58 /** Object type. */ 59 59 typedef struct { 60 /** @c trueif expression is a static CSI reference */61 bool_t static_ref;60 /** @c sn_static if expression is a static CSI reference */ 61 statns_t static_ref; 62 62 63 63 /** CSI definition */
Note:
See TracChangeset
for help on using the changeset viewer.