mlem_asm/
mlem-asm.rs

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}