1extern crate mlem;
2extern crate mlem_asm;
3use mlem_asm::{parse_program, program_to_writer};
4use mlem::Machine;
5use std::io::prelude::*;
6use std::io::{BufReader, BufWriter, Stdout, Stdin};
7use std::fs::File;
8use std::borrow::Borrow;
9
10fn usage() {
11 println!("Usage: ");
12 println!("\tmlem-asm a source [output]\tAssemble the given source file to the given output file, or stdout.");
13 println!("\tmlem-asm r source [input]\t\tAssemble the given source file and execute it, hooking up stdin and stdout.");
14}
15
16enum Output {
17 File(BufWriter<File>),
18 StdOut(BufWriter<Stdout>)
19}
20
21enum Input {
22 File(BufReader<File>),
23 StdIn(BufReader<Stdin>)
24}
25
26#[derive(Debug, PartialEq, Clone, Copy)]
27enum Mode {
28 Assemble,
29 Execute
30}
31
32fn main() {
33 let args: Vec<_> = std::env::args().collect();
34 if args.len() > 4 || args.len() < 3 {
35 usage();
36 std::process::exit(101);
37 }
38
39 let mode = match args[1].borrow() {
40 "a" => Mode::Assemble,
41 "r" => Mode::Execute,
42 other => { panic!("Unknown mode {}; try a for assemble or r for run", other); }
43 };
44
45 load_and_process(args, mode);
46
47}
48
49fn load_and_process(args: Vec<String>, mode: Mode) {
50 let mut f = BufReader::new(File::open(&args[2]).unwrap());
51 let mut contents = String::new();
52 f.read_to_string(&mut contents).unwrap();
53
54 let mut out: Option<Output> = None;
55 let mut inp: Option<Input> = None;
56
57 match mode {
58 Mode::Assemble => {
59 out = Some(if args.len() == 4 {
60 Output::File(BufWriter::new(File::create(&args[3]).unwrap()))
61 } else {
62 Output::StdOut(BufWriter::new(std::io::stdout()))
63 });
64 },
65 Mode::Execute => {
66 inp = Some(if args.len() == 4 {
67 Input::File(BufReader::new(File::create(&args[3]).unwrap()))
68 } else {
69 Input::StdIn(BufReader::new(std::io::stdin()))
70 });
71 }
72 };
73
74 let result = parse_program(&contents);
75
76 match result {
77 Ok(p) => {
78 match mode {
79 Mode::Assemble => {
80 match out.unwrap() {
81 Output::File(mut o) => { program_to_writer(&p, &mut o).unwrap(); },
82 Output::StdOut(mut o) => { program_to_writer(&p, &mut o).unwrap(); }
83 }
84 },
85 Mode::Execute => {
86 match inp.unwrap() {
87 Input::File(mut i) => {
88 let mut o = std::io::stdout();
89 let mut m = Machine::new(65535, &mut i, &mut o);
90 m.load_program(p);
91 println!("\n{:?}", m.run())
92 },
93 Input::StdIn(mut i) => {
94 let mut o = std::io::stdout();
95 let mut m = Machine::new(65535, &mut i, &mut o);
96 m.load_program(p);
97 println!("\n{:?}", m.run())
98 }
99 }
100 }
101 }
102 }
103 Err(e) => {
104 println!("Could not assemble program.");
105 for error in e {
106 println!("{:2}: {}", error.0, error.1);
107 }
108 std::process::exit(1);
109 }
110 }
111}