Skip to content

Commit

Permalink
multiple statements in single line evaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel-Durov committed Mar 15, 2023
1 parent 26add54 commit c7954b7
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 31 deletions.
78 changes: 48 additions & 30 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,23 @@ fn main() {
if args[1].ends_with(".yaiwr") {
run_from_file(&args[1], calc);
} else {
print_result(eval_line(&args[1], calc))
eval_statement(&args[1], calc);
}
} else {
repl(calc);
}
}

pub fn run_from_file(file_name: &str, calc: &mut Calc) {
let file_path = file_name;
match fs::read_to_string(file_name) {
Ok(content) => {
eval_statement(content.as_str(), calc);
}
Err(_) => print_result(Err(InterpError::ProgramFileNotFound(file_path.to_string()))),
}
}

fn print_result(result: Result<Option<u64>, InterpError>) {
match result {
Ok(Some(value)) => {
Expand All @@ -31,21 +41,6 @@ fn print_result(result: Result<Option<u64>, InterpError>) {
}
}

pub fn run_from_file(file_name: &str, calc: &mut Calc) {
match fs::read_to_string(file_name) {
Ok(content) => {
let lines: Vec<&str> = content
.split("\n")
.filter(|line| !line.trim().is_empty())
.collect();
for line in lines {
print_result(eval_line(line, calc));
}
}
Err(_) => print_result(Err(InterpError::ProgramFileNotFound(file_name.to_string()))),
}
}

fn repl(calc: &mut Calc) {
let stdin = io::stdin();
loop {
Expand All @@ -56,27 +51,50 @@ fn repl(calc: &mut Calc) {
if l.trim().is_empty() {
continue;
}
print_result(eval_line(l, calc));
if let Some(value) = eval_statement(l, calc) {
println!("{}", value);
}
}
_ => break,
}
}
}

fn eval_line(input: &str, calc: &mut Calc) -> Result<Option<u64>, InterpError> {
debug!("input: {:?}", &input);
let ast = calc.from_str(input);
match ast {
Ok(ast_node) => {
debug!("AST: {:?}", &ast_node);
let bytecode = &mut vec![];
calc.to_bytecode(ast_node, bytecode);
debug!("Bytecode: {:?}", &bytecode);
match calc.eval(bytecode) {
Ok(result) => Ok(result),
Err(err) => Err(err),
fn eval_statement(input: &str, calc: &mut Calc) -> Option<u64> {
let statements: Vec<String> = input
.replace("\n", "")
.split(";")
.map(|x| format!("{};", x))
.collect();

let mut result: Option<u64> = None;
for statement in statements {
if statement == ";" {
continue;
}
debug!("statement: {:?}", &statement);
let ast = calc.from_str(statement.as_str());
match ast {
Ok(ast_node) => {
debug!("AST: {:?}", &ast_node);
let bytecode = &mut vec![];
calc.to_bytecode(ast_node, bytecode);
debug!("Bytecode: {:?}", &bytecode);
match calc.eval(bytecode) {
Ok(eval_result) => {
result = eval_result;
}
Err(msg) => {
eprintln!("Evaluation error: {}", msg);
return None;
}
}
}
Err(msg) => {
eprintln!("Evaluation error: {}", msg);
return None;
}
}
Err(err) => Err(err),
}
return result;
}
2 changes: 1 addition & 1 deletion tests/err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ mod tests {
.expect(format!("command 'cargo run ???' failed").as_str());
assert_eq!(
String::from_utf8_lossy(&output.stderr),
"Parse error: Parsing error at line 1 column 4. Repair sequences found:\n 1: Delete )!\n"
"Evaluation error: Parse error: Parsing error at line 1 column 4. Repair sequences found:\n 1: Delete );!\n"
);
}
}

0 comments on commit c7954b7

Please sign in to comment.