1use crate::{Array, Boolean, Function, Integer, Map, Real, Reference, Text, Type, parser};
2use intuicio_core::{
3 IntuicioVersion, Visibility,
4 context::Context,
5 crate_version,
6 function::FunctionQuery,
7 object::Object,
8 registry::Registry,
9 script::{
10 BytesContentParser, ScriptContent, ScriptContentProvider, ScriptExpression, ScriptFunction,
11 ScriptFunctionParameter, ScriptFunctionSignature, ScriptHandle, ScriptModule,
12 ScriptOperation, ScriptPackage, ScriptStruct, ScriptStructField,
13 },
14 types::TypeQuery,
15};
16use serde::{Deserialize, Serialize};
17use std::{collections::HashMap, error::Error, path::PathBuf};
18
19const CLOSURES: &str = "_closures";
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub enum SimpletonScriptLiteral {
23 Null,
24 Boolean(Boolean),
25 Integer(Integer),
26 Real(Real),
27 Text(Text),
28 Array {
29 items_count: usize,
30 },
31 Map {
32 items_count: usize,
33 },
34 Object {
35 name: String,
36 module_name: String,
37 fields_count: usize,
38 },
39}
40
41impl SimpletonScriptLiteral {
42 fn evaluate(&self, context: &mut Context, registry: &Registry) {
43 match self {
44 Self::Null => context.stack().push(Reference::null()),
45 Self::Boolean(value) => context
46 .stack()
47 .push(Reference::new_boolean(*value, registry)),
48 Self::Integer(value) => context
49 .stack()
50 .push(Reference::new_integer(*value, registry)),
51 Self::Real(value) => context.stack().push(Reference::new_real(*value, registry)),
52 Self::Text(value) => context
53 .stack()
54 .push(Reference::new_text(value.to_owned(), registry)),
55 Self::Array { items_count } => {
56 let mut result = Array::with_capacity(*items_count);
57 for _ in 0..*items_count {
58 result.push(context.stack().pop::<Reference>().unwrap());
59 }
60 context.stack().push(Reference::new_array(result, registry))
61 }
62 Self::Map { items_count } => {
63 let mut result = Map::with_capacity(*items_count);
64 for _ in 0..*items_count {
65 let key = context
66 .stack()
67 .pop::<Reference>()
68 .unwrap()
69 .read::<Text>()
70 .unwrap()
71 .to_owned();
72 let value = context.stack().pop::<Reference>().unwrap();
73 result.insert(key, value);
74 }
75 context.stack().push(Reference::new_map(result, registry))
76 }
77 Self::Object {
78 name,
79 module_name,
80 fields_count,
81 } => {
82 let type_ = registry
83 .find_type(TypeQuery {
84 name: Some(name.into()),
85 module_name: Some(module_name.into()),
86 ..Default::default()
87 })
88 .unwrap();
89 let mut result = Object::new(type_);
90 for _ in 0..*fields_count {
91 let name = context.stack().pop::<Reference>().unwrap();
92
93 *result
94 .write_field::<Reference>(name.read::<Text>().unwrap().as_str())
95 .unwrap() = context.stack().pop::<Reference>().unwrap();
96 }
97 context.stack().push(Reference::new_raw(result))
98 }
99 };
100 }
101}
102
103#[derive(Debug, Serialize, Deserialize)]
104pub enum SimpletonScriptExpression {
105 FindStruct { name: String, module_name: String },
106 FindFunction { name: String, module_name: String },
107 Literal(SimpletonScriptLiteral),
108 StackDrop,
109 StackDuplicate,
110 StackSwap,
111 StackUnwrapBoolean,
112 StackValueOr(bool),
113 GetField { name: String },
114 SetField { name: String },
115}
116
117impl ScriptExpression for SimpletonScriptExpression {
118 fn evaluate(&self, context: &mut Context, registry: &Registry) {
119 match self {
120 Self::FindStruct { name, module_name } => {
121 context.stack().push(Reference::new_type(
122 Type::new(
123 registry
124 .find_type(TypeQuery {
125 name: Some(name.into()),
126 module_name: Some(module_name.into()),
127 ..Default::default()
128 })
129 .unwrap_or_else(|| {
130 panic!("Could not find struct: {module_name}::{name}")
131 }),
132 ),
133 registry,
134 ));
135 }
136 Self::FindFunction { name, module_name } => {
137 context.stack().push(Reference::new_function(
138 Function::new(
139 registry
140 .find_function(FunctionQuery {
141 name: Some(name.into()),
142 module_name: Some(module_name.into()),
143 ..Default::default()
144 })
145 .unwrap_or_else(|| {
146 panic!("Could not find function: {module_name}::{name}")
147 }),
148 ),
149 registry,
150 ));
151 }
152 Self::Literal(literal) => {
153 literal.evaluate(context, registry);
154 }
155 Self::StackDrop => {
156 context.stack().drop();
157 }
158 Self::StackDuplicate => {
159 let object = context
160 .stack()
161 .pop::<Reference>()
162 .expect("Could not pop object from stack to duplicate!");
163 context.stack().push(object.clone());
164 context.stack().push(object);
165 }
166 Self::StackSwap => {
167 let a = context
168 .stack()
169 .pop::<Reference>()
170 .expect("Could not pop first object from stack to swap!");
171 let b = context
172 .stack()
173 .pop::<Reference>()
174 .expect("Could not pop second object from stack to swap!");
175 context.stack().push(a);
176 context.stack().push(b);
177 }
178 Self::StackUnwrapBoolean => {
179 let value = context
180 .stack()
181 .pop::<Reference>()
182 .expect("Could not pop value from stack to unwrap as boolean!");
183 context.stack().push(
184 *value
185 .read::<Boolean>()
186 .expect("Value got from stack is not a boleean!"),
187 );
188 }
189 Self::StackValueOr(value) => {
190 let object = context.stack().pop::<Reference>().unwrap_or_else(|| {
191 panic!("Could not pop object from stack to tell if scope should continue!")
192 });
193 if object.is_null() {
194 context.stack().push(*value);
195 } else {
196 context.stack().push(object);
197 context.stack().push(!*value);
198 }
199 }
200 Self::GetField { name } => {
201 let object = context.stack().pop::<Reference>().unwrap_or_else(|| {
202 panic!("Could not pop parent object of `{name}` field from stack!")
203 });
204 if object.is_null() {
205 panic!("Trying to read `{name}` field of null reference!");
206 }
207 let value = object
208 .read_object()
209 .unwrap_or_else(|| {
210 panic!("Could not read object of `{name}` field got from stack!")
211 })
212 .read_field::<Reference>(name)
213 .unwrap_or_else(|| {
214 panic!("Could not read `{name}` field of object got from stack!")
215 })
216 .clone();
217 context.stack().push(value);
218 }
219 Self::SetField { name } => {
220 let mut object = context.stack().pop::<Reference>().unwrap_or_else(|| {
221 panic!("Could not pop parent object of `{name}` field from stack!")
222 });
223 if object.is_null() {
224 panic!("Trying to write `{name}` field of null reference!");
225 }
226 let value = context.stack().pop::<Reference>().unwrap();
227 *object
228 .write_object()
229 .unwrap_or_else(|| {
230 panic!("Could not write object of `{name}` field got from stack!")
231 })
232 .write_field::<Reference>(name)
233 .unwrap_or_else(|| {
234 panic!("Could not write `{name}` field of object got from stack!")
235 }) = value;
236 }
237 }
238 }
239}
240
241#[derive(Debug, Clone, Serialize, Deserialize)]
242pub enum SimpletonLiteral {
243 Null,
244 Boolean(Boolean),
245 Integer(Integer),
246 Real(Real),
247 Text(Text),
248 Array {
249 items: Vec<SimpletonExpressionStart>,
250 },
251 Map {
252 items: Vec<(String, SimpletonExpressionStart)>,
253 },
254 Object {
255 name: String,
256 module_name: String,
257 fields: Vec<(String, SimpletonExpressionStart)>,
258 },
259}
260
261impl SimpletonLiteral {
262 pub fn compile(
263 &self,
264 result: &mut Vec<ScriptOperation<SimpletonScriptExpression>>,
265 registers: &mut Vec<String>,
266 closures: &mut Vec<SimpletonFunction>,
267 closures_index: &mut usize,
268 ) -> SimpletonScriptLiteral {
269 match self {
270 Self::Null => SimpletonScriptLiteral::Null,
271 Self::Boolean(value) => SimpletonScriptLiteral::Boolean(*value),
272 Self::Integer(value) => SimpletonScriptLiteral::Integer(*value),
273 Self::Real(value) => SimpletonScriptLiteral::Real(*value),
274 Self::Text(value) => SimpletonScriptLiteral::Text(value.to_owned()),
275 Self::Array { items } => {
276 for item in items.iter().rev() {
277 item.compile(result, registers, closures, closures_index);
278 }
279 SimpletonScriptLiteral::Array {
280 items_count: items.len(),
281 }
282 }
283 Self::Map { items } => {
284 for (key, value) in items.iter().rev() {
285 value.compile(result, registers, closures, closures_index);
286 result.push(ScriptOperation::Expression {
287 expression: SimpletonScriptExpression::Literal(
288 SimpletonScriptLiteral::Text(key.to_owned()),
289 ),
290 });
291 }
292 SimpletonScriptLiteral::Map {
293 items_count: items.len(),
294 }
295 }
296 Self::Object {
297 name,
298 module_name,
299 fields,
300 } => {
301 for (key, value) in fields.iter().rev() {
302 value.compile(result, registers, closures, closures_index);
303 result.push(ScriptOperation::Expression {
304 expression: SimpletonScriptExpression::Literal(
305 SimpletonScriptLiteral::Text(key.to_owned()),
306 ),
307 });
308 }
309 SimpletonScriptLiteral::Object {
310 name: name.to_owned(),
311 module_name: module_name.to_owned(),
312 fields_count: fields.len(),
313 }
314 }
315 }
316 }
317}
318
319#[derive(Debug, Clone, Serialize, Deserialize)]
320pub enum SimpletonExpressionStart {
321 FindStruct {
322 name: String,
323 module_name: String,
324 next: Option<SimpletonExpressionNext>,
325 },
326 FindFunction {
327 name: String,
328 module_name: String,
329 next: Option<SimpletonExpressionNext>,
330 },
331 Closure {
332 captures: Vec<String>,
333 arguments: Vec<String>,
334 statements: Vec<SimpletonStatement>,
335 next: Option<SimpletonExpressionNext>,
336 },
337 Literal {
338 literal: SimpletonLiteral,
339 next: Option<SimpletonExpressionNext>,
340 },
341 GetVariable {
342 name: String,
343 next: Option<SimpletonExpressionNext>,
344 },
345 CallFunction {
346 name: String,
347 module_name: String,
348 arguments: Vec<SimpletonExpressionStart>,
349 next: Option<SimpletonExpressionNext>,
350 },
351}
352
353impl SimpletonExpressionStart {
354 pub fn compile(
355 &self,
356 result: &mut Vec<ScriptOperation<SimpletonScriptExpression>>,
357 registers: &mut Vec<String>,
358 closures: &mut Vec<SimpletonFunction>,
359 closures_index: &mut usize,
360 ) {
361 match self {
362 Self::FindStruct {
363 name,
364 module_name,
365 next,
366 } => {
367 result.push(ScriptOperation::Expression {
368 expression: SimpletonScriptExpression::FindStruct {
369 name: name.to_owned(),
370 module_name: module_name.to_owned(),
371 },
372 });
373 if let Some(next) = next {
374 next.compile(result, registers, closures, closures_index);
375 }
376 }
377 Self::FindFunction {
378 name,
379 module_name,
380 next,
381 } => {
382 result.push(ScriptOperation::Expression {
383 expression: SimpletonScriptExpression::FindFunction {
384 name: name.to_owned(),
385 module_name: module_name.to_owned(),
386 },
387 });
388 if let Some(next) = next {
389 next.compile(result, registers, closures, closures_index);
390 }
391 }
392 Self::Closure {
393 captures,
394 arguments,
395 statements,
396 next,
397 } => {
398 let name = format!("_{}", *closures_index);
399 *closures_index += 1;
400 closures.push(SimpletonFunction {
401 name: name.to_owned(),
402 arguments: captures.iter().chain(arguments.iter()).cloned().collect(),
403 statements: statements.to_owned(),
404 });
405 for capture in captures.iter().rev() {
406 let index = registers.iter().position(|n| n == capture).unwrap();
407 result.push(ScriptOperation::PushFromRegister { index });
408 result.push(ScriptOperation::Expression {
409 expression: SimpletonScriptExpression::StackDuplicate,
410 });
411 result.push(ScriptOperation::PopToRegister { index });
412 }
413 result.push(ScriptOperation::Expression {
414 expression: SimpletonScriptExpression::Literal(SimpletonScriptLiteral::Array {
415 items_count: captures.len(),
416 }),
417 });
418 result.push(ScriptOperation::Expression {
419 expression: SimpletonScriptExpression::FindFunction {
420 name,
421 module_name: CLOSURES.to_owned(),
422 },
423 });
424 result.push(ScriptOperation::CallFunction {
425 query: FunctionQuery {
426 name: Some("new".to_owned().into()),
427 module_name: Some("closure".to_owned().into()),
428 ..Default::default()
429 },
430 });
431 if let Some(next) = next {
432 next.compile(result, registers, closures, closures_index);
433 }
434 }
435 Self::Literal { literal, next } => {
436 let literal = literal.compile(result, registers, closures, closures_index);
437 result.push(ScriptOperation::Expression {
438 expression: SimpletonScriptExpression::Literal(literal),
439 });
440 if let Some(next) = next {
441 next.compile(result, registers, closures, closures_index);
442 }
443 }
444 Self::GetVariable { name, next } => {
445 let index = registers
446 .iter()
447 .position(|n| n == name.as_str())
448 .unwrap_or_else(|| panic!("Variable `{name}` not found!"));
449 result.push(ScriptOperation::PushFromRegister { index });
450 result.push(ScriptOperation::Expression {
451 expression: SimpletonScriptExpression::StackDuplicate,
452 });
453 result.push(ScriptOperation::PopToRegister { index });
454 if let Some(next) = next {
455 next.compile(result, registers, closures, closures_index);
456 }
457 }
458 Self::CallFunction {
459 name,
460 module_name,
461 arguments,
462 next,
463 } => {
464 for argument in arguments.iter().rev() {
465 argument.compile(result, registers, closures, closures_index);
466 }
467 result.push(ScriptOperation::CallFunction {
468 query: FunctionQuery {
469 name: Some(name.to_owned().into()),
470 module_name: Some(module_name.to_owned().into()),
471 ..Default::default()
472 },
473 });
474 if let Some(next) = next {
475 next.compile(result, registers, closures, closures_index);
476 }
477 }
478 }
479 }
480
481 pub fn compile_assign(
482 &self,
483 result: &mut Vec<ScriptOperation<SimpletonScriptExpression>>,
484 registers: &mut Vec<String>,
485 closures: &mut Vec<SimpletonFunction>,
486 closures_index: &mut usize,
487 ) {
488 match self {
489 Self::FindStruct {
490 name,
491 module_name,
492 next,
493 } => {
494 result.push(ScriptOperation::Expression {
495 expression: SimpletonScriptExpression::FindStruct {
496 name: name.to_owned(),
497 module_name: module_name.to_owned(),
498 },
499 });
500 if let Some(next) = next {
501 next.compile(result, registers, closures, closures_index);
502 } else {
503 panic!("Trying to assign value to structure type!");
504 }
505 }
506 Self::FindFunction {
507 name,
508 module_name,
509 next,
510 } => {
511 result.push(ScriptOperation::Expression {
512 expression: SimpletonScriptExpression::FindFunction {
513 name: name.to_owned(),
514 module_name: module_name.to_owned(),
515 },
516 });
517 if let Some(next) = next {
518 next.compile(result, registers, closures, closures_index);
519 } else {
520 panic!("Trying to assign value to function type!");
521 }
522 }
523 Self::Closure {
524 captures,
525 arguments,
526 statements,
527 next,
528 } => {
529 let name = format!("_{}", *closures_index);
530 *closures_index += 1;
531 closures.push(SimpletonFunction {
532 name: name.to_owned(),
533 arguments: captures.iter().chain(arguments.iter()).cloned().collect(),
534 statements: statements.to_owned(),
535 });
536 for capture in captures.iter().rev() {
537 let index = registers.iter().position(|n| n == capture).unwrap();
538 result.push(ScriptOperation::PushFromRegister { index });
539 result.push(ScriptOperation::Expression {
540 expression: SimpletonScriptExpression::StackDuplicate,
541 });
542 result.push(ScriptOperation::PopToRegister { index });
543 }
544 result.push(ScriptOperation::Expression {
545 expression: SimpletonScriptExpression::Literal(SimpletonScriptLiteral::Array {
546 items_count: captures.len(),
547 }),
548 });
549 result.push(ScriptOperation::Expression {
550 expression: SimpletonScriptExpression::FindFunction {
551 name,
552 module_name: CLOSURES.to_owned(),
553 },
554 });
555 result.push(ScriptOperation::CallFunction {
556 query: FunctionQuery {
557 name: Some("new".to_owned().into()),
558 module_name: Some("closure".to_owned().into()),
559 ..Default::default()
560 },
561 });
562 if let Some(next) = next {
563 next.compile(result, registers, closures, closures_index);
564 } else {
565 panic!("Trying to assign value to closure!");
566 }
567 }
568 Self::Literal { literal, next } => {
569 let literal = literal.compile(result, registers, closures, closures_index);
570 result.push(ScriptOperation::Expression {
571 expression: SimpletonScriptExpression::Literal(literal),
572 });
573 if let Some(next) = next {
574 next.compile_assign(result, registers, closures, closures_index);
575 } else {
576 panic!("Trying to assign value to literal!");
577 }
578 }
579 Self::GetVariable { name, next } => {
580 let index = registers.iter().position(|n| n == name.as_str()).unwrap();
581 if let Some(next) = next {
582 result.push(ScriptOperation::PushFromRegister { index });
583 result.push(ScriptOperation::Expression {
584 expression: SimpletonScriptExpression::StackDuplicate,
585 });
586 result.push(ScriptOperation::PopToRegister { index });
587 next.compile_assign(result, registers, closures, closures_index);
588 } else {
589 result.push(ScriptOperation::PopToRegister { index });
590 }
591 }
592 Self::CallFunction {
593 name,
594 module_name,
595 arguments,
596 next,
597 } => {
598 for argument in arguments.iter().rev() {
599 argument.compile(result, registers, closures, closures_index);
600 }
601 result.push(ScriptOperation::CallFunction {
602 query: FunctionQuery {
603 name: Some(name.to_owned().into()),
604 module_name: Some(module_name.to_owned().into()),
605 ..Default::default()
606 },
607 });
608 if let Some(next) = next {
609 next.compile_assign(result, registers, closures, closures_index);
610 } else {
611 panic!("Trying to assign value to function call!");
612 }
613 }
614 }
615 }
616}
617
618#[derive(Debug, Clone, Serialize, Deserialize)]
619pub enum SimpletonExpressionNext {
620 GetField {
621 name: String,
622 next: Option<Box<SimpletonExpressionNext>>,
623 },
624 GetArrayItem {
625 index: Box<SimpletonExpressionStart>,
626 next: Option<Box<SimpletonExpressionNext>>,
627 },
628 GetMapItem {
629 index: Box<SimpletonExpressionStart>,
630 next: Option<Box<SimpletonExpressionNext>>,
631 },
632}
633
634impl SimpletonExpressionNext {
635 pub fn compile(
636 &self,
637 result: &mut Vec<ScriptOperation<SimpletonScriptExpression>>,
638 registers: &mut Vec<String>,
639 closures: &mut Vec<SimpletonFunction>,
640 closures_index: &mut usize,
641 ) {
642 match self {
643 Self::GetField { name, next } => {
644 result.push(ScriptOperation::Expression {
645 expression: SimpletonScriptExpression::GetField {
646 name: name.to_owned(),
647 },
648 });
649 if let Some(next) = next {
650 next.compile(result, registers, closures, closures_index);
651 }
652 }
653 Self::GetArrayItem { index, next } => {
654 index.compile(result, registers, closures, closures_index);
655 result.push(ScriptOperation::Expression {
656 expression: SimpletonScriptExpression::StackSwap,
657 });
658 result.push(ScriptOperation::CallFunction {
659 query: FunctionQuery {
660 name: Some("get".into()),
661 module_name: Some("array".into()),
662 ..Default::default()
663 },
664 });
665 if let Some(next) = next {
666 next.compile(result, registers, closures, closures_index);
667 }
668 }
669 Self::GetMapItem { index, next } => {
670 index.compile(result, registers, closures, closures_index);
671 result.push(ScriptOperation::Expression {
672 expression: SimpletonScriptExpression::StackSwap,
673 });
674 result.push(ScriptOperation::CallFunction {
675 query: FunctionQuery {
676 name: Some("get".into()),
677 module_name: Some("map".into()),
678 ..Default::default()
679 },
680 });
681 if let Some(next) = next {
682 next.compile(result, registers, closures, closures_index);
683 }
684 }
685 }
686 }
687
688 pub fn compile_assign(
689 &self,
690 result: &mut Vec<ScriptOperation<SimpletonScriptExpression>>,
691 registers: &mut Vec<String>,
692 closures: &mut Vec<SimpletonFunction>,
693 closures_index: &mut usize,
694 ) {
695 match self {
696 Self::GetField { name, next } => {
697 if let Some(next) = next {
698 result.push(ScriptOperation::Expression {
699 expression: SimpletonScriptExpression::GetField {
700 name: name.to_owned(),
701 },
702 });
703 next.compile_assign(result, registers, closures, closures_index);
704 } else {
705 result.push(ScriptOperation::Expression {
706 expression: SimpletonScriptExpression::SetField {
707 name: name.to_owned(),
708 },
709 });
710 }
711 }
712 Self::GetArrayItem { index, next } => {
713 if let Some(next) = next {
714 index.compile(result, registers, closures, closures_index);
715 result.push(ScriptOperation::Expression {
716 expression: SimpletonScriptExpression::StackSwap,
717 });
718 result.push(ScriptOperation::CallFunction {
719 query: FunctionQuery {
720 name: Some("get".into()),
721 module_name: Some("array".into()),
722 ..Default::default()
723 },
724 });
725 next.compile_assign(result, registers, closures, closures_index);
726 } else {
727 index.compile(result, registers, closures, closures_index);
728 result.push(ScriptOperation::Expression {
729 expression: SimpletonScriptExpression::StackSwap,
730 });
731 result.push(ScriptOperation::CallFunction {
732 query: FunctionQuery {
733 name: Some("set".into()),
734 module_name: Some("array".into()),
735 ..Default::default()
736 },
737 });
738 result.push(ScriptOperation::Expression {
739 expression: SimpletonScriptExpression::StackDrop,
740 });
741 }
742 }
743 Self::GetMapItem { index, next } => {
744 if let Some(next) = next {
745 index.compile(result, registers, closures, closures_index);
746 result.push(ScriptOperation::Expression {
747 expression: SimpletonScriptExpression::StackSwap,
748 });
749 result.push(ScriptOperation::CallFunction {
750 query: FunctionQuery {
751 name: Some("get".into()),
752 module_name: Some("map".into()),
753 ..Default::default()
754 },
755 });
756 next.compile_assign(result, registers, closures, closures_index);
757 } else {
758 index.compile(result, registers, closures, closures_index);
759 result.push(ScriptOperation::Expression {
760 expression: SimpletonScriptExpression::StackSwap,
761 });
762 result.push(ScriptOperation::CallFunction {
763 query: FunctionQuery {
764 name: Some("set".into()),
765 module_name: Some("map".into()),
766 ..Default::default()
767 },
768 });
769 result.push(ScriptOperation::Expression {
770 expression: SimpletonScriptExpression::StackDrop,
771 });
772 }
773 }
774 }
775 }
776}
777
778#[derive(Debug, Clone, Serialize, Deserialize)]
779pub enum SimpletonStatement {
780 CreateVariable {
781 name: String,
782 value: SimpletonExpressionStart,
783 },
784 AssignValue {
785 object: SimpletonExpressionStart,
786 value: SimpletonExpressionStart,
787 },
788 Expression(SimpletonExpressionStart),
789 Return(SimpletonExpressionStart),
790 IfElse {
791 condition: SimpletonExpressionStart,
792 success: Vec<SimpletonStatement>,
793 failure: Option<Vec<SimpletonStatement>>,
794 },
795 While {
796 condition: SimpletonExpressionStart,
797 statements: Vec<SimpletonStatement>,
798 },
799 For {
800 variable: String,
801 iterator: SimpletonExpressionStart,
802 statements: Vec<SimpletonStatement>,
803 },
804}
805
806impl SimpletonStatement {
807 pub fn recursive_any(&self, f: &impl Fn(&Self) -> bool) -> bool {
808 if f(self) {
809 return true;
810 }
811 match self {
812 Self::IfElse {
813 success, failure, ..
814 } => {
815 for item in success {
816 if item.recursive_any(f) {
817 return true;
818 }
819 }
820 if let Some(failure) = failure.as_ref() {
821 for item in failure {
822 if item.recursive_any(f) {
823 return true;
824 }
825 }
826 }
827 }
828 Self::While { statements, .. } => {
829 for item in statements {
830 if item.recursive_any(f) {
831 return true;
832 }
833 }
834 }
835 Self::For { statements, .. } => {
836 for item in statements {
837 if item.recursive_any(f) {
838 return true;
839 }
840 }
841 }
842 _ => {}
843 }
844 false
845 }
846
847 pub fn compile(
848 &self,
849 result: &mut Vec<ScriptOperation<SimpletonScriptExpression>>,
850 registers: &mut Vec<String>,
851 closures: &mut Vec<SimpletonFunction>,
852 closures_index: &mut usize,
853 subscope_level: usize,
854 ) {
855 match self {
856 Self::CreateVariable { name, value } => {
857 if !registers.iter().any(|n| n == name) {
858 registers.push(name.to_owned());
859 }
860 result.push(ScriptOperation::DefineRegister {
861 query: TypeQuery::of::<Reference>(),
862 });
863 value.compile(result, registers, closures, closures_index);
864 result.push(ScriptOperation::PopToRegister {
865 index: registers.iter().position(|n| n == name).unwrap(),
866 });
867 }
868 Self::AssignValue { object, value } => {
869 value.compile(result, registers, closures, closures_index);
870 object.compile_assign(result, registers, closures, closures_index);
871 }
872 Self::Expression(expression) => {
873 expression.compile(result, registers, closures, closures_index);
874 result.push(ScriptOperation::Expression {
875 expression: SimpletonScriptExpression::StackDrop,
876 });
877 }
878 Self::Return(expression) => {
879 expression.compile(result, registers, closures, closures_index);
880 for _ in 0..(subscope_level + 1) {
881 result.push(ScriptOperation::Expression {
882 expression: SimpletonScriptExpression::Literal(
883 SimpletonScriptLiteral::Boolean(false),
884 ),
885 });
886 result.push(ScriptOperation::Expression {
887 expression: SimpletonScriptExpression::StackUnwrapBoolean,
888 });
889 }
890 result.push(ScriptOperation::ContinueScopeConditionally);
891 }
892 Self::IfElse {
893 condition,
894 success,
895 failure,
896 } => {
897 condition.compile(result, registers, closures, closures_index);
898 result.push(ScriptOperation::Expression {
899 expression: SimpletonScriptExpression::StackUnwrapBoolean,
900 });
901 let mut success_operations = vec![];
903 for statement in success {
904 statement.compile(
905 &mut success_operations,
906 registers,
907 closures,
908 closures_index,
909 subscope_level + 1,
910 );
911 }
912 success_operations.push(ScriptOperation::Expression {
913 expression: SimpletonScriptExpression::Literal(
914 SimpletonScriptLiteral::Boolean(true),
915 ),
916 });
917 success_operations.push(ScriptOperation::Expression {
918 expression: SimpletonScriptExpression::StackUnwrapBoolean,
919 });
920 let mut failure_operations = vec![];
922 if let Some(failure) = failure {
923 for statement in failure {
924 statement.compile(
925 &mut failure_operations,
926 registers,
927 closures,
928 closures_index,
929 subscope_level + 1,
930 );
931 }
932 }
933 failure_operations.push(ScriptOperation::Expression {
934 expression: SimpletonScriptExpression::Literal(
935 SimpletonScriptLiteral::Boolean(true),
936 ),
937 });
938 failure_operations.push(ScriptOperation::Expression {
939 expression: SimpletonScriptExpression::StackUnwrapBoolean,
940 });
941 result.push(ScriptOperation::BranchScope {
943 scope_success: ScriptHandle::new(success_operations),
944 scope_failure: Some(ScriptHandle::new(failure_operations)),
945 });
946 result.push(ScriptOperation::ContinueScopeConditionally);
947 }
948 Self::While {
949 condition,
950 statements,
951 } => {
952 let mut operations = vec![];
953 for statement in statements {
955 if statement.recursive_any(&|statement| {
956 matches!(statement, SimpletonStatement::Return(_))
957 }) {
958 panic!("Cannot return values inside while loops!");
959 }
960 statement.compile(&mut operations, registers, closures, closures_index, 0);
961 }
962 condition.compile(&mut operations, registers, closures, closures_index);
963 operations.push(ScriptOperation::Expression {
964 expression: SimpletonScriptExpression::StackUnwrapBoolean,
965 });
966 condition.compile(result, registers, closures, closures_index);
968 result.push(ScriptOperation::Expression {
969 expression: SimpletonScriptExpression::StackUnwrapBoolean,
970 });
971 result.push(ScriptOperation::LoopScope {
972 scope: ScriptHandle::new(operations),
973 });
974 }
975 Self::For {
976 variable,
977 iterator,
978 statements,
979 } => {
980 let mut operations = vec![];
981 if !registers.iter().any(|n| n == variable) {
983 registers.push(variable.to_owned());
984 }
985 operations.push(ScriptOperation::DefineRegister {
986 query: TypeQuery::of::<Reference>(),
987 });
988 let index = registers
989 .iter()
990 .position(|n| n == variable.as_str())
991 .unwrap();
992 operations.push(ScriptOperation::PopToRegister { index });
993 for statement in statements {
994 if statement.recursive_any(&|statement| {
995 matches!(statement, SimpletonStatement::Return(_))
996 }) {
997 panic!("Cannot return values inside for loops!");
998 }
999 statement.compile(&mut operations, registers, closures, closures_index, 0);
1000 }
1001 operations.push(ScriptOperation::Expression {
1002 expression: SimpletonScriptExpression::StackDuplicate,
1003 });
1004 operations.push(ScriptOperation::CallFunction {
1005 query: FunctionQuery {
1006 name: Some("next".to_owned().into()),
1007 module_name: Some("iter".to_owned().into()),
1008 ..Default::default()
1009 },
1010 });
1011 operations.push(ScriptOperation::Expression {
1012 expression: SimpletonScriptExpression::StackValueOr(false),
1013 });
1014 iterator.compile(result, registers, closures, closures_index);
1016 result.push(ScriptOperation::Expression {
1017 expression: SimpletonScriptExpression::StackDuplicate,
1018 });
1019 result.push(ScriptOperation::CallFunction {
1020 query: FunctionQuery {
1021 name: Some("next".to_owned().into()),
1022 module_name: Some("iter".to_owned().into()),
1023 ..Default::default()
1024 },
1025 });
1026 result.push(ScriptOperation::Expression {
1027 expression: SimpletonScriptExpression::StackValueOr(false),
1028 });
1029 result.push(ScriptOperation::LoopScope {
1030 scope: ScriptHandle::new(operations),
1031 });
1032 result.push(ScriptOperation::Expression {
1033 expression: SimpletonScriptExpression::StackDrop,
1034 });
1035 }
1036 }
1037 }
1038}
1039
1040#[derive(Debug, Clone, Serialize, Deserialize)]
1041pub struct SimpletonFunction {
1042 pub name: String,
1043 pub arguments: Vec<String>,
1044 pub statements: Vec<SimpletonStatement>,
1045}
1046
1047impl SimpletonFunction {
1048 pub fn compile(
1049 &self,
1050 module_name: &str,
1051 closures: &mut Vec<SimpletonFunction>,
1052 closures_index: &mut usize,
1053 ) -> ScriptFunction<'static, SimpletonScriptExpression> {
1054 let signature = ScriptFunctionSignature {
1055 meta: None,
1056 name: self.name.to_owned(),
1057 module_name: Some(module_name.to_owned()),
1058 type_query: None,
1059 visibility: Visibility::Public,
1060 inputs: self
1061 .arguments
1062 .iter()
1063 .map(|name| ScriptFunctionParameter {
1064 meta: None,
1065 name: name.to_owned(),
1066 type_query: TypeQuery::of::<Reference>(),
1067 })
1068 .collect(),
1069 outputs: vec![ScriptFunctionParameter {
1070 meta: None,
1071 name: "result".to_owned(),
1072 type_query: TypeQuery::of::<Reference>(),
1073 }],
1074 };
1075 let mut registers = Vec::new();
1076 let mut operations = vec![];
1077 for name in &self.arguments {
1078 if !registers.iter().any(|n| n == name) {
1079 registers.push(name.to_owned());
1080 }
1081 operations.push(ScriptOperation::DefineRegister {
1082 query: TypeQuery::of::<Reference>(),
1083 });
1084 operations.push(ScriptOperation::PopToRegister {
1085 index: registers.iter().position(|n| n == name).unwrap(),
1086 });
1087 }
1088 for statement in &self.statements {
1089 statement.compile(&mut operations, &mut registers, closures, closures_index, 0);
1090 }
1091 operations.push(ScriptOperation::Expression {
1092 expression: SimpletonScriptExpression::Literal(SimpletonScriptLiteral::Null),
1093 });
1094 ScriptFunction {
1095 signature,
1096 script: ScriptHandle::new(operations),
1097 }
1098 }
1099}
1100
1101#[derive(Debug, Clone, Serialize, Deserialize)]
1102pub struct SimpletonStruct {
1103 pub name: String,
1104 pub fields: Vec<String>,
1105}
1106
1107impl SimpletonStruct {
1108 pub fn compile(&self, module_name: &str) -> ScriptStruct<'static> {
1109 ScriptStruct {
1110 meta: None,
1111 name: self.name.to_owned(),
1112 module_name: Some(module_name.to_owned()),
1113 visibility: Visibility::Public,
1114 fields: self
1115 .fields
1116 .iter()
1117 .map(|name| ScriptStructField {
1118 meta: None,
1119 name: name.to_owned(),
1120 visibility: Visibility::Public,
1121 type_query: TypeQuery::of::<Reference>(),
1122 })
1123 .collect(),
1124 }
1125 }
1126}
1127
1128#[derive(Debug, Clone, Serialize, Deserialize)]
1129pub struct SimpletonModule {
1130 pub name: String,
1131 pub dependencies: Vec<String>,
1132 pub structs: Vec<SimpletonStruct>,
1133 pub functions: Vec<SimpletonFunction>,
1134}
1135
1136impl SimpletonModule {
1137 pub fn parse(content: &str) -> Result<Self, String> {
1138 parser::parse(content)
1139 }
1140
1141 pub fn compile(
1142 &self,
1143 closures: &mut Vec<SimpletonFunction>,
1144 closures_index: &mut usize,
1145 ) -> ScriptModule<'static, SimpletonScriptExpression> {
1146 ScriptModule {
1147 name: self.name.to_owned(),
1148 structs: self
1149 .structs
1150 .iter()
1151 .map(|type_| type_.compile(&self.name))
1152 .collect(),
1153 enums: vec![],
1154 functions: self
1155 .functions
1156 .iter()
1157 .map(|function| function.compile(&self.name, closures, closures_index))
1158 .collect(),
1159 }
1160 }
1161}
1162
1163#[derive(Debug, Default, Clone, Serialize, Deserialize)]
1164pub struct SimpletonPackage {
1165 pub modules: HashMap<String, SimpletonModule>,
1166}
1167
1168impl SimpletonPackage {
1169 pub fn new<CP>(path: &str, content_provider: &mut CP) -> Result<Self, Box<dyn Error>>
1170 where
1171 CP: ScriptContentProvider<SimpletonModule>,
1172 {
1173 let mut result = Self::default();
1174 result.load(path, content_provider)?;
1175 Ok(result)
1176 }
1177
1178 pub fn load<CP>(&mut self, path: &str, content_provider: &mut CP) -> Result<(), Box<dyn Error>>
1179 where
1180 CP: ScriptContentProvider<SimpletonModule>,
1181 {
1182 let path = content_provider.sanitize_path(path)?;
1183 if self.modules.contains_key(&path) {
1184 return Ok(());
1185 }
1186 for content in content_provider.unpack_load(&path)? {
1187 if let Some(module) = content.data? {
1188 let dependencies = module.dependencies.to_owned();
1189 self.modules.insert(content.name, module);
1190 for relative in dependencies {
1191 let path = content_provider.join_paths(&content.path, &relative)?;
1192 self.load(&path, content_provider)?;
1193 }
1194 }
1195 }
1196 Ok(())
1197 }
1198
1199 pub fn compile(&self) -> ScriptPackage<'static, SimpletonScriptExpression> {
1200 let mut closures = vec![];
1201 let mut closures_index = 0;
1202 let mut modules: Vec<ScriptModule<SimpletonScriptExpression>> = self
1203 .modules
1204 .values()
1205 .map(|module| module.compile(&mut closures, &mut closures_index))
1206 .collect();
1207 let mut closure_functions = vec![];
1208 loop {
1209 let mut result = vec![];
1210 for closure in &closures {
1211 closure_functions.push(closure.compile(CLOSURES, &mut result, &mut closures_index));
1212 }
1213 if result.is_empty() {
1214 break;
1215 }
1216 closures = result;
1217 }
1218 modules.push(ScriptModule {
1219 name: CLOSURES.to_owned(),
1220 structs: vec![],
1221 enums: vec![],
1222 functions: closure_functions,
1223 });
1224 ScriptPackage { modules }
1225 }
1226
1227 #[cfg(feature = "plugins")]
1228 pub fn install_plugins(&self, registry: &mut Registry, search_paths: &[&str]) {
1229 use intuicio_core::core_version;
1230 use intuicio_plugins::install_plugin;
1231 use std::env::consts::DLL_EXTENSION;
1232
1233 for module in self.modules.values() {
1234 'plugin: for path in &module.dependencies {
1235 let mut path = PathBuf::from(path);
1236 if path
1237 .extension()
1238 .map(|extension| extension == "plugin")
1239 .unwrap_or_default()
1240 {
1241 path.set_extension(DLL_EXTENSION);
1242 for search_path in search_paths {
1243 let path = PathBuf::from(search_path).join(&path);
1244 if install_plugin(
1245 path.to_string_lossy().as_ref(),
1246 registry,
1247 Some(core_version()),
1248 )
1249 .is_ok()
1250 {
1251 continue 'plugin;
1252 }
1253 }
1254 panic!("Could not load plugin: {path:?}");
1255 }
1256 }
1257 }
1258 }
1259}
1260
1261pub struct SimpletonContentParser;
1262
1263impl BytesContentParser<SimpletonModule> for SimpletonContentParser {
1264 fn parse(&self, bytes: Vec<u8>) -> Result<SimpletonModule, Box<dyn Error>> {
1265 let content = String::from_utf8(bytes)?;
1266 Ok(SimpletonModule::parse(&content)?)
1267 }
1268}
1269
1270#[derive(Debug, Serialize, Deserialize)]
1271pub struct SimpletonBinary {
1272 pub version: IntuicioVersion,
1273 pub modules: Vec<SimpletonModule>,
1274}
1275
1276impl SimpletonBinary {
1277 pub fn archive(
1278 package: SimpletonPackage,
1279 dependencies_filter: impl Fn(&str) -> bool,
1280 ) -> Result<Vec<u8>, Box<dyn Error>> {
1281 let binary = SimpletonBinary {
1282 version: crate_version!(),
1283 modules: package
1284 .modules
1285 .into_values()
1286 .map(|mut module| {
1287 module.dependencies.retain(|path| dependencies_filter(path));
1288 module
1289 })
1290 .collect(),
1291 };
1292 let config = bincode::config::legacy()
1293 .with_big_endian()
1294 .with_no_limit()
1295 .with_fixed_int_encoding();
1296 Ok(bincode::serde::encode_to_vec(&binary, config)?)
1297 }
1298}
1299
1300pub struct SimpletonBinaryFileContentProvider {
1301 extension: String,
1302}
1303
1304impl SimpletonBinaryFileContentProvider {
1305 pub fn new(extension: impl ToString) -> Self {
1306 Self {
1307 extension: extension.to_string(),
1308 }
1309 }
1310}
1311
1312impl ScriptContentProvider<SimpletonModule> for SimpletonBinaryFileContentProvider {
1313 fn load(&mut self, _: &str) -> Result<Option<SimpletonModule>, Box<dyn Error>> {
1314 Ok(None)
1315 }
1316
1317 fn unpack_load(
1318 &mut self,
1319 path: &str,
1320 ) -> Result<Vec<ScriptContent<SimpletonModule>>, Box<dyn Error>> {
1321 let config = bincode::config::legacy()
1322 .with_big_endian()
1323 .with_no_limit()
1324 .with_fixed_int_encoding();
1325 let bytes = std::fs::read(path)?;
1326 let binary = bincode::serde::decode_from_slice::<SimpletonBinary, _>(&bytes, config)?.0;
1327 let version = crate_version!();
1328 if !binary.version.is_compatible(&version) {
1329 return Err(format!(
1330 "Binary version: {} is not compatible with Simpleton version: {}",
1331 binary.version, version
1332 )
1333 .into());
1334 }
1335 Ok(binary
1336 .modules
1337 .into_iter()
1338 .enumerate()
1339 .map(|(index, module)| ScriptContent {
1340 path: path.to_owned(),
1341 name: format!("{path}#{index}"),
1342 data: Ok(Some(module)),
1343 })
1344 .collect())
1345 }
1346
1347 fn sanitize_path(&self, path: &str) -> Result<String, Box<dyn Error>> {
1348 let mut result = PathBuf::from(path);
1349 if result.extension().is_none() {
1350 result.set_extension(&self.extension);
1351 }
1352 Ok(result.canonicalize()?.to_string_lossy().into_owned())
1353 }
1354
1355 fn join_paths(&self, parent: &str, relative: &str) -> Result<String, Box<dyn Error>> {
1356 let mut path = PathBuf::from(parent);
1357 path.pop();
1358 Ok(path.join(relative).to_string_lossy().into_owned())
1359 }
1360}