Make interpret fallible, fix applications at end of file, add more checks
This commit is contained in:
parent
0abc74f043
commit
bf4a08e484
43
src/main.rs
43
src/main.rs
@ -209,7 +209,7 @@ fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec
|
||||
let output = if interpret
|
||||
{
|
||||
println!("---Starting to interpret the program---");
|
||||
Some(interpret_program(&operations, &mut Vec::new(), &functions, &mut arrays, &intrinsics, debug))
|
||||
Some(interpret_program(&operations, &mut Vec::new(), &functions, &mut arrays, &intrinsics, debug)?)
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -218,7 +218,7 @@ fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec
|
||||
return Ok(output);
|
||||
}
|
||||
|
||||
fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, functions: &Vec<Function>, arrays: &mut Vec<Arr>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, debug: bool) -> String
|
||||
fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, functions: &Vec<Function>, arrays: &mut Vec<Arr>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, debug: bool) -> Result<String,String>
|
||||
{
|
||||
let mut output = String::new();
|
||||
for operation in operations
|
||||
@ -263,7 +263,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
let val = queue.remove(0);
|
||||
function_context.push(val);
|
||||
}
|
||||
output += interpret_program(&function.content, function_context, functions, arrays, intrinsics, debug).as_str();
|
||||
output += interpret_program(&function.content, function_context, functions, arrays, intrinsics, debug)?.as_str();
|
||||
for val in function_context
|
||||
{
|
||||
queue.push(val.to_string());
|
||||
@ -274,11 +274,11 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
let val = queue.remove(0);
|
||||
if val == "true"
|
||||
{
|
||||
output += interpret_program(if_block, queue, functions, arrays, intrinsics, debug).as_str();
|
||||
output += interpret_program(if_block, queue, functions, arrays, intrinsics, debug)?.as_str();
|
||||
}
|
||||
else if let Some(else_block) = maybe_else_block
|
||||
{
|
||||
output += interpret_program(else_block, queue, functions, arrays, intrinsics, debug).as_str();
|
||||
output += interpret_program(else_block, queue, functions, arrays, intrinsics, debug)?.as_str();
|
||||
}
|
||||
}
|
||||
Operation::Intrinsic(intrinsic_name, line, col) =>
|
||||
@ -336,7 +336,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
}
|
||||
_ =>
|
||||
{
|
||||
panic!("Unexpected intrinsic '{}' at {}:{}", intrinsic_name, line, col);
|
||||
return Err(format!("Unexpected intrinsic '{}' at {}:{}", intrinsic_name, line, col));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -350,7 +350,11 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
let position: i64 = queue.remove(0).parse::<i64>().unwrap();
|
||||
if position >= arr.length
|
||||
{
|
||||
panic!("Attempted an out of bounds write for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col);
|
||||
return Err(format!("Attempted an out of bounds write for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
||||
}
|
||||
if position < 0
|
||||
{
|
||||
return Err(format!("Attempted an out of bounds write for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
||||
}
|
||||
arr.data[position as usize] = queue.remove(0);
|
||||
}
|
||||
@ -359,7 +363,11 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
let position: i64 = queue.remove(0).parse::<i64>().unwrap();
|
||||
if position >= arr.length
|
||||
{
|
||||
panic!("Attempted an out of bounds read for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col);
|
||||
return Err(format!("Attempted an out of bounds read for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
||||
}
|
||||
if position < 0
|
||||
{
|
||||
return Err(format!("Attempted an out of bounds read for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
||||
}
|
||||
queue.push(arr.data[position as usize].clone());
|
||||
}
|
||||
@ -367,7 +375,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
{
|
||||
queue.push(arr.length.to_string());
|
||||
}
|
||||
_ => panic!("Unexpected application '{}' at {}:{}", word, line, col)
|
||||
_ => return Err(format!("Unexpected application '{}' at {}:{}", word, line, col))
|
||||
}
|
||||
}
|
||||
Operation::While(while_block, _, _) =>
|
||||
@ -379,7 +387,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
{
|
||||
break;
|
||||
}
|
||||
output += interpret_program(while_block, queue, functions, arrays, intrinsics, debug).as_str();
|
||||
output += interpret_program(while_block, queue, functions, arrays, intrinsics, debug)?.as_str();
|
||||
}
|
||||
}
|
||||
Operation::Depth(_, _) =>
|
||||
@ -397,7 +405,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
println!("after: {:?}: {:?}, '{}'", operation, queue, output);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
return Ok(output);
|
||||
}
|
||||
|
||||
fn typecheck(operations: &Vec<Operation>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, arrays: &Vec<Arr>, debug: bool) -> Result<(), String>
|
||||
@ -626,6 +634,10 @@ fn get_return_type(operations: &Vec<Operation>, ins: &Vec<Datatype>, functions:
|
||||
return Err(format!("Expected a position for a write application at {}:{}", line, col));
|
||||
}
|
||||
let expected_type = arrays.iter().find(|x| &x.name == name).unwrap().datatype;
|
||||
if type_queue.is_empty()
|
||||
{
|
||||
return Err(format!("Expected data for a write application at {}:{}", line, col));
|
||||
}
|
||||
let actual_type = type_queue.remove(0);
|
||||
if actual_type != expected_type
|
||||
{
|
||||
@ -1187,7 +1199,14 @@ fn tokenize(text: &str) -> Result<Vec<Token>, String>
|
||||
TokenizerState::Whitespace | TokenizerState::Comment => {},
|
||||
TokenizerState::Keyword =>
|
||||
{
|
||||
tokens.push(Token::Keyword(word.clone(), line, col));
|
||||
if application_name.is_empty()
|
||||
{
|
||||
tokens.push(Token::Keyword(word.clone(), line, col));
|
||||
}
|
||||
else
|
||||
{
|
||||
tokens.push(Token::Apply(application_name.clone(), word.clone(), line, col));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(tokens)
|
||||
|
Loading…
x
Reference in New Issue
Block a user