diff --git a/src/main/wacc/ast.scala b/src/main/wacc/ast.scala index 8ea99d7..f885843 100644 --- a/src/main/wacc/ast.scala +++ b/src/main/wacc/ast.scala @@ -60,35 +60,45 @@ object ast { object Chr extends ParserBridgePos1[Expr6, Chr] // Binary operators - sealed trait BinaryOp extends Expr { + sealed trait BinaryOp(val name: String) extends Expr { val x: Expr val y: Expr } - case class Add(x: Expr4, y: Expr5)(val pos: Position) extends Expr4 with BinaryOp + case class Add(x: Expr4, y: Expr5)(val pos: Position) extends Expr4 with BinaryOp("addition") object Add extends ParserBridgePos2[Expr4, Expr5, Add] - case class Sub(x: Expr4, y: Expr5)(val pos: Position) extends Expr4 with BinaryOp + case class Sub(x: Expr4, y: Expr5)(val pos: Position) extends Expr4 with BinaryOp("subtraction") object Sub extends ParserBridgePos2[Expr4, Expr5, Sub] - case class Mul(x: Expr5, y: Expr6)(val pos: Position) extends Expr5 with BinaryOp + case class Mul(x: Expr5, y: Expr6)(val pos: Position) + extends Expr5 + with BinaryOp("multiplication") object Mul extends ParserBridgePos2[Expr5, Expr6, Mul] - case class Div(x: Expr5, y: Expr6)(val pos: Position) extends Expr5 with BinaryOp + case class Div(x: Expr5, y: Expr6)(val pos: Position) extends Expr5 with BinaryOp("division") object Div extends ParserBridgePos2[Expr5, Expr6, Div] - case class Mod(x: Expr5, y: Expr6)(val pos: Position) extends Expr5 with BinaryOp + case class Mod(x: Expr5, y: Expr6)(val pos: Position) extends Expr5 with BinaryOp("modulus") object Mod extends ParserBridgePos2[Expr5, Expr6, Mod] - case class Greater(x: Expr4, y: Expr4)(val pos: Position) extends Expr3 with BinaryOp + case class Greater(x: Expr4, y: Expr4)(val pos: Position) + extends Expr3 + with BinaryOp("strictly greater than") object Greater extends ParserBridgePos2[Expr4, Expr4, Greater] - case class GreaterEq(x: Expr4, y: Expr4)(val pos: Position) extends Expr3 with BinaryOp + case class GreaterEq(x: Expr4, y: Expr4)(val pos: Position) + extends Expr3 + with BinaryOp("greater than or equal to") object GreaterEq extends ParserBridgePos2[Expr4, Expr4, GreaterEq] - case class Less(x: Expr4, y: Expr4)(val pos: Position) extends Expr3 with BinaryOp + case class Less(x: Expr4, y: Expr4)(val pos: Position) + extends Expr3 + with BinaryOp("strictly less than") object Less extends ParserBridgePos2[Expr4, Expr4, Less] - case class LessEq(x: Expr4, y: Expr4)(val pos: Position) extends Expr3 with BinaryOp + case class LessEq(x: Expr4, y: Expr4)(val pos: Position) + extends Expr3 + with BinaryOp("less than or equal to") object LessEq extends ParserBridgePos2[Expr4, Expr4, LessEq] - case class Eq(x: Expr3, y: Expr3)(val pos: Position) extends Expr2 with BinaryOp + case class Eq(x: Expr3, y: Expr3)(val pos: Position) extends Expr2 with BinaryOp("equality") object Eq extends ParserBridgePos2[Expr3, Expr3, Eq] - case class Neq(x: Expr3, y: Expr3)(val pos: Position) extends Expr2 with BinaryOp + case class Neq(x: Expr3, y: Expr3)(val pos: Position) extends Expr2 with BinaryOp("inequality") object Neq extends ParserBridgePos2[Expr3, Expr3, Neq] - case class And(x: Expr2, y: Expr1)(val pos: Position) extends Expr1 with BinaryOp + case class And(x: Expr2, y: Expr1)(val pos: Position) extends Expr1 with BinaryOp("logical and") object And extends ParserBridgePos2[Expr2, Expr1, And] - case class Or(x: Expr1, y: Expr)(val pos: Position) extends Expr with BinaryOp + case class Or(x: Expr1, y: Expr)(val pos: Position) extends Expr with BinaryOp("logical or") object Or extends ParserBridgePos2[Expr1, Expr, Or] // Types diff --git a/src/main/wacc/typeChecker.scala b/src/main/wacc/typeChecker.scala index f0f523b..d9ebecc 100644 --- a/src/main/wacc/typeChecker.scala +++ b/src/main/wacc/typeChecker.scala @@ -233,13 +233,16 @@ object typeChecker { // Binary operators case op: (Add | Sub | Mul | Div | Mod) => - val operand = Constraint.Is(KnownType.Int, "binary operator must be applied to an int") + val operand = Constraint.Is(KnownType.Int, s"${op.name} operator must be applied to an int") checkValue(op.x, operand) checkValue(op.y, operand) KnownType.Int.satisfies(constraint, op.pos) case op: (Eq | Neq) => val xTy = checkValue(op.x, Constraint.Unconstrained) - checkValue(op.y, Constraint.Is(xTy, "equality must be applied to values of the same type")) + checkValue( + op.y, + Constraint.Is(xTy, s"${op.name} operator must be applied to values of the same type") + ) KnownType.Bool.satisfies(constraint, op.pos) case op: (Less | LessEq | Greater | GreaterEq) => val xTy = checkValue( @@ -247,13 +250,16 @@ object typeChecker { Constraint.IsEither( KnownType.Int, KnownType.Char, - "comparison must be applied to an int or char" + s"${op.name} operator must be applied to an int or char" ) ) - checkValue(op.y, Constraint.Is(xTy, "comparison must be applied to values of the same type")) + checkValue( + op.y, + Constraint.Is(xTy, s"${op.name} operator must be applied to values of the same type") + ) KnownType.Bool.satisfies(constraint, op.pos) case op: (And | Or) => - val operand = Constraint.Is(KnownType.Bool, "logical operator must be applied to a bool") + val operand = Constraint.Is(KnownType.Bool, s"${op.name} operator must be applied to a bool") checkValue(op.x, operand) checkValue(op.y, operand) KnownType.Bool.satisfies(constraint, op.pos)