use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
mod lexer;
mod parser;
mod env;
mod eval;
mod interp;
mod arena;
mod rust_jit;
mod graph_ir;
mod checkpoint;
mod trace;
mod type_check;
mod effect_check;
mod kg;
use eval::Evaluator;
use interp::{make_env, run_code, print_repr};
#[pyclass(name = "Rusty")]
pub struct RustyInterp;
#[pymethods]
impl RustyInterp {
#[new]
fn new() -> Self { RustyInterp }
fn eval(&self, code: &str) -> PyResult<String> {
let env = make_env();
match run_code(code, &env, &Evaluator::new()) {
Ok(v) => Ok(print_repr(&v)),
Err(e) => Err(pyo3::exceptions::PyRuntimeError::new_err(e)),
}
}
fn eval_repr(&self, code: &str) -> PyResult<String> {
let env = make_env();
match run_code(code, &env, &Evaluator::new()) {
Ok(v) => Ok(format!("{}", v)),
Err(e) => Err(pyo3::exceptions::PyRuntimeError::new_err(e)),
}
}
fn check(&self, code: &str) -> bool {
let tokens = lexer::Lexer::new(code).tokenize();
!parser::Parser::new(tokens).parse().is_empty()
}
fn __repr__(&self) -> &str { "<Rusty interpreter>" }
}
#[pyclass]
pub struct RustySession {
history: Vec<String>,
}
#[pymethods]
impl RustySession {
#[new]
fn new() -> Self { RustySession { history: Vec::new() } }
fn eval(&mut self, code: &str) -> PyResult<String> {
let env = make_env();
let eval = Evaluator::new();
for prev in &self.history {
let _ = run_code(prev, &env, &eval);
}
match run_code(code, &env, &eval) {
Ok(v) => {
self.history.push(code.to_string());
Ok(print_repr(&v))
}
Err(e) => Err(pyo3::exceptions::PyRuntimeError::new_err(e)),
}
}
fn reset(&mut self) { self.history.clear(); }
fn history_len(&self) -> usize { self.history.len() }
fn __repr__(&self) -> String {
format!("<RustySession history={}>", self.history.len())
}
}
#[pymodule]
fn rusty(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<RustyInterp>()?;
m.add_class::<RustySession>()?;
m.add_function(wrap_pyfunction!(eval_fn, m)?)?;
Ok(())
}
#[pyfunction]
#[pyo3(name = "eval")]
fn eval_fn(code: &str) -> PyResult<String> {
let env = make_env();
match run_code(code, &env, &Evaluator::new()) {
Ok(v) => Ok(print_repr(&v)),
Err(e) => Err(pyo3::exceptions::PyRuntimeError::new_err(e)),
}
}