ast_t* symtab_find(symtab_t* symtab, const char* name, sym_status_t* status) { symbol_t s1 = {name, NULL, SYM_NONE, 0}; symbol_t* s2 = symtab_get(symtab, &s1); if(s2 != NULL) { if(status != NULL) *status = s2->status; if(s2->status == SYM_NOCASE) return NULL; return s2->def; } if(status != NULL) *status = SYM_NONE; return NULL; }
void symtab_inherit_branch(symtab_t* dst, symtab_t* src) { size_t i = HASHMAP_BEGIN; symbol_t* sym; while((sym = symtab_next(src, &i)) != NULL) { // Only inherit symbols that were declared in an outer scope. if(sym->def != NULL) continue; symbol_t* dsym = symtab_get(dst, sym); if(dsym != NULL) { if(sym->status == SYM_DEFINED) { // Treat defined as adding one to the undefined branch count. if(dsym->status == SYM_UNDEFINED) dsym->branch_count++; } else if(sym->status == SYM_CONSUMED) { // Consumed overrides everything. dsym->status = SYM_CONSUMED; dsym->branch_count = 0; } } else { // Add this symbol to the destination. dsym = sym_dup(sym); if(dsym->status == SYM_DEFINED) { // Treat defined as undefined with a branch count of one. dsym->status = SYM_UNDEFINED; dsym->branch_count = 1; } symtab_put(dst, dsym); } } }
void symtab_inherit_status(symtab_t* dst, symtab_t* src) { size_t i = HASHMAP_BEGIN; symbol_t* sym; while((sym = symtab_next(src, &i)) != NULL) { // Only inherit symbols that were declared in an outer scope. if(sym->def != NULL) continue; symbol_t* dsym = symtab_get(dst, sym); if(dsym != NULL) { // Copy the source status the the destination. dsym->status = sym->status; } else { // Add this symbol to the destination. symtab_put(dst, sym_dup(sym)); } } }
static struct s_expr *s_expr(struct symtab *tab, struct p_expr *p) { struct s_expr *ex, *s; int i, children; ex = malloc(sizeof(*ex)); children = 0; switch (p->type) { case T_ID: s = symtab_get(tab, p->id); if (s == NULL) { ex->type = S_EXPR_LABEL; ex->id = p->id; } else { free(ex); ex = s; } break; case T_INT: ex->type = S_EXPR_IMMEDIATE; ex->n = p->num; break; case T_FN: ex->type = S_EXPR_APPLICATION; ex->app = s_apply(tab, p->fn); break; case T_LBRACK: case T_NEG: children = 1; break; case T_ADD: case T_SUB: case T_MUL: case T_DIV: case T_MOD: case T_AND: case T_OR: case T_XOR: case T_EQ: case T_NE: case T_GT: case T_LT: case T_COMMA: children = 2; break; case T_QUES: children = 3; break; default: ice("unknown expression type `%s'", lx_names[p->type]); } if (children > 0) { ex->op = p->type; switch (children) { case 1: ex->type = S_EXPR_UNARY_OPERATION; break; case 2: ex->type = S_EXPR_BINARY_OPERATION; break; case 3: ex->type = S_EXPR_CONDITIONAL; break; default: ice("can't expression with %d children", children); } for (i=0; i<children; i++) ex->child[i] = s_expr(tab, p->child[i]); } return ex; }
/* * search_libraries() * * scans through the list of libraries, attempting to match symbols * defined in library modules against symbols that are referenced but * not defined (segment = -1 in the symbol table) * * returns 1 if any extra library modules are included, indicating that * another pass through the library list should be made (possibly). */ int search_libraries() { struct librarynode *cur; rdffile f; int i; void *header; int segment; long offset; int doneanything = 0, pass = 1, keepfile; rdfheaderrec *hr; cur = libraries; while (cur) { if (options.verbose > 2) printf("scanning library `%s', pass %d...\n", cur->name, pass); for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++) { if (pass == 2 && lookformodule(f.name)) continue; if (options.verbose > 3) printf(" looking in module `%s'\n", f.name); header = malloc(f.header_len); if (!header) { fprintf(stderr, "ldrdf: not enough memory\n"); exit(1); } if (rdfloadseg(&f, RDOFF_HEADER, header)) { rdfperror("ldrdf", f.name); errorcount++; return 0; } keepfile = 0; while ((hr = rdfgetheaderrec(&f))) { /* We're only interested in exports, so skip others */ if (hr->type != RDFREC_GLOBAL) continue; /* * If the symbol is marked as SYM_GLOBAL, somebody will be * definitely interested in it.. */ if ((hr->e.flags & SYM_GLOBAL) == 0) { /* * otherwise the symbol is just public. Find it in * the symbol table. If the symbol isn't defined, we * aren't interested, so go on to the next. * If it is defined as anything but -1, we're also not * interested. But if it is defined as -1, insert this * module into the list of modules to use, and go * immediately on to the next module... */ if (!symtab_get(hr->e.label, &segment, &offset) || segment != -1) continue; } doneanything = 1; keepfile = 1; /* * as there are undefined symbols, we can assume that * there are modules on the module list by the time * we get here. */ lastmodule->next = malloc(sizeof(*lastmodule->next)); if (!lastmodule->next) { fprintf(stderr, "ldrdf: not enough memory\n"); exit(1); } lastmodule = lastmodule->next; memcpy(&lastmodule->f, &f, sizeof(f)); lastmodule->name = strdup(f.name); lastmodule->next = NULL; processmodule(f.name, lastmodule); break; } if (!keepfile) { free(f.name); f.name = NULL; f.fp = NULL; } } if (rdl_error != 0 && rdl_error != RDL_ENOTFOUND) rdl_perror("ldrdf", cur->name); cur = cur->next; if (cur == NULL && pass == 1) { cur = libraries; pass++; } } return doneanything; }