summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortyropro <[email protected]>2026-05-22 13:43:58 +0100
committertyropro <[email protected]>2026-05-22 13:44:38 +0100
commit6cd94ed60f143d5c69ef5b39da4472852243381a (patch)
treeed44306ca55643b644a42ecdf31a7c8461c78b80
initial commit
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml6
-rw-r--r--lmc_code/bubble_sort.lmc83
-rw-r--r--lmc_code/max.lmc15
-rw-r--r--lmc_code/output_max.lmc14
-rw-r--r--src/main.rs139
7 files changed, 265 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..e935386
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "lmc-interpreter"
+version = "0.1.0"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..4ea60b6
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "lmc-interpreter"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
diff --git a/lmc_code/bubble_sort.lmc b/lmc_code/bubble_sort.lmc
new file mode 100644
index 0000000..4f3c082
--- /dev/null
+++ b/lmc_code/bubble_sort.lmc
@@ -0,0 +1,83 @@
+ INP
+ STA num1
+ INP
+ STA num2
+ INP
+ STA num3
+ INP
+ STA num4
+ INP
+ STA num5
+start LDA zero
+ STA swaps
+ LDA num2
+ SUB num1
+ BRP num2_b
+ LDA swaps
+ ADD one
+ STA swaps
+ LDA num2
+ STA temp
+ LDA num1
+ STA num2
+ LDA temp
+ STA num1
+num2_b LDA num3
+ SUB num2
+ BRP num3_b
+ LDA swaps
+ ADD one
+ STA swaps
+ LDA num3
+ STA temp
+ LDA num2
+ STA num3
+ LDA temp
+ STA num2
+num3_b LDA num4
+ SUB num3
+ BRP num4_b
+ LDA swaps
+ ADD one
+ STA swaps
+ LDA num4
+ STA temp
+ LDA num3
+ STA num4
+ LDA temp
+ STA num3
+num4_b LDA num5
+ SUB num4
+ BRP num5_b
+ LDA swaps
+ ADD one
+ STA swaps
+ LDA num5
+ STA temp
+ LDA num4
+ STA num5
+ LDA temp
+ STA num4
+num5_b LDA swaps
+ BRZ sort_complete
+ BRA start
+sort_complete LDA num1
+ OUT
+ LDA num2
+ OUT
+ LDA num3
+ OUT
+ LDA num4
+ OUT
+ LDA num5
+ OUT
+ HLT
+num1 DAT 0
+num2 DAT 0
+num3 DAT 0
+num4 DAT 0
+num5 DAT 0
+temp DAT 0
+swaps DAT 0
+one DAT 1
+zero DAT 0
diff --git a/lmc_code/max.lmc b/lmc_code/max.lmc
new file mode 100644
index 0000000..008b970
--- /dev/null
+++ b/lmc_code/max.lmc
@@ -0,0 +1,15 @@
+INP
+SDA num1
+INP
+SDA num2
+LDA num1
+SUB num2
+BRP num1_larger
+LDA num2
+OUT
+HLT
+num1_larger LDA num1
+OUT
+HLT
+num1 DAT 0
+num2 DAT 0
diff --git a/lmc_code/output_max.lmc b/lmc_code/output_max.lmc
new file mode 100644
index 0000000..75ad81a
--- /dev/null
+++ b/lmc_code/output_max.lmc
@@ -0,0 +1,14 @@
+start INP
+ BRZ end
+ STA new
+ LDA max
+ SUB new
+ BRP max_b
+ LDA new
+ STA max
+max_b BRA start
+end LDA max
+ OUT
+ HLT
+max DAT 0
+new DAT 0
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..4945402
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,139 @@
+use std::env;
+use std::error::Error;
+use std::fs;
+
+// const MEMORY_SIZE: usize = 100;
+
+#[derive(Debug)]
+enum Mnemonic {
+ Load,
+ Save,
+ Halt,
+ Add,
+ Subtract,
+ Dat,
+ BranchPositive,
+ BranchZero,
+ BranchAlways,
+ Input,
+ Output,
+}
+
+#[derive(Debug)]
+enum Token {
+ Mnemonic(Mnemonic),
+ Literal(u16),
+ Label(String),
+}
+
+struct Instruction {
+ mnemonic: Mnemonic,
+ label: Option<String>,
+}
+
+impl Instruction {
+ fn new(mnemonic: Mnemonic, label: Option<String>) -> Self {
+ Self { mnemonic, label }
+ }
+}
+
+fn main() {
+ let file_name = env::args().nth(1).expect("ERR: No file provided");
+
+ let file_contents = fs::read_to_string(file_name).expect("ERR: File does not exist");
+
+ println!("{}", file_contents);
+
+ let tokens = parse_file(file_contents.trim().to_string());
+
+ println!("{:#?}", tokens);
+
+ // let mut acc = 0;
+ // let mut program_counter = 0;
+
+ // let mut memory = vec![0; MEMORY_SIZE];
+}
+
+fn parse_file(file_contents: String) -> Vec<Token> {
+ let lines: Vec<&str> = file_contents.split("\n").collect();
+
+ let tokens: Vec<Token> = tokenise(lines);
+
+ tokens
+}
+
+fn tokenise(lines: Vec<&str>) -> Vec<Token> {
+ let mut tokens: Vec<Token> = Vec::new();
+
+ for line in lines {
+ let words = line.split(" ");
+
+ for word in words {
+ match word {
+ "LDA" => tokens.push(Token::Mnemonic(Mnemonic::Load)),
+ "STA" => tokens.push(Token::Mnemonic(Mnemonic::Save)),
+ "HLT" => tokens.push(Token::Mnemonic(Mnemonic::Halt)),
+ "ADD" => tokens.push(Token::Mnemonic(Mnemonic::Add)),
+ "SUB" => tokens.push(Token::Mnemonic(Mnemonic::Subtract)),
+ "DAT" => tokens.push(Token::Mnemonic(Mnemonic::Dat)),
+ "BRP" => tokens.push(Token::Mnemonic(Mnemonic::BranchPositive)),
+ "BRZ" => tokens.push(Token::Mnemonic(Mnemonic::BranchZero)),
+ "BRA" => tokens.push(Token::Mnemonic(Mnemonic::BranchAlways)),
+ "INP" => tokens.push(Token::Mnemonic(Mnemonic::Input)),
+ "OUT" => tokens.push(Token::Mnemonic(Mnemonic::Output)),
+ _ => {
+ if is_number(word) {
+ println!("{}", word);
+ let number: u16 = word.trim().parse().unwrap();
+ tokens.push(Token::Literal(number));
+ } else {
+ tokens.push(Token::Label(word.trim().to_string()))
+ }
+ }
+ }
+ }
+ }
+
+ tokens
+}
+
+fn syntax_analysis(tokens: Vec<Token>) -> bool {
+ for index in 0..tokens.len() {
+ match &tokens[index] {
+ Token::Mnemonic(mnemonic) => match mnemonic {
+ Mnemonic::Add
+ | Mnemonic::Subtract
+ | Mnemonic::BranchAlways
+ | Mnemonic::BranchPositive
+ | Mnemonic::BranchZero
+ | Mnemonic::Dat
+ | Mnemonic::Load
+ | Mnemonic::Save => match &tokens[index + 1] {
+ Token::Label(_) => (),
+ _ => return false,
+ },
+ Mnemonic::Halt | Mnemonic::Input | Mnemonic::Output => match &tokens[index + 1] {
+ Token::Mnemonic(_) => (),
+ _ => return false,
+ },
+ },
+ Token::Label(_) => {}
+ Token::Literal(_) => {}
+ }
+ }
+
+ true
+}
+
+fn translate_to_opcodes(mnemonics: Vec<Mnemonic>) -> Vec<u16> {
+ todo!();
+}
+
+fn is_number(s: &str) -> bool {
+ for c in s.chars() {
+ if !c.is_numeric() {
+ return false;
+ }
+ }
+ true
+}