bendn 6 months ago
commit 5767c68
-rw-r--r--.gitignore2
-rw-r--r--Cargo.toml13
-rw-r--r--src/lib.rs10
-rw-r--r--src/run.rs99
-rw-r--r--tests/test.rs4
5 files changed, 128 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5556cac
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+Cargo.lock
+ronner \ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..0d21af6
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "mpy"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+syn = "2.0.104"
+proc-macro2 = "1.0.78"
+quote = "1.0.40"
+pyo3 = { version = "0.25.1", features = ["extension-module"] }
+
+[lib]
+proc-macro = true
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..d332303
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,10 @@
+#![feature(if_let_guard, proc_macro_quote)]
+mod run;
+use std::ffi::CString;
+
+use proc_macro::TokenStream;
+use syn::Lit;
+#[proc_macro]
+pub fn eval(i: TokenStream) -> TokenStream {
+ run::exec(&CString::new(i.to_string()).unwrap()).into()
+}
diff --git a/src/run.rs b/src/run.rs
new file mode 100644
index 0000000..e12450f
--- /dev/null
+++ b/src/run.rs
@@ -0,0 +1,99 @@
+pub fn runpy(py: String) {}
+use proc_macro::Ident;
+use proc_macro::Literal;
+use proc_macro::TokenStream;
+use proc_macro::quote;
+use std::cell::RefCell;
+use std::ffi::CStr;
+use std::ffi::CString;
+use std::sync::Mutex;
+use std::sync::RwLock;
+
+use proc_macro::Span;
+use proc_macro::TokenTree;
+use pyo3::exceptions::PyTypeError;
+use pyo3::prelude::*;
+use pyo3::types::*;
+
+struct R(proc_macro::TokenStream);
+impl<'py, 's> FromPyObject<'py> for R {
+ fn extract_bound(x: &Bound<'py, PyAny>) -> Result<R, PyErr> {
+ let tree: TokenTree = match () {
+ () if let Ok(x) = x.extract::<i128>() => Literal::i128_unsuffixed(x).into(),
+ () if let Ok(x) = x.extract::<f64>() => Literal::f64_unsuffixed(x).into(),
+ () if let Ok(x) = x.extract::<bool>() => {
+ Ident::new(&x.to_string(), Span::call_site()).into()
+ }
+ () if let Ok(x) = x.extract::<String>() => {
+ return Ok(R(x
+ .parse::<TokenStream>()
+ .unwrap_or(quote::quote!(compile_error!("lex failure")).into())));
+ }
+
+ // () if let Ok(x) = x.downcast::<PyList>() => {
+ // if let Ok(y) = x.get_item(0) {
+ // match () {
+ // () if y.is_instance_of::<PyFloat>() => Val::Array(Array::Float(
+ // x.into_iter().map(|x| x.extract::<f64>()).try_collect()?,
+ // )),
+ // () if y.is_instance_of::<PyInt>() => Val::Array(Array::Int(
+ // x.into_iter().map(|x| x.extract::<i128>()).try_collect()?,
+ // )),
+ // _ => {
+ // return Err(PyTypeError::new_err("bad array types"));
+ // }
+ // }
+ // } else {
+ // Val::Array(Array::Int(vec![]))
+ // }
+ // }
+ // () if let Ok(x) = x.downcast::<PySet>() => Val::Set(
+ // x.into_iter()
+ // .map(|x| x.extract::<Val<'s>>())
+ // .try_collect()?,
+ // ),
+ _ => return Err(PyTypeError::new_err("bad types")),
+ };
+ let mut t = TokenStream::new();
+ t.extend([tree]);
+ Ok(R(t))
+ }
+}
+
+pub fn exec<'s>(code: &CStr) -> TokenStream {
+ pyo3::prepare_freethreaded_python();
+ Python::with_gil(|g| {
+ g.run(
+ cr#"__import__("sys").stdout = __import__("io").StringIO()"#,
+ None,
+ None,
+ )
+ .unwrap();
+ Ok::<_, ()>(
+ g.run(&code, None, None)
+ .map(|()| {
+ g.eval(cr#"__import__("sys").stdout.getvalue()"#, None, None)
+ .unwrap()
+ .extract::<String>()
+ .unwrap()
+ .parse::<TokenStream>()
+ .unwrap()
+ })
+ .unwrap_or_else(|x| {
+ eprintln!("error:");
+ x.display(g);
+ let e = x.to_string();
+ quote::quote!(compile_error!("there was a problem running the python: ", #e))
+ .into()
+ }),
+ )
+ // stack.extend(
+ // x.into_iter()
+ // .skip(n.saturating_sub(argc.output))
+ // .map(|x| x.extract::<Val<'_>>().map(|x| x.spun(span)))
+ // .try_collect::<Vec<_>>()
+ // .map_err(|_| Error::lazy(code.span, "nooo"))?,
+ // );
+ })
+ .unwrap()
+}
diff --git a/tests/test.rs b/tests/test.rs
new file mode 100644
index 0000000..3500511
--- /dev/null
+++ b/tests/test.rs
@@ -0,0 +1,4 @@
+#[test]
+fn main() {
+ dbg!(mpy::eval! { "print([n for n in range(2)])" });
+}