From 14b5950cd4dfe002f459deca3fcd18194eab04f3 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Wed, 14 Dec 2022 00:01:28 +0100 Subject: [PATCH] add == , != , > --- baselib.ml | 28 +++++++++++++++++++++++++++- compiler.ml | 12 ++++++++++-- lexer.mll | 5 ++++- mips.ml | 3 +++ parser.mly | 21 ++++++++++++++++++--- 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/baselib.ml b/baselib.ml index 89b6348..fa57cba 100644 --- a/baselib.ml +++ b/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 ] diff --git a/compiler.ml b/compiler.ml index df237fd..99da664 100644 --- a/compiler.ml +++ b/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) ] ;; diff --git a/lexer.mll b/lexer.mll index f91dd7e..f2588bf 100644 --- a/lexer.mll +++ b/lexer.mll @@ -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 } diff --git a/mips.ml b/mips.ml index 7a39954..8cf8e62 100644 --- a/mips.ml +++ b/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 diff --git a/parser.mly b/parser.mly index 0b2f135..df5c3db 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 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) }