handle const vs var A instructions at parse time

This commit is contained in:
Konarak 2022-07-19 23:11:42 +05:30
parent d0835a9314
commit 9daff2f67d
2 changed files with 24 additions and 27 deletions

View File

@ -1,5 +1,6 @@
type expr = type expr =
| Comment of string | Comment of string
| Ginstr of string | Aconst of int
| Ainstr of string | Ainstr of string
| Ginstr of string
| Cinstr of string * string * string | Cinstr of string * string * string

View File

@ -8,29 +8,19 @@ let rec first_pass exprs st loc =
match exprs with match exprs with
| [] -> st | [] -> st
| Ginstr s :: t -> first_pass t (add_symbol st s loc) loc | 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 | _ :: t -> first_pass t st loc
;; ;;
let rec second_pass exprs st loc = let rec second_pass exprs st loc =
let is_new s = let is_new a = not (Map.mem st a) in
try
Int.of_string s |> ignore;
false
with
| Failure _ -> not (Map.mem st s)
in
match exprs with match exprs with
| [] -> st | [] -> st
| Ainstr a :: t when is_new a -> second_pass t (add_symbol st a loc) (loc + 1) | Ainstr a :: t when is_new a -> second_pass t (add_symbol st a loc) (loc + 1)
| _ :: t -> second_pass t st loc | _ :: t -> second_pass t st loc
;; ;;
let translate_ainstr addr st = let translate_ainstr addr =
let to_int addr =
try Map.find_exn st addr with
| Not_found_s _ -> Int.of_string addr
in
let pad binary = let pad binary =
let length = 16 - String.length binary in let length = 16 - String.length binary in
let prefix = String.init length ~f:(fun _ -> '0') 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" | 0 -> to_binary (a / 2) ^ "0"
| _ -> to_binary (a / 2) ^ "1") | _ -> to_binary (a / 2) ^ "1")
in 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 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 parse s =
let lexbuf = Lexing.from_string s in let lexbuf = Lexing.from_string s in
let ast = Parser.prog Lexer.read lexbuf 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_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 rec _translate exprs st tt =
let _st = first_pass exprs symbols 0 in match exprs with
second_pass exprs _st 16 | [] -> 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 = let translate lines =