handle const vs var A instructions at parse time
This commit is contained in:
parent
d0835a9314
commit
9daff2f67d
@ -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
|
||||||
|
@ -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 =
|
||||||
|
Loading…
Reference in New Issue
Block a user