void Expr::verify() { if (prev || next) if (!list) INT_FATAL(this, "Expr is in list but does not point at it"); if (prev && prev->next != this) INT_FATAL(this, "Bad Expr->prev->next"); if (next && next->prev != this) INT_FATAL(this, "Bad Expr->next->prev"); if (!parentSymbol) INT_FATAL(this, "Expr::parentSymbol is NULL"); if (parentExpr && parentExpr->parentSymbol != parentSymbol) INT_FATAL(this, "Bad Expr::parentSymbol"); if (list && parentExpr && list->parent != parentExpr) INT_FATAL(this, "Bad Expr::list::parent"); if (list && !parentExpr) { if (Symbol* lps = toSymbol(list->parent)) if (lps != parentSymbol) INT_FATAL(this, "Bad symbol Expr::list::parent"); if (Type* lpt = toType(list->parent)) if (lpt->symbol != parentSymbol) INT_FATAL(this, "Bad type Expr::list::parent"); if (isExpr(list->parent)) INT_FATAL(this, "Expr::list::parent is an Expr unexpectedly"); } }
// expr_list // : expr // | expr_list ',' expr // ; int isExprList() { int key = isExpr(); if (match(',')) { advance(); isExprList(); } return key; }
// expression_statement // : ';' // | expr ';' // ; int isExpressionStatement() { if (match(';')) { advance(); return 1; } if (isExpr()) { if (match(';')) { advance(); return 1; } } return 0; }
static void list_ast(BaseAST* ast, BaseAST* parentAst = NULL, int indent = 0) { bool do_list_line = false; bool is_C_loop = false; const char* block_explain = NULL; if (Expr* expr = toExpr(ast)) { do_list_line = !parentAst || list_line(expr, parentAst); if (do_list_line) { printf("%-7d ", expr->id); for (int i = 0; i < indent; i++) printf(" "); } if (GotoStmt* e = toGotoStmt(ast)) { printf("goto "); if (SymExpr* label = toSymExpr(e->label)) { if (label->var != gNil) { list_ast(e->label, ast, indent+1); } } else { list_ast(e->label, ast, indent+1); } } else if (toBlockStmt(ast)) { block_explain = block_explanation(ast, parentAst); printf("%s{\n", block_explain); } else if (toCondStmt(ast)) { printf("if "); } else if (CallExpr* e = toCallExpr(expr)) { if (e->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) is_C_loop = true; if (e->primitive) printf("%s( ", e->primitive->name); else printf("call( "); } else if (NamedExpr* e = toNamedExpr(expr)) { printf("%s = ", e->name); } else if (toDefExpr(expr)) { printf("def "); } else if (SymExpr* e = toSymExpr(expr)) { list_sym(e->var, false); } else if (UnresolvedSymExpr* e = toUnresolvedSymExpr(expr)) { printf("%s ", e->unresolved); } } if (Symbol* sym = toSymbol(ast)) list_sym(sym); bool early_newline = toFnSymbol(ast) || toModuleSymbol(ast); if (early_newline || is_C_loop) printf("\n"); int new_indent = indent; if (isExpr(ast)) if (do_list_line) new_indent = indent+2; AST_CHILDREN_CALL(ast, list_ast, ast, new_indent); if (Expr* expr = toExpr(ast)) { CallExpr* parent_C_loop = NULL; if (CallExpr* call = toCallExpr(parentAst)) if (call->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) parent_C_loop = call; if (toCallExpr(expr)) { printf(") "); } if (toBlockStmt(ast)) { printf("%-7d ", expr->id); if (*block_explain) indent -= 2; for (int i = 0; i < indent; i++) printf(" "); if ((parent_C_loop && parent_C_loop->get(3) == expr) || *block_explain) printf("} "); else printf("}\n"); } else if (CondStmt* cond = toCondStmt(parentAst)) { if (cond->condExpr == expr) printf("\n"); } else if (!toCondStmt(expr) && do_list_line) { DefExpr* def = toDefExpr(expr); if (!(def && early_newline)) if (!parent_C_loop) printf("\n"); } } }
static void list_ast(BaseAST* ast, BaseAST* parentAst = NULL, int indent = 0) { bool do_list_line = false; bool is_C_loop = false; const char* block_explain = NULL; if (Expr* expr = toExpr(ast)) { if (ForallStmt* pfs = toForallStmt(parentAst)) { if (expr == pfs->fRecIterIRdef) { printf("fRecIterIRdef"); } else if (expr == pfs->loopBody()) { if (pfs->numShadowVars() == 0) print_on_its_own_line(indent, "with() do\n"); else print_on_its_own_line(indent, "do\n", false); indent -= 2; } } do_list_line = !parentAst || list_line(expr, parentAst); if (do_list_line) { printf("%-7d ", expr->id); print_indent(indent); } if (const char* expl = forall_explanation_start(ast, parentAst)) printf("%s", expl); if (GotoStmt* e = toGotoStmt(ast)) { printf("goto "); if (SymExpr* label = toSymExpr(e->label)) { if (label->symbol() != gNil) { list_ast(e->label, ast, indent+1); } } else { list_ast(e->label, ast, indent+1); } } else if (toBlockStmt(ast)) { block_explain = block_explanation(ast, parentAst); const char* block_kind = ast->astTagAsString(); if (!strcmp(block_kind, "BlockStmt")) block_kind = ""; printf("%s{%s\n", block_explain, block_kind); } else if (toCondStmt(ast)) { printf("if "); } else if (toIfExpr(ast)) { printf("IfExpr "); } else if (toForallStmt(ast)) { printf("forall\n"); } else if (CallExpr* e = toCallExpr(expr)) { if (e->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) is_C_loop = true; if (e->primitive) printf("%s( ", e->primitive->name); else printf("call( "); } else if (ForallExpr* e = toForallExpr(expr)) { if (e->zippered) printf("zip "); printf("forall( "); } else if (NamedExpr* e = toNamedExpr(expr)) { printf("%s = ", e->name); } else if (toDefExpr(expr)) { Symbol* sym = toDefExpr(expr)->sym; if (sym->type != NULL) { printf("def %s ", sym->qualType().qualStr()); } else { printf("def "); } } else if (SymExpr* e = toSymExpr(expr)) { list_sym(e->symbol(), false); } else if (UnresolvedSymExpr* e = toUnresolvedSymExpr(expr)) { printf("%s ", e->unresolved); } else if (isUseStmt(expr)) { printf("use "); } } if (Symbol* sym = toSymbol(ast)) list_sym(sym); bool early_newline = toFnSymbol(ast) || toModuleSymbol(ast); if (early_newline || is_C_loop) printf("\n"); int new_indent = indent; if (isExpr(ast)) if (do_list_line) new_indent = indent+2; AST_CHILDREN_CALL(ast, list_ast, ast, new_indent); if (Expr* expr = toExpr(ast)) { CallExpr* parent_C_loop = NULL; if (CallExpr* call = toCallExpr(parentAst)) if (call->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) parent_C_loop = call; if (toCallExpr(expr)) { printf(") "); } if (toBlockStmt(ast)) { printf("%-7d ", expr->id); if (*block_explain) indent -= 2; print_indent(indent); if ((parent_C_loop && parent_C_loop->get(3) == expr) || *block_explain) printf("} "); else if (isDeferStmt(parentAst)) printf("}"); // newline is coming else printf("}\n"); if (isForallLoopBody(expr) && parentAst != NULL) { print_indent(indent); printf(" end forall %d", parentAst->id); } } else if (ForallExpr* e = toForallExpr(expr)) { if (e->cond) printf(") "); else printf("} "); } else if (UseStmt* use = toUseStmt(expr)) { if (!use->isPlainUse()) { if (use->hasExceptList()) { printf("except "); } else { printf("only "); } bool first = true; for_vector(const char, str, use->named) { if (first) { first = false; } else { printf(", "); } printf("%s", str); } for (std::map<const char*, const char*>::iterator it = use->renamed.begin(); it != use->renamed.end(); ++it) { if (first) { first = false; } else { printf(", "); } printf("%s as %s", it->second, it->first); } printf("\n"); } } else if (CondStmt* cond = toCondStmt(parentAst)) {
// primary_expr // : ID '(' expr_list ')' // | ID '(' ')' // | '(' expr ')' // | ID // | NUMBER // | STRING // | ID ASSIGN expr // | ID '=' expr // | ID '[' expr ']' // | ID '[' expr ']' '=' expr // ; int isPrimaryExpr() { if (match(ID)) { advance(); if (match('(')) { advance(); if (isExprList()) { if (match(')')) { advance(); return 1; } } if (match(')')) { advance(); return 1; } } if (match(ASSIGN)) { advance(); if (isExpr()) { return 1; } } if (match('=')) { advance(); if (isExpr()) { return 1; } } if (match('[')) { advance(); if (isExpr()) { if (match(']')) { advance(); if (match('=')) { advance(); if (isExpr()) { return 1; } } return 1; } } } return 1; } if (match('(')) { advance(); if (isExpr()) { if (match(')')) { advance(); return 1; } } } if (match(NUMBER)) { advance(); return 1; } if (match(STRING)) { advance(); return 1; } return 0; }
// statement // : type declarator_list ';' // | '{' statement_list '}' // | expr_statement // | IF '(' expr ')' statement // | IF '(' expr ')' statement ELSE statement // | WHILE '(' expr ')' statement // | RETURN ';' // | RETURN expr ';' // | PRINT '; // | PRINT expr_list ';' // | SCAN id_list ';' // ; int isStatement() { if (isType()) { if(isDeclaratorList()) { if (match(';')) { advance(); return 1; } } } if (match('{')) { advance(); if (isStatementList()) { if (match('}')) { advance(); return 1; } } } if (isExpressionStatement()) { return 1; } if (match(IF)) { advance(); if (match('(')) { advance(); if (isExpr()) { if (match(')')) { advance(); if (isStatement()) { if (match(ELSE)) { advance(); if (isStatement()) { return 1; } } return 1; } } } } } if (match(WHILE)) { advance(); if (match('(')) { advance(); if (isExpr()) { if (match(')')) { advance(); if (isStatement()) { return 1; } } } } } if (match(RETURN)) { advance(); if (match(';')) { advance(); return 1; } if (isExpr()) { if (match(';')) { advance(); return 1; } } } if (match(PRINT)) { advance(); if (match(';')) { advance(); return 1; } if (isExprList()) { if (match(';')) { advance(); return 1; } } } if (match(SCAN)) { advance(); if (isIDList()) { if (match(';')) { return 1; } } } return 0; }
// declarator // : ID // | ID '=' expr // | ID '(' parameter_list ')' // | ID '(' ')' // | ID '[' expr ']' // | ID '[' ']' // | ID '[' expr ']' '=' '{' intstr_list '}' // | ID '[' ']' '=' '{' intstr_list '}' // ; int isDeclarator() { if (match(ID)) { advance(); if (match('=')) { advance(); if(isExpr()); return 1; } else if (match('(')) { advance(); if (isParameterList()) { if(match(')')) { advance(); return 1; } } else if (match(')')) { advance(); return 1; } } if (match('[')) { advance(); if (isExpr()) { if (match(']')) { advance(); if (match('=')) { advance(); if (match('{')) { advance(); if (isIntstrList()) { if (match('}')) { advance(); return 1; } } } } return 1; } } else if(match(']')) { advance(); if (match('=')) { advance(); if (match('}')) { if (isIntstrList()) { if (match('}')) { advance(); return 1; } } } } } } return 1; } return 0; }