1use pyo3::prelude::*;
18use pyo3::wrap_pyfunction;
19
20mod lexer;
21mod parser;
22mod resolve;
23mod env;
24mod eval;
25mod interp;
26mod arena;
27mod rust_jit;
28mod graph_ir;
29mod checkpoint;
30mod trace;
31mod type_check;
32mod effect_check;
33mod kg;
34
35use eval::Evaluator;
36use interp::{make_env, run_code, print_repr};
37
38#[pyclass(name = "Rusty")]
43pub struct RustyInterp;
44
45#[pymethods]
46impl RustyInterp {
47 #[new]
48 fn new() -> Self { RustyInterp }
49
50 fn eval(&self, code: &str) -> PyResult<String> {
52 let env = make_env();
53 match run_code(code, &env, &Evaluator::new()) {
54 Ok(v) => Ok(print_repr(&v)),
55 Err(e) => Err(pyo3::exceptions::PyRuntimeError::new_err(e)),
56 }
57 }
58
59 fn eval_repr(&self, code: &str) -> PyResult<String> {
61 let env = make_env();
62 match run_code(code, &env, &Evaluator::new()) {
63 Ok(v) => Ok(format!("{}", v)),
64 Err(e) => Err(pyo3::exceptions::PyRuntimeError::new_err(e)),
65 }
66 }
67
68 fn check(&self, code: &str) -> bool {
70 let tokens = lexer::Lexer::new(code).tokenize();
71 match parser::Parser::new(tokens).parse_checked() {
74 Ok(ast) => !ast.is_empty(),
75 Err(_) => false,
76 }
77 }
78
79 fn __repr__(&self) -> &str { "<Rusty interpreter>" }
80}
81
82#[pyclass]
87pub struct RustySession {
88 history: Vec<String>,
89}
90
91#[pymethods]
92impl RustySession {
93 #[new]
94 fn new() -> Self { RustySession { history: Vec::new() } }
95
96 fn eval(&mut self, code: &str) -> PyResult<String> {
98 let env = make_env();
99 let eval = Evaluator::new();
100 for prev in &self.history {
101 let _ = run_code(prev, &env, &eval);
102 }
103 match run_code(code, &env, &eval) {
104 Ok(v) => {
105 self.history.push(code.to_string());
106 Ok(print_repr(&v))
107 }
108 Err(e) => Err(pyo3::exceptions::PyRuntimeError::new_err(e)),
109 }
110 }
111
112 fn reset(&mut self) { self.history.clear(); }
114
115 fn history_len(&self) -> usize { self.history.len() }
117
118 fn __repr__(&self) -> String {
119 format!("<RustySession history={}>", self.history.len())
120 }
121}
122
123#[pymodule]
126fn rusty(m: &Bound<'_, PyModule>) -> PyResult<()> {
127 m.add_class::<RustyInterp>()?;
128 m.add_class::<RustySession>()?;
129 m.add_function(wrap_pyfunction!(eval_fn, m)?)?;
130 Ok(())
131}
132
133#[pyfunction]
135#[pyo3(name = "eval")]
136fn eval_fn(code: &str) -> PyResult<String> {
137 let env = make_env();
138 match run_code(code, &env, &Evaluator::new()) {
139 Ok(v) => Ok(print_repr(&v)),
140 Err(e) => Err(pyo3::exceptions::PyRuntimeError::new_err(e)),
141 }
142}