feat: include operator name in type errors
This commit is contained in:
parent
319fa606d9
commit
3430299847
@ -60,35 +60,45 @@ object ast {
|
|||||||
object Chr extends ParserBridgePos1[Expr6, Chr]
|
object Chr extends ParserBridgePos1[Expr6, Chr]
|
||||||
|
|
||||||
// Binary operators
|
// Binary operators
|
||||||
sealed trait BinaryOp extends Expr {
|
sealed trait BinaryOp(val name: String) extends Expr {
|
||||||
val x: Expr
|
val x: Expr
|
||||||
val y: 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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
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]
|
object Or extends ParserBridgePos2[Expr1, Expr, Or]
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
@ -233,13 +233,16 @@ object typeChecker {
|
|||||||
|
|
||||||
// Binary operators
|
// Binary operators
|
||||||
case op: (Add | Sub | Mul | Div | Mod) =>
|
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.x, operand)
|
||||||
checkValue(op.y, operand)
|
checkValue(op.y, operand)
|
||||||
KnownType.Int.satisfies(constraint, op.pos)
|
KnownType.Int.satisfies(constraint, op.pos)
|
||||||
case op: (Eq | Neq) =>
|
case op: (Eq | Neq) =>
|
||||||
val xTy = checkValue(op.x, Constraint.Unconstrained)
|
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)
|
KnownType.Bool.satisfies(constraint, op.pos)
|
||||||
case op: (Less | LessEq | Greater | GreaterEq) =>
|
case op: (Less | LessEq | Greater | GreaterEq) =>
|
||||||
val xTy = checkValue(
|
val xTy = checkValue(
|
||||||
@ -247,13 +250,16 @@ object typeChecker {
|
|||||||
Constraint.IsEither(
|
Constraint.IsEither(
|
||||||
KnownType.Int,
|
KnownType.Int,
|
||||||
KnownType.Char,
|
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)
|
KnownType.Bool.satisfies(constraint, op.pos)
|
||||||
case op: (And | Or) =>
|
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.x, operand)
|
||||||
checkValue(op.y, operand)
|
checkValue(op.y, operand)
|
||||||
KnownType.Bool.satisfies(constraint, op.pos)
|
KnownType.Bool.satisfies(constraint, op.pos)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user