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