public TypeDenoter VisitBinaryExpression(BinaryExpression ast, Void arg) { TypeDenoter e1Type = ast.LeftExpression.Visit(this, null); TypeDenoter e2Type = ast.RightExpression.Visit(this, null); Declaration binding = ast.Operation.Visit(this, null); if (binding is BinaryOperatorDeclaration bbinding) { if (bbinding.FirstArgument == StandardEnvironment.AnyType) { CheckAndReportError(e1Type.Equals(e2Type), "incompatible argument types for \"%\"", ast.Operation, ast); } else { CheckAndReportError(e1Type.Equals(bbinding.FirstArgument), "wrong argument type for \"%\"", ast.Operation, ast.LeftExpression); CheckAndReportError(e2Type.Equals(bbinding.SecondArgument), "wrong argument type for \"%\"", ast.Operation, ast.RightExpression); } ast.Type = bbinding.Result; } else { ReportUndeclaredOrError(binding, ast.Operation, "\"%\" is not a binary operator"); ast.Type = StandardEnvironment.ErrorType; } return(ast.Type); }
public TypeDenoter VisitTernaryExpression(TernaryExpression ast, Void arg) { TypeDenoter e2Type = ast.LeftExpression.Visit(this, null); TypeDenoter e3Type = ast.RightExpression.Visit(this, null); TypeDenoter e1Type = ast.Condition.Visit(this, null); if (e1Type is BoolTypeDenoter) { if (e1Type.Equals(true)) { ast.Type = e2Type; } else { ast.Type = e3Type; CheckAndReportError(e2Type.Equals(e3Type), "incompatible argument type for \"%\"", ast.Type.ToString(), ast.RightExpression.Position); } } else { ReportError("\"%\" is not a valid boolean", e1Type); } return(ast.Type); }
public TypeDenoter VisitTernaryExpression(TernaryExpression ast, Void arg) { TypeDenoter e1Type = ast.Condition.Visit(this, null); TypeDenoter e2Type = ast.LeftExpression.Visit(this, null); TypeDenoter e3Type = ast.RightExpression.Visit(this, null); if (e1Type == StandardEnvironment.BooleanType) { if (e2Type == e3Type) { ast.Type = StandardEnvironment.AnyType; } else { CheckAndReportError(e2Type.Equals(e3Type), "ternary expression member \"%\" must have the same type", ast.LeftExpression); CheckAndReportError(e3Type.Equals(e2Type), "ternary expression member \"%\" must have the same type", ast.RightExpression); ast.Type = StandardEnvironment.ErrorType; } } else { CheckAndReportError(e1Type.Equals(StandardEnvironment.BooleanType), "argument type \"%\" is not a boolean", ast.Condition); ast.Type = StandardEnvironment.ErrorType; } return(ast.Type); }
public Void VisitWhileCommand(WhileCommand ast, Void arg) { System.Console.WriteLine("Visiting WhileCommand"); TypeDenoter expressionType = ast.Expression.Visit(this, null); CheckAndReportError(expressionType.Equals(StandardEnvironment.BooleanType), "expression type must be boolean", ast); return(ast.Command.Visit(this, null)); }
public Void VisitAssignCommand(AssignCommand ast, Void arg) { TypeDenoter identifierType = ast.Identifier.Visit(this, null).Type; TypeDenoter expressionType = ast.Expression.Visit(this, null); CheckAndReportError(ast.Identifier.IsVariable, "LHS of assignment is not a variable", ast.Identifier); CheckAndReportError(expressionType.Equals(identifierType), "assignment incompatibilty", ast); return(null); }
// Actual Parameters // Always returns null. Uses the given FormalParameter. public Void VisitValueParameter(ValueParameter ast, FormalParameter arg) { TypeDenoter expressionType = ast.Expression.Visit(this, null); if (arg is ConstFormalParameter param) { CheckAndReportError(expressionType.Equals(param.Type), "wrong type for const actual parameter", ast.Expression); } else { ReportError("const actual parameter not expected here", ast); } return(null); }
public TypeDenoter VisitUnaryExpression(UnaryExpression ast, Void arg) { TypeDenoter expressionType = ast.Expression.Visit(this, null); Declaration binding = ast.Operator.Visit(this, null); if (binding is UnaryOperatorDeclaration ubinding) { CheckAndReportError(expressionType.Equals(ubinding.Argument), "wrong argument type for \"%\"", ast.Operator); ast.Type = ubinding.Result; } else { ReportUndeclaredOrError(binding, ast.Operator, "\"%\" is not a unary operator"); ast.Type = StandardEnvironment.ErrorType; } return(ast.Type); }
public TypeDenoter VisitTernaryExpression(TernaryExpression ast, Void arg) { TypeDenoter condition = ast.Condition.Visit(this, null); TypeDenoter e2Type = ast.LeftExpression.Visit(this, null); TypeDenoter e3Type = ast.RightExpression.Visit(this, null); if (condition is BoolTypeDenoter) { if (e2Type.GetType() == e3Type.GetType()) { ast.Type = e3Type; } else { CheckAndReportError(e2Type.Equals(e3Type), "icompatible arguement types for \"%\"", ast.Type.ToString(), ast.Position); } } else { ReportError("\"%\" incompatible boolean", condition); } return(ast.Type); }