Implement core modules and initial interpreter setup for SLS Rust

This commit is contained in:
Kyler Olsen 2025-12-01 09:08:27 -07:00
parent b70634b450
commit 6f81cbdf15
11 changed files with 172 additions and 1 deletions

View File

@ -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())
}

View File

@ -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),
}
}
}

16
SLS_Rust/sls/src/file.rs Normal file
View File

@ -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<String>) -> Self {
SlsFile { path: path.into() }
}
pub fn read_all(&self) -> Result<String, SlsError> {
fs::read_to_string(&self.path).map_err(|e| SlsError::Io(e.to_string()))
}
}

View File

@ -0,0 +1,25 @@
use std::collections::HashMap;
use crate::types::Value;
#[derive(Debug, Default)]
pub struct HashTable {
pub map: HashMap<String, Value>,
}
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<Value> {
self.map.remove(key)
}
}

View File

@ -0,0 +1,17 @@
use crate::types::Value;
use std::collections::HashMap;
pub struct Interpreter {
pub globals: HashMap<String, Value>,
}
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<Value, Box<dyn std::error::Error>> {
Ok(Value::Nil)
}
}

17
SLS_Rust/sls/src/lexer.rs Normal file
View File

@ -0,0 +1,17 @@
#[derive(Debug, Clone)]
pub struct Lexer {
pub input: String,
pub pos: usize,
}
impl Lexer {
pub fn new(input: impl Into<String>) -> 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<String> {
// placeholder for a real lexer implementation
None
}
}

View File

@ -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();
}

2
SLS_Rust/sls/src/meta.rs Normal file
View File

@ -0,0 +1,2 @@
pub const VERSION: &str = "0.1.0";
pub const NAME: &str = "sls_rust";

8
SLS_Rust/sls/src/repl.rs Normal file
View File

@ -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("");
}

View File

@ -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
}

28
SLS_Rust/sls/src/types.rs Normal file
View File

@ -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<String, Value>),
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",
}
}
}