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