mirror of
https://github.com/LucasVbr/croissant.git
synced 2026-05-13 17:12:10 +00:00
265 lines
9.2 KiB
OCaml
265 lines
9.2 KiB
OCaml
class virtual binaryOperator =
|
|
object
|
|
inherit Node.node
|
|
method virtual check_type : Types.t * Types.t -> Types.t
|
|
|
|
method virtual eval
|
|
: Literals.literal_value * Literals.literal_value ->
|
|
Literals.literal_value
|
|
end
|
|
|
|
class add =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "Add"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.IntegerType, Types.IntegerType -> Types.IntegerType
|
|
| Types.FloatType, Types.FloatType -> Types.FloatType
|
|
| Types.FloatType, Types.IntegerType -> Types.FloatType
|
|
| Types.IntegerType, Types.FloatType -> Types.FloatType
|
|
| Types.StringType, Types.StringType -> Types.StringType
|
|
| _ -> raise (Failure "Add: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Int (a + b)
|
|
| `Float a, `Float b -> `Float (a +. b)
|
|
| `Float a, `Int b -> `Float (a +. float_of_int b)
|
|
| `Int a, `Float b -> `Float (float_of_int a +. b)
|
|
| `String a, `String b -> `String (a ^ b) (* Concatenation *)
|
|
| _ -> raise (Failure "Add: operands must be numbers")
|
|
end
|
|
|
|
class subtract =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "Subtract"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.IntegerType, Types.IntegerType -> Types.IntegerType
|
|
| Types.FloatType, Types.FloatType -> Types.FloatType
|
|
| Types.FloatType, Types.IntegerType -> Types.FloatType
|
|
| Types.IntegerType, Types.FloatType -> Types.FloatType
|
|
| _ -> raise (Failure "Subtract: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Int (a - b)
|
|
| `Float a, `Float b -> `Float (a -. b)
|
|
| `Float a, `Int b -> `Float (a -. float_of_int b)
|
|
| `Int a, `Float b -> `Float (float_of_int a -. b)
|
|
| _ -> raise (Failure "Subtract: operands must be numbers")
|
|
end
|
|
|
|
class multiply =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "Multiply"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.IntegerType, Types.IntegerType -> Types.FloatType
|
|
| Types.FloatType, Types.FloatType -> Types.FloatType
|
|
| Types.FloatType, Types.IntegerType -> Types.FloatType
|
|
| Types.IntegerType, Types.FloatType -> Types.FloatType
|
|
| _ -> raise (Failure "Multiply: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Float (float_of_int a *. float_of_int b)
|
|
| `Float a, `Float b -> `Float (a *. b)
|
|
| `Float a, `Int b -> `Float (a *. float_of_int b)
|
|
| `Int a, `Float b -> `Float (float_of_int a *. b)
|
|
| _ -> raise (Failure "Multiply: operands must be numbers")
|
|
end
|
|
|
|
class divide =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "Divide"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.IntegerType, Types.IntegerType -> Types.FloatType
|
|
| Types.FloatType, Types.FloatType -> Types.FloatType
|
|
| Types.FloatType, Types.IntegerType -> Types.FloatType
|
|
| Types.IntegerType, Types.FloatType -> Types.FloatType
|
|
| _ -> raise (Failure "Divide: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Float (float_of_int a /. float_of_int b)
|
|
| `Float a, `Float b -> `Float (a /. b)
|
|
| `Float a, `Int b -> `Float (a /. float_of_int b)
|
|
| `Int a, `Float b -> `Float (float_of_int a /. b)
|
|
| _ -> raise (Failure "Divide: operands must be numbers")
|
|
end
|
|
|
|
class equals =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "Equals"
|
|
|
|
method check_type (left, right) =
|
|
if left = right then Types.BooleanType
|
|
else raise (Failure "Equals: operands must have the same type")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Bool (a = b)
|
|
| `Float a, `Float b -> `Bool (a = b)
|
|
| `Float a, `Int b -> `Bool (a = float_of_int b)
|
|
| `Int a, `Float b -> `Bool (float_of_int a = b)
|
|
| `String a, `String b -> `Bool (a = b)
|
|
| `Bool a, `Bool b -> `Bool (a = b)
|
|
| `Char a, `Char b -> `Bool (a = b)
|
|
| `Null, `Null -> `Bool true
|
|
| `Void, `Void -> `Bool true
|
|
| _ -> raise (Failure "Equals: operands must have the same type")
|
|
end
|
|
|
|
class notEquals =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "NotEquals"
|
|
|
|
method check_type (left, right) =
|
|
if left = right then Types.BooleanType
|
|
else raise (Failure "Equals: operands must have the same type")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Bool (a <> b)
|
|
| `Float a, `Float b -> `Bool (a <> b)
|
|
| `Float a, `Int b -> `Bool (a <> float_of_int b)
|
|
| `Int a, `Float b -> `Bool (float_of_int a <> b)
|
|
| `String a, `String b -> `Bool (a <> b)
|
|
| `Bool a, `Bool b -> `Bool (a <> b)
|
|
| `Char a, `Char b -> `Bool (a <> b)
|
|
| `Null, `Null -> `Bool false
|
|
| `Void, `Void -> `Bool false
|
|
| _ -> raise (Failure "NotEquals: operands must have the same type")
|
|
end
|
|
|
|
class lessThan =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "LessThan"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.IntegerType, Types.IntegerType -> Types.BooleanType
|
|
| Types.FloatType, Types.FloatType -> Types.BooleanType
|
|
| Types.FloatType, Types.IntegerType -> Types.BooleanType
|
|
| Types.IntegerType, Types.FloatType -> Types.BooleanType
|
|
| _ -> raise (Failure "LessThan: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Bool (a < b)
|
|
| `Float a, `Float b -> `Bool (a < b)
|
|
| `Float a, `Int b -> `Bool (a < float_of_int b)
|
|
| `Int a, `Float b -> `Bool (float_of_int a < b)
|
|
| _ -> raise (Failure "LessThan: operands must be numbers")
|
|
end
|
|
|
|
class lessThanEquals =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "LessThanEquals"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.IntegerType, Types.IntegerType -> Types.BooleanType
|
|
| Types.FloatType, Types.FloatType -> Types.BooleanType
|
|
| Types.FloatType, Types.IntegerType -> Types.BooleanType
|
|
| Types.IntegerType, Types.FloatType -> Types.BooleanType
|
|
| _ -> raise (Failure "LessThanEquals: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Bool (a <= b)
|
|
| `Float a, `Float b -> `Bool (a <= b)
|
|
| `Float a, `Int b -> `Bool (a <= float_of_int b)
|
|
| `Int a, `Float b -> `Bool (float_of_int a <= b)
|
|
| _ -> raise (Failure "LessThanEquals: operands must be numbers")
|
|
end
|
|
|
|
class greaterThan =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "GreaterThan"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.IntegerType, Types.IntegerType -> Types.BooleanType
|
|
| Types.FloatType, Types.FloatType -> Types.BooleanType
|
|
| Types.FloatType, Types.IntegerType -> Types.BooleanType
|
|
| Types.IntegerType, Types.FloatType -> Types.BooleanType
|
|
| _ -> raise (Failure "GreaterThan: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Bool (a > b)
|
|
| `Float a, `Float b -> `Bool (a > b)
|
|
| `Float a, `Int b -> `Bool (a > float_of_int b)
|
|
| `Int a, `Float b -> `Bool (float_of_int a > b)
|
|
| _ -> raise (Failure "GreaterThan: operands must be numbers")
|
|
end
|
|
|
|
class greaterThanEquals =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "GreaterThanEquals"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.IntegerType, Types.IntegerType -> Types.BooleanType
|
|
| Types.FloatType, Types.FloatType -> Types.BooleanType
|
|
| Types.FloatType, Types.IntegerType -> Types.BooleanType
|
|
| Types.IntegerType, Types.FloatType -> Types.BooleanType
|
|
| _ -> raise (Failure "GreaterThanEquals: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Int a, `Int b -> `Bool (a >= b)
|
|
| `Float a, `Float b -> `Bool (a >= b)
|
|
| `Float a, `Int b -> `Bool (a >= float_of_int b)
|
|
| `Int a, `Float b -> `Bool (float_of_int a >= b)
|
|
| _ -> raise (Failure "GreaterThanEquals: operands must be numbers")
|
|
end
|
|
|
|
class logicalAnd =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "And"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.BooleanType, Types.BooleanType -> Types.BooleanType
|
|
| _ -> raise (Failure "And: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Bool a, `Bool b -> `Bool (a && b)
|
|
| _ -> raise (Failure "And: operands must be booleans")
|
|
end
|
|
|
|
class logicalOr =
|
|
object
|
|
inherit binaryOperator
|
|
method to_string = "Or"
|
|
|
|
method check_type (left, right) =
|
|
match (left, right) with
|
|
| Types.BooleanType, Types.BooleanType -> Types.BooleanType
|
|
| _ -> raise (Failure "Or: operands must be numbers")
|
|
|
|
method eval (left, right) =
|
|
match (left, right) with
|
|
| `Bool a, `Bool b -> `Bool (a || b)
|
|
| _ -> raise (Failure "Or: operands must be booleans")
|
|
end |