static void dump_ast(const char *code) { struct ast ast; ast_init(&ast, 0); aparse(&ast, code, 1); ast_dump(stdout, &ast, 0); ast_free(&ast); }
int main(int argc, char **argv) { char **real_argv = argv; struct scan_st *sc; struct symbol_table *stab; struct ast *a; char *source = NULL; int opt; int err_count = 0; #ifdef DEBUG int run_program = 1; int dump_symbols = 0; int dump_program = 0; int dump_icode = 0; #endif #ifdef DEBUG setvbuf(stdout, NULL, _IOLBF, 0); #endif /* * Get command-line arguments. */ while ((opt = getopt(argc, argv, OPTS)) != -1) { switch(opt) { #ifdef DEBUG case 'c': trace_scheduling++; break; #ifdef POOL_VALUES case 'd': trace_pool++; break; #endif case 'g': trace_gc++; break; #endif case 'G': gc_trigger = atoi(optarg); break; #ifdef DEBUG case 'i': dump_icode++; break; case 'l': trace_gen++; break; case 'm': trace_vm++; break; case 'n': run_program = 0; break; case 'o': trace_valloc++; break; case 'p': dump_program = 1; break; case 's': dump_symbols = 1; break; case 'v': trace_activations++; break; case 'y': trace_type_inference++; break; #endif case '?': default: usage(argv); } } argc -= optind; argv += optind; if (*argv != NULL) source = *argv; else usage(real_argv); #ifdef POOL_VALUES value_pool_new(); #endif gc_target = gc_trigger; if ((sc = scan_open(source)) != NULL) { stab = symbol_table_new(NULL, 0); global_ar = activation_new_on_heap(100, NULL, NULL); register_std_builtins(stab); report_start(); a = parse_program(sc, stab); scan_close(sc); #ifdef DEBUG if (dump_symbols) symbol_table_dump(stab, 1); if (dump_program) { ast_dump(a, 0); } #endif #ifndef DEBUG symbol_table_free(stab); types_free(); #endif err_count = report_finish(); if (err_count == 0) { struct iprogram *ip; struct vm *vm; struct process *p; unsigned char *program; program = bhuna_malloc(16384); ip = ast_gen_iprogram(a); iprogram_eliminate_nops(ip); iprogram_eliminate_useless_jumps(ip); iprogram_optimize_tail_calls(ip); iprogram_optimize_push_small_ints(ip); iprogram_eliminate_dead_code(ip); iprogram_gen(&program, ip); #ifdef DEBUG if (dump_icode > 0) iprogram_dump(ip, program); #endif vm = vm_new(program, 16384); vm_set_pc(vm, program); vm->current_ar = global_ar; p = process_new(vm); /* ast_dump(a, 0); */ if (RUN_PROGRAM) { process_scheduler(); } vm_free(vm); bhuna_free(program); /*value_dump_global_table();*/ } ast_free(a); /* XXX move on up */ /* gc(); */ /* actually do a full blow out at the end */ /* activation_free_from_stack(global_ar); */ #ifdef DEBUG symbol_table_free(stab); types_free(); if (trace_valloc > 0) { /* value_dump_global_table(); */ printf("Created: %8d\n", num_vars_created); printf("Cached: %8d\n", num_vars_cached); printf("Freed: %8d\n", num_vars_freed); } if (trace_activations > 0) { printf("AR's alloc'ed: %8d\n", activations_allocated); printf("AR's freed: %8d\n", activations_freed); } #ifdef POOL_VALUES if (trace_pool > 0) { pool_report(); } #endif #endif return(0); } else { fprintf(stderr, "Can't open `%s'\n", source); return(1); } }
int main(int argc, const char *args[]) { if (argc != 3) { printf("USAGE: %s [i|s|r] file\n", args[0]); return -1; } char mode = args[1][0]; simple_stream_s s; ast_node_t n; interp_s __interp; interp_t interp = &__interp; object_t prog; switch (mode) { case 'i': case 's': simple_stream_open(&s, fopen(args[2], "r")); n = ast_simple_parse_char_stream((stream_in_f)simple_stream_in, &s); simple_stream_close(&s); if (n != NULL) { if (mode == 'i') { ast_dump(n, stdout); ast_free(n); break; } ast_syntax_parse(n, 0); sematic_symref_analyse(n); ast_dump(n, stdout); ast_free(n); } break; case 'r': interp_initialize(interp, 16); simple_stream_open(&s, fopen(args[2], "r")); prog = interp_eval(interp, (stream_in_f)simple_stream_in, &s, NULL); simple_stream_close(&s); if (prog != NULL) interp_apply(interp, prog, 0, NULL); int ex_argc = 0; object_t *ex_args; object_t ex_ret = NULL; int i; object_t __me = interp_object_new(interp); __me->string = xstring_from_cstr("SEE interpreter", -1); OBJECT_TYPE_INIT(__me, OBJECT_TYPE_STRING); interp_protect(interp, __me); while (1) { int r = interp_run(interp, ex_ret, &ex_argc, &ex_args); if (r <= 0) break; switch (r) { case VM_EXTERNAL_CALL: ex_ret = OBJECT_NULL; /* An example for handling external calls: display */ if (OBJECT_TYPE(ex_args[0]) == OBJECT_TYPE_STRING) { if (xstring_equal_cstr(ex_args[0]->string, "display", -1)) { for (i = 1; i != ex_argc; ++ i) { object_dump(ex_args[i], stdout); } printf("\n"); } } /* The caller should unprotect the ex arguments by themself */ for (i = 0; i != ex_argc; ++ i) interp_unprotect(interp, ex_args[i]); break; case VM_EXTERNAL_CONSTANT: /* An example for handling external constant. */ /* remember that we should never create objects from * heap for the external constant */ if (xstring_equal_cstr(interp->ex->exp->constant.name, "#answer-to-the-universe", -1)) ex_ret = INT_BOX(42); else ex_ret = OBJECT_NULL; break; case VM_EXTERNAL_LOAD: /* Handling external load */ ex_ret = OBJECT_NULL; if (xstring_equal_cstr(interp->ex->exp->load.name, "me", -1)) { ex_ret = __me; } break; case VM_EXTERNAL_STORE: /* Handler external store */ ex_ret = OBJECT_NULL; if (xstring_equal_cstr(interp->ex->exp->store.name, "me", -1)) { fprintf(stderr, "Setting ``me'' is impossible\n"); fprintf(stderr, "VALUE: \n"); object_dump(interp->ex->value, stderr); fprintf(stderr, "\n"); } break; default: ex_ret = OBJECT_NULL; break; } } interp_uninitialize(interp); break; default: printf("ERROR OPTION\n"); return -1; } return 0; }
void ast_dump(struct ast *a, int indent) { #ifdef DEBUG int i; if (a == NULL) { return; } for (i = 0; i < indent; i++) printf(" "); if (a->label != NULL) { /* XXX printf("@#%d -> ", a->label - (vm_label_t)program); */ printf("@#%08lx -> ", (unsigned long)a->label); } printf(ast_name(a)); printf("="); type_print(stdout, a->datatype); switch (a->type) { case AST_LOCAL: printf("(%d,%d)=", a->u.local.index, a->u.local.upcount); if (a->u.local.sym != NULL) symbol_dump(a->u.local.sym, 0); printf("\n"); break; case AST_VALUE: printf("("); value_print(a->u.value.value); printf(")\n"); break; case AST_BUILTIN: printf("`"); fputsu8(stdout, a->u.builtin.bi->name); printf("`{\n"); ast_dump(a->u.builtin.right, indent + 1); for (i = 0; i < indent; i++) printf(" "); printf("}\n"); break; case AST_APPLY: printf("{\n"); ast_dump(a->u.apply.left, indent + 1); ast_dump(a->u.apply.right, indent + 1); for (i = 0; i < indent; i++) printf(" "); printf("}\n"); break; case AST_ARG: printf("{\n"); ast_dump(a->u.arg.left, indent + 1); ast_dump(a->u.arg.right, indent + 1); for (i = 0; i < indent; i++) printf(" "); printf("}\n"); break; case AST_ROUTINE: printf("{\n"); ast_dump(a->u.routine.body, indent + 1); for (i = 0; i < indent; i++) printf(" "); printf("}\n"); break; case AST_STATEMENT: printf("{\n"); ast_dump(a->u.statement.left, indent + 1); ast_dump(a->u.statement.right, indent + 1); for (i = 0; i < indent; i++) printf(" "); printf("}\n"); break; case AST_ASSIGNMENT: printf("(%s){\n", a->u.assignment.defining ? "definition" : "application"); ast_dump(a->u.assignment.left, indent + 1); ast_dump(a->u.assignment.right, indent + 1); for (i = 0; i < indent; i++) printf(" "); printf("}\n"); break; case AST_CONDITIONAL: printf("{\n"); ast_dump(a->u.conditional.test, indent + 1); ast_dump(a->u.conditional.yes, indent + 1); if (a->u.conditional.no != NULL) ast_dump(a->u.conditional.no, indent + 1); for (i = 0; i < indent; i++) printf(" "); printf("}\n"); break; case AST_WHILE_LOOP: printf("{\n"); ast_dump(a->u.while_loop.test, indent + 1); ast_dump(a->u.while_loop.body, indent + 1); for (i = 0; i < indent; i++) printf(" "); printf("}\n"); break; case AST_RETR: printf("{\n"); ast_dump(a->u.retr.body, indent + 1); for (i = 0; i < indent; i++) printf(" "); printf("}\n"); break; } #endif }