#include "Evalvisitor.h" #include #include #include "Python3ParserBaseVisitor.h" #include "int2048/int2048.h" #include "names.h" #include "utils.h" VariableContainer Variables; FucntionContainer Functions; std::any EvalVisitor::visitFile_input(Python3Parser::File_inputContext *ctx) { return visitChildren(ctx); } std::any EvalVisitor::visitFuncdef(Python3Parser::FuncdefContext *ctx) { std::vector paraVec = std::any_cast>( visitParameters(ctx->parameters())); std::string name = ctx->NAME()->getText(); Functions.AddFunction(name, FunctionItem(ctx->suite(), paraVec)); return NoneType(); } std::any EvalVisitor::visitParameters(Python3Parser::ParametersContext *ctx) { if (!ctx->typedargslist()) return std::vector(); else return visitTypedargslist(ctx->typedargslist()); } std::any EvalVisitor::visitTypedargslist( Python3Parser::TypedargslistContext *ctx) { auto tfpdef_list = ctx->tfpdef(); auto default_value_list = ctx->test(); const int lenght_delta = tfpdef_list.size() - default_value_list.size(); std::vector res; res.reserve(tfpdef_list.size()); for (int i = 0; i < lenght_delta; i++) res.emplace_back(tfpdef_list[i]->NAME()->getText(), nullptr); for (int i = lenght_delta; i < tfpdef_list.size(); i++) res.emplace_back(tfpdef_list[i]->NAME()->getText(), DeQuate(visitTest(default_value_list[i - lenght_delta]), Variables)); return res; } std::any EvalVisitor::visitTfpdef(Python3Parser::TfpdefContext *ctx) { return ctx->NAME()->getText(); } std::any EvalVisitor::visitStmt(Python3Parser::StmtContext *ctx) { if (ctx->compound_stmt()) return visitCompound_stmt(ctx->compound_stmt()); return visitSimple_stmt(ctx->simple_stmt()); } std::any EvalVisitor::visitSimple_stmt(Python3Parser::Simple_stmtContext *ctx) { return visitSmall_stmt(ctx->small_stmt()); } std::any EvalVisitor::visitSmall_stmt(Python3Parser::Small_stmtContext *ctx) { if (ctx->expr_stmt()) return visitExpr_stmt(ctx->expr_stmt()); else return visitFlow_stmt(ctx->flow_stmt()); } std::any EvalVisitor::visitExpr_stmt(Python3Parser::Expr_stmtContext *ctx) { if (!ctx->augassign() && !ctx->ASSIGN(0)) return visitTestlist(ctx->testlist(0)); if (ctx->augassign()) { auto left_value = visitTestlist(ctx->testlist(0)); auto right_value = visitTestlist(ctx->testlist(1)); right_value = DeQuate(right_value, Variables); RawVarible *ptr_var = std::any_cast(&left_value); std::vector *ptr_vec = std::any_cast>(&left_value); if (!ptr_var && !ptr_vec) throw InterpretException( "visitExpr_stmt: Expect left value or tuple at the left of " "augassign"); if (ptr_var) { std::any old_val = DeQuate(*ptr_var, Variables); if (ctx->augassign()->ADD_ASSIGN()) SelfAdd(old_val, right_value); else if (ctx->augassign()->SUB_ASSIGN()) SelfSub(old_val, right_value); else if (ctx->augassign()->MULT_ASSIGN()) SelfMul(old_val, right_value); else if (ctx->augassign()->DIV_ASSIGN()) SelfDiv(old_val, right_value); else if (ctx->augassign()->IDIV_ASSIGN()) SelfDivv(old_val, right_value); else if (ctx->augassign()->MOD_ASSIGN()) SelfMod(old_val, right_value); else throw FatalError("visitExpr_stmt: Unknown operator at augassign"); Variables.WriteVariable(ptr_var->name, old_val); } else { if (ptr_vec->size() != std::any_cast>(right_value).size()) throw InterpretException("visitExpr_stmt: Tuple size not match"); for (int i = 0; i < ptr_vec->size(); i++) { ptr_var = std::any_cast(&(*ptr_vec)[i]); if (!ptr_var) throw InterpretException( "visitExpr_stmt: Expect left value at the left of augassign"); std::any old_val = DeQuate(*ptr_var, Variables); if (ctx->augassign()->ADD_ASSIGN()) SelfAdd(old_val, std::any_cast>(right_value)[i]); else if (ctx->augassign()->SUB_ASSIGN()) SelfSub(old_val, std::any_cast>(right_value)[i]); else if (ctx->augassign()->MULT_ASSIGN()) SelfMul(old_val, std::any_cast>(right_value)[i]); else if (ctx->augassign()->DIV_ASSIGN()) SelfDiv(old_val, std::any_cast>(right_value)[i]); else if (ctx->augassign()->IDIV_ASSIGN()) SelfDivv(old_val, std::any_cast>(right_value)[i]); else if (ctx->augassign()->MOD_ASSIGN()) SelfMod(old_val, std::any_cast>(right_value)[i]); else throw FatalError("visitExpr_stmt: Unknown operator at augassign"); Variables.WriteVariable(ptr_var->name, old_val); } } return nullptr; } auto testlist_list = ctx->testlist(); auto val = visitTestlist(testlist_list[testlist_list.size() - 1]); val = DeQuate(val, Variables); for (int i = testlist_list.size() - 2; i >= 0; i--) { auto dest = visitTestlist(testlist_list[i]); RawVarible *ptr_dest_single = std::any_cast(&dest); std::vector *ptr_dest_tuple = std::any_cast>(&dest); if (ptr_dest_single) Variables.WriteVariable(ptr_dest_single->name, val); else if (ptr_dest_tuple) { if (ptr_dest_tuple->size() != std::any_cast>(val).size()) throw InterpretException("visitExpr_stmt: Tuple size not match"); for (int j = 0; j < ptr_dest_tuple->size(); j++) { ptr_dest_single = std::any_cast(&(*ptr_dest_tuple)[j]); if (!ptr_dest_single) throw InterpretException( "visitExpr_stmt: Expect left value at the left of assign"); Variables.WriteVariable(ptr_dest_single->name, std::any_cast>(val)[j]); } } else throw InterpretException( "visitExpr_stmt: Expect left value or tuple at the left of assign"); } return nullptr; } std::any EvalVisitor::visitAugassign(Python3Parser::AugassignContext *ctx) { throw FatalError("Function visitAugassign Shouldn't be called"); } std::any EvalVisitor::visitFlow_stmt(Python3Parser::Flow_stmtContext *ctx) { if (ctx->break_stmt()) return visitBreak_stmt(ctx->break_stmt()); if (ctx->continue_stmt()) return visitContinue_stmt(ctx->continue_stmt()); if (ctx->return_stmt()) return visitReturn_stmt(ctx->return_stmt()); } std::any EvalVisitor::visitBreak_stmt(Python3Parser::Break_stmtContext *ctx) { return FlowType(BREAK); } std::any EvalVisitor::visitContinue_stmt( Python3Parser::Continue_stmtContext *ctx) { return FlowType(CONTINUE); } std::any EvalVisitor::visitReturn_stmt(Python3Parser::Return_stmtContext *ctx) { if (!ctx->testlist()) return FlowType(RETURN, std::vector()); std::any val = visitTestlist(ctx->testlist()); std::vector *val_ptr = std::any_cast>(&val); if (val_ptr) return FlowType(RETURN, *val_ptr); std::vector tmp; tmp.push_back(val); // std::cerr << "ready to send return value" << Any2String(val) << std::endl; return FlowType(RETURN, tmp); } std::any EvalVisitor::visitCompound_stmt( Python3Parser::Compound_stmtContext *ctx) { if (ctx->if_stmt()) return visitIf_stmt(ctx->if_stmt()); if (ctx->while_stmt()) return visitWhile_stmt(ctx->while_stmt()); if (ctx->funcdef()) return visitFuncdef(ctx->funcdef()); } std::any EvalVisitor::visitIf_stmt(Python3Parser::If_stmtContext *ctx) { auto test_list = ctx->test(); auto suite_list = ctx->suite(); if (test_list.size() - suite_list.size() != -1 && test_list.size() - suite_list.size() != 0) throw InterpretException("test and suite doesn't match in If_stmt"); for (int i = 0; i < test_list.size(); i++) if (Any2Bool(DeQuate(visitTest(test_list[i]), Variables))) return visitSuite(suite_list[i]); if (test_list.size() - suite_list.size() == 1) return visitSuite(suite_list[suite_list.size() - 1]); return nullptr; } std::any EvalVisitor::visitWhile_stmt(Python3Parser::While_stmtContext *ctx) { auto test = ctx->test(); auto suite = ctx->suite(); while (Any2Bool(DeQuate(visitTest(test), Variables))) { auto res = visitSuite(suite); FlowType *res_ptr = std::any_cast(&res); if (res_ptr) { if (res_ptr->Status == BREAK) break; if (res_ptr->Status == CONTINUE) continue; if (res_ptr->Status == RETURN) return *res_ptr; } } return nullptr; } std::any EvalVisitor::visitSuite(Python3Parser::SuiteContext *ctx) { if (ctx->simple_stmt()) return visitSimple_stmt(ctx->simple_stmt()); auto stmt_list = ctx->stmt(); std::any res; for (int i = 0; i < stmt_list.size(); i++) { res = visitStmt(stmt_list[i]); FlowType *res_ptr = std::any_cast(&res); if (res_ptr) return res; } return res; } std::any EvalVisitor::visitTestlist(Python3Parser::TestlistContext *ctx) { auto test_list = ctx->test(); if (test_list.size() == 1) return visitTest(test_list[0]); std::vector res; for (auto item : test_list) { res.push_back(visitTest(item)); } return res; } std::any EvalVisitor::visitTest(Python3Parser::TestContext *ctx) { return visitOr_test(ctx->or_test()); } std::any EvalVisitor::visitOr_test(Python3Parser::Or_testContext *ctx) { auto or_list = ctx->and_test(); if (or_list.size() == 1) return visitAnd_test(or_list[0]); for (auto or_item : or_list) { if (Any2Bool(DeQuate(visitAnd_test(or_item), Variables))) return true; } return false; } std::any EvalVisitor::visitAnd_test(Python3Parser::And_testContext *ctx) { auto not_list = ctx->not_test(); if (not_list.size() == 1) return visitNot_test(not_list[0]); for (auto not_item : not_list) { if (!Any2Bool(DeQuate(visitNot_test(not_item), Variables))) return false; } return true; } std::any EvalVisitor::visitNot_test(Python3Parser::Not_testContext *ctx) { if (!ctx->NOT()) return visitComparison(ctx->comparison()); return !Any2Bool(DeQuate(visitNot_test(ctx->not_test()), Variables)); } std::any EvalVisitor::visitComparison(Python3Parser::ComparisonContext *ctx) { auto arith_expr_list = ctx->arith_expr(); auto last_val = visitArith_expr(arith_expr_list[0]); if (arith_expr_list.size() == 1) return last_val; last_val = DeQuate(last_val, Variables); auto op_list = ctx->comp_op(); for (int i = 0; i < op_list.size(); i++) { auto cur = visitArith_expr(arith_expr_list[i + 1]); cur = DeQuate(cur, Variables); bool ok = false; if (op_list[i]->GREATER_THAN()) ok = Greater(last_val, cur); else if (op_list[i]->LESS_THAN()) ok = Less(last_val, cur); else if (op_list[i]->EQUALS()) ok = Equal(last_val, cur); else if (op_list[i]->NOT_EQ_2()) ok = NotEqual(last_val, cur); else if (op_list[i]->GT_EQ()) ok = GreaterEqual(last_val, cur); else if (op_list[i]->LT_EQ()) ok = LessEqual(last_val, cur); else throw InterpretException("visitComparison: Unknown operator"); if (!ok) return false; last_val = cur; } return true; } std::any EvalVisitor::visitComp_op(Python3Parser::Comp_opContext *ctx) { throw FatalError("Function visitComp_op Shouldn't be called"); } std::any EvalVisitor::visitArith_expr(Python3Parser::Arith_exprContext *ctx) { auto term_list = ctx->term(); auto ans = visitTerm(term_list[0]); if (term_list.size() == 1) return ans; auto op_list = ctx->addorsub_op(); ans = DeQuate(ans, Variables); for (int i = 0; i < op_list.size(); i++) { auto cur = visitTerm(term_list[i + 1]); cur = DeQuate(cur, Variables); if (op_list[i]->ADD()) SelfAdd(ans, cur); else if (op_list[i]->MINUS()) SelfSub(ans, cur); else throw FatalError("visitArith_expr: Unknown operator"); } return ans; } std::any EvalVisitor::visitAddorsub_op(Python3Parser::Addorsub_opContext *ctx) { throw FatalError("Function visitAddorsub_op Shouldn't be called"); } std::any EvalVisitor::visitTerm(Python3Parser::TermContext *ctx) { auto factor_list = ctx->factor(); auto ans = visitFactor(factor_list[0]); if (factor_list.size() == 1) return ans; auto op_list = ctx->muldivmod_op(); ans = DeQuate(ans, Variables); for (int i = 0; i < op_list.size(); i++) { auto cur = visitFactor(factor_list[i + 1]); cur = DeQuate(cur, Variables); if (op_list[i]->STAR()) SelfMul(ans, cur); else if (op_list[i]->DIV()) SelfDiv(ans, cur); else if (op_list[i]->IDIV()) SelfDivv(ans, cur); else if (op_list[i]->MOD()) SelfMod(ans, cur); else throw FatalError("visitTerm: Unknown operator"); } return ans; } std::any EvalVisitor::visitMuldivmod_op( Python3Parser::Muldivmod_opContext *ctx) { throw FatalError("Function visitMuldivmod_op Shouldn't be called"); } std::any EvalVisitor::visitFactor(Python3Parser::FactorContext *ctx) { if (ctx->atom_expr()) return visitAtom_expr(ctx->atom_expr()); std::any res = visitFactor(ctx->factor()); res = DeQuate(res, Variables); if (ctx->MINUS()) res = Neg(res); return res; } std::any EvalVisitor::visitAtom_expr(Python3Parser::Atom_exprContext *ctx) { if (!ctx->trailer()) return visitAtom(ctx->atom()); std::string func_name = ctx->atom()->NAME()->getText(); std::vector args = std::any_cast>( visitTrailer(ctx->trailer())); return Functions.CallFunction(func_name, args, Variables); } std::any EvalVisitor::visitTrailer(Python3Parser::TrailerContext *ctx) { if (!ctx->arglist()) return std::vector(); return visitArglist(ctx->arglist()); } std::any EvalVisitor::visitArglist(Python3Parser::ArglistContext *ctx) { auto argument_list = ctx->argument(); std::vector resolved_args; for (auto item : argument_list) { resolved_args.push_back( std::any_cast(visitArgument(item))); } return resolved_args; } std::any EvalVisitor::visitArgument(Python3Parser::ArgumentContext *ctx) { auto arg_list = ctx->test(); if (arg_list.size() != 1 && arg_list.size() != 2) throw FatalError("visitArgument: arg_list.size()!=1&&arg_list!=2"); if (arg_list.size() == 1) return ParaArguItemType("", DeQuate(visitTest(arg_list[0]), Variables)); else return ParaArguItemType(arg_list[0]->getText(), DeQuate(visitTest(arg_list[1]), Variables)); } std::any EvalVisitor::visitAtom(Python3Parser::AtomContext *ctx) { if (ctx->NONE()) return NoneType(); else if (ctx->TRUE()) return true; else if (ctx->FALSE()) return false; else if (ctx->NUMBER()) { std::string num = ctx->getText(); if (num.find('.') == std::string::npos) return std::move(ZYM::int2048(num)); else return std::stod(num); } else if (ctx->test()) return visitTest(ctx->test()); else if (ctx->NAME()) { return RawVarible(ctx->getText()); } else { auto string_lists = ctx->STRING(); std::string res; for (auto item : string_lists) { const std::string &tmp = item->getText(); res.append(tmp, 1, tmp.size() - 2); } // std::cerr<<"[Log] The string is : "<