From 103068c96ed4be719e608c18b8b5d219aa2e3ff3 Mon Sep 17 00:00:00 2001 From: Nilstrieb Date: Fri, 17 Sep 2021 14:13:16 +0200 Subject: [PATCH] inital commit --- .gitignore | 3 +++ Cargo.lock | 7 +++++++ Cargo.toml | 8 ++++++++ src/main.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ test.m8 | 22 ++++++++++++++++++++++ 5 files changed, 94 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs create mode 100644 test.m8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b82e25 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +.idea +*.iml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..93bedae --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "m8ni-rs" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f25889d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "m8ni-rs" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..b5d0721 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,54 @@ +enum Stmt { + Inc(usize), + Dec(usize), + IsZero(usize, usize), + Jump(usize), + Stop +} + +fn main() { + let filename = match std::env::args().skip(1).next() { + Some(name) => name, + None => eprintln!("error: no file provided.\nUsage: "), + }; + + let program = std::fs::read_to_string(filename).unwrap(); + let statements = parse(&program); +} + +fn parse(text: &str) -> Result, String> { + text.lines().map(parse_line).collect() +} + + +fn parse_line(line: &str) -> Result { + const NO_REGISTER: fn() -> String = || "No register".to_string(); + const NO_LINE_NUMBER: fn() -> String = || "No line number".to_string(); + const EMPTY_LINE: fn() -> String = || "Empty line not allowed".to_string(); + + + let mut iter = line.split_ascii_whitespace(); + let first = iter.next().ok_or_else(EMPTY_LINE)?; + + Ok(match first { + "INC" => { + let register = iter.next().ok_or_else(NO_REGISTER)?.parse()?; + Stmt::Inc(register) + } + "DEC" => { + let register = iter.next().ok_or_else(NO_REGISTER)?.parse()?; + Stmt::Dec(register) + } + "IS_ZERO" => { + let register = iter.next().ok_or_else(NO_REGISTER)?.parse()?; + let line_number = iter.next().ok_or_else(NO_LINE_NUMBER)?.parse()?; + Stmt::IsZero(register, line_number) + } + "JUMP" => { + let line_number = iter.next().ok_or_else(NO_LINE_NUMBER)?.parse()?; + Stmt::Jump(line_number) + } + "STOP" => Stmt::Stop, + stmt => return Err(format!("Illegal instruction: '{}'", stmt)), + }) +} diff --git a/test.m8 b/test.m8 new file mode 100644 index 0000000..0118e76 --- /dev/null +++ b/test.m8 @@ -0,0 +1,22 @@ +INC 1 +INC 1 +INC 1 +INC 2 +INC 2 +IS_ZERO 1 22 +DEC 1 +IS_ZERO 2 13 +INC 4 +INC 5 +DEC 2 +JUMP 8 +IS_ZERO 4 17 +INC 3 +DEC 4 +JUMP 13 +IS_ZERO 5 21 +INC 2 +DEC 5 +JUMP 17 +JUMP 6 +STOP \ No newline at end of file