type type_t = | Int_t | Float_t | Char_t | Str_t | Void_t | Bool_t | Func_t of type_t * type_t list | Point_t of type_t (* | Array_t of int * type_t *) let rec string_of_type_t t = match t with | Int_t -> "int" | Float_t -> "float" | Char_t -> "char" | Str_t -> "string" | Void_t -> "void" | Bool_t -> "bool" (* | Array_t (n, t) -> string_of_type_t t *) | Point_t t -> string_of_type_t t | Func_t (r, a) -> (if List.length a > 1 then "(" else "") ^ String.concat ", " (List.map string_of_type_t a) ^ (if List.length a > 1 then ")" else "") ^ " -> " ^ string_of_type_t r ;; module Syntax = struct type ident = string type expr = | Int of { value : int ; pos : Lexing.position } | Float of { value : float ; pos : Lexing.position } | Char of { value : string ; pos : Lexing.position } | Str of { value : string ; pos : Lexing.position } (* | Array of *) (* { value : expr list *) (* ; cap : int option *) (* ; pos : Lexing.position *) (* } *) | Bool of { value : bool ; pos : Lexing.position } | Var of { name : ident ; pos : Lexing.position } | Call of { func : ident ; args : expr list ; pos : Lexing.position } type instr = | Assign of { var : ident ; expr : expr ; pos : Lexing.position } | Decl of { var : ident ; typ : type_t ; pos : Lexing.position } | Expr of { expr : expr ; pos : Lexing.position } | Return of { expr : expr ; pos : Lexing.position } | Cond of { expr : expr ; blockt : block ; blockf : block ; pos : Lexing.position } | Loop of { expr : expr ; block : block ; pos : Lexing.position } and block = instr list type def = | Func of { typ : type_t ; name : ident ; args : (type_t * ident) list ; block : block ; pos : Lexing.position } type prog = def list end module IR = struct type ident = string type expr = | Int of int | Float of float | Char of char | Str of string | Void | Bool of bool (* | Array of int * expr list *) | Var of ident | Call of ident * expr list type instr = | Decl of ident | Expr of expr | Assign of ident * expr | Return of expr | Cond of expr * block * block | Loop of expr * block and block = instr list type def = Func of ident * ident list * block type prog = def list let string_of_ir ast = let rec fmt_e = function | Int n -> "Int " ^ string_of_int n | Float n -> "Float " ^ string_of_float n | Char c -> "Char " ^ String.make 1 c | Str s -> "Str \"" ^ s ^ "\"" (* | Array (n, e) -> "Array (" ^ string_of_int n ^ ", " ^ String.concat " ; " (List.map fmt_e e) ^ ")" *) | Void -> "Void" | Bool b -> "Bool " ^ string_of_bool b | Var v -> "Var \"" ^ v ^ "\"" | Call (f, a) -> "Call (\"" ^ f ^ "\", [ " ^ String.concat " ; " (List.map fmt_e a) ^ " ])" and fmt_i = function | Decl v -> "Decl \"" ^ v ^ "\"" | Assign (v, e) -> "Assign (\"" ^ v ^ "\", " ^ fmt_e e ^ ")" | Expr e -> "Expr (" ^ fmt_e e ^ ")" | Return e -> "Return (" ^ fmt_e e ^ ")" | Cond (e, bt, bf) -> "Cond (" ^ fmt_e e ^ ", " ^ fmt_b bt ^ "\n, " ^ fmt_b bf ^ ")" | Loop (e, b) -> "Loop (" ^ fmt_e e ^ ",\n" ^ fmt_b b ^ ")" and fmt_b b = "\t[ " ^ String.concat "\n\t; " (List.map fmt_i b) ^ " ]" and fmt_arg a = "\"" ^ a ^ "\"" and fmt_d = function | Func (name, args, b) -> "[ Func (\"" ^ name ^ "\", " ^ "[ " ^ String.concat " ; " (List.map fmt_arg args) ^ " ],\n" ^ fmt_b b ^ ")" ^ "]" and fmt_p p = "[\n " ^ String.concat "\n " (List.map fmt_d p) ^ "\n]" in fmt_p ast ;; end module IR2 = struct type ident = string type value = | Nil | Bool of bool | Int of int | Float of float | Char of char | Data of string type expr = | Value of value | Var of ident | Call of ident * expr list (* type lvalue = *) (* | LVar of ident *) (* | LAddr of expr *) type instr = | Decl of ident | Return of expr | Expr of expr | Assign of expr * expr | Cond of expr * block * block | Loop of expr * block and block = instr list type def = Func of ident * ident list * block type prog = def list end