diff --git a/projects/06/assembler/lib/Ast.ml b/projects/06/assembler/lib/Ast.ml index a6bb63f..91299df 100644 --- a/projects/06/assembler/lib/Ast.ml +++ b/projects/06/assembler/lib/Ast.ml @@ -1,5 +1,6 @@ type expr = | Comment of string - | Ginstr of string + | Aconst of int | Ainstr of string + | Ginstr of string | Cinstr of string * string * string diff --git a/projects/06/assembler/lib/Translate.ml b/projects/06/assembler/lib/Translate.ml index ce81106..59aa02b 100644 --- a/projects/06/assembler/lib/Translate.ml +++ b/projects/06/assembler/lib/Translate.ml @@ -8,29 +8,19 @@ let rec first_pass exprs st loc = match exprs with | [] -> st | Ginstr s :: t -> first_pass t (add_symbol st s loc) loc - | (Ainstr _ | Cinstr _) :: t -> first_pass t st (loc + 1) + | (Ainstr _ | Aconst _ | Cinstr _) :: t -> first_pass t st (loc + 1) | _ :: t -> first_pass t st loc ;; let rec second_pass exprs st loc = - let is_new s = - try - Int.of_string s |> ignore; - false - with - | Failure _ -> not (Map.mem st s) - in + let is_new a = not (Map.mem st a) in match exprs with | [] -> st | Ainstr a :: t when is_new a -> second_pass t (add_symbol st a loc) (loc + 1) | _ :: t -> second_pass t st loc ;; -let translate_ainstr addr st = - let to_int addr = - try Map.find_exn st addr with - | Not_found_s _ -> Int.of_string addr - in +let translate_ainstr addr = let pad binary = let length = 16 - String.length binary in let prefix = String.init length ~f:(fun _ -> '0') in @@ -45,30 +35,36 @@ let translate_ainstr addr st = | 0 -> to_binary (a / 2) ^ "0" | _ -> to_binary (a / 2) ^ "1") in - pad (to_binary (to_int addr)) + pad (to_binary addr) ;; let translate_cinstr (d, c, j) = String.concat [ "111"; comp c; dest d; jump j ] -let rec _translate exprs st tt = - match exprs with - | [] -> tt - | Ainstr a :: t -> translate_ainstr a st :: _translate t st tt - | Cinstr (d, c, j) :: t -> translate_cinstr (d, c, j) :: _translate t st tt - | _ :: t -> _translate t st tt -;; - let parse s = let lexbuf = Lexing.from_string s in let ast = Parser.prog Lexer.read lexbuf in - ast + let eval_ainstr str = + try Aconst (Int.of_string str) with + | Failure _ -> Ainstr str + in + let _parse expr = + match expr with + | Ainstr str -> eval_ainstr str + | _ -> expr + in + _parse ast ;; let generate_exprs lines = List.map lines ~f:parse +let generate_st exprs = second_pass exprs (first_pass exprs symbols 0) 16 -let generate_st exprs = - let _st = first_pass exprs symbols 0 in - second_pass exprs _st 16 +let rec _translate exprs st tt = + match exprs with + | [] -> tt + | Aconst a :: t -> translate_ainstr a :: _translate t st tt + | Ainstr a :: t -> translate_ainstr (Map.find_exn st a) :: _translate t st tt + | Cinstr (d, c, j) :: t -> translate_cinstr (d, c, j) :: _translate t st tt + | _ :: t -> _translate t st tt ;; let translate lines =