type value = | Int of int | Float of float;; let string_of_value x = match x with | Int i -> string_of_int i; | Float f -> string_of_float f;; (********* Exercice 1 *********) let sum_of_values a b = match (a,b) with | (Int i,Int j) -> Int(i+j) | (Int i,Float f) -> Float((float i)+.f) | (Float f,Float g) -> Float (f+.g);; (********* Exercice 2 *********) type 'a bintree = | BinEmpty | BinNode of 'a * 'a bintree * 'a bintree let rec bintree_build f h x = if (h <= 0) then BinEmpty else let (x1,x2) = f(x) in BinNode (x, (bintree_build f (h-1) x1), (bintree_build f (h-1) x2));; let a : number = 7; let b : number = 6; console.log("The answer is equal to " + a * b); (********* Exercice 3 *********) // Operators interface Plus { kind: "op_plus"; } interface Minus { kind: "op_minus"; } interface Equal { kind: "op_equal"; } interface Mult { kind: "op_mult"; } type Op = Plus | Minus | Equal | Mult; // Expressions interface ExprInt { kind: "expr_int", int: number } // Integer expression interface ExprVar { kind: "expr_var", var: string } // Variable expression interface ExprBin { kind: "expr_bin", lhs: Expr, op: Op, rhs : Expr } // Binary operation type Expr = ExprInt | ExprVar | ExprBin; // Values interface ValInt { kind: "val_int", val: number } // Integer value interface ValBool { kind: "val_bool", val: boolean } // Boolean value type Value = ValInt | ValBool; type Env = { [id: string] : Value; } // Lookup value inside the environment function env_lookup(env: Env, id: string) : Value { return env[id]; } // Add the relation id:val into the environment and return it function env_add(env: Env, id: string, val: Value) : Env { env[id] = val; return env; } // Instructions interface InstrGoto { kind: "instr_goto", line: number } interface InstrJumpIf { kind: "instr_jumpif", cond: Expr, line: number } interface InstrLet { kind: "instr_let", id: string, expr: Expr } type Instr = InstrGoto | InstrJumpIf | InstrLet ; interface Line { instr : Instr, line: number } type Prog = Line[]; interface State { env: Env, line: number } let prog : Prog = [ { line: 10, instr: { kind: "instr_let", id: "i", expr: { kind: "expr_int", int: 1}} }, { line: 20, instr: { kind: "instr_let", id: "s", expr: { kind: "expr_int", int: 1}} }, { line: 30, instr: { kind: "instr_let", id: "i", expr: { kind: "expr_bin", op: { kind: "op_plus"}, lhs: { kind: "expr_var", var: "i"}, rhs: { kind: "expr_int", int: 1} }} }, { line: 40, instr: { kind: "instr_let", id: "s", expr: { kind: "expr_bin", op: { kind: "op_mult"}, lhs: { kind: "expr_var", var: "i"}, rhs: { kind: "expr_var", var: "s"} }} }, { line: 50, instr: { kind: "instr_jumpif", cond: { kind: "expr_bin", op: { kind: "op_equal" }, lhs: { kind: "expr_var", var: "i"}, rhs: {kind: "expr_var", var: "n"}}, line: 70} }, { line: 60, instr: { kind: "instr_goto", line: 30} }, ] function eval_expr(expr: Expr, env: Env) : Value { // TODO } function eval_instr(instr: Instr, state: State) : State { // TODO } // Returns a particular line of a program function prog_lookup(prog: Prog, line: number) : Line | undefined { return prog.find((l) => l.line == line); } function eval_prog(prog: Prog, start: number, env: Env) : Env { // TODO } let res : Env = eval_prog(prog, 10, { n: { kind: "val_int", val: 4 }});