POETCode* eval_cvar_attr(CodeVar* cv, LocalVar* lv) { CvarSymbolTable::Entry cv_e = cv->get_entry(); LvarSymbolTable* symTable = cv_e.get_symTable(); LvarSymbolTable::Entry e = lv->get_entry(); if (symTable->find(e.get_name()) != lv) return 0; POETCode* res = 0; switch (e.get_entry_type()) { case LVAR_CODEPAR: res = eval_tuple_access(cv->get_args(), e.get_code()); break; case LVAR_ATTR: for (int i = 0; i < cv_e.attr_size(); ++i) { if (cv_e.get_attr(i) == lv) { POETCode* tuple = cv->get_attr(); if (tuple == 0) res = e.get_code(); else res = eval_tuple_access(tuple,i); break; } } break; default: /*QY: access is a local variable. treat this as tuple access*/ res = eval_tuple_access(cv, lv); } return res; }
POETCode* CodeVar::get_static_attr(const std::string& name) const { LvarSymbolTable* local = get_entry().get_symTable(); LocalVar* b = local->find(ASTFactory::inst()->new_string(name)); if (b != 0) return b->get_entry().get_code(); return 0; }
virtual void visitCodeVar(CodeVar* v) { try { POETCode* _listsep = listsep; CodeVar* _listelem = listelem; POETCode* result = v->invoke_output(v->get_args()); if (result != 0 && result != v) { listsep = 0; listelem=0; result->visit(this); listsep = _listsep; listelem=_listelem; return; } CvarSymbolTable::Entry e = v->get_entry(); LvarSymbolTable *local = 0; POETCode* f = 0; POETCode *parse = e.get_parse(); if (parse != 0 && parse->get_enum()==SRC_OP) { POETOperator* op = static_cast<POETOperator*>(parse); if (op->get_op() == POET_OP_LIST || op->get_op()==POET_OP_LIST1) { listsep = op->get_arg(1); listelem=dynamic_cast<CodeVar*>(op->get_arg(0)); f = v->get_args(); } } if (f == 0) { listsep = 0; listelem=0; f = e.get_code(); if (f == 0) { if (parse==0) { CODE_SYNTAX_UNDEFINED(v->toString()); } else f = v->get_args(); } else { local = e.get_symTable(); if (local != 0) local->push_table(false); POETCode* pars = e.get_param(); if (pars != 0 && !match_parameters(pars, v->get_args(),MATCH_PAR_MOD_CODE)) CVAR_MISMATCH(v,pars, v->get_args()); v->set_attr(); } } if (f == 0) { CODE_SYNTAX_UNDEFINED(v->toString()); } int save = align; align = start_pos; f->visit(this); align = save; if (local != 0) local->pop_table(); listsep = _listsep; listelem=_listelem; } catch (Error err) { std::cerr << " From unparsing code template " << SHORT(v->toString(),500) << "\n"; throw err; } }
extern "C" POETCode* make_localPar(POETCode* id, POETCode* restr, LocalVarType type) { try { LvarSymbolTable* local = top_scope(); assert(local != 0); LocalVar* res = local->insert(id, type); POETCode* restr1 = res->get_entry().get_restr(); if (restr != 0 && restr1 != 0 && restr != restr1 && !match_AST(restr,restr1, MATCH_AST_EQ)) { SYM_DIFF_DEFINED(id->toString() + ":" + restr->get_className() + ":" + restr->toString(),restr1->get_className() + ":" + restr1->toString()); return res; } if (restr != 0) res->get_entry().set_restr(restr); return res; } catch (Error err) { std::cerr << "\nAt line " << yylineno << " of file " << curfile->get_filename() << "\n"; exit(1); } }
POETCode* eval_cvar_access(CodeVar* cv, POETCode* access) { POETCode* res = 0; CvarSymbolTable::Entry cv_e = cv->get_entry(); LvarSymbolTable* symTable = cv_e.get_symTable(); symTable->push_table(true); /* push symbol table for evaluation of access*/ if (access->get_enum() != SRC_LVAR) access= apply(access); switch (access->get_enum()) { case SRC_LVAR: { cv->get_entry().get_symTable()->pop_table(); LocalVar* lv = static_cast<LocalVar*>(access); res = eval_cvar_attr(cv, lv); if (res == 0) { CVAR_ACC_MISMATCH( cv,access); } break; } case SRC_OP: { POETOperator* op = static_cast<POETOperator*>(access); if (op->get_op() == TYPE_TOR) { cv->get_entry().get_symTable()->pop_table(); for (int i = 0; i < op->numOfArgs(); ++i) { POETCode* cur = apply(op->get_arg(i)); LocalVar* lv = dynamic_cast<LocalVar*>(cur); if (lv == 0) { CVAR_ACC_MISMATCH( cv,access); } res = eval_cvar_attr(cv, lv); if (res != 0) return res; } CVAR_ACC_MISMATCH( cv,access); } } default: if (cv->get_args() != 0) CVAR_ACC_MISMATCH( cv, access); /*QY: access is used to set optional attribute values of code template; return a new code template object with the given attribute*/ res = ASTFactory::inst()->build_codeRef(cv->get_entry(),0); cv->get_entry().get_symTable()->pop_table(); break; } return res; }