add == , != , >
This commit is contained in:
parent
9ef121370b
commit
14b5950cd4
5 changed files with 62 additions and 7 deletions
28
baselib.ml
28
baselib.ml
|
@ -10,13 +10,18 @@ let _types_ =
|
|||
; "%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 ])
|
||||
; "puti", Func_t (Void_t, [ Int_t ])
|
||||
; "puts", Func_t (Void_t, [ Str_t ])
|
||||
; "geti", Func_t (Int_t, [])
|
||||
])
|
||||
;;
|
||||
|
||||
let builtins =
|
||||
let builtins_special = [ "%equ"; "%neq" ]
|
||||
|
||||
let builtins uniq =
|
||||
List.fold_left
|
||||
(fun env (fn, impl) -> Env.add fn impl env)
|
||||
Env.empty
|
||||
|
@ -25,6 +30,27 @@ let builtins =
|
|||
; "%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)
|
||||
] )
|
||||
; "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 ]
|
||||
|
|
12
compiler.ml
12
compiler.ml
|
@ -12,6 +12,7 @@ type info =
|
|||
}
|
||||
|
||||
let puf = "f_" (* prefix user function *)
|
||||
let cnt_inline = ref (-1)
|
||||
|
||||
let compile_value = function
|
||||
| Void -> [ Li (V0, 0) ]
|
||||
|
@ -29,10 +30,17 @@ 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
|
||||
then Env.find f Baselib.builtins
|
||||
if Env.mem f (Baselib.builtins uniq)
|
||||
then Env.find f (Baselib.builtins uniq)
|
||||
else [ Jal (puf ^ f); Addi (SP, SP, 4 * List.length args) ]
|
||||
;;
|
||||
|
||||
|
|
|
@ -34,7 +34,10 @@ rule token = parse
|
|||
| '-' { Lsub }
|
||||
| '*' { Lmul }
|
||||
| '/' { Ldiv }
|
||||
| '<' { Lbig }
|
||||
| '<' { Lsmaller }
|
||||
| '>' { Lbigger }
|
||||
| "==" { Leq }
|
||||
| "!=" { Lneq }
|
||||
| '"' { read_string (Buffer.create 16) lexbuf }
|
||||
| ident as i { Lvar i }
|
||||
| '#' { comment lexbuf }
|
||||
|
|
3
mips.ml
3
mips.ml
|
@ -50,6 +50,7 @@ type instr =
|
|||
| Slt of reg * reg * reg
|
||||
| Syscall
|
||||
| B of label
|
||||
| Beq of reg * reg * label
|
||||
| Beqz of reg * label
|
||||
| Jal of label
|
||||
| J of label
|
||||
|
@ -130,6 +131,8 @@ let fmt_instr ?(indent = " ") = function
|
|||
Printf.sprintf "%sslt %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) ->
|
||||
Printf.sprintf "%sbeq %s, %s, %s" indent (fmt_reg rs) (fmt_reg rt) l
|
||||
| Beqz (r, l) -> Printf.sprintf "%sbeqz %s, %s" indent (fmt_reg r) l
|
||||
| Jal l -> Printf.sprintf "%sjal %s" indent l
|
||||
| J l -> Printf.sprintf "%sj %s" indent l
|
||||
|
|
21
parser.mly
21
parser.mly
|
@ -11,10 +11,10 @@
|
|||
%token Lend Lassign Lsc Lreturn
|
||||
%token Lbracedeb Lbracefin
|
||||
%token Lpardeb Lparfin Lcomma
|
||||
%token Ladd Lsub Lmul Ldiv Lbig
|
||||
%token Ladd Lsub Lmul Ldiv Lbigger Lsmaller Leq Lneq
|
||||
%token Lif Lelse Lwhile
|
||||
|
||||
%left Ladd Lsub Lmul Ldiv Lbig
|
||||
%left Ladd Lsub Lmul Ldiv Lbigger Lsmaller Leq Lneq
|
||||
|
||||
%left Lbracedeb Lparfin Lbracefin Lreturn
|
||||
%left Ltype Lbool Lint Lvar Lstr
|
||||
|
@ -172,10 +172,25 @@ expr:
|
|||
}
|
||||
|
||||
/* e < e */
|
||||
| a = expr ; Lbig ; b = expr {
|
||||
| a = expr ; Lsmaller ; b = expr {
|
||||
Call { func = "%big" ; args = [ a ; b ] ; pos = $startpos($2) }
|
||||
}
|
||||
|
||||
/* e > e */
|
||||
| a = expr ; Lbigger ; b = expr {
|
||||
Call { func = "%sml" ; 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 ; Lneq ; b = expr {
|
||||
Call { func = "%neq" ; args = [ a ; b ] ; pos = $startpos($2) }
|
||||
}
|
||||
|
||||
/* function(a */
|
||||
| f = Lvar ; Lpardeb ; a = args_expr {
|
||||
Call { func = f ; args = a ; pos = $startpos(a) }
|
||||
|
|
Reference in a new issue