mirror of
https://github.com/LucasVbr/croissant.git
synced 2026-05-14 01:22:06 +00:00
feat: Implement eval methods for expressions
This commit is contained in:
+264
-26
@@ -1,27 +1,265 @@
|
||||
type binary_operators =
|
||||
| Add
|
||||
| Subtract
|
||||
| Multiply
|
||||
| Divide
|
||||
| Equals
|
||||
| NotEquals
|
||||
| LessThan
|
||||
| LessThanEquals
|
||||
| GreaterThan
|
||||
| GreaterThanEquals
|
||||
| And
|
||||
| Or
|
||||
class virtual binaryOperator =
|
||||
object
|
||||
inherit Node.node
|
||||
method virtual check_type : Types.t * Types.t -> Types.t
|
||||
|
||||
let pp_binary_operators = function
|
||||
| Add -> "Add"
|
||||
| Subtract -> "Subtract"
|
||||
| Multiply -> "Multiply"
|
||||
| Divide -> "Divide"
|
||||
| Equals -> "Equals"
|
||||
| NotEquals -> "NotEquals"
|
||||
| LessThan -> "LessThan"
|
||||
| LessThanEquals -> "LessThanEquals"
|
||||
| GreaterThan -> "GreaterThan"
|
||||
| GreaterThanEquals -> "GreaterThanEquals"
|
||||
| And -> "And"
|
||||
| Or -> "Or"
|
||||
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
|
||||
@@ -0,0 +1,27 @@
|
||||
class evalEnvironment =
|
||||
object
|
||||
val mutable env : (string, Literals.literal_value) Hashtbl.t =
|
||||
Hashtbl.create 10
|
||||
|
||||
method add (name : string) (lit : Literals.literal_value) =
|
||||
Hashtbl.add env name lit
|
||||
|
||||
method find (name : string) = Hashtbl.find env name
|
||||
|
||||
method clone : evalEnvironment =
|
||||
let new_env = new evalEnvironment in
|
||||
Hashtbl.iter (fun k v -> new_env#add k v) env;
|
||||
new_env
|
||||
end
|
||||
|
||||
class typeEnvironments =
|
||||
object
|
||||
val mutable env : (string, Types.t) Hashtbl.t = Hashtbl.create 10
|
||||
method add (name : string) (tp : Types.t) = Hashtbl.add env name tp
|
||||
method find (name : string) = Hashtbl.find env name
|
||||
|
||||
method clone : typeEnvironments =
|
||||
let new_env = new typeEnvironments in
|
||||
Hashtbl.iter (fun k v -> new_env#add k v) env;
|
||||
new_env
|
||||
end
|
||||
+57
-21
@@ -1,23 +1,59 @@
|
||||
open Literals
|
||||
open UnaryOperators
|
||||
open BinaryOperators
|
||||
class virtual expression =
|
||||
object
|
||||
inherit Node.node
|
||||
method virtual check_type : Environments.typeEnvironments -> Types.t
|
||||
method virtual eval : Environments.evalEnvironment -> Literals.literal_value
|
||||
end
|
||||
|
||||
type expressions =
|
||||
| Literal of literals
|
||||
| Identifier of string
|
||||
| UnaryExpression of unary_operators * expressions
|
||||
| BinaryExpression of binary_operators * expressions * expressions
|
||||
class literal (lit : Literals.literal) =
|
||||
object
|
||||
inherit expression
|
||||
method to_string = "Literal(" ^ lit#to_string ^ ")"
|
||||
method check_type _ = lit#check_type
|
||||
method eval _ = lit#value
|
||||
end
|
||||
|
||||
let rec pp_expressions = function
|
||||
| Literal l ->
|
||||
let pp_l = pp_literals l in
|
||||
Printf.sprintf "Literal(%s)" pp_l
|
||||
| Identifier i -> Printf.sprintf "Identifier(\"%s\")" i
|
||||
| UnaryExpression (op, e) ->
|
||||
let pp_op = pp_unary_operators op and pp_e = pp_expressions e in
|
||||
Printf.sprintf "UnaryExpression(%s, %s)" pp_op pp_e
|
||||
| BinaryExpression (op, e1, e2) ->
|
||||
let pp_op = pp_binary_operators op
|
||||
and pp_e1 = pp_expressions e1
|
||||
and pp_e2 = pp_expressions e2 in
|
||||
Printf.sprintf "BinaryExpression(%s, %s, %s)" pp_op pp_e1 pp_e2
|
||||
class identifier (name : string) =
|
||||
object
|
||||
inherit expression
|
||||
method to_string = "Identifier(" ^ name ^ ")"
|
||||
|
||||
method check_type env =
|
||||
try env#find name
|
||||
with Not_found ->
|
||||
raise (Failure ("Identifier '" ^ name ^ "' not found"))
|
||||
|
||||
method eval env = env#find name
|
||||
end
|
||||
|
||||
class unaryOperation (operator : UnaryOperators.unaryOperator)
|
||||
(operand : expression) =
|
||||
object
|
||||
inherit expression
|
||||
|
||||
method to_string =
|
||||
"UnaryOperation(" ^ operator#to_string ^ ", " ^ operand#to_string ^ ")"
|
||||
|
||||
method check_type env =
|
||||
let operand_type = operand#check_type env in
|
||||
operator#check_type operand_type
|
||||
|
||||
method eval env = operator#eval (operand#eval env)
|
||||
end
|
||||
|
||||
class binaryOperation (operator : BinaryOperators.binaryOperator)
|
||||
(left : expression) (right : expression) =
|
||||
object
|
||||
inherit expression
|
||||
|
||||
method to_string =
|
||||
"BinaryOperation(" ^ operator#to_string ^ ", " ^ left#to_string ^ ", "
|
||||
^ right#to_string ^ ")"
|
||||
|
||||
method check_type env =
|
||||
let left_type = left#check_type env in
|
||||
let right_type = right#check_type env in
|
||||
operator#check_type (left_type, right_type)
|
||||
|
||||
method eval env = operator#eval (left#eval env, right#eval env)
|
||||
end
|
||||
+79
-14
@@ -1,15 +1,80 @@
|
||||
type literals =
|
||||
| Integer of int
|
||||
| Float of float
|
||||
| Character of char
|
||||
| String of string
|
||||
| Boolean of bool
|
||||
| Null
|
||||
type literal_value =
|
||||
[ `Int of int
|
||||
| `Float of float
|
||||
| `String of string
|
||||
| `Bool of bool
|
||||
| `Char of char
|
||||
| `Null
|
||||
| `Void ]
|
||||
|
||||
let pp_literals = function
|
||||
| Integer i -> Printf.sprintf "Integer(%d)" i
|
||||
| Float f -> Printf.sprintf "Float(%f)" f
|
||||
| Character c -> Printf.sprintf "Character('%c')" c
|
||||
| String s -> Printf.sprintf "String(\"%s\")" s
|
||||
| Boolean b -> Printf.sprintf "Boolean(%b)" b
|
||||
| Null -> "Null"
|
||||
let string_of_literal_value = function
|
||||
| `Int i -> string_of_int i
|
||||
| `Float f -> string_of_float f
|
||||
| `String s -> "\"" ^ s ^ "\""
|
||||
| `Bool b -> string_of_bool b
|
||||
| `Char c -> "'" ^ String.make 1 c ^ "'"
|
||||
| `Null -> "null"
|
||||
| `Void -> "void"
|
||||
|
||||
class virtual literal =
|
||||
object
|
||||
inherit Node.node
|
||||
method virtual value : literal_value
|
||||
method virtual check_type : Types.t
|
||||
end
|
||||
|
||||
class eInteger (value : int) =
|
||||
object
|
||||
inherit literal
|
||||
method value = `Int value
|
||||
method to_string = "Integer(" ^ string_of_int value ^ ")"
|
||||
method check_type = Types.IntegerType
|
||||
end
|
||||
|
||||
class eFloat (value : float) =
|
||||
object
|
||||
inherit literal
|
||||
method value = `Float value
|
||||
method to_string : string = "Float(" ^ string_of_float value ^ ")"
|
||||
method check_type = Types.FloatType
|
||||
end
|
||||
|
||||
class eString (value : string) =
|
||||
object
|
||||
inherit literal
|
||||
method value = `String value
|
||||
method to_string = "String(\"" ^ value ^ "\")"
|
||||
method check_type = Types.StringType
|
||||
end
|
||||
|
||||
class eBoolean (value : bool) =
|
||||
object
|
||||
inherit literal
|
||||
method value = `Bool value
|
||||
method to_string = "Boolean(" ^ string_of_bool value ^ ")"
|
||||
method check_type = Types.BooleanType
|
||||
end
|
||||
|
||||
class eCharacter (value : char) =
|
||||
object
|
||||
inherit literal
|
||||
method value = `Char value
|
||||
method to_string = "Character(" ^ String.make 1 value ^ ")"
|
||||
method check_type = Types.CharacterType
|
||||
end
|
||||
|
||||
class eNull =
|
||||
object
|
||||
inherit literal
|
||||
method value = `Null
|
||||
method to_string = "Null"
|
||||
method check_type = Types.NullType
|
||||
end
|
||||
|
||||
class eVoid =
|
||||
object
|
||||
inherit literal
|
||||
method value = `Void
|
||||
method to_string = "Void"
|
||||
method check_type = Types.VoidType
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
class virtual node =
|
||||
object
|
||||
method virtual to_string : string
|
||||
(* method virtual check_type : Types.type_ *)
|
||||
(* method virtual eval *)
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
class program (statement : Statements.statement) =
|
||||
object
|
||||
inherit Node.node
|
||||
method to_string = "Program(" ^ statement#to_string ^ ")"
|
||||
|
||||
method check_type =
|
||||
let env : Environments.typeEnvironments =
|
||||
new Environments.typeEnvironments
|
||||
in
|
||||
statement#check_type env
|
||||
|
||||
method eval =
|
||||
let env : Environments.evalEnvironment =
|
||||
new Environments.evalEnvironment
|
||||
in
|
||||
statement#eval env
|
||||
end
|
||||
@@ -1,8 +0,0 @@
|
||||
open Statements
|
||||
|
||||
type source_files = SourceFile of statements
|
||||
|
||||
let pp_source_files = function
|
||||
| SourceFile stmts ->
|
||||
let pp_stmt = pp_statements stmts in
|
||||
Printf.sprintf "SourceFile(%s)" pp_stmt
|
||||
+50
-11
@@ -1,13 +1,52 @@
|
||||
open Expressions
|
||||
class virtual statement =
|
||||
object
|
||||
inherit Node.node
|
||||
method virtual check_type : Environments.typeEnvironments -> Types.t
|
||||
method virtual eval : Environments.evalEnvironment -> Literals.literal_value
|
||||
end
|
||||
|
||||
type statements =
|
||||
| SequenceStatement of statements * statements
|
||||
| ExpressionStatement of expressions
|
||||
class sequence (left : statement) (right : statement) =
|
||||
object
|
||||
inherit statement
|
||||
|
||||
let rec pp_statements = function
|
||||
| SequenceStatement (stmt1, stmt2) ->
|
||||
let pp_stmt1 = pp_statements stmt1 and pp_stmt2 = pp_statements stmt2 in
|
||||
Printf.sprintf "SequenceStatement(%s, %s)" pp_stmt1 pp_stmt2
|
||||
| ExpressionStatement expr ->
|
||||
let pp_expr = pp_expressions expr in
|
||||
Printf.sprintf "ExpressionStatement(%s)" pp_expr
|
||||
method to_string =
|
||||
"Sequence(" ^ left#to_string ^ ", " ^ right#to_string ^ ")"
|
||||
|
||||
method check_type env =
|
||||
let _ = left#check_type env in
|
||||
right#check_type env
|
||||
|
||||
method eval env =
|
||||
let _ = left#eval env in
|
||||
right#eval env
|
||||
end
|
||||
|
||||
class expression (expression : Expressions.expression) =
|
||||
object
|
||||
inherit statement
|
||||
method to_string = "Expression(" ^ expression#to_string ^ ")"
|
||||
method check_type env = expression#check_type env
|
||||
method eval env = expression#eval env
|
||||
end
|
||||
|
||||
class variableDeclaration (name : string) (tp : Types.t)
|
||||
(expression : Expressions.expression) =
|
||||
object
|
||||
inherit statement
|
||||
|
||||
method to_string =
|
||||
"VariableDeclaration(" ^ name ^ ", " ^ Types.string_of_t tp ^ ", "
|
||||
^ expression#to_string ^ ")"
|
||||
|
||||
method check_type env =
|
||||
let expression_type = expression#check_type env in
|
||||
if tp = expression_type then (
|
||||
env#add name expression_type;
|
||||
Types.VoidType)
|
||||
else raise (Failure "VariableDeclaration: type mismatch")
|
||||
|
||||
method eval env =
|
||||
let value = expression#eval env in
|
||||
env#add name value;
|
||||
value
|
||||
end
|
||||
+9
-7
@@ -1,15 +1,17 @@
|
||||
type types =
|
||||
type t =
|
||||
| IntegerType
|
||||
| FloatType
|
||||
| CharacterType
|
||||
| StringType
|
||||
| BooleanType
|
||||
| StringType
|
||||
| CharacterType
|
||||
| NullType
|
||||
| VoidType
|
||||
|
||||
let pp_types = function
|
||||
let string_of_t = function
|
||||
| IntegerType -> "IntegerType"
|
||||
| FloatType -> "FloatType"
|
||||
| CharacterType -> "CharacterType"
|
||||
| StringType -> "StringType"
|
||||
| BooleanType -> "BooleanType"
|
||||
| VoidType -> "VoidType"
|
||||
| StringType -> "StringType"
|
||||
| CharacterType -> "CharacterType"
|
||||
| NullType -> "NullType"
|
||||
| VoidType -> "VoidType"
|
||||
@@ -1,5 +1,40 @@
|
||||
type unary_operators = ArithmeticNegation | LogicalNegation
|
||||
class virtual unaryOperator =
|
||||
object
|
||||
inherit Node.node
|
||||
method virtual check_type : Types.t -> Types.t
|
||||
method virtual eval : Literals.literal_value -> Literals.literal_value
|
||||
end
|
||||
|
||||
let pp_unary_operators = function
|
||||
| ArithmeticNegation -> "ArithmeticNegation"
|
||||
| LogicalNegation -> "LogicalNegation"
|
||||
class arithmeticNegation =
|
||||
object
|
||||
inherit unaryOperator
|
||||
method to_string = "ArithmeticNegation"
|
||||
|
||||
method check_type (operand : Types.t) =
|
||||
match operand with
|
||||
| Types.IntegerType -> Types.IntegerType
|
||||
| Types.FloatType -> Types.FloatType
|
||||
| _ -> raise (Failure "ArithmeticNegation: operand must be a number")
|
||||
|
||||
method eval operand =
|
||||
match operand with
|
||||
| `Int i -> `Int (-i)
|
||||
| `Float f -> `Float (-.f)
|
||||
| _ -> raise (Failure "ArithmeticNegation: operand must be a number")
|
||||
end
|
||||
|
||||
class logicalNegation =
|
||||
object
|
||||
inherit unaryOperator
|
||||
method to_string = "LogicalNegation"
|
||||
|
||||
method check_type (operand : Types.t) =
|
||||
match operand with
|
||||
| Types.BooleanType -> Types.BooleanType
|
||||
| _ -> raise (Failure "LogicalNegation: operand must be a boolean")
|
||||
|
||||
method eval operand =
|
||||
match operand with
|
||||
| `Bool b -> `Bool (not b)
|
||||
| _ -> raise (Failure "LogicalNegation: operand must be a boolean")
|
||||
end
|
||||
+7
-3
@@ -1,10 +1,14 @@
|
||||
(library
|
||||
(name Syntax)
|
||||
(name syntax)
|
||||
(modules
|
||||
Node
|
||||
Types
|
||||
Literals
|
||||
Environments
|
||||
BinaryOperators
|
||||
UnaryOperators
|
||||
Literals
|
||||
Expressions
|
||||
Statements
|
||||
SourceFiles))
|
||||
Roots)
|
||||
; (libraries typing)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user