aiscript_vm/
lib.rs

1mod ai;
2mod ast;
3mod builtins;
4mod chunk;
5mod compiler;
6mod module;
7mod object;
8mod parser;
9mod stdlib;
10mod string;
11mod ty;
12mod value;
13mod vm;
14
15use std::collections::HashMap;
16use std::fmt::Display;
17use std::ops::Deref;
18
19use aiscript_arena::Collect;
20use aiscript_arena::Mutation;
21pub(crate) use aiscript_lexer as lexer;
22pub(crate) use chunk::{Chunk, OpCode};
23use serde::Serialize;
24use serde::ser::SerializeMap;
25use serde::ser::SerializeSeq;
26pub use value::Value;
27use vm::State;
28pub use vm::Vm;
29pub use vm::VmError;
30
31type NativeFnInner<'gc> = fn(&mut State<'gc>, Vec<Value<'gc>>) -> Result<Value<'gc>, VmError>;
32type BuiltinMethodInner<'gc> = fn(
33    &'gc Mutation<'gc>,
34    // receiver
35    Value<'gc>,
36    // args
37    Vec<Value<'gc>>,
38) -> Result<Value<'gc>, VmError>;
39
40#[derive(Debug, Clone, Copy)]
41pub struct NativeFn<'gc>(NativeFnInner<'gc>);
42
43#[derive(Debug, Clone, Copy)]
44pub struct BuiltinMethod<'gc>(BuiltinMethodInner<'gc>);
45
46impl<'gc> Deref for NativeFn<'gc> {
47    type Target = NativeFnInner<'gc>;
48
49    fn deref(&self) -> &Self::Target {
50        &self.0
51    }
52}
53
54impl<'gc> Deref for BuiltinMethod<'gc> {
55    type Target = BuiltinMethodInner<'gc>;
56
57    fn deref(&self) -> &Self::Target {
58        &self.0
59    }
60}
61
62unsafe impl Collect for NativeFn<'_> {
63    fn needs_trace() -> bool
64    where
65        Self: Sized,
66    {
67        false
68    }
69
70    fn trace(&self, _cc: &aiscript_arena::Collection) {}
71}
72
73unsafe impl Collect for BuiltinMethod<'_> {
74    fn needs_trace() -> bool
75    where
76        Self: Sized,
77    {
78        false
79    }
80
81    fn trace(&self, _cc: &aiscript_arena::Collection) {}
82}
83
84#[derive(Debug, PartialEq)]
85pub enum ReturnValue {
86    Number(f64),
87    Boolean(bool),
88    String(String),
89    Array(Vec<serde_json::Value>),
90    Object(HashMap<String, serde_json::Value>),
91    Response(HashMap<String, serde_json::Value>),
92    Agent(String), // agent name
93    Nil,
94}
95
96impl ReturnValue {
97    pub fn as_object(&self) -> Option<&HashMap<String, serde_json::Value>> {
98        match self {
99            Self::Object(obj) => Some(obj),
100            _ => None,
101        }
102    }
103}
104
105impl Serialize for ReturnValue {
106    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
107    where
108        S: serde::Serializer,
109    {
110        match self {
111            ReturnValue::Number(n) => serializer.serialize_f64(*n),
112            ReturnValue::Boolean(b) => serializer.serialize_bool(*b),
113            ReturnValue::String(s) => serializer.serialize_str(s),
114            ReturnValue::Array(vec) => {
115                let mut s = serializer.serialize_seq(Some(vec.len()))?;
116                for item in vec {
117                    s.serialize_element(item)?;
118                }
119                s.end()
120            }
121            ReturnValue::Object(obj) | ReturnValue::Response(obj) => {
122                let mut s = serializer.serialize_map(Some(obj.len()))?;
123                for (key, value) in obj {
124                    s.serialize_entry(key, value)?;
125                }
126                s.end()
127            }
128            ReturnValue::Agent(name) => serializer.serialize_str(name),
129            ReturnValue::Nil => serializer.serialize_none(),
130        }
131    }
132}
133
134impl Display for ReturnValue {
135    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136        match self {
137            Self::String(s) => write!(f, "{s}"),
138            Self::Number(n) => write!(f, "{n}"),
139            Self::Array(array) => {
140                write!(f, "[")?;
141                for (i, value) in array.iter().enumerate() {
142                    if i > 0 {
143                        write!(f, ", ")?;
144                    }
145                    write!(f, "{}", value)?;
146                }
147                write!(f, "]")
148            }
149            Self::Boolean(b) => write!(f, "{b}"),
150            Self::Agent(name) => write!(f, "{name}"),
151            Self::Object(obj) | Self::Response(obj) => {
152                write!(f, "{}", serde_json::to_string(obj).unwrap())
153            }
154            Self::Nil => write!(f, ""),
155        }
156    }
157}
158
159impl<'gc> From<Value<'gc>> for ReturnValue {
160    fn from(value: Value<'gc>) -> Self {
161        match value {
162            Value::Number(value) => ReturnValue::Number(value),
163            Value::Boolean(value) => ReturnValue::Boolean(value),
164            Value::String(value) => ReturnValue::String(value.to_string()),
165            Value::IoString(value) => ReturnValue::String(value.to_string()),
166            Value::List(value) => ReturnValue::Array(
167                value
168                    .borrow()
169                    .data
170                    .iter()
171                    .map(|item| item.to_serde_value())
172                    .collect::<Vec<_>>(),
173            ),
174            Value::Instance(instance) => {
175                if instance.borrow().class.borrow().name.to_str().unwrap() == "Response" {
176                    return ReturnValue::Response(
177                        instance
178                            .borrow()
179                            .fields
180                            .iter()
181                            .map(|(key, value)| (key.to_string(), value.to_serde_value()))
182                            .collect(),
183                    );
184                } else {
185                    ReturnValue::Object(
186                        instance
187                            .borrow()
188                            .fields
189                            .iter()
190                            .map(|(key, value)| (key.to_string(), value.to_serde_value()))
191                            .collect(),
192                    )
193                }
194            }
195            Value::Object(obj) => ReturnValue::Object(
196                obj.borrow()
197                    .fields
198                    .iter()
199                    .map(|(key, value)| (key.to_string(), value.to_serde_value()))
200                    .collect(),
201            ),
202            Value::Agent(agent) => ReturnValue::Agent(agent.name.to_string()),
203            _ => ReturnValue::Nil,
204        }
205    }
206}
207
208pub fn eval(source: &'static str) -> Result<ReturnValue, VmError> {
209    let mut vm = Vm::default();
210    vm.compile(source)?;
211    vm.interpret()
212}
213
214#[cfg(test)]
215mod tests {
216    use super::*;
217    #[test]
218    fn test_expression() {
219        assert_eq!(eval("return 1 + 2 * 3;").unwrap(), ReturnValue::Number(7.0));
220    }
221}