add some comparisons instructions, and fix older one
This commit is contained in:
parent
338194dadb
commit
fa95a3f071
5 changed files with 58 additions and 55 deletions
42
baselib.ml
42
baselib.ml
|
@ -9,19 +9,19 @@ let _types_ =
|
||||||
; "%sub", Func_t (Int_t, [ Int_t; Int_t ])
|
; "%sub", Func_t (Int_t, [ Int_t; Int_t ])
|
||||||
; "%mul", 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 ])
|
; "%div", Func_t (Int_t, [ Int_t; Int_t ])
|
||||||
; "%big", Func_t (Bool_t, [ Int_t; Int_t ])
|
; "%seq", Func_t (Bool_t, [ Int_t; Int_t ])
|
||||||
; "%sml", Func_t (Bool_t, [ Int_t; Int_t ])
|
; "%sge", Func_t (Bool_t, [ Int_t; Int_t ])
|
||||||
; "%equ", Func_t (Bool_t, [ Int_t; Int_t ])
|
; "%sgt", Func_t (Bool_t, [ Int_t; Int_t ])
|
||||||
; "%neq", 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 ])
|
; "puti", Func_t (Void_t, [ Int_t ])
|
||||||
; "puts", Func_t (Void_t, [ Str_t ])
|
; "puts", Func_t (Void_t, [ Str_t ])
|
||||||
; "geti", Func_t (Int_t, [])
|
; "geti", Func_t (Int_t, [])
|
||||||
])
|
])
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let builtins_special = [ "%equ"; "%neq" ]
|
let builtins =
|
||||||
|
|
||||||
let builtins uniq =
|
|
||||||
List.fold_left
|
List.fold_left
|
||||||
(fun env (fn, impl) -> Env.add fn impl env)
|
(fun env (fn, impl) -> Env.add fn impl env)
|
||||||
Env.empty
|
Env.empty
|
||||||
|
@ -29,28 +29,12 @@ let builtins uniq =
|
||||||
; "%sub", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sub (V0, T0, T1) ]
|
; "%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) ]
|
; "%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) ]
|
; "%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) ]
|
; "%seq", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Seq (V0, T0, T1) ]
|
||||||
; "%sml", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Slt (V0, T1, T0) ]
|
; "%sge", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sge (V0, T0, T1) ]
|
||||||
; ( "%equ"
|
; "%sgt", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sgt (V0, T0, T1) ]
|
||||||
, [ Lw (T0, Mem (SP, 0))
|
; "%sle", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sle (V0, T0, T1) ]
|
||||||
; Lw (T1, Mem (SP, 4))
|
; "%slt", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Slt (V0, T0, T1) ]
|
||||||
; Beq (T0, T1, "_equ" ^ uniq)
|
; "%sne", [ Lw (T0, Mem (SP, 4)); Lw (T1, Mem (SP, 0)); Sne (V0, T0, T1) ]
|
||||||
; 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)
|
|
||||||
] )
|
|
||||||
; "puti", [ Lw (A0, Mem (SP, 0)); Li (V0, Syscall.print_int); Syscall ]
|
; "puti", [ Lw (A0, Mem (SP, 0)); Li (V0, Syscall.print_int); Syscall ]
|
||||||
; "puts", [ Lw (A0, Mem (SP, 0)); Li (V0, Syscall.print_str); 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 ]
|
; "geti", [ Lw (A0, Mem (SP, 0)); Li (V0, Syscall.read_int); Syscall ]
|
||||||
|
|
12
compiler.ml
12
compiler.ml
|
@ -12,7 +12,6 @@ type info =
|
||||||
}
|
}
|
||||||
|
|
||||||
let puf = "f_" (* prefix user function *)
|
let puf = "f_" (* prefix user function *)
|
||||||
let cnt_inline = ref (-1)
|
|
||||||
|
|
||||||
let compile_value = function
|
let compile_value = function
|
||||||
| Void -> [ Li (V0, 0) ]
|
| 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)) ])
|
(fun a -> compile_expr env a @ [ Addi (SP, SP, -4); Sw (V0, Mem (SP, 0)) ])
|
||||||
args
|
args
|
||||||
in
|
in
|
||||||
let uniq =
|
|
||||||
if List.mem f Baselib.builtins_special
|
|
||||||
then (
|
|
||||||
incr cnt_inline;
|
|
||||||
string_of_int !cnt_inline)
|
|
||||||
else ""
|
|
||||||
in
|
|
||||||
List.flatten ca
|
List.flatten ca
|
||||||
@
|
@
|
||||||
if Env.mem f (Baselib.builtins uniq)
|
if Env.mem f Baselib.builtins
|
||||||
then Env.find f (Baselib.builtins uniq)
|
then Env.find f Baselib.builtins
|
||||||
else [ Jal (puf ^ f); Addi (SP, SP, 4 * List.length args) ]
|
else [ Jal (puf ^ f); Addi (SP, SP, 4 * List.length args) ]
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
10
lexer.mll
10
lexer.mll
|
@ -34,10 +34,12 @@ rule token = parse
|
||||||
| '-' { Lsub }
|
| '-' { Lsub }
|
||||||
| '*' { Lmul }
|
| '*' { Lmul }
|
||||||
| '/' { Ldiv }
|
| '/' { Ldiv }
|
||||||
| '<' { Lsmaller }
|
| "==" { Lseq }
|
||||||
| '>' { Lbigger }
|
| ">=" { Lsge }
|
||||||
| "==" { Leq }
|
| ">" { Lsgt }
|
||||||
| "!=" { Lneq }
|
| "<=" { Lsle }
|
||||||
|
| "<" { Lslt }
|
||||||
|
| "!=" { Lsne }
|
||||||
| '"' { read_string (Buffer.create 16) lexbuf }
|
| '"' { read_string (Buffer.create 16) lexbuf }
|
||||||
| ident as i { Lvar i }
|
| ident as i { Lvar i }
|
||||||
| '#' { comment lexbuf }
|
| '#' { comment lexbuf }
|
||||||
|
|
15
mips.ml
15
mips.ml
|
@ -47,7 +47,12 @@ type instr =
|
||||||
| Mul of reg * reg * reg
|
| Mul of reg * reg * reg
|
||||||
| Sub of reg * reg * reg
|
| Sub of reg * reg * reg
|
||||||
| Div 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
|
| Slt of reg * reg * reg
|
||||||
|
| Sne of reg * reg * reg
|
||||||
| Syscall
|
| Syscall
|
||||||
| B of label
|
| B of label
|
||||||
| Beq of reg * reg * 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)
|
Printf.sprintf "%ssub %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg rt)
|
||||||
| Div (rd, rs, rt) ->
|
| Div (rd, rs, rt) ->
|
||||||
Printf.sprintf "%sdiv %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg 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) ->
|
| Slt (rd, rs, rt) ->
|
||||||
Printf.sprintf "%sslt %s, %s, %s" indent (fmt_reg rd) (fmt_reg rs) (fmt_reg 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
|
| Syscall -> Printf.sprintf "%ssyscall" indent
|
||||||
| B l -> Printf.sprintf "%sb %s" indent l
|
| B l -> Printf.sprintf "%sb %s" indent l
|
||||||
| Beq (rs, rt, l) ->
|
| Beq (rs, rt, l) ->
|
||||||
|
|
34
parser.mly
34
parser.mly
|
@ -11,10 +11,10 @@
|
||||||
%token Lend Lassign Lsc Lreturn
|
%token Lend Lassign Lsc Lreturn
|
||||||
%token Lbracedeb Lbracefin
|
%token Lbracedeb Lbracefin
|
||||||
%token Lpardeb Lparfin Lcomma
|
%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
|
%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 Lbracedeb Lparfin Lbracefin Lreturn
|
||||||
%left Ltype Lbool Lint Lvar Lstr
|
%left Ltype Lbool Lint Lvar Lstr
|
||||||
|
@ -171,24 +171,34 @@ expr:
|
||||||
Call { func = "%div" ; args = [ a ; b ] ; pos = $startpos($2) }
|
Call { func = "%div" ; args = [ a ; b ] ; pos = $startpos($2) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* e < e */
|
/* e == e */
|
||||||
| a = expr ; Lsmaller ; b = expr {
|
| a = expr ; Lseq ; b = expr {
|
||||||
Call { func = "%big" ; args = [ a ; b ] ; pos = $startpos($2) }
|
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 */
|
/* e > e */
|
||||||
| a = expr ; Lbigger ; b = expr {
|
| a = expr ; Lsgt ; b = expr {
|
||||||
Call { func = "%sml" ; args = [ a ; b ] ; pos = $startpos($2) }
|
Call { func = "%sgt" ; args = [ a ; b ] ; pos = $startpos($2) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* e == e */
|
/* e <= e */
|
||||||
| a = expr ; Leq ; b = expr {
|
| a = expr ; Lsle ; b = expr {
|
||||||
Call { func = "%equ" ; args = [ a ; b ] ; pos = $startpos($2) }
|
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 */
|
/* e != e */
|
||||||
| a = expr ; Lneq ; b = expr {
|
| a = expr ; Lsne ; b = expr {
|
||||||
Call { func = "%neq" ; args = [ a ; b ] ; pos = $startpos($2) }
|
Call { func = "%sne" ; args = [ a ; b ] ; pos = $startpos($2) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* function(a */
|
/* function(a */
|
||||||
|
|
Reference in a new issue