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; } }
void output(POETString* s) { ASTFactory* fac = ASTFactory::inst(); std::string r = s->get_content(); if (r == "\n") { for (int i = 0; i < align; ++i) r = r + " "; s = fac->new_string(r); } if (output_xform == 0) output_content(r,r); else { POETCode* args = fac->new_pair(s, fac->new_iconst(cur_pos)); if (!match_parameters(output_xform->get_entry().get_param(), args, MATCH_PAR_MOD_CODE)) INCORRECT_XFORM_DEF("output(string,cur_pos)", output_xform->toString()); XformVarInvoke invoke(output_xform->get_entry(), output_xform->get_config(), args); POETCode* res = invoke.eval(0); output_content(res->toString(OUTPUT_NO_DEBUG),r); } }
CodeVar* ASTFactory:: build_codeRef(CvarSymbolTable::Entry e, POETCode* args, POETCode* attr) { POETCode* pars=e.get_param(); if (pars != 0 && args != 0) { e.get_symTable()->push_table(false); if (!match_parameters(pars, args, MATCH_PAR_MOD_CODE)) CVAR_MISMATCH(e.get_name(), pars, args); } int size = e.attr_size(); if (size > 0 && attr == 0) { if (size == 1) attr = eval_AST(e.get_attr(0)->get_entry().get_code()); else { attr = new_pair(eval_AST(e.get_attr(0)->get_entry().get_code()), eval_AST(e.get_attr(1)->get_entry().get_code())); for (int i = 2; i < size; ++i) attr = append_tuple(attr, eval_AST(e.get_attr(i)->get_entry().get_code())); } } if (pars != 0 && args != 0) e.get_symTable()->pop_table(); CvarTable* m = get_cvarTable(e); return static_cast<CodeVar*>(m->new_item(args, attr)); }
static void run_decoders(struct parser_state *state) { size_t i; const char* name; struct tokens *tokens = &state->tokens; for(i = 0; i < tokens->cnt; i++) { const char *cstring = TOKEN_GET(&tokens->data[i], cstring); struct decode_result res; res.pos_begin = res.pos_end = 0; res.append = 0; if(tokens->data[i].type == TOK_FUNCTION && i+13 < tokens->cnt) { name = NULL; ++i; if(tokens->data[i].type == TOK_IDENTIFIER_NAME) { cstring = TOKEN_GET(&tokens->data[i], cstring); name = cstring; ++i; } if(match_parameters(&tokens->data[i], de_packer_3, sizeof(de_packer_3)/sizeof(de_packer_3[0])) != -1 || match_parameters(&tokens->data[i], de_packer_2, sizeof(de_packer_2)/sizeof(de_packer_2[0])) != -1) { /* find function decl. end */ handle_de(tokens->data, i, tokens->cnt, name, &res); } } else if(i+2 < tokens->cnt && tokens->data[i].type == TOK_IDENTIFIER_NAME && cstring && !strcmp("dF", cstring) && tokens->data[i+1].type == TOK_PAR_OPEN) { /* TODO: also match signature of dF function (possibly * declared using unescape */ handle_df(tokens->data, i+2, &res); } else if(i+2 < tokens->cnt && tokens->data[i].type == TOK_IDENTIFIER_NAME && cstring && !strcmp("eval", cstring) && tokens->data[i+1].type == TOK_PAR_OPEN) { handle_eval(tokens, i+2, &res); } if(res.pos_end > res.pos_begin) { struct tokens parent_tokens; if(res.pos_end < tokens->cnt && tokens->data[res.pos_end].type == TOK_SEMICOLON) res.pos_end++; parent_tokens = state->tokens;/* save current tokens */ /* initialize embedded context */ memset(&state->tokens, 0, sizeof(state->tokens)); if(++state->rec > 16) cli_dbgmsg(MODULE "recursion limit reached\n"); else { cli_js_process_buffer(state, res.txtbuf.data, res.txtbuf.pos); --state->rec; } free(res.txtbuf.data); /* state->tokens still refers to the embedded/nested context * here */ if(!res.append) { replace_token_range(&parent_tokens, res.pos_begin, res.pos_end, &state->tokens); } else { /* delete tokens */ replace_token_range(&parent_tokens, res.pos_begin, res.pos_end, NULL); append_tokens(&parent_tokens, &state->tokens); } /* end of embedded context, restore tokens state */ free(state->tokens.data); state->tokens = parent_tokens; } state_update_scope(state, &state->tokens.data[i]); } }