diff --git a/baselib.ml b/baselib.ml index fa57cba..b27515b 100644 --- a/baselib.ml +++ b/baselib.ml @@ -9,19 +9,19 @@ let _types_ = ; "%sub", Func_t (Int_t, [ Int_t; Int_t ]) ; "%mul", Func_t (Int_t, [ Int_t; Int_t ]) ; "%div", Func_t (Int_t, [ Int_t; Int_t ]) - ; "%big", Func_t (Bool_t, [ Int_t; Int_t ]) - ; "%sml", Func_t (Bool_t, [ Int_t; Int_t ]) - ; "%equ", Func_t (Bool_t, [ Int_t; Int_t ]) - ; "%neq", Func_t (Bool_t, [ Int_t; Int_t ]) + ; "%seq", Func_t (Bool_t, [ Int_t; Int_t ]) + ; "%sge", Func_t (Bool_t, [ Int_t; Int_t ]) + ; "%sgt", Func_t (Bool_t, [ Int_t; Int_t ]) + ; "%sle", Func_t (Bool_t, [ Int_t; Int_t ]) + ; "%slt", Func_t (Bool_t, [ Int_t; Int_t ]) + ; "%sne", Func_t (Bool_t, [ Int_t; Int_t ]) ; "puti", Func_t (Void_t, [ Int_t ]) ; "puts", Func_t (Void_t, [ Str_t ]) ; "geti", Func_t (Int_t, []) ]) ;; -let builtins_special = [ "%equ"; "%neq" ] - -let builtins uniq = +let builtins = List.fold_left (fun env (fn, impl) -> Env.add fn impl env) Env.empty @@ -29,28 +29,12 @@ let builtins uniq = ; "%sub", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sub (V0, T0, T1) ] ; "%mul", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Mul (V0, T0, T1) ] ; "%div", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Div (V0, T0, T1) ] - ; "%big", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Slt (V0, T0, T1) ] - ; "%sml", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Slt (V0, T1, T0) ] - ; ( "%equ" - , [ Lw (T0, Mem (SP, 0)) - ; Lw (T1, Mem (SP, 4)) - ; Beq (T0, T1, "_equ" ^ uniq) - ; Li (V0, 0) - ; J ("_equend" ^ uniq) - ; Label ("_equ" ^ uniq) - ; Li (V0, 1) - ; Label ("_equend" ^ uniq) - ] ) - ; ( "%neq" - , [ Lw (T0, Mem (SP, 0)) - ; Lw (T1, Mem (SP, 4)) - ; Beq (T0, T1, "_neq" ^ uniq) - ; Li (V0, 1) - ; J ("_neqend" ^ uniq) - ; Label ("_neq" ^ uniq) - ; Li (V0, 0) - ; Label ("_neqend" ^ uniq) - ] ) + ; "%seq", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Seq (V0, T0, T1) ] + ; "%sge", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sge (V0, T0, T1) ] + ; "%sgt", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sgt (V0, T0, T1) ] + ; "%sle", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sle (V0, T0, T1) ] + ; "%slt", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Slt (V0, T0, T1) ] + ; "%sne", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sne (V0, T0, T1) ] ; "puti", [ Lw (A0, Mem (SP, 0)); Li (V0, Syscall.print_int); Syscall ] ; "puts", [ Lw (A0, Mem (SP, 0)); Li (V0, Syscall.print_str); Syscall ] ; "geti", [ Lw (A0, Mem (SP, 0)); Li (V0, Syscall.read_int); Syscall ] diff --git a/compiler.ml b/compiler.ml index 99da664..df237fd 100644 --- a/compiler.ml +++ b/compiler.ml @@ -12,7 +12,6 @@ type info = } let puf = "f_" (* prefix user function *) -let cnt_inline = ref (-1) let compile_value = function | Void -> [ Li (V0, 0) ] @@ -30,17 +29,10 @@ let rec compile_expr env = function (fun a -> compile_expr env a @ [ Addi (SP, SP, -4); Sw (V0, Mem (SP, 0)) ]) args in - let uniq = - if List.mem f Baselib.builtins_special - then ( - incr cnt_inline; - string_of_int !cnt_inline) - else "" - in List.flatten ca @ - if Env.mem f (Baselib.builtins uniq) - then Env.find f (Baselib.builtins uniq) + if Env.mem f Baselib.builtins + then Env.find f Baselib.builtins else [ Jal (puf ^ f); Addi (SP, SP, 4 * List.length args) ] ;; diff --git a/lexer.mll b/lexer.mll index f2588bf..af4915d 100644 --- a/lexer.mll +++ b/lexer.mll @@ -34,10 +34,12 @@ rule token = parse | '-' { Lsub } | '*' { Lmul } | '/' { Ldiv } - | '<' { Lsmaller } - | '>' { Lbigger } - | "==" { Leq } - | "!=" { Lneq } + | "==" { Lseq } + | ">=" { Lsge } + | ">" { Lsgt } + | "<=" { Lsle } + | "<" { Lslt } + | "!=" { Lsne } | '"' { read_string (Buffer.create 16) lexbuf } | ident as i { Lvar i } | '#' { comment lexbuf } diff --git a/mips.ml b/mips.ml index 8cf8e62..c1d8c5e 100644 --- a/mips.ml +++ b/mips.ml @@ -47,7 +47,12 @@ type instr = | Mul of reg * reg * reg | Sub of reg * reg * reg | Div of reg * reg * reg + | Seq of reg * reg * reg + | Sge of reg * reg * reg + | Sgt of reg * reg * reg + | Sle of reg * reg * reg | Slt of reg * reg * reg + | Sne of reg * reg * reg | Syscall | B of label | Beq of reg * reg * label @@ -127,8 +132,18 @@ let fmt_instr ?(indent = " ") = function Printf.sprintf "%ssub %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) | Div (rd, rs, rt) -> Printf.sprintf "%sdiv %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) + | Seq (rd, rs, rt) -> + Printf.sprintf "%sseq %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) + | Sge (rd, rs, rt) -> + Printf.sprintf "%ssge %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) + | Sgt (rd, rs, rt) -> + Printf.sprintf "%ssgt %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) + | Sle (rd, rs, rt) -> + Printf.sprintf "%ssle %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) | Slt (rd, rs, rt) -> Printf.sprintf "%sslt %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) + | Sne (rd, rs, rt) -> + Printf.sprintf "%ssne %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg rt) | Syscall -> Printf.sprintf "%ssyscall" indent | B l -> Printf.sprintf "%sb %s" indent l | Beq (rs, rt, l) -> diff --git a/parser.mly b/parser.mly index df5c3db..95faf63 100644 --- a/parser.mly +++ b/parser.mly @@ -11,10 +11,10 @@ %token Lend Lassign Lsc Lreturn %token Lbracedeb Lbracefin %token Lpardeb Lparfin Lcomma -%token Ladd Lsub Lmul Ldiv Lbigger Lsmaller Leq Lneq +%token Ladd Lsub Lmul Ldiv Lseq Lsge Lsgt Lsle Lslt Lsne %token Lif Lelse Lwhile -%left Ladd Lsub Lmul Ldiv Lbigger Lsmaller Leq Lneq +%left Ladd Lsub Lmul Ldiv Lbigger Lseq Lsge Lsgt Lsle Lslt Lsne %left Lbracedeb Lparfin Lbracefin Lreturn %left Ltype Lbool Lint Lvar Lstr @@ -171,24 +171,34 @@ expr: Call { func = "%div" ; args = [ a ; b ] ; pos = $startpos($2) } } - /* e < e */ - | a = expr ; Lsmaller ; b = expr { - Call { func = "%big" ; args = [ a ; b ] ; pos = $startpos($2) } + /* e == e */ + | a = expr ; Lseq ; b = expr { + Call { func = "%seq" ; args = [ a ; b ] ; pos = $startpos($2) } + } + + /* e >= e */ + | a = expr ; Lsge ; b = expr { + Call { func = "%sge" ; args = [ a ; b ] ; pos = $startpos($2) } } /* e > e */ - | a = expr ; Lbigger ; b = expr { - Call { func = "%sml" ; args = [ a ; b ] ; pos = $startpos($2) } + | a = expr ; Lsgt ; b = expr { + Call { func = "%sgt" ; args = [ a ; b ] ; pos = $startpos($2) } } - /* e == e */ - | a = expr ; Leq ; b = expr { - Call { func = "%equ" ; args = [ a ; b ] ; pos = $startpos($2) } + /* e <= e */ + | a = expr ; Lsle ; b = expr { + Call { func = "%sle" ; args = [ a ; b ] ; pos = $startpos($2) } + } + + /* e < e */ + | a = expr ; Lslt ; b = expr { + Call { func = "%slt" ; args = [ a ; b ] ; pos = $startpos($2) } } /* e != e */ - | a = expr ; Lneq ; b = expr { - Call { func = "%neq" ; args = [ a ; b ] ; pos = $startpos($2) } + | a = expr ; Lsne ; b = expr { + Call { func = "%sne" ; args = [ a ; b ] ; pos = $startpos($2) } } /* function(a */