1pub mod code_writer;
6mod constants;
7pub mod parser;
8
9use glob::glob;
10use std:: path::Path;
11
12use code_writer::CodeWriter;
13use parser::{CommandType, Parser};
14
15fn vm_functionality(parser: &mut Parser, code_writer: &mut CodeWriter) {
16 while parser.has_more_lines() {
17 parser.advance();
18 match parser.command_type() {
19 CommandType::C_PUSH(_) | CommandType::C_POP(_) => code_writer.write_push_pop(
20 Some(parser.current_command.as_str()),
21 parser.command_type(),
22 parser.arg1().as_str(),
23 parser.arg2(),
24 ),
25 CommandType::C_LABEL(_) => code_writer.write_label(&parser.arg1()),
26 CommandType::C_GOTO(_) => code_writer.write_goto(&parser.arg1()),
27 CommandType::C_IF(_) => code_writer.write_if(&parser.arg1()),
28 CommandType::C_FUNCTION(_) => code_writer.write_function(&parser.arg1(), parser.arg2()),
29 CommandType::C_ARITHMETIC(_) => code_writer
30 .write_arithmetic(Some(parser.current_command.as_str()), parser.command_type()),
31 CommandType::C_RETURN => code_writer.write_return(),
32 CommandType::C_CALL(_) => code_writer.write_call(&parser.arg1(), parser.arg2()),
33 };
34 }
35}
36
37pub fn vm_translator(mut args: impl Iterator<Item = String>) {
38 args.next(); let filepath = args.next().expect("Filepath is required!");
41 let filepath = Path::new(&filepath);
42 let output_filepath = if !filepath.is_dir() {
43 filepath.with_extension("asm")
44 } else {
45 filepath
46 .join(filepath.file_name().unwrap())
47 .with_extension("asm")
48 };
49 let mut code_writer = CodeWriter::new(&output_filepath);
50
51 if filepath.is_dir() {
52 let file_pattern = filepath.join("**").join("*.vm");
53 for entry in glob(file_pattern.to_str().unwrap()).unwrap() {
54 match entry {
55 Ok(file_path) => {
56 let mut parser = Parser::new(&file_path);
57 code_writer.set_file_name(
59 file_path.as_path()
60 .file_stem().unwrap().to_str().expect("Invalid file encountered in dir")
61 );
62 vm_functionality(&mut parser, &mut code_writer);
63 }
64 Err(e) => println!("Invalid path dir provided {:?}", e),
65 }
66 }
67 } else {
68 let mut parser = Parser::new(filepath);
69 vm_functionality(&mut parser, &mut code_writer);
70 }
71}