YREA-SLS/SLS_Rust/sls/src/file.rs

72 lines
2.0 KiB
Rust

use std::fs;
use std::io;
use crate::interpreter::InterpreterState;
use crate::lexer::{LexerInfo, lexical_analysis};
use crate::string::SlsStr;
use crate::errors::{LexerResult, LexerTokenResult};
/// Execute the contents of a script file.
pub fn exec_file(interpreter: &mut InterpreterState, filename: SlsStr) -> bool {
// Read the whole file
let source = match fs::read_to_string(&filename.str) {
Ok(s) => s,
Err(e) => {
eprintln!("Cannot read file: {} ({})", filename.str, e);
return false;
}
};
// Wrap source in SlsStr
let code = SlsStr::from_string(source);
let mut lexer_info = LexerInfo::new(filename.clone(), code);
let result = lexical_analysis(&mut lexer_info);
match result {
LexerResult::Error(err) => {
eprintln!("{}", err.message);
false
}
LexerResult::Ok(mut head) => {
let mut node = Some(head.as_mut());
while let Some(tok) = node {
match tok {
LexerTokenResult::Error(err) => {
eprintln!("{}", err.message);
return false;
}
LexerTokenResult::Token(token) => {
if !interpreter.execute(token) {
eprintln!("A runtime error occurred!");
return false;
}
node = None; // No linked list, next handled below
}
LexerTokenResult::Next(_, next) => {
node = next.as_deref_mut();
}
}
}
true
}
}
}
/// Stand-alone file execution entry point.
pub fn run_file(filename: SlsStr) -> i32 {
println!("Executing file: {}", filename.str);
let mut interpreter = match InterpreterState::new() {
Some(i) => i,
None => return 1,
};
if exec_file(&mut interpreter, filename) {
0
} else {
1
}
}