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 Value<'gc>,
36 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), 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}