void TypeDeduction::Visit(ConditionalExpression* node) { std::map<Expression *, Expression *> *condBranches = node->GetConditionalBranches(); for (std::map<Expression *, Expression *>::iterator it = condBranches->begin(); it != condBranches->end(); ++it) { Expression *condition = it->first; Expression *condExpr = it->second; condition->Accept(this); condExpr->Accept(this); Type *conditionType = condition->GetTag<Type>("Type"); if (!conditionType->CanImplicitlyConvertTo(new BooleanType())) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Boolean expression expected."); } } node->GetDefaultBranch()->Accept(this); Type *defType = node->GetDefaultBranch()->GetTag<Type>("Type"); for (std::map<Expression *, Expression *>::iterator it = condBranches->begin(); it != condBranches->end(); ++it) { Expression *condition = it->first; Expression *condExpr = it->second; Type *exprType = condExpr->GetTag<Type>("Type"); if (!defType->Equals(exprType)) { node->SetTag<Type>("Type", new VoidType()); return; } } node->SetTag<Type>("Type", defType); }
void TypeDeduction::Visit(NewRunnerExpression* node) { node->GetTarget()->Accept(this); std::vector<Expression *> *arguments = node->GetArgumentList(); for (std::vector<Expression *>::iterator it = arguments->begin(); it != arguments->end(); ++it) { Expression *arg = *it; arg->Accept(this); //TODO: Check the parameter types, and do implicit conversion if needed } std::vector<Expression *> *usingRanges = node->GetUsingList(); for (std::vector<Expression *>::iterator it = usingRanges->begin(); it != usingRanges->end(); ++it) { Expression *expr = *it; expr->Accept(this); } std::vector<Expression *> *watchingRanges = node->GetWatchingList(); for (std::vector<Expression *>::iterator it = watchingRanges->begin(); it != watchingRanges->end(); ++it) { Expression *expr = *it; expr->Accept(this); } std::vector<Expression *> *space = node->GetSpace(); for (std::vector<Expression *>::iterator it = space->begin(); it != space->end(); ++it) { Expression *expr = *it; expr->Accept(this); } FunctionType *funcType = dynamic_cast<FunctionType *>(node->GetTarget()->GetTag<Type>("Type")); if (funcType == NULL) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Requires a function type."); } if (!funcType->GetReturnType()->Equals(new VoidType())) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Runner function cannot have return value."); } node->SetTag<Type>("Type", funcType->GetReturnType()); }
void TypeDeduction::Visit(AssignExpression* node) { Expression *source = node->GetSource(); Expression *target = node->GetTarget(); source->Accept(this); target->Accept(this); Expression *lvalue = target->GetLValue(); if (lvalue == NULL) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Assignment target is not an l-value."); } if (lvalue->GetTag<Type>("Type") == NULL) { lvalue->Accept(this); } Type *sourceType = source->GetTag<Type>("Type"); Type *targetType = lvalue->GetTag<Type>("Type"); if (!sourceType->CanImplicitlyConvertTo(targetType)) { if (sourceType->CanExplicitlyConvertTo(targetType)) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Cannot assign %s to %s, an explicit conversion is required.", sourceType->ToString().c_str(), targetType->ToString().c_str()); } else { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Cannot assign %s to %s.", sourceType->ToString().c_str(), targetType->ToString().c_str()); } } else { if (!sourceType->Equals(targetType)) { ConvertExpression *castExpr = new ConvertExpression(targetType, source); node->SetSource(castExpr); castExpr->SetTag<Type>("Type", targetType); } node->SetTag<Type>("Type", targetType); } }
void TypeDeduction::Visit(BlockExpression* node) { SymbolScope *oldScope = _currentScope; _currentScope = node->GetBlockScope(); //TODO: Finish it. std::vector<Expression *> *exprList = node->GetExpressionList(); for (std::vector<Expression *>::iterator it = exprList->begin(); it != exprList->end(); ++it) { Expression *expr = *it; expr->Accept(this); } if (exprList->size() > 0) { Type *lastExprType = exprList->back()->GetTag<Type>("Type"); assert(lastExprType != NULL); node->SetTag<Type>("Type", lastExprType); } else { node->SetTag<Type>("Type", new VoidType()); } _currentScope = oldScope; }
void MacroExpChecker::Do(const Expression& Exp, const vector<const ESFixedTypeBase*>& DomainTypes, const ESFixedTypeBase* RangeType, vector<Expression>& FormalParamExps) { if (Exp->GetType() != RangeType) { throw TypeException((string)"Macro Expression has mismatched type"); } MacroExpChecker Checker; Exp->Accept(&Checker); // Check if the formal param expressions obtained have the same type as expected // Also, ALL formal params MUST be used for (uint32 i = 0; i < DomainTypes.size(); ++i) { auto it = Checker.FormalParamExpressions.find(i); if (it == Checker.FormalParamExpressions.end()) { throw TypeException((string)"Formal parameter " + to_string(i) + " unused in macro. " + "Please eliminate unused parameters from macro definitions."); } if (it->second->GetType() != DomainTypes[i]) { throw TypeException((string)"Formal parameter type mismatch at position " + to_string(i) + " in macro definition"); } FormalParamExps.push_back(it->second); } }
Expression SpecRewriter::Do(ESolver* Solver, const Expression& Exp, vector<EvalRule>& EvalRules, vector<const AuxVarOperator*>& BaseAuxVarsOps, vector<const AuxVarOperator*>& DerivedAuxVarOps) { SpecRewriter Rewriter(Solver); Exp->Accept(&Rewriter); EvalRules = Rewriter.EvalRules; BaseAuxVarsOps = Rewriter.BaseAuxVarOps; DerivedAuxVarOps = Rewriter.DerivedAuxVarOps; // Assign positions for base and derived aux vars uint32 AuxVarCounter = 0; for (auto const& BaseAV : BaseAuxVarsOps) { BaseAV->SetPosition(AuxVarCounter++); } for (auto const& DerivedAV : DerivedAuxVarOps) { DerivedAV->SetPosition(AuxVarCounter++); } // Fixup the param maps in the eval rules for (auto const& Rule : EvalRules) { ParamMapFixup::Do(Rule.GetRHS()); } return Rewriter.RewriteStack.back(); }
void TypeDeduction::Visit(ProgramExpression* node) { SymbolScope *oldScope = _currentScope; _currentScope = SymbolScope::GetRootScope(); std::vector<Expression *> *functions = node->GetFunctions(); for (std::vector<Expression *>::iterator it = functions->begin(); it != functions->end(); ++it) { Expression *func = *it; func->Accept(this); } _currentScope = oldScope; }
void TypeDeduction::Visit(CallExpression* node) { node->GetTarget()->Accept(this); std::vector<Expression *> *arguments = node->GetArgumentList(); for (std::vector<Expression *>::iterator it = arguments->begin(); it != arguments->end(); ++it) { Expression *arg = *it; arg->Accept(this); //TODO: Check the parameter types, and do implicit conversion if needed } FunctionType *funcType = dynamic_cast<FunctionType *>(node->GetTarget()->GetTag<Type>("Type")); if (funcType == NULL) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Requires a function type."); } node->SetTag<Type>("Type", funcType->GetReturnType()); }
void LetBindingChecker::Do(const Expression& Exp) { LetBindingChecker Checker; Exp->Accept(&Checker); return; }
void ParamMapFixup::Do(const Expression& Exp) { ParamMapFixup Fixup; Exp->Accept(&Fixup); return; }