luna_lib/
lib.rs

1pub mod lang;
2pub mod luna_impl;
3#[cfg(test)]
4pub mod tests;
5
6use lang::{
7    code::Closure,
8    tokens::Token,
9    value::{Function, Value},
10};
11use luna_impl::{
12    compiler::{Compilable, Compiler},
13    interpreter::Interpreter,
14    lexer::Lexer,
15    parser::{Parsable, ParseError},
16    position::{Located, PathLocated},
17};
18use std::{cell::RefCell, env, error::Error, fmt::Display, rc::Rc};
19
20pub fn lex_str(text: &str) -> Result<Vec<Located<Token>>, Located<Box<dyn Error>>> {
21    Lexer::from(text)
22        .lex()
23        .map_err(|err| err.map(|err| err.into()))
24}
25pub fn parse_str<A: Parsable>(text: &str) -> Result<Located<A>, Located<Box<dyn Error>>> {
26    let mut lexer = lex_str(text)?.into_iter().peekable();
27    let ast = A::parse(&mut lexer).map_err(|err| err.map(|err| err.into()))?;
28    if let Some(Located { value: token, pos }) = lexer.next() {
29        return Err(Located::new(ParseError::UnexpectedToken(token).into(), pos));
30    }
31    Ok(ast)
32}
33pub fn compile_str<A: Parsable>(
34    text: &str,
35    path: Option<&str>,
36) -> Result<Rc<RefCell<Closure>>, Located<Box<dyn Error>>>
37where
38    Located<A>: Compilable<Output = Rc<RefCell<Closure>>>,
39{
40    let ast = parse_str::<A>(text)?;
41    let closure = ast.compile(&mut Compiler {
42        path: path.map(|s| s.to_string()),
43        ..Default::default()
44    })?;
45    Ok(closure)
46}
47pub fn run_str<A: Parsable>(
48    text: &str,
49    path: Option<&str>,
50) -> Result<Option<Value>, PathLocated<Box<dyn Error>>>
51where
52    Located<A>: Compilable<Output = Rc<RefCell<Closure>>>,
53{
54    let closure = compile_str(text, path).map_err(|err| {
55        err.with_path(
56            path.map(|path| path.to_string())
57                .unwrap_or("<input>".to_string()),
58        )
59    })?;
60    let function = Rc::new(Function {
61        closure,
62        upvalues: vec![],
63    });
64    let mut interpreter = Interpreter::default().with_global_path(env::var("LUNA_PATH").ok());
65    interpreter.call(&function, vec![], None);
66    interpreter.run().map_err(|err| {
67        err.map(|err| err.into())
68            .with_path(interpreter.path().unwrap_or("<input>".to_string()))
69    })
70}
71
72#[macro_export]
73macro_rules! int {
74    ($v:literal) => {
75        Value::Int($v.into())
76    };
77}
78#[macro_export]
79macro_rules! float {
80    ($v:literal) => {
81        Value::Float($v.into())
82    };
83}
84#[macro_export]
85macro_rules! bool {
86    ($v:literal) => {
87        Value::Bool($v.into())
88    };
89}
90#[macro_export]
91macro_rules! char {
92    ($v:literal) => {
93        Value::Char($v.into())
94    };
95}
96#[macro_export]
97macro_rules! string {
98    ($v:literal) => {
99        Value::String($v.to_string())
100    };
101}
102#[macro_export]
103macro_rules! vector {
104    [$($v:literal),*] => {
105        Value::Vector(Rc::new(RefCell::new(vec![$($v.into()),*])))
106    };
107    ($v:expr) => {
108        Value::Vector(Rc::new(RefCell::new($v.into())))
109    };
110}
111#[macro_export]
112macro_rules! object {
113    {$($k:literal = $v:expr),*} => {
114        {
115            #[allow(unused_variables, unused_mut)]
116            let mut map = HashMap::new();
117            $(
118                map.insert($k.into(), $v.into());
119            ) *
120            Value::Object(Rc::new(RefCell::new(Object::new(map))))
121        }
122    };
123    ($v:expr) => {
124        Value::Object(Rc::new(RefCell::new(Object::new($v))))
125    };
126}
127#[macro_export]
128macro_rules! function {
129    ($name:ident) => {
130        Value::Function(FunctionKind::UserFunction(Rc::new($name)))
131    };
132}
133#[macro_export]
134macro_rules! set_field {
135    ($map:ident . $field:literal = $value:expr) => {
136        $map.insert($field.to_string(), Rc::new(RefCell::new($value)));
137    };
138    ($map:ident . $field:ident = $value:expr) => {
139        $map.insert($field.to_string(), Rc::new(RefCell::new($value)));
140    };
141}
142#[derive(Debug, Clone, PartialEq)]
143pub struct ExpectedType {
144    pub idx: usize,
145    pub expected: &'static str,
146    pub got: &'static str,
147}
148impl Display for ExpectedType {
149    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150        write!(
151            f,
152            "expected {} for argument #{}, got {}",
153            self.expected, self.idx, self.got
154        )
155    }
156}
157impl Error for ExpectedType {}
158#[derive(Debug, Clone, PartialEq)]
159pub struct ExpectedTypes {
160    pub idx: usize,
161    pub expected: Vec<&'static str>,
162    pub got: &'static str,
163}
164impl Display for ExpectedTypes {
165    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166        write!(
167            f,
168            "expected {} for argument #{}, got {}",
169            self.expected.join("/"),
170            self.idx,
171            self.got
172        )
173    }
174}
175impl Error for ExpectedTypes {}
176#[macro_export]
177macro_rules! typed {
178    ($args:ident) => {{
179        let (_, arg) = $args.next().unwrap_or(($args.len(), Value::default()));
180        arg
181    }};
182    ($args:ident : $type:ident) => {{
183        let (idx, arg) = $args.next().unwrap_or(($args.len(), Value::default()));
184        if let Value::$type(value) = arg {
185            value
186        } else {
187            return Err(ExpectedType {
188                idx,
189                expected: Value::$type(Default::default()).typ(),
190                got: arg.typ(),
191            }
192            .into());
193        }
194    }};
195    ($args:ident : $type:ident ?) => {{
196        let (idx, arg) = $args.next().unwrap_or(($args.len(), Value::default()));
197        if arg == Value::default() {
198            None
199        } else {
200            if let Value::$type(value) = arg {
201                Some(value)
202            } else {
203                return Err(ExpectedType {
204                    idx,
205                    expected: Value::$type(Default::default()).typ(),
206                    got: arg.typ(),
207                }
208                .into());
209            }
210        }
211    }};
212    ($args:ident : $type:ident $param:ident => $value:expr) => {{
213        let (idx, arg) = $args.next().unwrap_or(($args.len(), Value::default()));
214        if let Value::$type($param) = arg {
215            $value
216        } else {
217            return Err(ExpectedType {
218                idx,
219                expected: Value::$type(Default::default()).typ(),
220                got: arg.typ(),
221            }
222            .into());
223        }
224    }};
225    ($args:ident : $type:ident ? $param:ident => $value:expr) => {{
226        let (idx, arg) = $args.next().unwrap_or(($args.len(), Value::default()));
227        if arg == Value::default() {
228            None
229        } else {
230            if let Value::$type($param) = arg {
231                Some($value)
232            } else {
233                return Err(ExpectedType {
234                    idx,
235                    expected: Value::$type(Default::default()).typ(),
236                    got: arg.typ(),
237                }
238                .into());
239            }
240        }
241    }};
242}
243#[macro_export]
244macro_rules! option {
245    ($args:ident : $($type:ident => $value:ident $body:block),+) => {{
246        let (idx, arg) = $args.next().unwrap_or(($args.len(), Value::default()));
247        match arg {
248            $(
249                Value::$type($value) => $body,
250            ) +
251            arg => {
252                return Err(ExpectedTypes {
253                    idx,
254                    expected: vec![$(Value::$type(Default::default()).typ()),+],
255                    got: arg.typ(),
256                }
257                .into())
258            }
259        }
260    }};
261}
262#[macro_export]
263macro_rules! userobject {
264    (
265        $name:ident : $typ_name:literal ;
266        $self:ident
267        $(static ($fn_self:ident, $fn_args:ident) { $(
268            $fn_name:ident : $fn_literal_name:literal $fn_body:block
269        ) *})?
270        $(mut ($fn_mut_self:ident, $fn_mut_args:ident) { $(
271            $fn_mut_name:ident : $fn_mut_literal_name:literal $fn_mut_body:block
272        ) *})?
273    ) => {
274        impl UserObject for $name {
275            fn typ(&self) -> &'static str {
276                $typ_name
277            }
278            fn get(&$self, key: &str) -> Option<Value> {
279                match key {
280                    $(
281                        $(
282                            $fn_literal_name => Some(Value::Function(FunctionKind::UserFunction(Rc::new(
283                                Box::new(Self::$fn_name),
284                            )))),
285                        )*
286                    )?
287                    $(
288                        $(
289                            $fn_mut_literal_name => Some(Value::Function(FunctionKind::UserFunction(Rc::new(
290                                Box::new(Self::$fn_mut_name),
291                            )))),
292                        )*
293                    )?
294                    _ => None,
295                }
296            }
297            $(
298                #[allow(unused_variables)]
299                fn call(&$fn_self, key: &str, $fn_args: Vec<Value>) -> Result<Value, Box<dyn Error>> {
300                    match key {
301                        $(
302                            $fn_literal_name => $fn_body,
303                        )+
304                        _ => Err(Box::new(UserObjectError::CannotCallNull))
305                    }
306                }
307            )?
308            $(
309                #[allow(unused_variables)]
310                fn call_mut(&mut $fn_mut_self, key: &str, $fn_mut_args: Vec<Value>) -> Result<Value, Box<dyn Error>> {
311                    match key {
312                        $(
313                            $fn_mut_literal_name => $fn_mut_body,
314                        )+
315                        _ => Err(Box::new(UserObjectError::CannotCallNull))
316                    }
317                }
318            )?
319        }
320        impl $name {
321            $(
322                $(
323                    pub fn $fn_name(_: &mut Interpreter, mut $fn_args: Vec<Value>) -> Result<Value, Box<dyn Error>> {
324                        let Some(_self) = $fn_args.first().cloned() else {
325                            return Err(Box::new(UserObjectError::ExpectedSelf("null")));
326                        };
327                        $fn_args.remove(0);
328                        if let Value::UserObject(_self) = _self {
329                            let mut _self = _self.borrow_mut();
330                            _self.call($fn_literal_name, $fn_args)
331                        } else {
332                            Err(Box::new(UserObjectError::ExpectedSelf(_self.typ())))
333                        }
334                    }
335                ) *
336            )?
337            $(
338                $(
339                    pub fn $fn_mut_name(_: &mut Interpreter, mut $fn_mut_args: Vec<Value>) -> Result<Value, Box<dyn Error>> {
340                        let Some(_self) = $fn_mut_args.first().cloned() else {
341                            return Err(Box::new(UserObjectError::ExpectedSelf("null")));
342                        };
343                        $fn_mut_args.remove(0);
344                        if let Value::UserObject(_self) = _self {
345                            let mut _self = _self.borrow_mut();
346                            _self.call_mut($fn_mut_literal_name, $fn_mut_args)
347                        } else {
348                            Err(Box::new(UserObjectError::ExpectedSelf(_self.typ())))
349                        }
350                    }
351                ) *
352            )?
353        }
354    };
355}