From 6f81cbdf1582aa1158548e12fc47f5a432f93848 Mon Sep 17 00:00:00 2001 From: Kyler Date: Mon, 1 Dec 2025 09:08:27 -0700 Subject: [PATCH] Implement core modules and initial interpreter setup for SLS Rust --- SLS_Rust/sls/src/builtin.rs | 6 ++++++ SLS_Rust/sls/src/errors.rs | 20 ++++++++++++++++++++ SLS_Rust/sls/src/file.rs | 16 ++++++++++++++++ SLS_Rust/sls/src/hash_table.rs | 25 +++++++++++++++++++++++++ SLS_Rust/sls/src/interpreter.rs | 17 +++++++++++++++++ SLS_Rust/sls/src/lexer.rs | 17 +++++++++++++++++ SLS_Rust/sls/src/main.rs | 23 ++++++++++++++++++++++- SLS_Rust/sls/src/meta.rs | 2 ++ SLS_Rust/sls/src/repl.rs | 8 ++++++++ SLS_Rust/sls/src/sls_string.rs | 11 +++++++++++ SLS_Rust/sls/src/types.rs | 28 ++++++++++++++++++++++++++++ 11 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 SLS_Rust/sls/src/builtin.rs create mode 100644 SLS_Rust/sls/src/errors.rs create mode 100644 SLS_Rust/sls/src/file.rs create mode 100644 SLS_Rust/sls/src/hash_table.rs create mode 100644 SLS_Rust/sls/src/interpreter.rs create mode 100644 SLS_Rust/sls/src/lexer.rs create mode 100644 SLS_Rust/sls/src/meta.rs create mode 100644 SLS_Rust/sls/src/repl.rs create mode 100644 SLS_Rust/sls/src/sls_string.rs create mode 100644 SLS_Rust/sls/src/types.rs diff --git a/SLS_Rust/sls/src/builtin.rs b/SLS_Rust/sls/src/builtin.rs new file mode 100644 index 0000000..7b22861 --- /dev/null +++ b/SLS_Rust/sls/src/builtin.rs @@ -0,0 +1,6 @@ +use crate::types::Value; + +/// Collection of builtin functions. This is a placeholder module. +pub fn hello() -> Value { + Value::Str("hello from builtin".to_string()) +} diff --git a/SLS_Rust/sls/src/errors.rs b/SLS_Rust/sls/src/errors.rs new file mode 100644 index 0000000..fa46543 --- /dev/null +++ b/SLS_Rust/sls/src/errors.rs @@ -0,0 +1,20 @@ +use std::fmt; + +#[derive(Debug)] +pub enum SlsError { + Runtime(String), + Lexer(String), + Io(String), +} + +impl std::error::Error for SlsError {} + +impl fmt::Display for SlsError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + SlsError::Runtime(s) => write!(f, "Runtime: {}", s), + SlsError::Lexer(s) => write!(f, "Lexer: {}", s), + SlsError::Io(s) => write!(f, "IO: {}", s), + } + } +} diff --git a/SLS_Rust/sls/src/file.rs b/SLS_Rust/sls/src/file.rs new file mode 100644 index 0000000..1aa4622 --- /dev/null +++ b/SLS_Rust/sls/src/file.rs @@ -0,0 +1,16 @@ +use crate::errors::SlsError; +use std::fs; + +pub struct SlsFile { + pub path: String, +} + +impl SlsFile { + pub fn open(path: impl Into) -> Self { + SlsFile { path: path.into() } + } + + pub fn read_all(&self) -> Result { + fs::read_to_string(&self.path).map_err(|e| SlsError::Io(e.to_string())) + } +} diff --git a/SLS_Rust/sls/src/hash_table.rs b/SLS_Rust/sls/src/hash_table.rs new file mode 100644 index 0000000..1843518 --- /dev/null +++ b/SLS_Rust/sls/src/hash_table.rs @@ -0,0 +1,25 @@ +use std::collections::HashMap; +use crate::types::Value; + +#[derive(Debug, Default)] +pub struct HashTable { + pub map: HashMap, +} + +impl HashTable { + pub fn new() -> Self { + HashTable { map: HashMap::new() } + } + + pub fn get(&self, key: &str) -> Option<&Value> { + self.map.get(key) + } + + pub fn set(&mut self, key: String, val: Value) { + self.map.insert(key, val); + } + + pub fn remove(&mut self, key: &str) -> Option { + self.map.remove(key) + } +} diff --git a/SLS_Rust/sls/src/interpreter.rs b/SLS_Rust/sls/src/interpreter.rs new file mode 100644 index 0000000..43f61c4 --- /dev/null +++ b/SLS_Rust/sls/src/interpreter.rs @@ -0,0 +1,17 @@ +use crate::types::Value; +use std::collections::HashMap; + +pub struct Interpreter { + pub globals: HashMap, +} + +impl Interpreter { + pub fn new() -> Self { + Interpreter { globals: HashMap::new() } + } + + /// Evaluate source and return a Value. This is a stubbed placeholder. + pub fn eval(&mut self, _src: &str) -> Result> { + Ok(Value::Nil) + } +} diff --git a/SLS_Rust/sls/src/lexer.rs b/SLS_Rust/sls/src/lexer.rs new file mode 100644 index 0000000..d4a4abe --- /dev/null +++ b/SLS_Rust/sls/src/lexer.rs @@ -0,0 +1,17 @@ +#[derive(Debug, Clone)] +pub struct Lexer { + pub input: String, + pub pos: usize, +} + +impl Lexer { + pub fn new(input: impl Into) -> Self { + Lexer { input: input.into(), pos: 0 } + } + + /// Stub: return next token as a string or None at EOF. + pub fn next_token(&mut self) -> Option { + // placeholder for a real lexer implementation + None + } +} diff --git a/SLS_Rust/sls/src/main.rs b/SLS_Rust/sls/src/main.rs index e7a11a9..ece9f37 100644 --- a/SLS_Rust/sls/src/main.rs +++ b/SLS_Rust/sls/src/main.rs @@ -1,3 +1,24 @@ +mod types; +mod errors; +mod hash_table; +mod sls_string; +mod file; +mod lexer; +mod interpreter; +mod repl; +mod meta; +mod builtin; + +use crate::interpreter::Interpreter; + fn main() { - println!("Hello, world!"); + println!("Starting sls (Rust) - {} v{}", meta::NAME, meta::VERSION); + let mut interp = Interpreter::new(); + // placeholder: evaluate empty program to ensure basic startup + match interp.eval("") { + Ok(_) => println!("Interpreter initialized."), + Err(e) => eprintln!("Interpreter failed to initialize: {}", e), + } + // start REPL stub + repl::run_repl(); } diff --git a/SLS_Rust/sls/src/meta.rs b/SLS_Rust/sls/src/meta.rs new file mode 100644 index 0000000..347d4c9 --- /dev/null +++ b/SLS_Rust/sls/src/meta.rs @@ -0,0 +1,2 @@ +pub const VERSION: &str = "0.1.0"; +pub const NAME: &str = "sls_rust"; diff --git a/SLS_Rust/sls/src/repl.rs b/SLS_Rust/sls/src/repl.rs new file mode 100644 index 0000000..4999145 --- /dev/null +++ b/SLS_Rust/sls/src/repl.rs @@ -0,0 +1,8 @@ +use crate::interpreter::Interpreter; + +pub fn run_repl() { + let mut interp = Interpreter::new(); + println!("SLS REPL (stub). Type Ctrl+C to exit."); + // For now just call eval once as a smoke test + let _ = interp.eval(""); +} diff --git a/SLS_Rust/sls/src/sls_string.rs b/SLS_Rust/sls/src/sls_string.rs new file mode 100644 index 0000000..ae49a2e --- /dev/null +++ b/SLS_Rust/sls/src/sls_string.rs @@ -0,0 +1,11 @@ +use crate::types::SlsStr; + +pub fn from_str(s: &str) -> SlsStr { + s.to_string() +} + +pub fn concat(a: &SlsStr, b: &SlsStr) -> SlsStr { + let mut r = a.clone(); + r.push_str(b); + r +} diff --git a/SLS_Rust/sls/src/types.rs b/SLS_Rust/sls/src/types.rs new file mode 100644 index 0000000..658a971 --- /dev/null +++ b/SLS_Rust/sls/src/types.rs @@ -0,0 +1,28 @@ +use std::collections::HashMap; + +pub type SlsStr = String; + +#[derive(Debug, Clone)] +pub enum Value { + Nil, + Bool(bool), + Int(i64), + Float(f64), + Str(SlsStr), + Object(HashMap), + Function(String), +} + +impl Value { + pub fn type_name(&self) -> &'static str { + match self { + Value::Nil => "nil", + Value::Bool(_) => "bool", + Value::Int(_) => "int", + Value::Float(_) => "float", + Value::Str(_) => "str", + Value::Object(_) => "object", + Value::Function(_) => "function", + } + } +}