bool symtab_add(symtab_t* symtab, const char* name, ast_t* def, sym_status_t status) { const char* no_case = name_without_case(name); if(no_case != name) { symbol_t s1 = {no_case, def, SYM_NOCASE, 0}; symbol_t* s2 = symtab_get(symtab, &s1); if(s2 != NULL) return false; symtab_put(symtab, sym_dup(&s1)); } symbol_t s1 = {name, def, status, 0}; symbol_t* s2 = symtab_get(symtab, &s1); if(s2 != NULL) return false; symtab_put(symtab, sym_dup(&s1)); return true; }
static val_ptr eval_define(tree_ptr t) { val_ptr v = (val_ptr)pbc_malloc(sizeof(*v)); v->type = v_def; v->def = t; symtab_put(tab, v, ((tree_ptr)darray_at(t->child, 0))->id); return v; }
static val_ptr eval_assign(tree_ptr t) { tree_ptr tid = (tree_ptr)darray_at(t->child, 0); val_ptr v = tree_eval((tree_ptr)darray_at(t->child, 1)); if (symtab_at(reserved, tid->id)) { return val_new_error("%s is reserved", tid->id); } symtab_put(tab, v, tid->id); return v; }
void symtab_set_status(symtab_t* symtab, const char* name, sym_status_t status) { symbol_t s1 = {name, NULL, status, 0}; symbol_t* s2 = symtab_get(symtab, &s1); if(s2 != NULL) s2->status = status; else symtab_put(symtab, sym_dup(&s1)); }
symtab_t* symtab_dup(symtab_t* symtab) { symtab_t* n = POOL_ALLOC(symtab_t); symtab_init(n, symtab_size(symtab)); size_t i = HASHMAP_BEGIN; symbol_t* sym; while((sym = symtab_next(symtab, &i)) != NULL) symtab_put(n, sym_dup(sym)); return n; }
static void read_symtab(symtab_t tab, const char *input, size_t limit) { token_t tok; const char *inputend = limit ? input + limit : NULL; token_init(tok); for (;;) { input = token_get(tok, input, inputend); if (tok->type != token_word) break; char *key = pbc_strdup(tok->s); input = token_get(tok, input, inputend); if (tok->type != token_word) { pbc_free(key); break; } symtab_put(tab, pbc_strdup(tok->s), key); pbc_free(key); } token_clear(tok); }
static val_ptr v_def_call(val_ptr v, tree_ptr t) { int i; const char* name = ((tree_ptr)darray_at(v->def->child, 0))->id; darray_ptr parm = ((tree_ptr)darray_at(v->def->child, 1))->child; int n = darray_count(parm); if (1 + n != darray_count(t->child)) { return val_new_error("%s: wrong number of arguments", name); } for (i = 0; i < n; i++) { const char *id = ((tree_ptr)darray_at(parm, i))->id; val_ptr v1 = tree_eval((tree_ptr)darray_at(t->child, i)); // TODO: Stack frames for recursion. symtab_put(tab, v1, id); } // Evaluate function body. darray_ptr a = ((tree_ptr)darray_at(v->def->child, 2))->child; darray_forall(a, eval_stmt); 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)); } } }
int main(int argc, char **argv) { for (;;) { int c = getopt(argc, argv, "y"); if (c == -1) break; switch (c) { case 'y': option_easy = 1; option_prompt = "> "; break; default: fprintf(stderr, "unrecognized option: %c\n", c); break; } } field_init_z(Z); field_init_multiz(M); symtab_init(tab); builtin(fun_rnd); builtin(fun_random); builtin(fun_ord); builtin(fun_order); builtin(fun_nextprime); builtin(fun_sqrt); builtin(fun_inv); builtin(fun_type); builtin(fun_pairing); builtin(fun_zmod); builtin(fun_poly); builtin(fun_polymod); builtin(fun_extend); builtin(fun_exit); builtin(fun_CHECK); builtin(fun_init_pairing_a); builtin(fun_init_pairing_d); builtin(fun_init_pairing_e); builtin(fun_init_pairing_f); builtin(fun_init_pairing_g); builtin(fun_init_pairing_i); run_init_pairing_a(NULL); symtab_put(reserved, val_new_field(M), "M"); symtab_put(reserved, val_new_field(Z), "Z"); if (argc > optind) { FILE *fp = fopen(argv[optind], "r"); if (!fp) pbc_die("fopen failed on %s", argv[optind]); YY_BUFFER_STATE st = yy_create_buffer(fp, YY_BUF_SIZE); yy_switch_to_buffer(st); yywrapfun = yywrap_return1; yyparse(); yy_delete_buffer(st); } else { yywrapfun = yywrap_readline; yywrap(); while (!end_of_input) { if (2 == yyparse()) pbc_die("parser out of memory"); } putchar('\n'); } symtab_clear(tab); field_clear(M); return 0; }
static void builtin(fun_ptr fun) { symtab_put(reserved, val_new_fun(fun), fun->name); }
static void assign_field(field_ptr f, const char* s) { symtab_put(tab, val_new_field(f), s); }
static void builtin(fun_ptr fun, const char *s) { symtab_put(reserved, val_new_fun(fun), s); }