void CodeGen::Visit(FuncDefNode* _node) { auto c_state = state; int var_id = -1; if (_node->name) var_id = state->AddVariable(_node->name->name); auto new_state = GenState::CreateNewState(state); state = new_state; for (auto i = _node->parameters.begin(); i != _node->parameters.end(); ++i) Visit(*i); Visit(_node->block); AddInst(Instruction(VM_CODE::RETURN, 0)); state = new_state->GetPrevState(); auto new_fun = Context::GetGC()->New<Function>(GenState::GenerateCodePack(new_state)); delete new_state; int const_id = state->AddConstant(new_fun->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, const_id)); AddInst(Instruction(VM_CODE::CLOSURE, 0)); if (var_id >= 0) AddInst(Instruction(VM_CODE::STORE_V, var_id)); }
void CodeGen::Visit(InvokeExprNode* _node) { Visit(_node->source); auto _name_id = state->AddConstant( String::FromU16String(_node->id->name)->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, _name_id)); AddInst(Instruction(VM_CODE::DOT, 0)); }
void CodeGen::Visit(FuncCallNode* _node) { for (auto i = _node->parameters.begin(); i != _node->parameters.end(); ++i) Visit(*i); AddInst(Instruction(VM_CODE::PUSH_NULL, 0)); // Push This Visit(_node->exp); AddInst(Instruction(VM_CODE::CALL, _node->parameters.size())); }
void CodeGen::Visit(ReturnStmtNode* _node) { if (_node->expression) { Visit(_node->expression); AddInst(Instruction(VM_CODE::RETURN, 1)); } else AddInst(Instruction(VM_CODE::RETURN, 0)); }
void CodeGen::Visit(StringNode* _node) { auto index = state->AddConstant( Value(String::FromU16String(_node->content), TypeId::String)); AddInst(Instruction(VM_CODE::LOAD_C, index)); }
Function* CodeGen::generate(Parser* p) { parser = p; Visit(parser->getRoot()); AddInst(Instruction(VM_CODE::STOP, 0)); return Context::GetGC()->New<Function>(GenState::GenerateCodePack(state)); }
void CodeGen::Visit(IdentifierNode* _node) { auto _var = FindVar(state, _node->name); switch (_var.type()) { case VarType::TYPE::GLOBAL: AddInst(Instruction(VM_CODE::LOAD_G, _var.id())); break; case VarType::TYPE::LOCAL: AddInst(Instruction(VM_CODE::LOAD_V, _var.id())); break; case VarType::TYPE::UPVAL: AddInst(Instruction(VM_CODE::LOAD_UPVAL, _var.id())); break; case VarType::TYPE::NONE: // ReportError(std::u16string(u"<Identifier>Variables not found: ") + utils::utf8_to_utf16(_node->name)); break; } }
void CodeGen::Visit(NumberNode* _node) { unsigned int index; if (_node->maybeInt) index = state->AddConstant(Value(static_cast<TSmallInt>(_node->number))); else index = state->AddConstant(Value(_node->number)); AddInst(Instruction(VM_CODE::LOAD_C, index)); }
void CodeGen::Visit(VarSubExprNode* _node) { auto _id_node = _node->varName; int _id = state->AddVariable(_id_node->name); // you must add the name first and then Visit the expression. // to generate the next code if (_node->expression) { Visit(_node->expression); AddInst(Instruction(VM_CODE::STORE_V, _id)); } }
void CodeGen::Visit(BlockExprNode* _node) { for (auto i = _node->children.begin(); i != _node->children.end(); ++i) { (*i)->Visit(this); // TODO: debug if ((*i)->asUnaryExpression() || (*i)->asBinaryExpression() || (*i)->asIdentifier() || (*i)->asNumber()) AddInst(Instruction(VM_CODE::OUT, 0)); } }
C4SoundInstance *C4SoundEffect::New(bool fLoop, int32_t iVolume, C4Object *pObj, int32_t iCustomFalloffDistance) { // check: too many instances? if (!fLoop && Instances >= C4MaxSoundInstances) return NULL; // create & init sound instance C4SoundInstance *pInst = new C4SoundInstance(); if (!pInst->Create(this, fLoop, iVolume, pObj, 0, iCustomFalloffDistance)) { delete pInst; return NULL; } // add to list AddInst(pInst); // return return pInst; }
void CodeGen::Visit(AssignmentNode* _node) { // find if the var is exisits // if not exisits add a possition for it auto _id_node = dynamic_cast<IdentifierNode*>(_node->identifier); auto _var = FindVar(state, _id_node->name); int _id; switch(_var.type()) { case VarType::TYPE::GLOBAL: Visit(_node->expression); AddInst(Instruction(VM_CODE::STORE_G, _var.id())); AddInst(Instruction(VM_CODE::LOAD_G, _var.id())); break; case VarType::TYPE::LOCAL: Visit(_node->expression); AddInst(Instruction(VM_CODE::STORE_V, _var.id())); AddInst(Instruction(VM_CODE::LOAD_V, _var.id())); break; case VarType::TYPE::UPVAL: Visit(_node->expression); AddInst(Instruction(VM_CODE::STORE_UPVAL, _var.id())); AddInst(Instruction(VM_CODE::LOAD_UPVAL, _var.id())); break; case VarType::TYPE::NONE: if (_var_statement) { _id = state->AddVariable(_id_node->name); // you must add the name first and then Visit the expression. // to generate the next code Visit(_node->expression); AddInst(Instruction(VM_CODE::STORE_V, _id)); AddInst(Instruction(VM_CODE::LOAD_V, _id)); } else { // i don't know how to fix it, f**k you. // ReportError(std::u16string(u"<Assignment>Identifier not found: ") + _id_node->name); } break; } }
void CodeGen::Visit(UnaryExprNode* _node) { Visit(_node->child); unsigned int id; switch (_node->op) { case OperatorType::SUB: id = state->AddConstant(Context::StringBuffer::__REVERSE__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 0)); break; case OperatorType::NOT: id = state->AddConstant(Context::StringBuffer::__NOT__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 0)); break; } }
void CodeGen::Visit(BinaryExprNode* _node) { Visit(_node->right); Visit(_node->left); unsigned int id; switch (_node->op) { case OperatorType::ADD: id = state->AddConstant(Context::StringBuffer::__ADD__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::SUB: id = state->AddConstant(Context::StringBuffer::__SUB__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::MUL: id = state->AddConstant(Context::StringBuffer::__MUL__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::DIV: id = state->AddConstant(Context::StringBuffer::__DIV__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::MOD: id = state->AddConstant(Context::StringBuffer::__MOD__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::POW: id = state->AddConstant(TEXT("__pow__")); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::GT: id = state->AddConstant(Context::StringBuffer::__GT__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::LT: id = state->AddConstant(Context::StringBuffer::__LT__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::GTEQ: id = state->AddConstant(Context::StringBuffer::__GTEQ__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::LTEQ: id = state->AddConstant(Context::StringBuffer::__LTEQ__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::EQ: id = state->AddConstant(Context::StringBuffer::__EQ__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::AND: id = state->AddConstant(Context::StringBuffer::__AND__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; case OperatorType::OR: id = state->AddConstant(Context::StringBuffer::__OR__->toValue()); AddInst(Instruction(VM_CODE::LOAD_C, id)); AddInst(Instruction(VM_CODE::DOT, 0)); AddInst(Instruction(VM_CODE::CALL, 1)); break; default: // runtime error AddInst(Instruction(VM_CODE::POP, 0)); // pack.instructions.push_back(Instruction(VM_CODE::POP, 0)); } }