void CheckVisitor::visit(ReturnNode* node) { node -> expr() -> accept(*this); if ( node -> isInInlineCall() ) return; if ( function_scopes.empty() ) throw SemanticError("return is not in a function"); auto enclosing_function = function_scopes.top() -> func; node -> function(enclosing_function); auto unqualified_type = node -> expr() -> getType().unqualified(); if ( unqualified_type -> isObjectType() ) { auto obj_type = static_cast<const ObjectType*>(unqualified_type); auto ref_to_obj_type = TypeFactory::getReference(obj_type); // auto copy_constr = obj_type -> resolveMethod(obj_type -> typeName(), {VariableType(TypeFactory::getReference(obj_type), true)}); auto copy_constr = obj_type -> methodWith(obj_type -> typeName(), {ref_to_obj_type, VariableType(ref_to_obj_type, true)}); if ( copy_constr == nullptr ) throw SemanticError("Cannot initialize return value of type '" + enclosing_function -> type().returnType().getName() + "' with value of type '" + obj_type -> typeName() + "'"); checkCall(copy_constr, {valueOf(node -> expr())}); } }
openddl::Tree openddl::Tree::parse(const std::string & i) { Tree::Impl * impl = new Tree::Impl(); std::vector<detail::Token> tokens; std::vector<detail::Error> errors; if (!detail::lex(i, tokens, errors)) { throw LexerError(errors); } else if (!detail::parse(tokens, impl->commands, errors)) { throw ParseError(errors); } else if (!detail::semantic_check(impl->commands, errors, impl->global_names, impl->local_names)) { throw SemanticError(errors); } //Build the child table to avoid walking the table whenever running visitors across the data for (unsigned int i = 0; i < impl->commands.size(); i++) { auto it = impl->child_table.find(impl->commands[i].parent); if (it == impl->child_table.end()) it = impl->child_table.emplace(impl->commands[i].parent,std::vector<unsigned int>()).first; it->second.push_back(i); } Tree t; t.implementation.reset(impl); return std::move(t); }
Expr *CheckForHiddenVaryingReferences( CgContext *cg, Expr *fExpr, void *arg1, int arg2) { Binding *lBind; Symbol *lSymb; Type *lType; switch (fExpr->kind) { case SYMB_N: if (static_cast< Symb * >( fExpr )->op == VARIABLE_OP || static_cast< Symb * >( fExpr )->op == MEMBER_OP) { lSymb = static_cast< Symb * >( fExpr )->symbol; if (lSymb->kind == SK_Variable) { lType = static_cast< Symb * >( fExpr )->type; lBind = lSymb->details.var.bind; if (lBind && lBind->properties & BIND_HIDDEN) { SemanticError( cg, cg->pLastSourceLoc, ERROR_SS_VAR_SEMANTIC_NOT_VISIBLE, cg->GetString(lSymb->name), cg->GetString(lBind->name)); } } } break; default: break; } return fExpr; } // CheckForHiddenVaryingReferences
bool NameServiceClient::service_info_query( const std::string &in_service_name, ServiceInfoPtr &out_info ) { if( !m_client || !m_client->get_is_connected() ) { throw SemanticError() <<errinfo_errorid( ErrorID::SEMANTIC_ERR_NOT_CONNECTED); } ServiceRequestData request; request.m_service_name = in_service_name; std::ostringstream sout; { boost::archive::text_oarchive oa( sout ); oa & request; } DataServiceMessage message( DATA_SERVICE_INFO_REQUEST ); std::strncpy( message.m_data, sout.str().c_str(), sout.str().size()); MemInfo data( reinterpret_cast<char *>( &message ), sizeof(DataServiceMessage)); m_client->send_data( data ); std::unique_lock<std::mutex> l( m_mutex ); while( !m_stop && !m_response_ready ) { m_response_ready_cond.wait( l ); } if( m_stop ) { return false; } bool status = m_status; m_status = false; m_response_ready = false; out_info = m_info; m_info.reset(); return status; }
static Expr *CheckNodeForUndefinedFunctions( CgContext *cg, Expr *fExpr, void *arg1, int arg2) { Symbol *lSymb; Expr *lExpr; int *count = (int *) arg1; switch (fExpr->kind) { case DECL_N: case SYMB_N: case CONST_N: case UNARY_N: break; case BINARY_N: if (static_cast< Binary * >( fExpr )->op == FUN_CALL_OP) { lExpr = static_cast< Binary * >( fExpr )->left; if (lExpr->kind == SYMB_N) { lSymb = static_cast< Symb * >( lExpr )->symbol; if (IsFunction(lSymb)) { if (!(lSymb->properties & SYMB_IS_DEFINED)) { SemanticError( cg, cg->pLastSourceLoc, ERROR_S_CALL_UNDEF_FUN, cg->GetString(lSymb->name)); count++; } else { if (lSymb->flags == BEING_CHECKED) { SemanticError( cg, cg->pLastSourceLoc, ERROR_S_RECURSION, cg->GetString(lSymb->name)); count++; } else { CheckFunctionDefinition( cg, NULL, lSymb, 0); } } } } } break; case TRINARY_N: break; default: assert(!"bad kind to CheckNodeForUndefinedFunctions()"); break; } return fExpr; } // CheckNodeForUndefinedFunctions
void CheckVisitor::visit(DotNode* node) { node -> base() -> accept(*this); auto base_type = node -> base() -> getType().unqualified(); if ( !base_type -> isObjectType() ) throw SemanticError("'" + node -> base() -> toString() + "' is not an instance of struct."); node -> baseType(static_cast<const ObjectType*>(base_type)); auto mem = node -> baseType() -> resolveMember(node -> memberName()); if ( mem == nullptr ) mem = node -> baseType() -> resolveMethod(node -> memberName(), getCallArguments()); if ( mem == nullptr ) throw SemanticError(node -> memberName() + " is not member of " + node -> baseType() -> typeName()); node -> member(mem); }
void CheckVisitor::visit(AddrNode* node) { node -> expr() -> accept(*this); if ( node -> op() == AddrOp::REF ) { if ( !node -> expr() -> isLeftValue() ) { throw SemanticError("expression is not an lvalue"); } } else { auto type = node -> expr() -> getType().unqualified(); if ( !type -> isPointer() ) { throw SemanticError("Type of " + node -> toString() + " is not a pointer type."); } } }
void Palette::realize(const ByteArray *text, Token *objectToken) { scopeName_ = resourceContext()->top()->fileName(); if (scopeName_ == "default") { scope_ = SyntaxDefinition::scope(scopeName_); for (int i = 0; i < children()->count(); ++i) { Style *style = cast<Style>(children()->at(i)); style->rule_ = defaultRuleByName(style->ruleName()); if (style->rule_ == Undefined) { Token *token = childToken(objectToken, i); token = valueToken(text, token, "name"); throw SemanticError( Format("Undefined default style '%%'") << style->ruleName(), text, token->i1() ); } styleByRule_->establish(style->rule_, style); } return; } Language *language = 0; if (!registry()->lookupLanguageByName(scopeName_, &language)) throw SemanticError(Format("Undefined language '%%'") << scopeName_); const SyntaxDefinition *syntax = language->highlightingSyntax(); scope_ = syntax->id(); for (int i = 0; i < children()->count(); ++i) { Style *style = cast<Style>(children()->at(i)); try { style->rule_ = syntax->ruleByName(style->ruleName()); styleByRule_->insert(style->rule_, style); } catch (DebugError &ex) { Token *token = childToken(objectToken, i); token = valueToken(text, token, "name"); throw SemanticError(ex.message(), text, token->i1()); } } }
void DefineTexunitBinding(SourceLoc *loc, int pname, int aname, int unitno) { BindingTree *lTree; lTree = LookupBinding(pname, aname); if (lTree) { SemanticError(loc, ERROR_SSSD_DUPLICATE_BINDING, GetAtomString(atable, pname), GetAtomString(atable, aname), GetAtomString(atable, lTree->loc.file), lTree->loc.line); return; } lTree = NewTexunitBindingTree(loc, pname, aname, unitno); AddBinding(lTree); } // DefineTexunitBinding
void DefineDefaultBinding(SourceLoc *loc, int pname, int aname, int count, float *fval) { BindingTree *lTree; lTree = LookupBinding(pname, aname); if (lTree) { SemanticError(loc, ERROR_SSSD_DUPLICATE_BINDING, GetAtomString(atable, pname), GetAtomString(atable, aname), GetAtomString(atable, lTree->loc.file), lTree->loc.line); return; } lTree = NewConstDefaultBindingTree(loc, BK_DEFAULT, pname, aname, count, fval); AddBinding(lTree); } // DefineDefaultBinding
void DefineConnectorBinding(SourceLoc *loc, int cname, int mname, int rname) { BindingTree *lTree; lTree = LookupBinding(cname, mname); if (lTree) { SemanticError(loc, ERROR_SSSD_DUPLICATE_BINDING, GetAtomString(atable, cname), GetAtomString(atable, mname), GetAtomString(atable, lTree->loc.file), lTree->loc.line); return; } lTree = NewConnectorBindingTree(loc, cname, mname, rname); AddBinding(lTree); } // DefineConnectorBinding
void DefineRegArrayBinding(SourceLoc *loc, int pname, int aname, int rname, int index, int count) { BindingTree *lTree; lTree = LookupBinding(pname, aname); if (lTree) { SemanticError(loc, ERROR_SSSD_DUPLICATE_BINDING, GetAtomString(atable, pname), GetAtomString(atable, aname), GetAtomString(atable, lTree->loc.file), lTree->loc.line); return; } lTree = NewRegArrayBindingTree(loc, pname, aname, rname, index, count); AddBinding(lTree); } // DefineRegArrayBinding
void CheckVisitor::visit(FunctionNode* node) { try { getCallArguments(); } catch ( SemanticError& e ) { throw SemanticError("No arguments provided to '" + node -> name() + "'"); } auto sym = (node -> module() ? node -> module() : node -> scope.get()) -> resolveFunction(node -> name(), getCallArguments()); if ( sym == nullptr ) throw NoViableOverloadError(node -> name(), getCallArguments().params()); node -> function(sym); }
bool NameServiceClient::register_service( const std::string &in_service_name, int32_t in_port ) { if( !m_client || !m_client->get_is_connected() ) { throw SemanticError() <<errinfo_errorid( ErrorID::SEMANTIC_ERR_NOT_CONNECTED); } char hostname[NAME_MAX]; if( -1 == gethostname( hostname, NAME_MAX ) ) { throw SyscallError() <<boost::errinfo_errno(errno) << boost::errinfo_api_function("gethostname"); } ServiceRequestData request; request.m_service_name = in_service_name; request.m_hostname = hostname; request.m_port = in_port; std::ostringstream sout; { boost::archive::text_oarchive oa( sout ); oa & request; } DataServiceMessage message( DATA_SERVICE_REGISTER ); std::strncpy( message.m_data, sout.str().c_str(), sout.str().size()); MemInfo data( reinterpret_cast<char *>( &message ), sizeof(DataServiceMessage)); m_client->send_data( data ); std::unique_lock<std::mutex> l( m_mutex ); while( !m_stop && !m_response_ready ) { m_response_ready_cond.wait( l ); } if( m_stop ) { return false; } bool status = m_status; m_status = false; m_response_ready = false; return status; }
void CheckVisitor::visit(VariableDeclarationNode* node) { for ( auto param : node -> typeInfo().templateArgumentsInfo() ) { if ( param.which() == 0 ) { boost::get< std::shared_ptr<ExprNode> >(param) -> accept(*this); } } if ( !node -> isField() ) { auto types = std::vector<VariableType> { }; for ( const auto& param : node -> constructorParams() ) { param -> accept(*this); types.emplace_back(param -> getType()); } if ( !node -> typeInfo().isRef() && node -> typeInfo().modifiers().empty() ) { auto var_type = fromTypeInfo(node -> typeInfo(), node -> scope.get()); assert(var_type.unqualified() -> isObjectType()); auto struct_symbol = static_cast<const ObjectType*>(var_type.unqualified()); auto arguments = extractArguments(node -> constructorParams()); auto constructor = struct_symbol -> resolveMethod(struct_symbol -> typeName(), types); if ( constructor == nullptr ) { throw SemanticError("No constructor defined"); } node -> callInfo(checkCall(constructor, arguments)); } } }
void Semantic::analysis(std::unordered_map<std::string, Schema::Relation> &relations) const { for(const std::string &relationname : query.relations){ auto it = relations.find(relationname); if(it == relations.end()) throw SemanticError(relationname + " relation doesn't exist"); } unsigned rnum = query.relations.size(); std::unordered_map<std::string, Schema::Relation::Attribute> attributes; for(const std::string &relationname : query.relations){ bool flag = false; auto itr = relations.find(relationname); for(Schema::Relation::Attribute attribute : itr->second.attributes){ attributes.insert({attribute.name, attribute}); for(const std::pair<std::string, std::string>& joincondition : query.joinconditions){ if(flag) break; if(attribute.name == joincondition.first || attribute.name == joincondition.second){ flag = true; break; } } } if(!flag && rnum != 1) throw SemanticError(relationname + " has no join condition"); } for(const std::string& selectname : query.selectnames){ auto itr = attributes.find(selectname); if(itr == attributes.end()) throw SemanticError("Attribute " + selectname + " doesn't exist in any table"); } for(const std::pair<std::string, std::string> &joincondition : query.joinconditions){ auto itr = attributes.find(joincondition.first); if(itr == attributes.end()) throw SemanticError("Attribute " + joincondition.first + " doesn't exist in any table"); itr = attributes.find(joincondition.second); if(itr == attributes.end()) throw SemanticError("Attribute " + joincondition.second + " doesn't exist in any table"); } for(const std::pair<std::string, std::string> &selectcondition : query.selectconditions){ auto itr = attributes.find(selectcondition.first); if(itr == attributes.end()) throw SemanticError("Attribute " + selectcondition.first + " doesn't exist in any table"); switch(itr->second.type ){ case Types::Tag::Integer: try{ std::stoi(selectcondition.second); }catch(std::exception const &e){ std::string tem = selectcondition.second; tem[0] = ' '; tem[tem.size()-2]=' '; throw SemanticError(selectcondition.first +" is Integer type but "+tem + " is not a integer"); } break; default: break; } } std::ofstream out; out.open("tree_expression.cpp"); out << "#include \"task6.hpp\"" << std::endl; out << "extern \"C\" void print(Customer *customer, Order *order, Orderline *orderline, Warehouse *warehouse, District *district, Item *item){" << std::endl; out << "initialize();" << std::endl; int scanNumber = 0; std::unordered_map<std::string, std::string> operation; for(const std::string &relationname: query.relations){ bool flag = false; auto it = relations.find(relationname); Schema::Relation& relation = it->second; flag = true; out << "TableScan* tableScan" + std::to_string(scanNumber) + " = new TableScan(" + relationname + ");" << std::endl; operation[relationname] = "tableScan" + std::to_string(scanNumber); bool selectname = false; for(const std::pair<std::string, std::string> &select : query.selectconditions){ for(const Schema::Relation::Attribute &attribute : relation.attributes){ if(attribute.name == select.first){ if(!selectname){ out << "Selection* selection"+std::to_string(scanNumber) + " = new Selection(tableScan"+std::to_string(scanNumber) + ");" << std::endl; operation[relationname] = "selection" + std::to_string(scanNumber); selectname = true; } out << "selection" + std::to_string(scanNumber) + "->condition.push_back(std::make_pair(\""+select.first+"\", " + "\""+select.second + "\"));" << std::endl; } } } if(!flag){ throw SemanticError(relationname + " relation doesn't exist"); }else{ scanNumber++; } } int joinNumber = 0; if(query.relations.size() > 1){ for(unsigned i = 0; i < query.relations.size() - 1; i++){ for(const Schema::Relation& relation : schema->relations){ if(query.relations[i] == relation.name){ for(const Schema::Relation& relationA : schema->relations){ if(query.relations[i+1] == relationA.name){ bool joinname = false; for(const std::pair<std::string, std::string> &join : query.joinconditions){ for(const Schema::Relation::Attribute &attribute : relation.attributes){ if(attribute.name == join.first){ for(const Schema::Relation::Attribute &attributeA : relationA.attributes){ if(attributeA.name == join.second){ if(!joinname){ out << "HashJoin* hashJoin"+std::to_string(joinNumber) + " = new HashJoin("+ operation[relation.name] +", " + operation[relationA.name] + ");" << std::endl; joinname = true; out << "hashJoin" + std::to_string(joinNumber) + "->joinname = \"hashJoin" + std::to_string(joinNumber) + "\";" << std::endl; } out << "hashJoin" + std::to_string(joinNumber) + "->condition.push_back(std::make_pair(\""+join.first+"\", " + "\""+join.second + "\"));" << std::endl; operation[relationA.name] = "hashJoin" + std::to_string(joinNumber); } } }else if(attribute.name == join.second){ for(Schema::Relation::Attribute attributeA : relationA.attributes){ if(attributeA.name == join.first){ if(!joinname){ out << "HashJoin* hashJoin"+std::to_string(joinNumber) + " = new HashJoin("+ operation[relation.name] +", " + operation[relationA.name] + ");" << std::endl; joinname = true; out << "hashJoin" + std::to_string(joinNumber) + "->joinname = \"hashJoin" + std::to_string(joinNumber)+"\";" << std::endl; } out << "hashJoin" + std::to_string(joinNumber) + "->condition.push_back(std::make_pair(\""+join.second+"\", " + "\""+join.first + "\"));" << std::endl; operation[relationA.name] = "hashJoin" + std::to_string(joinNumber); } } } } } joinNumber++; } } } } } } if(query.relations.size() == 0) return; out << "Print *print = new Print(" + operation[query.relations[query.relations.size()-1]]+");" <<std::endl; for(const std::string &printname : query.selectnames) out << "print->cnames.push_back(\"" + printname + "\");" << std::endl; out << "print->produce();" << std::endl; out << "finish();" << std::endl; out << "}" << std::endl; out.close(); }
static Stmt *CheckForReturnStmts( CgContext *cg, Stmt *fStmt, void *arg1, int arg2) { if (fStmt->kind == RETURN_STMT) SemanticError( cg, &fStmt->loc, ERROR___RETURN_NOT_LAST); return fStmt; } // CheckForReturnStmts
static Expr *CheckConnectorUsage( CgContext *cg, Expr *fExpr, void *arg1, int arg2) { int WeAreWriting = arg2; Symbol *lSymb; Expr *lExpr; Binding *lBind; lExpr = fExpr; if (fExpr) { switch (fExpr->kind) { case DECL_N: break; case SYMB_N: lSymb = static_cast< Symb * >( lExpr )->symbol; if (lSymb->properties & SYMB_IS_CONNECTOR_REGISTER) { if (!(lSymb->properties & (SYMB_CONNECTOR_CAN_WRITE | SYMB_CONNECTOR_CAN_READ))) { SemanticError( cg, cg->pLastSourceLoc, ERROR_S_CMEMBER_NOT_VISIBLE, cg->GetString(lSymb->name)); } else { if (WeAreWriting) { if (!(lSymb->properties & SYMB_CONNECTOR_CAN_WRITE)) { SemanticError( cg, cg->pLastSourceLoc, ERROR_S_CMEMBER_NOT_WRITABLE, cg->GetString(lSymb->name)); } } else { if (!(lSymb->properties & SYMB_CONNECTOR_CAN_READ)) { SemanticError( cg, cg->pLastSourceLoc, ERROR_S_CMEMBER_NOT_READABLE, cg->GetString(lSymb->name)); } } } } break; case CONST_N: break; case UNARY_N: static_cast< Unary * >( fExpr )->arg = CheckConnectorUsage( cg, static_cast< Unary * >( fExpr )->arg, arg1, arg2); break; case BINARY_N: switch (static_cast< Binary * >( fExpr )->op) { case MEMBER_SELECTOR_OP: lExpr = static_cast< Binary * >( fExpr )->right; if (lExpr && lExpr->kind == SYMB_N && WeAreWriting) { // Mark connector registers that are written. lSymb = static_cast< Symb * >( lExpr )->symbol; lBind = lSymb->details.var.bind; if (lBind) lBind->properties |= BIND_WAS_WRITTEN; } static_cast< Binary * >( fExpr )->left = CheckConnectorUsage( cg, static_cast< Binary * >( fExpr )->left, arg1, arg2); static_cast< Binary * >( fExpr )->right = CheckConnectorUsage( cg, static_cast< Binary * >( fExpr )->right, arg1, arg2); lExpr = fExpr; break; case ASSIGN_OP: case ASSIGN_V_OP: case ASSIGN_GEN_OP: case ASSIGN_MASKED_KV_OP: static_cast< Binary * >( fExpr )->left = CheckConnectorUsage( cg, static_cast< Binary * >( fExpr )->left, arg1, 1); static_cast< Binary * >( fExpr )->right = CheckConnectorUsage( cg, static_cast< Binary * >( fExpr )->right, arg1, 0); break; case FUN_ARG_OP: arg2 = SUBOP_GET_MASK(static_cast< Binary * >( fExpr )->subop) & 2 ? 1 : 0; static_cast< Binary * >( fExpr )->left = CheckConnectorUsage( cg, static_cast< Binary * >( fExpr )->left, arg1, arg2); static_cast< Binary * >( fExpr )->right = CheckConnectorUsage( cg, static_cast< Binary * >( fExpr )->right, arg1, 0); break; default: static_cast< Binary * >( fExpr )->left = CheckConnectorUsage( cg, static_cast< Binary * >( fExpr )->left, arg1, arg2); static_cast< Binary * >( fExpr )->right = CheckConnectorUsage( cg, static_cast< Binary * >( fExpr )->right, arg1, arg2); break; } break; case TRINARY_N: switch (static_cast< Binary * >( fExpr )->op) { case ASSIGN_COND_OP: case ASSIGN_COND_V_OP: case ASSIGN_COND_SV_OP: case ASSIGN_COND_GEN_OP: static_cast< Trinary * >( fExpr )->arg1 = CheckConnectorUsage( cg, static_cast< Trinary * >( fExpr )->arg1, arg1, 1); static_cast< Trinary * >( fExpr )->arg2 = CheckConnectorUsage( cg, static_cast< Trinary * >( fExpr )->arg2, arg1, 0); static_cast< Trinary * >( fExpr )->arg3 = CheckConnectorUsage( cg, static_cast< Trinary * >( fExpr )->arg3, arg1, 0); break; default: static_cast< Trinary * >( fExpr )->arg1 = CheckConnectorUsage( cg, static_cast< Trinary * >( fExpr )->arg1, arg1, arg2); static_cast< Trinary * >( fExpr )->arg2 = CheckConnectorUsage( cg, static_cast< Trinary * >( fExpr )->arg2, arg1, arg2); static_cast< Trinary * >( fExpr )->arg3 = CheckConnectorUsage( cg, static_cast< Trinary * >( fExpr )->arg3, arg1, arg2); break; } break; default: FatalError( cg, "bad kind to CheckConnectorUsage()"); break; } } else { lExpr = NULL; } return lExpr; } // CheckConnectorUsage
const FunctionTypeInfo& CheckVisitor::getCallArguments() { if ( arguments_stack.empty() ) throw SemanticError("Internal error"); return arguments_stack.top(); }