This repository has been archived on 2022-12-27. You can view files and clone it, but cannot push or open issues or pull requests.
compilateurMIPS/compiler.ml
2022-12-09 14:45:59 +01:00

73 lines
1.6 KiB
OCaml

open Ast.IR
open Mips
module Env = Map.Make (String)
type info =
{ asm : instr list
; env : loc Env.t
; fpo : int (* FP offset *)
; cnt : int (* Counter *)
; ret : string (* Return *)
}
let compile_value = function
| Int n -> [ Li (V0, n) ]
| Bool b -> [ Li (V0, if b then 1 else 0) ]
;;
let rec compile_expr env = function
| Val v -> compile_value v
| Var v -> [ Lw (V0, Env.find v env) ]
| Call (f, args) ->
let ca =
List.map
(fun a -> compile_expr env a @ [ Addi (SP, SP, -4); Sw (V0, Mem (SP, 0)) ])
args
in
List.flatten ca @ Env.find f Baselib.builtins
;;
let compile_instr info = function
| Decl v ->
{ info with env = Env.add v (Mem (FP, -info.fpo)) info.env; fpo = info.fpo + 4 }
| Assign (v, e) ->
{ info with
asm = info.asm @ compile_expr info.env e @ [ Sw (V0, Env.find v info.env) ]
}
| Return e -> { info with asm = info.asm @ compile_expr info.env e @ [ B info.ret ] }
;;
let rec compile_block info = function
| [] -> info
| i :: b -> compile_block (compile_instr info i) b
;;
let compile_body body counter =
let compiled =
compile_block
{ asm = []
; env = Env.empty
; fpo = 8
; cnt = counter + 1
; ret = "ret" ^ string_of_int counter
}
body
in
[ Addi (SP, SP, -compiled.fpo)
; Sw (RA, Mem (SP, compiled.fpo - 4))
; Sw (FP, Mem (SP, compiled.fpo - 8))
; Addi (FP, SP, compiled.fpo - 4)
]
@ compiled.asm
@ [ Label compiled.ret
; Addi (SP, SP, compiled.fpo)
; Lw (RA, Mem (FP, 0))
; Lw (FP, Mem (FP, -4))
; Jr RA
]
;;
let compile ir =
let asm = compile_body ir 0 in
{ text = asm; data = [] }
;;