sandwich

A funny programming language written in Rust
git clone https://tilde.team/~karx/sandwich.git
Log | Files | Refs | README | LICENSE

commit 237a1fae31acf577ef8625c3eabfe4bd96e81a9f
parent 4984839191acb049cadc4abf3c944c56559ec850
Author: ~karx <karx@tilde.team>
Date:   Sun,  7 Feb 2021 18:10:56 +0000

Add comments to code

Diffstat:
MREADME.md | 2+-
Msrc/main.rs | 22+++++++++++++++++-----
2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md @@ -56,7 +56,7 @@ Read [this guide](https://git-send-email.io) for more information. ## TODO -- [ ] Better documentation +- [x] Better documentation - [ ] Ability to explicitly print math output and assign math output to variables - [ ] Add support for comments (should be pretty easy) - [ ] Unit testing and CI/CD diff --git a/src/main.rs b/src/main.rs @@ -18,7 +18,6 @@ impl Program { for opcode in program.split("\n").collect::<Vec<&str>>() { let new_op = opcode.to_owned(); - // new_op = new_op.replace("\n", ""); if new_op.len() != 0 { op_list.push(new_op.to_owned()); @@ -28,21 +27,27 @@ impl Program { return Program{ data: op_list, pc: 0, vars: HashMap::new() }; } + // Reads the arguments passed to an opcode, and inserts variables where necessary fn args_or_vars(&self, arguments: &str) -> String { - let mut builder = String::from(""); - let argument_vec: Vec<char> = arguments.chars().collect(); + let mut builder = String::from(""); // Empty string that will be rebuilt based on the loop + let argument_vec: Vec<char> = arguments.chars().collect(); // Deconstructed arguments + // Iterate through each char for index in 0..argument_vec.len() { let current_char = argument_vec[index]; let str_to_push: String; if index > 0 { + // Only test for the dollar sign if it's not the first character + // This is because there can't be anything before the first character, otherwise it's not the first if argument_vec[index-1] == '$' { + // If the previous character is a dollar sign, we can skip this iteration because we know the variable has already been handled continue; } } if current_char == '$' { + // If the current char is a $, we know that the next char should be a variable let variable = argument_vec[index+1]; let key = self.vars.get(&variable); @@ -52,6 +57,7 @@ impl Program { } } else { + // If there's no variable, then just push the char that was already there str_to_push = current_char.to_string(); } @@ -65,12 +71,13 @@ impl Program { fn add_var(&mut self, arguments: &str) { let argument_vec: Vec<char> = arguments.chars().collect(); let name = argument_vec[0]; - let value = argument_vec[1..].into_iter().collect::<String>(); + let value: String = argument_vec[1..].into_iter().collect(); self.vars.insert(name, value); } fn parse(&mut self, instruction: &String) { + // Opcode is the first character, arguments are everything after the first char let opcode = instruction.chars().collect::<Vec<char>>()[0]; let arguments = &instruction[1..]; @@ -88,11 +95,12 @@ impl Program { fn run(&mut self) { println!("{}", self); while self.pc < self.data.len() { + // Grab instruction from op list and parse the instruction let instruction = self.data[self.pc].to_owned(); self.parse(&instruction); - self.pc = self.pc + 1; + self.pc += 1; } } } @@ -104,13 +112,17 @@ impl fmt::Display for Program { } fn main() { + // Grab args and a filename let args: Vec<String> = env::args().collect(); if args.len() == 1 { + // Args will always have at least 1 argument, which is the name of the executable. + // That's why we're checking index 1, not index 0. panic!("You must provide a filename!"); } let filename = &args[1]; + // Read contents of the provided file and construct a symbolic Program from it let contents = fs::read_to_string(filename).expect("Something went wrong reading the file"); let mut prog = Program::from_string(contents); prog.run();