Skip to content

Commit

Permalink
Improved error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
pgattic committed May 10, 2024
1 parent 6fefd8b commit ff26102
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ $main
- `swp` (pops 2, pushes 2): Switches the location of the top two items in the stack (`a b` -> `b a`)
- `over` (pops 3, pushes 3): Rearranges the top three values of the stack like this: `a b c` -> `b c a` (a moves to the top of the stack)
- `?[val1]:[val2]:...:[valN]` (pops 1, pushes 0): Match statement (TODO: describe in further detail)
- `exit` (pops 1, pushes 0): Exit the program with error code of the popped value

## Data Types

Expand Down
52 changes: 41 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,20 @@ fn main() {
let args: Vec<String> = env::args().collect();

if args.len() < 2 {
println!("Please specify a file.");
return;
println!("[{}]: Shell mode is a planned feature. See https://github.com/pgattic/cairn/issues/1 for progress updates.", args[0]);
eprintln!("Please specify a file.");
std::process::exit(1);
}

let target_file = args.get(1).expect("owie");
let target_file = &args[1];

let contents: String = fs::read_to_string(target_file).expect("Failed to read file");
let contents: String = match fs::read_to_string(target_file) {
Ok(data) => data,
Err(err) => {
eprintln!("{}: can't open file '{}': {}", args[0], target_file, err);
std::process::exit(2);
}
};

let code: Vec<&str> = split_code(&contents);

Expand All @@ -33,7 +40,7 @@ fn main() {
}

//println!("{:?}", functions);
_ = execute(functions);
execute(functions);
}

fn split_code(input: &str) -> Vec<&str> {
Expand All @@ -58,15 +65,23 @@ fn split_code(input: &str) -> Vec<&str> {
_ => {}
}
}
if in_str {
eprintln!("ERROR: Unclosed string");
std::process::exit(1);
}
if word_start < input.len() { // Check for no ending whitespace
result.push(&input[word_start..]);
}
result
}

fn execute(code: HashMap<&str, Vec<&str>>) -> Result<(), String> {
fn execute(code: HashMap<&str, Vec<&str>>) {
let mut stack: Vec<BigInt> = Vec::new();
if !code.contains_key("main") { // I can has main function?
return;
}
let mut instructions: Vec<&str> = code["main"].iter().cloned().collect();
let mut last_func: &str = "main";

while !instructions.is_empty() {
// println!("{:?} {:?}", stack, instructions);
Expand All @@ -85,7 +100,7 @@ fn execute(code: HashMap<&str, Vec<&str>>) -> Result<(), String> {
}
"putln" => {
if let Some(value) = stack.pop() {
print!("{}\n", value);
println!("{}", value);
} else {
println!();
}
Expand Down Expand Up @@ -113,6 +128,20 @@ fn execute(code: HashMap<&str, Vec<&str>>) -> Result<(), String> {
}
stack.push(BigInt::from_bytes_be(Plus, input.as_bytes()));
}
"exit" => {
if let Some(value) = stack.pop() {
match value.try_into() {
Ok(val_u32) => {
std::process::exit(val_u32);
},
Err(_) => {
std::process::exit(1);
}
}
} else {
std::process::exit(0);
}
}
"--" => {
if let Some(value) = stack.last_mut() {
*value -= 1;
Expand Down Expand Up @@ -249,20 +278,21 @@ fn execute(code: HashMap<&str, Vec<&str>>) -> Result<(), String> {
let value = &s[1..s.len()-1];
stack.push(BigInt::from_bytes_be(Plus, value.as_bytes()));
}
&_ => { // Code-defined procedures
_ => { // Code-defined procedures
if let Some(values) = code.get(c_instr) {
last_func = c_instr;
for value in values.iter().rev() {
instructions.insert(0, *value);
}
} else {
println!("Unresolved Symbol: {}", c_instr);
return Ok(());
eprintln!("ERROR: Unresolved Symbol: \"{}\"", c_instr);
eprintln!(" In \"${}\"", last_func);
std::process::exit(1);
}
}
}
}
}
}
Ok(())
}

0 comments on commit ff26102

Please sign in to comment.