diff --git a/SLS_Rust/sls/build.rs b/SLS_Rust/sls/build.rs index ed4dc0f..1bf2e81 100644 --- a/SLS_Rust/sls/build.rs +++ b/SLS_Rust/sls/build.rs @@ -9,11 +9,11 @@ fn try_cmd(cmd: &mut Command) -> Option { Some(String::from_utf8_lossy(&out.stdout).trim().to_string()) } -fn main() -> Result<(), Box> { - // Emit vergen default build info (BUILD_DATE / BUILD_TIME) - EmitBuilder::builder().build()?; +fn main() { + // Emit all default vergen build info (BUILD_DATE / BUILD_TIME, etc.) + EmitBuilder::builder().all_build(); - // Git describe + commit date (exact match to your Python) + // Git describe + commit date (matches your Python logic) let commit_info = (|| { let hash = try_cmd( Command::new("git") @@ -36,12 +36,10 @@ fn main() -> Result<(), Box> { println!("cargo:rustc-env=GIT_COMMIT_HASH={}", commit_info); - // Compiler name and rustc version + // Compiler info println!("cargo:rustc-env=COMPILER_NAME=rustc"); let rustc_ver = try_cmd(Command::new("rustc").arg("--version")) .unwrap_or_else(|| "unknown".into()); println!("cargo:rustc-env=COMPILER_VER={}", rustc_ver); - - Ok(()) } diff --git a/SLS_Rust/sls/src/file.rs b/SLS_Rust/sls/src/file.rs index d9cbf8d..0d306eb 100644 --- a/SLS_Rust/sls/src/file.rs +++ b/SLS_Rust/sls/src/file.rs @@ -1,67 +1,45 @@ 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}; +use crate::lexer::{LexerInfo, lexical_analysis, LexResult}; /// Execute the contents of a script file. -pub fn exec_file(interpreter: &mut InterpreterState, filename: SlsStr) -> bool { +pub fn exec_file(interpreter: &mut InterpreterState, filename: &str) -> bool { // Read the whole file - let source = match fs::read_to_string(&filename.str) { + let source = match fs::read_to_string(filename) { Ok(s) => s, Err(e) => { - eprintln!("Cannot read file: {} ({})", filename.str, e); + eprintln!("Cannot read file: {} ({})", filename, e); return false; } }; - // Wrap source in SlsStr - let code = SlsStr::from_string(source); - let mut lexer_info = LexerInfo::new(filename.clone(), code); + let mut lexer_info = LexerInfo::new(filename.clone(), source.clone()); 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(); - } + LexResult::Ok(tokens) => { + for token in tokens { + if !interpreter.execute(token) { + return false; } } true } + + LexResult::Err(err) => { + eprintln!("{}", err.message); + false + } } } /// Stand-alone file execution entry point. -pub fn run_file(filename: SlsStr) -> i32 { - println!("Executing file: {}", filename.str); +pub fn run_file(filename: &str) -> i32 { + println!("Executing file: {}", filename); - let mut interpreter = match InterpreterState::new() { - Some(i) => i, - None => return 1, - }; + let mut interpreter = InterpreterState::new(); if exec_file(&mut interpreter, filename) { 0 diff --git a/SLS_Rust/sls/src/interpreter.rs b/SLS_Rust/sls/src/interpreter.rs index 294661d..4842980 100644 --- a/SLS_Rust/sls/src/interpreter.rs +++ b/SLS_Rust/sls/src/interpreter.rs @@ -18,8 +18,8 @@ pub enum StackValue { U16(u16), U8(u8), - Float(f32), - Double(f64), + F32(f32), + F64(f64), Character(u8), Boolean(bool), @@ -48,79 +48,83 @@ impl InterpreterState { functions: HashMap::new(), } } -} -pub fn push_token(state: &mut InterpreterState, token: Token) -> bool { - let value = match token { - Token::Eof => return true, + pub fn push_token(&mut self, token: Token) -> bool { + let value = match token { + Token::Eof => return true, - Token::Identifier(id) => { - StackValue::Identifier(id) - } + Token::Identifier(id) => { + StackValue::Identifier(id) + } - Token::I64(v) => StackValue::I64(v), - Token::I32(v) => StackValue::I32(v), - Token::I16(v) => StackValue::I16(v), - Token::I8(v) => StackValue::I8(v), + Token::I64(v) => StackValue::I64(v), + Token::I32(v) => StackValue::I32(v), + Token::I16(v) => StackValue::I16(v), + Token::I8(v) => StackValue::I8(v), - Token::U64(v) => StackValue::U64(v), - Token::U32(v) => StackValue::U32(v), - Token::U16(v) => StackValue::U16(v), - Token::U8(v) => StackValue::U8(v), + Token::U64(v) => StackValue::U64(v), + Token::U32(v) => StackValue::U32(v), + Token::U16(v) => StackValue::U16(v), + Token::U8(v) => StackValue::U8(v), - Token::Float(v) => StackValue::Float(v), - Token::Double(v) => StackValue::Double(v), + Token::Float(v) => StackValue::F32(v), + Token::Double(v) => StackValue::F64(v), - Token::Character(c) => StackValue::Character(c), - Token::Boolean(b) => StackValue::Boolean(b), + Token::Character(c) => StackValue::Character(c), + Token::Boolean(b) => StackValue::Boolean(b), - Token::TokenString(ts) => StackValue::TokenString(ts), + Token::TokenString(ts) => StackValue::TokenString(ts), - Token::StringLiteral(_) | - Token::Array(_) | - Token::TypeTuple(_) => return false, - }; + Token::StringLiteral(_) | + Token::Array(_) | + Token::TypeTuple(_) => return false, + }; - state.stack.push(value); - true -} - -pub fn execute_func(state: &mut InterpreterState, key: &str) -> bool { - let item = match state.functions.get(key) { - Some(v) => v.clone(), - None => return false, - }; - - match item { - FunctionItem::Builtin(f) => f(state), - FunctionItem::TokenString(ts) => execute_token_string(state, ts), + self.stack.push(value); + true } -} -pub fn execute_token_string(state: &mut InterpreterState, ts: TokenString) -> bool { - for token in ts.tokens { - if let Token::Identifier(id) = &token { - if !id.is_literal { - if !execute_func(state, &id.name) { - return false; + pub fn execute_func(&mut self, key: &str) -> bool { + let item = match self.functions.get(key) { + Some(v) => v.clone(), + None => return false, + }; + + match item { + FunctionItem::Builtin(f) => f(self), + FunctionItem::TokenString(ts) => self.execute_token_string(ts), + } + } + + pub fn execute_token_string(&mut self, ts: TokenString) -> bool { + for token in ts.tokens { + if let Token::Identifier(id) = &token { + if !id.is_literal { + if !self.execute_func(&id.name) { + return false; + } + continue; } - continue; + } + + if !self.push_token(token) { + return false; } } + true + } - if !push_token(state, token) { - return false; + pub fn execute(&mut self, token: Token) -> bool { + match token { + Token::Identifier(id) if !id.is_literal => { + self.execute_func(&id.name) + } + _ => self.push_token(token), } } - true -} -pub fn execute(state: &mut InterpreterState, token: Token) -> bool { - match token { - Token::Identifier(id) if !id.is_literal => { - execute_func(state, &id.name) - } - _ => push_token(state, token), + pub fn stack_top(&self) -> Option<&StackValue> { + self.stack.get(0) } } diff --git a/SLS_Rust/sls/src/main.rs b/SLS_Rust/sls/src/main.rs index f70da23..8f942ce 100644 --- a/SLS_Rust/sls/src/main.rs +++ b/SLS_Rust/sls/src/main.rs @@ -1,9 +1,14 @@ +mod builtin; +mod file; +mod interpreter; +mod lexer; +mod repl; + use std::env; use std::process; -use crate::file::run_file; -use crate::repl::repl; -use crate::string::SlsStr; +use file::run_file; +use repl::repl; // These mirror the C macros. const SLS_NAME: &str = "SLS_RUST"; @@ -14,20 +19,15 @@ const GIT_COMMIT_HASH: &str = env!("GIT_COMMIT_HASH", "UNKNOWN"); const COMPILER_NAME: &str = env!("COMPILER_NAME", "Unknown"); const COMPILER_VER: &str = env!("COMPILER_VER", "0"); -fn print_version() { - println!( - "YREA SLS ({}) {} ({})", - SLS_NAME, - SLS_VER, - GIT_COMMIT_HASH - ); - println!( - "Compiled with {} {} on {} {}", - COMPILER_NAME, - COMPILER_VER, - env!("BUILD_DATE"), - env!("BUILD_TIME") - ); +pub fn print_version() { + let git_hash = option_env!("GIT_COMMIT_HASH").unwrap_or("unknown"); + let compiler = option_env!("COMPILER_NAME").unwrap_or("rustc"); + let compiler_ver = option_env!("COMPILER_VER").unwrap_or("unknown"); + let build_date = std::env::var("BUILD_DATE").unwrap_or_else(|_| "unknown".into()); + let build_time = std::env::var("BUILD_TIME").unwrap_or_else(|_| "unknown".into()); + + println!("YREA SLS (SLS_RUST) a.0.0 ({git_hash})"); + println!("Compiled with {compiler} {compiler_ver} at {build_date} {build_time}"); } fn main() { @@ -58,8 +58,7 @@ fn main() { } if let Some(file) = filename { - let sls_filename = SlsStr::from_string(file); - let status = run_file(sls_filename); + let status = run_file(&file); process::exit(status); } diff --git a/SLS_Rust/sls/src/repl.rs b/SLS_Rust/sls/src/repl.rs index 59acbb3..1bfa9be 100644 --- a/SLS_Rust/sls/src/repl.rs +++ b/SLS_Rust/sls/src/repl.rs @@ -1,10 +1,8 @@ use std::io::{self, Write}; -use crate::lexer::{Lexer, LexerInfo, lexical_analysis}; -use crate::meta::print_version; -use crate::interpreter::{InterpreterState, StackType}; -use crate::string::{SlsStr}; -use crate::errors::{LexerTokenResult, LexerResult}; +use crate::lexer::{LexerInfo, LexResult, lexical_analysis}; +use crate::print_version; +use crate::interpreter::{InterpreterState, StackValue}; static REPL_FILE_NAME: &str = ""; @@ -14,28 +12,28 @@ fn print_top_of_stack(state: &InterpreterState) { return; }; - match &item.value { - StackType::Identifier(id) => { + match &item { + StackValue::Identifier(id) => { println!("#0: ::{}", id.name); } - StackType::I64(v) => println!("#0: {}", v), - StackType::I32(v) => println!("#0: {}:i32", v), - StackType::I16(v) => println!("#0: {}:i16", v), - StackType::I8(v) => println!("#0: {}:i8", v), + StackValue::I64(v) => println!("#0: {}", v), + StackValue::I32(v) => println!("#0: {}:i32", v), + StackValue::I16(v) => println!("#0: {}:i16", v), + StackValue::I8(v) => println!("#0: {}:i8", v), - StackType::U64(v) => println!("#0: {}:u64", v), - StackType::U32(v) => println!("#0: {}:u32", v), - StackType::U16(v) => println!("#0: {}:u16", v), - StackType::U8(v) => println!("#0: {}:u8", v), + StackValue::U64(v) => println!("#0: {}:u64", v), + StackValue::U32(v) => println!("#0: {}:u32", v), + StackValue::U16(v) => println!("#0: {}:u16", v), + StackValue::U8(v) => println!("#0: {}:u8", v), - StackType::F32(v) => println!("#0: {}:f32", v), - StackType::F64(v) => println!("#0: {}", v), + StackValue::F32(v) => println!("#0: {}:f32", v), + StackValue::F64(v) => println!("#0: {}", v), - StackType::Character(ch) => println!("#0: {}", ch), - StackType::Boolean(b) => println!("#0: {}", if *b { "TRUE" } else { "FALSE" }), + StackValue::Character(ch) => println!("#0: {}", ch), + StackValue::Boolean(b) => println!("#0: {}", if *b { "TRUE" } else { "FALSE" }), - StackType::TokenString(_) => println!("#0: "), - StackType::Callable(_) => println!("#0: "), + StackValue::TokenString(_) => println!("#0: "), + StackValue::Callable(_) => println!("#0: "), }; } @@ -45,10 +43,7 @@ pub fn repl() -> i32 { println!("Type `#exit` to exit."); io::stdout().flush().unwrap(); - let mut interpreter = match InterpreterState::new() { - Some(i) => i, - None => return 1, - }; + let mut interpreter = InterpreterState::new(); let stdin = io::stdin(); let mut buf = String::new(); @@ -64,41 +59,24 @@ pub fn repl() -> i32 { return 0; } - let code = SlsStr::from_string(buf.clone()); - let mut lexer_info = LexerInfo::new(REPL_FILE_NAME.into(), code.clone()); + let code = buf.clone(); + let mut lexer_info = LexerInfo::new(REPL_FILE_NAME, code.clone()); let result = lexical_analysis(&mut lexer_info); match result { - LexerResult::Error(err) => { - println!("{}", err.message); - } - - LexerResult::Ok(mut head) => { - let mut node = Some(head.as_mut()); - - while let Some(tok_node) = node { - match tok_node { - LexerTokenResult::Error(err) => { - println!("{}", err.message); - break; - } - LexerTokenResult::Token(tok) => { - if !interpreter.execute(tok) { - println!("A runtime error occurred!"); - break; - } - } - LexerTokenResult::Next(_, next) => { - node = next.as_deref_mut(); - continue; - } + LexResult::Ok(tokens) => { + for token in tokens { + if !interpreter.execute(token) { + return 1; } - - node = None; } print_top_of_stack(&interpreter); } + + LexResult::Err(err) => { + println!("{}", err.message); + } } } }