void ByteCodeVisitor::visitCallNode(mathvm::CallNode *node) { unsigned long stackSize = currStack->size(); AstFunction *astFunction = currScope->lookupFunction(node->name(), true); AstFunctionInfo *functionInfo = (AstFunctionInfo *) astFunction->info(); Scope *parameterScope = astFunction->scope(); if (node->parametersNumber() != parameterScope->variablesCount()) { error("parameters number mistmach in calling %s", node->name().c_str()); } vector<VarType> declaredParameters; declaredParameters.reserve(parameterScope->variablesCount()); Scope::VarIterator varIterator(parameterScope); while (varIterator.hasNext()) { declaredParameters.push_back(varIterator.next()->type()); } vector<VarType>::reverse_iterator it = declaredParameters.rbegin(); for (uint32_t i = node->parametersNumber(); i > 0; --i, ++it) { AstNode *n = node->parameterAt(i - 1); n->visit(this); cast(topStack(), (*it)); } insn(BC_CALL); typed(functionInfo->function->id()); if (astFunction->returnType() != VT_VOID) { pushStack(astFunction->returnType()); } }
void BytecodeVisitor::visitBlockNode(BlockNode *node) { Scope::VarIterator it_var(node->scope()); while (it_var.hasNext()) { AstVar* var = it_var.next(); context_->addVar(var); } Scope::FunctionIterator it_f(node->scope()); while (it_f.hasNext()) { AstFunction* af = it_f.next(); BytecodeFunction* bf = (BytecodeFunction*) code_->functionByName(af->name()); if (!bf) { bf = new BytecodeFunction(af); code_->addFunction(bf); } else { throw new std::runtime_error("Uncorrect function"); } } it_f = Scope::FunctionIterator(node->scope()); while (it_f.hasNext()) { translateFunction(it_f.next()); } for (uint i = 0; i < node->nodes(); ++i) { node->nodeAt(i)->visit(this); } setTosType(VT_VOID); }
void ByteCodeVisitor::visitFunctionNode(mathvm::FunctionNode *node) { BytecodeFunction *dump = currentBytecodeFunction; if (currScope) { AstFunction *function = currScope->lookupFunction(node->name()); if (!function) { error("undeclared function %s", node->name().c_str()); } AstFunctionInfo *astFunctionInfo = (AstFunctionInfo *) function->info(); currentBytecodeFunction = astFunctionInfo->function; } else { currentBytecodeFunction = dynamic_cast<BytecodeFunction *>(interpreterCode->functionById((uint16_t) 0)); } std::vector<VarType> newStack; currStack = &newStack; Scope::VarIterator varIterator(node->body()->scope()->parent()); while (varIterator.hasNext()) { AstVar *var = varIterator.next(); pushStack(var->type());//ensure that variables on stack is ok store(var); } visitBlockNode(node->body()); currentBytecodeFunction = dump; currScope = currScope->parent();//jump parameters scope }
void PrintVisitor::visit(const AstFunction &ref) { cout << "AstFunction<Name=" << ref.GetName() << ";\n"; cout << "ReturnType=" << ref.GetReturnType().ToString() << ";\n"; cout << "Arguments="; ref.GetArguments()->accept(*this); cout << ";\n"; cout << "Code="; ref.GetCode()->accept(*this); cout << "\n>"; }
void BytecodeGenerationVisitor::visitBlockNode(BlockNode* node) { // DONE Scope* prevScope = currentScope; currentScope = node->scope(); Scope::VarIterator varsToSave(currentScope); while (varsToSave.hasNext()) { AstVar* v = varsToSave.next(); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_LOADVAR]); bytecode->addInt16(getVarId(v)); locals.push_back(v); } Scope::VarIterator varsToInit(currentScope); while (varsToInit.hasNext()) { AstVar* v = varsToInit.next(); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_LOAD0]); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]); bytecode->addInt16(getVarId(v)); } Scope::FunctionIterator functionsToAdd(node -> scope()); while (functionsToAdd.hasNext()) { AstFunction *astFunction = functionsToAdd.next(); BytecodeFunction *bytecodeFunction = new BytecodeFunction(astFunction); code -> addFunction(bytecodeFunction); } Scope::FunctionIterator functionsToBuild(node -> scope()); while (functionsToBuild.hasNext()) { AstFunction *astFunction = functionsToBuild.next(); astFunction->node()->visit(this); } for (unsigned int i = 0; i < (node -> nodes()); i++) { node -> nodeAt(i) -> visit(this); if (currentType != VT_VOID && !(node->nodeAt(i)->isReturnNode())) { bytecode -> addInsn(BC_POP); } } Scope::VarIterator varsToRestore(currentScope); stack<AstVar*> variables; while (varsToRestore.hasNext()) { variables.push(varsToRestore.next()); } while (!variables.empty()) { AstVar* v = variables.top(); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]); bytecode->addInt16(getVarId(v)); locals.pop_back(); variables.pop(); } currentScope = prevScope; currentType = VT_VOID; }
void TypeChecker::visitFunDefs(BlockNode* node) { Scope::FunctionIterator funIt(node->scope()); while(funIt.hasNext()) { AstFunction* fun = funIt.next(); size_t dbg_cur_size = _funs.size(); _funs.push(fun); fun->node()->visit(this); _funs.pop(); assert(dbg_cur_size == _funs.size()); } }
void ByteCodeVisitor::visitBlockNode(mathvm::BlockNode *node) { currScope = node->scope(); for (uint32_t i = 0; i < node->nodes(); ++i) { AstNode *n = node->nodeAt(i); n->visit(this); } Scope::FunctionIterator functionIterator(currScope); while (functionIterator.hasNext()) { AstFunction *astFunction = functionIterator.next(); visitFunctionNode(astFunction->node()); } currScope = currScope->parent(); }
void BytecodeGenerationVisitor::visitCallNode(CallNode* node) { const Signature& sign = code->functionByName(node->name())->signature(); AstFunction* f = currentScope->lookupFunction(node->name()); for (unsigned int i = 0; i < node->parametersNumber(); i++) { AstVar* v = f->scope()->lookupVariable(sign[i + 1].second); uint16_t varId = getVarId(v); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_LOADVAR]); bytecode->addInt16(varId); } for (unsigned int i = 0; i < node->parametersNumber(); i++) { node->parameterAt(i)->visit(this); if (currentType == VT_INT && sign[i + 1].first == VT_DOUBLE) { bytecode->addInsn(BC_I2D); } else if (currentType == VT_DOUBLE && sign[i + 1].first == VT_INT) { bytecode->addInsn(BC_D2I); } } for (int i = node->parametersNumber(); i > 0; i--) { AstVar* v = f->scope()->lookupVariable(sign[i].second); uint16_t varId = getVarId(v); bytecode->addInsn(insnByUntypedInsn[sign[i].first][UT_STOREVAR]); bytecode->addInt16(varId); } bytecode->addInsn(BC_CALL); bytecode->addInt16(code->functionByName(node->name())->id()); if (sign[0].first == VT_VOID) { for (unsigned int i = node->parametersNumber(); i > 0; i--) { AstVar* v = f->scope()->lookupVariable(sign[i].second); uint16_t varId = getVarId(v); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]); bytecode->addInt16(varId); } } else { for (unsigned int i = node->parametersNumber(); i > 0; i--) { AstVar* v = f->scope()->lookupVariable(sign[i].second); uint16_t varId = getVarId(v); bytecode->addInsn(BC_SWAP); bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]); bytecode->addInt16(varId); } } currentType = sign[0].first; }
void TypeCheckerVisitor::visitCallNode(CallNode* node) { uint32_t params_count = node->parametersNumber(); AstFunction* refFunc = _current_scope->lookupFunction(node->name(), true); bool matchesRefedFunction = (refFunc!= NULL) && (refFunc->parametersNumber() == params_count); for (uint32_t i = 0; i < params_count; i++) { AstNode* param = node->parameterAt(i); param->visit(this); if (matchesRefedFunction && !isAssignable(refFunc->parameterType(i), getNodeType(param))) { setErrorMessage(param, "Wrong type parameter"); } } if (matchesRefedFunction) { setNodeType(node, refFunc->returnType()); } else { setNodeType(node, VT_INVALID); } }
void BytecodeGenerator::secondRun(Scope * scope) { Scope::FunctionIterator it(scope); while (it.hasNext()) { AstFunction *func = it.next(); BytecodeFunction *bcf = (BytecodeFunction*) code->functionByName(func->name()); fBC = bcf->bytecode(); currentFun = bcf->id(); returnType = func->returnType(); func->node()->body()->visit(this); bcf->setLocalsNumber(localsCounter[currentFun]); } for (size_t i = 0; i < scope->childScopeNumber(); ++i) { secondRun(scope->childScopeAt(i)); } }
void ASTtoByteCodeTranslator::createFunMap(Scope* scope){ Scope::FunctionIterator funIt(scope); while(funIt.hasNext()) { AstFunction* fun = funIt.next(); if (fun->node()->body()->nodeAt(0)->isNativeCallNode()) fun->node()->visit(this); else{ BytecodeFunction* bcFun = new BytecodeFunction(fun); code->addFunction(bcFun); funMap.insert(std::make_pair(fun, bcFun)); funStack.push(bcFun); fun->node()->visit(this); funStack.pop(); } } }
void printScope(Scope * scope) { Scope::VarIterator varIt(scope); while(varIt.hasNext()) { AstVar* var = varIt.next(); os << indent(); os << typeToName(var->type()) << " " << var->name() << ";" << endl; } Scope::FunctionIterator funcIt(scope); while(funcIt.hasNext()) { AstFunction* func = funcIt.next(); os << indent(); func->node()->visit(this); } }
void BytecodeTranslatorVisitor::visitCallNode(CallNode* node) { onVisitNode(node); AstFunction* f = scope()->lookupFunction(node->name()); if (!f) ERROR("Unknown function " + f->name()); checkSignature(node, f); for (uint16_t i = 0; i < node->parametersNumber(); i++) visitTyped(node->parameterAt(i), f->parameterType(i)); if (isNative(f)) EMIT(BC_CALLNATIVE); else EMIT(BC_CALL); EMIT_ID(getFunctionId(f)); pushType(f->returnType()); }
void TypeChecker::visitCallNode(CallNode* node) { size_t nodePos = node->position(); string const callName = node->name(); Scope* curScope = currentScope(); AstFunction* funToCall = curScope->lookupFunction(callName); if(funToCall == 0) { throw ExceptionWithPos(undeclaredFunMsg(callName), nodePos); } for(size_t i = 0; i != node->parametersNumber(); ++i) { node->parameterAt(i)->visit(this); VarType actualArgType = nodeType(node->parameterAt(i)); VarType expectedArgType = funToCall->parameterType(i); if(actualArgType != expectedArgType && !isIntDoublePair(actualArgType, expectedArgType)) { throw ExceptionWithPos(wrongArgTypeMsg(callName, i), nodePos); } } node->setInfo(new VarType(funToCall->returnType())); }
void BytecodeGenerator::firstRun(Scope * scope) { Scope::FunctionIterator it(scope); while (it.hasNext()) { AstFunction *func = it.next(); BytecodeFunction *bcf = new BytecodeFunction(func); currentFun = code->addFunction(bcf); initFunLocals(currentFun); Scope::VarIterator vi(func->scope()); fBC = bcf->bytecode(); while (vi.hasNext()) { AstVar * var = vi.next(); int index = localsCounter[currentFun]; incFunLocals(currentFun); varIds[var] = make_pair(currentFun, index); storeVar(var); } } for (size_t i = 0; i < scope->childScopeNumber(); ++i) { firstRun(scope->childScopeAt(i)); } }
void TypeCheckerVisitor::visitBlockNode(BlockNode* node) { _current_scope = node->scope(); Scope::FunctionIterator funcIt(_current_scope); while (funcIt.hasNext()) { AstFunction* func = funcIt.next(); func->node()->visit(this); } int nodes_count = node->nodes(); VarType commonType = VT_VOID; for (int i = 0; i != nodes_count; ++i) { AstNode* currentNode = node->nodeAt(i); currentNode->visit(this); bool isBlockNode = currentNode->isForNode() || currentNode->isWhileNode() || currentNode->isIfNode(); VarType currentNodeType = getNodeType(currentNode); bool hasType = currentNodeType != VT_VOID; if ((isBlockNode && hasType) || (i == nodes_count - 1)) { commonType = getUpperCommonType(commonType, currentNodeType); } } setNodeType(node, commonType); _current_scope = node->scope()->parent(); }
void Generator::visitCallNode(CallNode *node) { AstFunction *function = lookup_function(node->name()); uint16_t id = lookup_function(function)->id(); for (uint32_t i = 0; i != node->parametersNumber(); ++i) { uint32_t pos = node->parametersNumber() - i - 1; switch (function->parameterType(pos)) { case VT_INT: eval_int(node->parameterAt(pos)); break; case VT_DOUBLE: eval_double(node->parameterAt(pos)); break; case VT_STRING: eval_string(node->parameterAt(pos)); break; default: assert(0); } } bytecode()->addInsn(BC_CALL); bytecode()->addInt16(id); switch (function->returnType()) { case VT_INT: bytecode()->addInsn(BC_LOADIVAR0); break; case VT_DOUBLE: bytecode()->addInsn(BC_LOADDVAR0); break; case VT_STRING: bytecode()->addInsn(BC_LOADSVAR0); break; default: break; } }
void TypeInferenceVisitor::visitCallNode(CallNode* node) { node->visitChildren(this); AstFunction* function = _scopes.top()->lookupFunction(node->name()); _types[node] = function->returnType(); }