Re *re_new(const char *rep, int opts) { Re *re = malloc(sizeof(Re)); bzero(re, sizeof re); input = (char *)rep; re_setopt(re, opts); yyparse(re); re->ast = ast_new(Paren, 0, re->ast, NULL); if (!re_getopt(re, RE_ANCHOR_HEAD)) { ReAst *ast = ast_new(Star, 0, ast_new(Any, 0, NULL, NULL), NULL); ast->nongreedy = 1; re->ast = ast_new(Concat, 0, ast, re->ast); } dumpast(re->ast, 0); int nr_insts = visit_ast(re->ast, collect_insts) + 1; // plus 1 for IMatch debug("insts size: %d\n", nr_insts); re->insts = malloc(sizeof(Inst) * nr_insts); re_compile(re, re->ast); re_addInst(re, IMatch, 0, NULL, NULL); dumpinsts(re); return re; }
astp ast_new_wparam(int type,const char * text, astp p1){ if (print) { printf("ast_new_wparam...%s->%s",text,p1->text); fflush(stdout);} astp r=ast_new(type,text); ast_add_parameter(r,p1); if (print) printf("done\n"); return r; }
struct ast * ast_new_statement(struct ast *left, struct ast *right) { struct ast *a; if (left == NULL && right == NULL) return(NULL); if (left == NULL) return(right); if (right == NULL) return(left); a = ast_new(AST_STATEMENT); a->u.statement.left = left; a->u.statement.right = right; /* XXX check that a->u.statement.left->datatype is VOID ?? */ a->datatype = a->u.statement.right->datatype; /* haha... */ /* a->datatype = type_new_set(a->u.statement.left->datatype, a->u.statement.right->datatype); */ #ifdef DEBUG if (trace_type_inference) { printf("(statement)*****\n"); printf("type is: "); type_print(stdout, a->datatype); printf("\n****\n"); } #endif return(a); }
astp ast_new_w3params(int type,const char * text, astp p1, astp p2, astp p3){ if (print) { printf("ast_new_w3params...%s",text); fflush(stdout);} astp r=ast_new(type,text); ast_add_parameter(r,p1); ast_add_parameter(r,p2); ast_add_parameter(r,p3); if (print) printf("done\n"); return r; }
/* ast_ident_new: */ AST *ast_ident_new ( const gchar *name ) { AST *node; if (!(node = g_hash_table_lookup(ident_cache, name))) { node = ast_new(AST_TYPE_IDENT); node->ident.name = g_strdup(name); g_hash_table_insert(ident_cache, node->ident.name, node); } return node; }
struct ast * ast_new_conditional(struct scan_st *sc, struct ast *test, struct ast *yes, struct ast *no) { struct ast *a; int unify; struct type *t; a = ast_new(AST_CONDITIONAL); a->u.conditional.test = test; a->u.conditional.yes = yes; a->u.conditional.no = no; /* check that a->u.conditional.test is BOOLEAN */ /* XXX need not be new boolean - reuse an old one */ unify = type_unify_crit(sc, test->datatype, type_new(TYPE_BOOLEAN)); #ifdef DEBUG if (trace_type_inference) { printf("(if)*****\n"); printf("type of YES is: "); type_print(stdout, yes->datatype); if (no != NULL) { printf("\ntype of NO is: "); type_print(stdout, no->datatype); } } #endif /* XXX check that a->u.conditional.yes is VOID */ /* XXX check that a->u.conditional.no is VOID */ /* actually, either of these can be VOID, in which case, pick the other */ /* unify = type_unify_crit(sc, yes->datatype, no->datatype); */ /* haha */ if (no == NULL) { t = type_new(TYPE_VOID); } else { t = a->u.conditional.no->datatype; } a->datatype = type_new_set(a->u.conditional.yes->datatype, t); #ifdef DEBUG if (trace_type_inference) { printf("\nresult type is: "); type_print(stdout, a->datatype); printf("\n****\n"); } #endif return(a); }
void *ast_add_root(void *o) { t_ast *a; t_ast *r; a = o; if (!a) return (0); if (a->n_children <= 1) return (a); r = ast_new(">", ""); ast_add_child(r, a); return (r); }
/* ast_list_prepend: */ AST *ast_list_prepend ( AST *list, AST *item ) { AST *link; link = ast_new(AST_TYPE_LIST); AST_LIST(link)->item = item; if (list) { ASSERT(AST_IS_LIST(list)); ASSERT(!AST_LIST_PREV(list)); AST_LIST(list)->prev = link; AST_LIST(link)->next = list; } return link; }
// Add an AST node for the specified token, which may be deferred void add_deferrable_ast(parser_t* parser, rule_state_t* state, token_id id) { assert(parser->token != NULL); if(!state->matched && state->ast == NULL && !state->deferred) { // This is the first AST node, defer creation state->deferred = true; state->deferred_id = id; state->line = token_line_number(parser->token); state->pos = token_line_position(parser->token); return; } add_ast(parser, state, ast_new(parser->token, id), default_builder); }
t_ast *ast_new_from_string(char *input, int ast_flags, int line) { t_ast *ast; t_lst *tokens; t_tokenizer *tokenizer; print_if_verbose(input, ast_flags); tokenizer = tokenizer_new(input); tokenizer->cur_line = line; tokens = tokenizer_tokenize(tokenizer); ast = ast_new(tokens, ast_flags); twl_lst_iter(tokenizer->tok_open_stack, push_to_ast_open_stack, ast->ast_open_stack); tokenizer_del(tokenizer); token_mgr_del(tokens); return (ast); }
struct ast * ast_new_apply(struct scan_st *sc, struct ast *fn, struct ast *args, int is_pure) { struct ast *a; int unify; a = ast_new(AST_APPLY); a->u.apply.left = fn; a->u.apply.right = args; a->u.apply.is_pure = is_pure; type_ensure_routine(fn->datatype); #ifdef DEBUG if (trace_type_inference) { printf("(apply)*****\n"); printf("type of args is: "); if (args == NULL) printf("N/A"); else type_print(stdout, args->datatype); printf("\ntype of closure is: "); type_print(stdout, fn->datatype); } #endif if (args == NULL) { unify = type_unify_crit(sc, type_representative(fn->datatype)->t.closure.domain, type_new(TYPE_VOID)); /* XXX need not be new */ } else { unify = type_unify_crit(sc, type_representative(fn->datatype)->t.closure.domain, args->datatype); } #ifdef DEBUG if (trace_type_inference) { printf("\nthese unify? --> %d <--", unify); printf("\n****\n"); } #endif a->datatype = type_representative(fn->datatype)->t.closure.range; return(a); }
struct ast * ast_new_value(struct value v, struct type *t) { struct ast *a; a = ast_new(AST_VALUE); a->u.value.value = v; a->datatype = t; #ifdef DEBUG if (trace_type_inference) { printf("(value)*****\n"); printf("type is: "); type_print(stdout, a->datatype); printf("\n*******\n"); } #endif return(a); }
/* ast_list_append: */ AST *ast_list_append ( AST *list, AST *item ) { AST *link; link = ast_new(AST_TYPE_LIST); AST_LIST(link)->item = item; if (list) { AST *tail; ASSERT(AST_IS_LIST(list)); tail = ast_list_tail(list); AST_LIST(tail)->next = link; AST_LIST(link)->prev = tail; return list; } else { return link; } }
struct ast * ast_new_arg(struct ast *left, struct ast *right) { struct ast *a; if (left == NULL) return(NULL); a = ast_new(AST_ARG); a->u.arg.left = left; a->u.arg.right = right; if (a->u.arg.right == NULL) { a->datatype = a->u.arg.left->datatype; } else { a->datatype = type_new_arg( a->u.arg.left->datatype, a->u.arg.right->datatype); } return(a); }
struct ast * ast_new_retr(struct ast *body) { struct ast *a; a = ast_new(AST_RETR); a->u.retr.body = body; /* XXX check against other return statements in same function... somehow... */ a->datatype = a->u.retr.body->datatype; #ifdef DEBUG if (trace_type_inference) { printf("(retr)*****\n"); printf("type is: "); type_print(stdout, a->datatype); printf("\n****\n"); } #endif return(a); }
struct ast * ast_new_local(struct symbol_table *stab, struct symbol *sym) { struct ast *a; a = ast_new(AST_LOCAL); a->u.local.index = sym->index; a->u.local.upcount = stab->level - sym->in->level; a->u.local.sym = sym; a->datatype = sym->type; #ifdef DEBUG if (trace_type_inference) { printf("(new-local)*****\n"); printf("type is: "); type_print(stdout, a->datatype); printf("\n*******\n"); } #endif return(a); }
GtkWidget * create_view_and_model (SCTX_ void *ptr) { GtkTreeViewColumn *text; GtkCellRenderer *renderer; AstNode *root; GtkWidget *view; root = ast_new(sctx_ NULL, 0, "", ptr, inspect_symbol_list); view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(root)); g_object_unref(root); /* destroy store automatically with view */ renderer = gtk_cell_renderer_text_new(); text = gtk_tree_view_column_new_with_attributes("Node", renderer, "text", AST_COL_NAME, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(view), text); return view; }
struct ast * ast_new_assignment(struct scan_st *sc, struct ast *left, struct ast *right, int defining) { struct ast *a; int unify; /* * Do some 'self-repairing' in the case of syntax errors that * generate a corrupt AST (e.g. Foo = <eof>) */ if (right == NULL) return(left); a = ast_new(AST_ASSIGNMENT); a->u.assignment.left = left; a->u.assignment.right = right; a->u.assignment.defining = defining; unify = type_unify_crit(sc, left->datatype, right->datatype); #ifdef DEBUG if (trace_type_inference) { printf("(assign)*****\n"); printf("type of LHS is: "); type_print(stdout, left->datatype); printf("\ntype of RHS is: "); type_print(stdout, right->datatype); printf("\nthese unify? --> %d <--", unify); printf("\ntype of LHS is now: "); type_print(stdout, left->datatype); printf("\n****\n"); } #endif a->datatype = type_new(TYPE_VOID); return(a); }
/* ast_decl_new: */ static AST *ast_decl_new ( ASTType type, AST *context, CIdentType ident_type, AST *ident ) { AST *node; ASSERT(ast_type_isa(type, AST_TYPE_DECL)); ASSERT(AST_IS_IDENT(ident)); node = ast_new(type); AST_DECL(node)->ident = ident; if (context) { ASSERT(AST_IS_DECL(context)); AST_DECL(node)->context = context; AST_DECL(context)->members = ast_list_append(AST_DECL(context)->members, node); AST_DECL(node)->cident = c_ident_new(ident_type, AST_IDENT_NAME(ident), AST_DECL(context)->cident); } else { AST_DECL(node)->cident = c_ident_new(ident_type, AST_IDENT_NAME(ident), NULL); } return node; }
struct ast * ast_new_routine(struct ast *body) { struct ast *a; a = ast_new(AST_ROUTINE); a->u.routine.body = body; if (a->u.routine.body != NULL) a->datatype = a->u.routine.body->datatype; else a->datatype = type_new(TYPE_VOID); #ifdef DEBUG if (trace_type_inference) { printf("(routine)*****\n"); printf("type is: "); type_print(stdout, a->datatype); printf("\n****\n"); } #endif return(a); }
void ast_add_symbol(astp t,int type,char * c) { astp n=ast_new(type,c); ast_add_parameter(t,n); }
Ast* ast_insert_after(Ast* t) { Ast* p = ast_new(t->lineno, t->col); p->next = t->next; t->next = p; return p; }
/* * The main routine that takes the parse tree and coordinates all processing */ void process_tree(char *aspis_home, char* outpath, char * taintspath, char* prototypespath, char * categories, char *filename, astp tree) { FILE * fout = NULL; if (outpath != NULL && !COLLECT_INFO) { fout = fopen(outpath, "w"); if (fout == NULL) { die("Cannot write to output"); } } else fout = stdout; if (!is_online) { printf("\n\n==========================\n"); printf("| Parsing AST |\n"); printf("==========================\n\n"); } if (tree->type != T_INLINE_HTML && tree->type != T_INLINE_HTML_EQUALS) { astp p = ast_new(T_INLINE_HTML, ""); ast_add_child(p, tree); tree = p; } if (!is_online) ast_print_bfs(stdout, tree); if (!is_online) { printf("\n\n==========================\n"); printf("| Transforming AST |\n"); printf("==========================\n\n"); } astp functions_used; ast_transform(stdout,aspis_home, taintspath, prototypespath, categories, filename, &tree, &functions_used); if (!is_online) { printf("\n\n==========================\n"); printf("| Improving AST |\n"); printf("==========================\n\n"); } ast_improve(stdout, &tree); if (!is_online) { printf("\n\n==========================\n"); printf("| Final AST |\n"); printf("==========================\n\n"); } script_stage = 0; if (!COLLECT_INFO) ast_print_bfs(fout, tree); if (!is_online) { printf("\n\n==========================\n"); printf("| Built-in Functions used |\n"); printf("==========================\n\n"); } script_stage = 0; if (COLLECT_INFO) { FILE * fused = fopen("fused.txt", "a"); ast_print_bfs(fused, functions_used); fclose(fused); } //let's output the result if (fout!=stdout && !is_online ) { fflush(fout); fclose(fout); printf("File (%s) closed\n",outpath); char str[1000]; sprintf(str,"cat %s",outpath); printf("--------->%s\n",str); if (system(str)==-1) die("cat failed?!"); printf("\n----------\n"); } }
struct ast * ast_new_builtin(struct scan_st *sc, struct builtin *bi, struct ast *right) { struct ast *a; struct type *t, *tr; int unify = 0; t = bi->ty(); type_ensure_routine(t); #ifdef DEBUG if (trace_type_inference) { printf("(builtin `"); fputsu8(stdout, bi->name); printf("`)*****\n"); printf("type of args is: "); if (right != NULL) type_print(stdout, right->datatype); printf("\ntype of builtin is: "); type_print(stdout, t); } #endif if (right == NULL) tr = type_new(TYPE_VOID); else tr = right->datatype; unify = type_unify_crit(sc, type_representative(t)->t.closure.domain, tr); #ifdef DEBUG if (trace_type_inference) { printf("\nthese unify? --> %d <--", unify); printf("\n****\n"); } #endif /* * Fold constants. */ if (bi->is_pure && ast_is_constant(right)) { struct value v; struct activation *ar; struct ast *g; int i = 0; int varity; if (bi->arity == -1) { varity = ast_count_args(right); } else { varity = bi->arity; } if (unify) { ar = activation_new_on_heap(varity, NULL, NULL); for (g = right, i = 0; g != NULL && g->type == AST_ARG && i < varity; g = g->u.arg.right, i++) { if (g->u.arg.left != NULL) activation_initialize_value(ar, i, g->u.arg.left->u.value.value); } v = bi->fn(ar); } else { a = NULL; } a = ast_new_value(v, type_representative(t)->t.closure.range); return(a); } a = ast_new(AST_BUILTIN); a->u.builtin.bi = bi; a->u.builtin.right = right; a->datatype = type_representative(t)->t.closure.range; return(a); }