move assembler out of project dir

This commit is contained in:
2022-07-20 14:38:05 +05:30
parent 9daff2f67d
commit e5d84c9716
12 changed files with 0 additions and 0 deletions

View File

@@ -1 +0,0 @@
_build

View File

@@ -1,2 +0,0 @@
profile = janestreet
version = 0.24.1

View File

@@ -1 +0,0 @@

View File

@@ -1,31 +0,0 @@
open Core
open Hack
let read_file file =
let not_empty str = not (String.is_empty str) in
List.filter (In_channel.read_lines file) ~f:not_empty
;;
let outfile file = String.concat [ Filename.chop_extension file; ".hack" ]
let gen_hack file =
let assembly = read_file file in
let binary = Translate.translate assembly in
let outchan = Out_channel.create (outfile file) in
Out_channel.output_lines outchan binary;
Out_channel.close outchan
;;
let param =
let open Command.Param in
anon ("filename" %: string)
;;
let command =
Command.basic
~summary:"Translate <filename>.asm to <filename>.hack"
~readme:(fun () -> "Assembler for project 6 of Nand2Tetris")
(Command.Param.map param ~f:(fun filename () -> gen_hack filename))
;;
let () = Command_unix.run command

View File

@@ -1,3 +0,0 @@
(executable
(name assembler)
(libraries hack core core_unix.command_unix))

View File

@@ -1,2 +0,0 @@
(lang dune 3.3)
(using menhir 2.0)

View File

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

View File

@@ -1,24 +0,0 @@
{
open Parser
}
let white = [' ' '\t']+
let comment = "//" _*
let newline = '\n' | '\r'
let digit = ['0'-'9']
let letter = ['a'-'z' 'A'-'Z']
let special = ['.' '$' '_' '-' '+' '&' '!' '|']
let id = (digit | letter | special)+
rule read =
parse
| white { read lexbuf }
| "@" { AT }
| "(" { LPAREN }
| ")" { RPAREN }
| ";" { SCOLON }
| "=" { EQUALS }
| comment as c { COMMENT (c) }
| id as id { ID (id) }
| eof { EOF }

View File

@@ -1,30 +0,0 @@
%{
open Ast
%}
%token <string> ID
%token <string> COMMENT
%token AT
%token LPAREN
%token RPAREN
%token SCOLON
%token EQUALS
%token EOF
%start <Ast.expr> prog
%%
prog:
| e = expr; EOF { e }
;
expr:
| c = COMMENT { Comment c }
| AT; a = ID; { Ainstr a }
| LPAREN; s = ID; RPAREN { Ginstr s }
| c = ID; SCOLON; j = ID { Cinstr ("", c, j) }
| d = ID; EQUALS; c = ID { Cinstr (d, c, "") }
| c = ID; { Cinstr ("", c, "") }
| e = expr; COMMENT { e }
;

View File

@@ -1,89 +0,0 @@
open Base
let symbols =
Map.of_alist_exn
(module String)
[ "R0", 0
; "R1", 1
; "R2", 2
; "R3", 3
; "R4", 4
; "R5", 5
; "R6", 6
; "R7", 7
; "R8", 8
; "R9", 9
; "R10", 10
; "R11", 11
; "R12", 12
; "R13", 13
; "R14", 14
; "R15", 15
; "SP", 0
; "LCL", 1
; "ARG", 2
; "THIS", 3
; "THAT", 4
; "SCREEN", 16384
; "KBD", 24576
]
;;
let comp c =
match c with
| "0" -> "0101010"
| "1" -> "0111111"
| "-1" -> "0111010"
| "D" -> "0001100"
| "A" -> "0110000"
| "M" -> "1110000"
| "!D" -> "0001101"
| "!A" -> "0110001"
| "!M" -> "1110001"
| "-D" -> "0001111"
| "-A" -> "0110011"
| "-M" -> "1110011"
| "D+1" -> "0011111"
| "A+1" -> "0110111"
| "M+1" -> "1110111"
| "D-1" -> "0001110"
| "A-1" -> "0110010"
| "M-1" -> "1110010"
| "D+A" -> "0000010"
| "D+M" -> "1000010"
| "D-A" -> "0010011"
| "D-M" -> "1010011"
| "A-D" -> "0000111"
| "M-D" -> "1000111"
| "D&A" -> "0000000"
| "D&M" -> "1000000"
| "D|A" -> "0010101"
| "D|M" -> "1010101"
| _ -> failwith "Unknown COMP Instruction"
;;
let dest d =
match d with
| "" -> "000"
| "M" -> "001"
| "D" -> "010"
| "MD" -> "011"
| "A" -> "100"
| "AM" -> "101"
| "AD" -> "110"
| "ADM" -> "111"
| _ -> failwith "Unknown DEST Instruction"
;;
let jump j =
match j with
| "" -> "000"
| "JGT" -> "001"
| "JEQ" -> "010"
| "JGE" -> "011"
| "JLT" -> "100"
| "JNE" -> "101"
| "JLE" -> "110"
| "JMP" -> "111"
| _ -> failwith "Unknown JUMP Instruction"
;;

View File

@@ -1,74 +0,0 @@
open Base
open Ast
open Predef
let add_symbol map k d = if Map.mem map k then map else Map.add_exn map ~key:k ~data:d
let rec first_pass exprs st loc =
match exprs with
| [] -> st
| Ginstr s :: t -> first_pass t (add_symbol st s loc) loc
| (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 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 =
let pad binary =
let length = 16 - String.length binary in
let prefix = String.init length ~f:(fun _ -> '0') in
String.concat [ prefix; binary ]
in
let rec to_binary a =
match a with
| 0 -> ""
| _ ->
let rem = a % 2 in
(match rem with
| 0 -> to_binary (a / 2) ^ "0"
| _ -> to_binary (a / 2) ^ "1")
in
pad (to_binary addr)
;;
let translate_cinstr (d, c, j) = String.concat [ "111"; comp c; dest d; jump j ]
let parse s =
let lexbuf = Lexing.from_string s in
let ast = Parser.prog Lexer.read lexbuf in
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 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 =
let exprs = generate_exprs lines in
let st = generate_st exprs in
_translate exprs st []
;;

View File

@@ -1,8 +0,0 @@
(ocamllex Lexer)
(menhir
(modules Parser))
(library
(name hack)
(libraries base))