finish project eight backend compiler
- modify existing implementation to use variant types for a more accurate representation of the vm byte code - switch to fold from recursion for the main translate function - use separate modules for translating different vm commands - move static arithmetic command translations to a map
This commit is contained in:
61
compiler/backend/bin/compiler.ml
Normal file
61
compiler/backend/bin/compiler.ml
Normal file
@@ -0,0 +1,61 @@
|
||||
open Core
|
||||
open Backend
|
||||
|
||||
let read_file file =
|
||||
let lines = In_channel.read_lines file in
|
||||
let not_empty str = not (String.is_empty str) in
|
||||
List.filter lines ~f:not_empty
|
||||
|
||||
|
||||
let is_vm_file f =
|
||||
match Filename.split_extension f with
|
||||
| _, Some ext -> String.equal ext "vm"
|
||||
| _, None -> false
|
||||
|
||||
|
||||
let generate_hack f =
|
||||
let bytecode = read_file f in
|
||||
let class_name = Filename.basename f in
|
||||
Translate.translate class_name bytecode
|
||||
|
||||
|
||||
let write_hack path hack =
|
||||
let output_channel = Out_channel.create path in
|
||||
Out_channel.output_lines output_channel hack;
|
||||
Out_channel.close output_channel
|
||||
|
||||
|
||||
let compile path =
|
||||
let ext = ".asm" in
|
||||
let absolute_path x = path ^ x in
|
||||
let open Filename_base in
|
||||
if Sys_unix.is_directory_exn path then
|
||||
let output_file = concat path (basename path ^ ext) in
|
||||
let hack =
|
||||
path
|
||||
|> Sys_unix.ls_dir
|
||||
|> List.map ~f:absolute_path
|
||||
|> List.filter ~f:is_vm_file
|
||||
|> List.concat_map ~f:generate_hack
|
||||
|> List.append Translate.bootstrap
|
||||
in
|
||||
write_hack output_file hack
|
||||
else if Sys_unix.is_file_exn path && is_vm_file path then
|
||||
let output_file = chop_extension path ^ ext in
|
||||
let hack = generate_hack path in
|
||||
write_hack output_file hack
|
||||
else
|
||||
failwith "Incompatible!"
|
||||
|
||||
|
||||
let command =
|
||||
let summary = "Translate Jack byte code to Hack assembly" in
|
||||
let readme () = "Compiler (backend) for project 7/8 of Nand2Tetris" in
|
||||
let param_spec = Command.Param.(anon ("path" %: string)) in
|
||||
let param_handler path () = compile path in
|
||||
Command.basic
|
||||
~summary:summary ~readme:readme
|
||||
(Command.Param.map param_spec ~f:param_handler)
|
||||
|
||||
|
||||
let () = Command_unix.run command
|
1
compiler/backend/bin/compiler.mli
Normal file
1
compiler/backend/bin/compiler.mli
Normal file
@@ -0,0 +1 @@
|
||||
val command : Command.t
|
5
compiler/backend/bin/dune
Normal file
5
compiler/backend/bin/dune
Normal file
@@ -0,0 +1,5 @@
|
||||
(executable
|
||||
(modes byte exe)
|
||||
(name compiler)
|
||||
(public_name compiler)
|
||||
(libraries backend core core_unix.command_unix))
|
Reference in New Issue
Block a user