1use piston_meta::{Convert, MetaData};
4use range::Range;
5use std::cell::Cell;
6use std::collections::HashMap;
7use std::sync::{self, Arc};
8
9use crate::{
10 FnIndex,
11 Module,
12 Prelude,
13 Type,
14 Variable
15};
16
17mod infer_len;
18mod replace;
19
20pub fn convert(
22 file: Arc<String>,
23 source: Arc<String>,
24 data: &[Range<MetaData>],
25 ignored: &mut Vec<Range>,
26 module: &mut Module,
27) -> Result<(), ()> {
28 let mut convert = Convert::new(data);
29
30 let namespace = if let Ok((range, val)) = Namespace::from_meta_data(convert, ignored) {
31 convert.update(range);
32 val.names
33 } else {
34 Arc::new(vec![])
35 };
36
37 let use_lookup = if let Ok((range, val)) = Uses::from_meta_data(convert, ignored) {
38 convert.update(range);
39 UseLookup::from_uses_module(&val, module)
40 } else {
41 UseLookup::new()
42 };
43
44 loop {
45 if let Ok((range, function)) =
46 Function::from_meta_data(&namespace, &file, &source, "fn", convert, ignored)
47 {
48 convert.update(range);
49 module.register(function);
50 } else if convert.remaining_data_len() > 0 {
51 return Err(());
52 } else {
53 break;
54 }
55 }
56 let mut new_functions = module.functions.clone();
57 for i in 0..new_functions.len() {
58 new_functions[i].get_locals(i, module, &use_lookup);
59 }
60 module.functions = new_functions;
61 Ok(())
62}
63
64#[derive(Copy, Clone)]
66pub enum FnAlias {
67 Loaded(usize),
69 External(usize),
71}
72
73pub struct UseLookup {
75 pub aliases: HashMap<Arc<String>, HashMap<Arc<String>, FnAlias>>,
79}
80
81impl Default for UseLookup {
82 fn default() -> UseLookup {
83 UseLookup::new()
84 }
85}
86
87impl UseLookup {
88 pub fn new() -> UseLookup {
90 UseLookup {
91 aliases: HashMap::new(),
92 }
93 }
94
95 pub fn from_uses_module(uses: &Uses, module: &Module) -> UseLookup {
97 let mut aliases = HashMap::new();
98 for use_import in &uses.use_imports {
100 if !use_import.fns.is_empty() {
101 continue;
102 }
103 if !aliases.contains_key(&use_import.alias) {
104 aliases.insert(use_import.alias.clone(), HashMap::new());
105 }
106 let fns = aliases.get_mut(&use_import.alias).unwrap();
107 for (i, f) in module.functions.iter().enumerate().rev() {
108 if *f.namespace == use_import.names {
109 fns.insert(f.name.clone(), FnAlias::Loaded(i));
110 }
111 }
112 for (i, f) in module.ext_prelude.iter().enumerate().rev() {
113 if *f.namespace == use_import.names {
114 fns.insert(f.name.clone(), FnAlias::External(i));
115 }
116 }
117 }
118 for use_import in &uses.use_imports {
120 if use_import.fns.is_empty() {
121 continue;
122 }
123 if !aliases.contains_key(&use_import.alias) {
124 aliases.insert(use_import.alias.clone(), HashMap::new());
125 }
126 let fns = aliases.get_mut(&use_import.alias).unwrap();
127 for use_fn in &use_import.fns {
128 for (i, f) in module.functions.iter().enumerate().rev() {
129 if *f.namespace != use_import.names {
130 continue;
131 }
132 if f.name == use_fn.0 {
133 fns.insert(
134 use_fn.1.as_ref().unwrap_or(&use_fn.0).clone(),
135 FnAlias::Loaded(i),
136 );
137 } else if f.name.len() > use_fn.0.len()
138 && f.name.starts_with(&**use_fn.0)
139 && f.name.as_bytes()[use_fn.0.len()] == b'('
140 {
141 let mut name: Arc<String> = use_fn.1.as_ref().unwrap_or(&use_fn.0).clone();
143 Arc::make_mut(&mut name).push_str(&f.name.as_str()[use_fn.0.len()..]);
144 fns.insert(name, FnAlias::Loaded(i));
145 }
146 }
147 for (i, f) in module.ext_prelude.iter().enumerate().rev() {
148 if *f.namespace != use_import.names {
149 continue;
150 }
151 if f.name == use_fn.0 {
152 fns.insert(
153 use_fn.1.as_ref().unwrap_or(&use_fn.0).clone(),
154 FnAlias::External(i),
155 );
156 } else if f.name.len() > use_fn.0.len()
157 && f.name.starts_with(&**use_fn.0)
158 && f.name.as_bytes()[use_fn.0.len()] == b'('
159 {
160 let mut name: Arc<String> = use_fn.1.as_ref().unwrap_or(&use_fn.0).clone();
162 Arc::make_mut(&mut name).push_str(&f.name.as_str()[use_fn.0.len()..]);
163 fns.insert(f.name.clone(), FnAlias::External(i));
164 }
165 }
166 }
167 }
168 UseLookup { aliases }
169 }
170
171 pub fn from_uses_prelude(uses: &Uses, prelude: &Prelude) -> UseLookup {
174 let mut aliases = HashMap::new();
175 for use_import in &uses.use_imports {
177 if !use_import.fns.is_empty() {
178 continue;
179 }
180 if !aliases.contains_key(&use_import.alias) {
181 aliases.insert(use_import.alias.clone(), HashMap::new());
182 }
183 let fns = aliases.get_mut(&use_import.alias).unwrap();
184 for (i, f) in prelude.namespaces.iter().enumerate().rev() {
185 if *f.0 == use_import.names {
186 fns.insert(f.1.clone(), FnAlias::Loaded(i));
187 }
188 }
189 }
190 for use_import in &uses.use_imports {
192 if use_import.fns.is_empty() {
193 continue;
194 }
195 if !aliases.contains_key(&use_import.alias) {
196 aliases.insert(use_import.alias.clone(), HashMap::new());
197 }
198 let fns = aliases.get_mut(&use_import.alias).unwrap();
199 for use_fn in &use_import.fns {
200 for (i, f) in prelude.namespaces.iter().enumerate().rev() {
201 if *f.0 != use_import.names {
202 continue;
203 }
204 if f.1 == use_fn.0 {
205 fns.insert(
206 use_fn.1.as_ref().unwrap_or(&use_fn.0).clone(),
207 FnAlias::Loaded(i),
208 );
209 } else if f.1.len() > use_fn.0.len()
210 && f.1.starts_with(&**use_fn.0)
211 && f.1.as_bytes()[use_fn.0.len()] == b'('
212 {
213 let mut name: Arc<String> = use_fn.1.as_ref().unwrap_or(&use_fn.0).clone();
215 Arc::make_mut(&mut name).push_str(&f.1.as_str()[use_fn.0.len()..]);
216 fns.insert(name, FnAlias::Loaded(i));
217 }
218 }
219 }
220 }
221 UseLookup { aliases }
222 }
223}
224
225#[derive(Debug, Clone)]
229pub struct Namespace {
230 pub names: Arc<Vec<Arc<String>>>,
232}
233
234impl Namespace {
235 pub fn from_meta_data(
237 mut convert: Convert,
238 ignored: &mut Vec<Range>,
239 ) -> Result<(Range, Namespace), ()> {
240 let start = convert;
241 let node = "ns";
242 let start_range = convert.start_node(node)?;
243 convert.update(start_range);
244
245 let mut names: Vec<Arc<String>> = vec![];
246 loop {
247 if let Ok(range) = convert.end_node(node) {
248 convert.update(range);
249 break;
250 } else if let Ok((range, val)) = convert.meta_string("name") {
251 convert.update(range);
252 names.push(val);
253 } else {
254 let range = convert.ignore();
255 convert.update(range);
256 ignored.push(range);
257 }
258 }
259
260 Ok((
261 convert.subtract(start),
262 Namespace {
263 names: Arc::new(names),
264 },
265 ))
266 }
267}
268
269#[derive(Debug, Clone)]
271pub struct Uses {
272 pub use_imports: Vec<UseImport>,
274}
275
276impl Uses {
277 pub fn from_meta_data(
279 mut convert: Convert,
280 ignored: &mut Vec<Range>,
281 ) -> Result<(Range, Uses), ()> {
282 let start = convert;
283 let node = "uses";
284 let start_range = convert.start_node(node)?;
285 convert.update(start_range);
286
287 let mut use_imports = vec![];
288 loop {
289 if let Ok(range) = convert.end_node(node) {
290 convert.update(range);
291 break;
292 } else if let Ok((range, val)) = UseImport::from_meta_data(convert, ignored) {
293 convert.update(range);
294 use_imports.push(val);
295 } else {
296 let range = convert.ignore();
297 convert.update(range);
298 ignored.push(range);
299 }
300 }
301
302 Ok((convert.subtract(start), Uses { use_imports }))
303 }
304}
305
306#[derive(Debug, Clone)]
308pub struct UseImport {
309 pub names: Vec<Arc<String>>,
311 pub fns: Vec<(Arc<String>, Option<Arc<String>>)>,
313 pub alias: Arc<String>,
315}
316
317impl UseImport {
318 pub fn from_meta_data(
320 mut convert: Convert,
321 ignored: &mut Vec<Range>,
322 ) -> Result<(Range, UseImport), ()> {
323 let start = convert;
324 let node = "use";
325 let start_range = convert.start_node(node)?;
326 convert.update(start_range);
327
328 let mut names: Vec<Arc<String>> = vec![];
329 let mut alias: Option<Arc<String>> = None;
330 let mut fns = vec![];
331 loop {
332 if let Ok(range) = convert.end_node(node) {
333 convert.update(range);
334 break;
335 } else if let Ok((range, val)) = convert.meta_string("name") {
336 convert.update(range);
337 names.push(val);
338 } else if let Ok((range, val)) = convert.meta_string("use_fn") {
339 convert.update(range);
340
341 let fn_alias = if let Ok((range, val)) = convert.meta_string("use_fn_alias") {
342 convert.update(range);
343 Some(val)
344 } else {
345 None
346 };
347 fns.push((val, fn_alias));
348 } else if let Ok((range, val)) = convert.meta_string("alias") {
349 convert.update(range);
350 alias = Some(val);
351 } else {
352 let range = convert.ignore();
353 convert.update(range);
354 ignored.push(range);
355 }
356 }
357
358 let alias = alias.ok_or(())?;
359 Ok((convert.subtract(start), UseImport { names, fns, alias }))
360 }
361}
362
363#[derive(Debug, Clone)]
365pub struct Function {
366 pub namespace: Arc<Vec<Arc<String>>>,
368 pub name: Arc<String>,
370 pub file: Arc<String>,
372 pub source: Arc<String>,
374 pub args: Vec<Arg>,
376 pub lazy_inv: Vec<Vec<Lazy>>,
378 pub currents: Vec<Current>,
380 pub block: Block,
382 pub ret: Type,
384 pub looked_up: Arc<sync::atomic::AtomicBool>,
386 pub source_range: Range,
388 pub senders: Arc<(
390 sync::atomic::AtomicBool,
391 sync::Mutex<Vec<sync::mpsc::Sender<Variable>>>,
392 )>,
393}
394
395impl Function {
396 pub fn from_meta_data(
398 namespace: &Arc<Vec<Arc<String>>>,
399 file: &Arc<String>,
400 source: &Arc<String>,
401 node: &str,
402 mut convert: Convert,
403 ignored: &mut Vec<Range>,
404 ) -> Result<(Range, Function), ()> {
405 use std::sync::atomic::AtomicBool;
406 use std::sync::Mutex;
407
408 let start = convert;
409 let start_range = convert.start_node(node)?;
410 convert.update(start_range);
411
412 let mut name: Option<Arc<String>> = None;
413 let mut args: Vec<Arg> = vec![];
414 let mut currents: Vec<Current> = vec![];
415 let mut block: Option<Block> = None;
416 let mut expr: Option<Expression> = None;
417 let mut ret: Option<Type> = None;
418 let mut lazy_inv: Vec<Vec<Lazy>> = vec![];
419 loop {
420 if let Ok(range) = convert.end_node(node) {
421 convert.update(range);
422 break;
423 } else if let Ok((range, val)) = convert.meta_string("name") {
424 convert.update(range);
425 name = Some(val);
426 } else if let Ok((range, val, lazy)) =
427 Arg::from_meta_data(file, source, convert, ignored)
428 {
429 convert.update(range);
430 args.push(val);
431 lazy_inv.push(lazy);
432 } else if let Ok((range, val)) = Current::from_meta_data(convert, ignored) {
433 convert.update(range);
434 currents.push(val);
435 } else if let Ok((range, val)) = convert.meta_bool("returns") {
436 convert.update(range);
437 ret = Some(if val { Type::Any } else { Type::Void })
438 } else if let Ok((range, val)) = Type::from_meta_data("ret_type", convert, ignored) {
439 convert.update(range);
440 ret = Some(val);
441 } else if let Ok((range, val)) =
442 Block::from_meta_data(file, source, "block", convert, ignored)
443 {
444 convert.update(range);
445 block = Some(val);
446 } else if let Ok((range, val)) =
447 Expression::from_meta_data(file, source, "expr", convert, ignored)
448 {
449 convert.update(range);
450 expr = Some(val);
451 ret = Some(Type::Any);
452 } else if convert.start_node("ty").is_ok() {
453 let range = convert.ignore();
456 convert.update(range);
457 } else {
458 let range = convert.ignore();
459 convert.update(range);
460 ignored.push(range);
461 }
462 }
463
464 let mut name = name.ok_or(())?;
465 let block = match expr {
466 None => block.ok_or(())?,
467 Some(expr) => {
468 let source_range = expr.source_range();
469 Block {
470 expressions: vec![Expression::Return(Box::new(expr))],
471 source_range,
472 }
473 }
474 };
475 let mutable_args = args.iter().any(|arg| arg.mutable);
476 if mutable_args {
477 let mut name_plus_args = String::from(&**name);
478 name_plus_args.push('(');
479 let mut first = true;
480 for arg in &args {
481 if !first {
482 name_plus_args.push(',');
483 }
484 name_plus_args.push_str(if arg.mutable { "mut" } else { "_" });
485 first = false;
486 }
487 name_plus_args.push(')');
488 name = Arc::new(name_plus_args);
489 }
490 let ret = ret.ok_or(())?;
491 while let Some(true) = lazy_inv.last().map(|lz| lz.is_empty()) {
493 lazy_inv.pop();
494 }
495 Ok((
496 convert.subtract(start),
497 Function {
498 namespace: namespace.clone(),
499 looked_up: Arc::new(AtomicBool::new(false)),
500 name,
501 file: file.clone(),
502 source: source.clone(),
503 args,
504 lazy_inv,
505 currents,
506 block,
507 ret,
508 source_range: convert.source(start).unwrap(),
509 senders: Arc::new((AtomicBool::new(false), Mutex::new(vec![]))),
510 },
511 ))
512 }
513
514 pub fn returns(&self) -> bool {
516 self.ret != Type::Void
517 }
518
519 fn get_locals(&mut self, relative: usize, module: &Module, use_lookup: &UseLookup) {
520 use std::sync::atomic::Ordering;
521
522 if self.looked_up.load(Ordering::SeqCst) {
524 return;
525 }
526 let mut stack: Vec<Option<Arc<String>>> = vec![];
527 let mut closure_stack: Vec<usize> = vec![];
528 if self.returns() {
529 stack.push(Some(crate::runtime::RETURN_TYPE.clone()));
531 }
532 for arg in &self.args {
533 stack.push(Some(arg.name.clone()));
534 }
535 for current in &self.currents {
536 stack.push(Some(current.name.clone()));
537 }
538 self.block.get_locals(relative, &mut stack, &mut closure_stack, module, use_lookup);
539 self.looked_up.store(true, Ordering::SeqCst);
540 }
541}
542
543#[derive(Debug, Clone)]
545pub struct Closure {
546 pub file: Arc<String>,
548 pub source: Arc<String>,
550 pub args: Vec<Arg>,
552 pub currents: Vec<Current>,
554 pub expr: Expression,
556 pub ret: Type,
558 pub source_range: Range,
560}
561
562impl Closure {
563 pub fn from_meta_data(
565 file: &Arc<String>,
566 source: &Arc<String>,
567 node: &str,
568 mut convert: Convert,
569 ignored: &mut Vec<Range>,
570 ) -> Result<(Range, Closure), ()> {
571 let start = convert;
572 let start_range = convert.start_node(node)?;
573 convert.update(start_range);
574
575 let mut args: Vec<Arg> = vec![];
576 let mut currents: Vec<Current> = vec![];
577 let mut expr: Option<Expression> = None;
578 let mut ret: Option<Type> = None;
579 loop {
580 if let Ok(range) = convert.end_node(node) {
581 convert.update(range);
582 break;
583 } else if let Ok((range, val, _)) = Arg::from_meta_data(file, source, convert, ignored)
584 {
585 convert.update(range);
586 args.push(val);
587 } else if let Ok((range, val)) = Current::from_meta_data(convert, ignored) {
588 convert.update(range);
589 currents.push(val);
590 } else if let Ok((range, val)) = convert.meta_bool("returns") {
591 convert.update(range);
592 ret = Some(if val { Type::Any } else { Type::Void })
593 } else if let Ok((range, val)) = Type::from_meta_data("ret_type", convert, ignored) {
594 convert.update(range);
595 ret = Some(val);
596 } else if let Ok((range, val)) =
597 Expression::from_meta_data(file, source, "expr", convert, ignored)
598 {
599 convert.update(range);
600 expr = Some(val);
601 ret = Some(Type::Any);
602 } else {
603 let range = convert.ignore();
604 convert.update(range);
605 ignored.push(range);
606 }
607 }
608
609 let ret = ret.ok_or(())?;
610 let expr = expr.ok_or(())?;
611 Ok((
612 convert.subtract(start),
613 Closure {
614 file: file.clone(),
615 source: source.clone(),
616 args,
617 currents,
618 expr,
619 ret,
620 source_range: convert.source(start).unwrap(),
621 },
622 ))
623 }
624
625 pub fn returns(&self) -> bool {
627 self.ret != Type::Void
628 }
629
630 fn get_locals(
631 &mut self,
632 relative: usize,
633 stack: &mut Vec<Option<Arc<String>>>,
634 closure_stack: &mut Vec<usize>,
635 module: &Module,
636 use_lookup: &UseLookup,
637 ) {
638 let cs = closure_stack.len();
642 closure_stack.push(stack.len());
643 if self.returns() {
644 stack.push(Some(crate::runtime::RETURN_TYPE.clone()));
646 }
647 for arg in &self.args {
648 stack.push(Some(arg.name.clone()));
649 }
650 for current in &self.currents {
651 stack.push(Some(current.name.clone()));
652 }
653 self.expr.get_locals(relative, stack, closure_stack, module, use_lookup);
654 closure_stack.truncate(cs);
655 }
656}
657
658#[derive(Debug, Clone)]
660pub struct Grab {
661 pub level: u16,
663 pub expr: Expression,
665 pub source_range: Range,
667}
668
669impl Grab {
670 pub fn from_meta_data(
672 file: &Arc<String>,
673 source: &Arc<String>,
674 mut convert: Convert,
675 ignored: &mut Vec<Range>,
676 ) -> Result<(Range, Grab), ()> {
677 let start = convert;
678 let node = "grab";
679 let start_range = convert.start_node(node)?;
680 convert.update(start_range);
681
682 let mut level: Option<u16> = None;
683 let mut expr: Option<Expression> = None;
684 loop {
685 if let Ok(range) = convert.end_node(node) {
686 convert.update(range);
687 break;
688 } else if let Ok((range, val)) = convert.meta_f64("grab_level") {
689 convert.update(range);
690 level = Some(val as u16);
691 } else if let Ok((range, val)) =
692 Expression::from_meta_data(file, source, "expr", convert, ignored)
693 {
694 convert.update(range);
695 expr = Some(val);
696 } else {
697 let range = convert.ignore();
698 convert.update(range);
699 ignored.push(range);
700 }
701 }
702
703 let level = level.unwrap_or(1);
704 let expr = expr.ok_or(())?;
705 Ok((
706 convert.subtract(start),
707 Grab {
708 level,
709 expr,
710 source_range: convert.source(start).unwrap(),
711 },
712 ))
713 }
714
715 fn precompute(&self) -> Option<Variable> {
716 self.expr.precompute()
717 }
718
719 fn get_locals(
720 &mut self,
721 relative: usize,
722 stack: &mut Vec<Option<Arc<String>>>,
723 closure_stack: &mut Vec<usize>,
724 module: &Module,
725 use_lookup: &UseLookup,
726 ) {
727 let d = if closure_stack.len() < self.level as usize {
729 0
732 } else {
733 closure_stack.len() - self.level as usize
734 };
735 let last = match closure_stack.get(d) {
736 None => return,
737 Some(&x) => x,
738 };
739 let mut tmp_stack: Vec<_> = stack[0..last].into();
741 self.expr.get_locals(relative, &mut tmp_stack, closure_stack, module, use_lookup)
742 }
743}
744
745#[derive(Debug, Clone)]
749pub struct TryExpr {
750 pub expr: Expression,
752 pub source_range: Range,
754}
755
756impl TryExpr {
757 pub fn from_meta_data(
759 file: &Arc<String>,
760 source: &Arc<String>,
761 mut convert: Convert,
762 ignored: &mut Vec<Range>,
763 ) -> Result<(Range, TryExpr), ()> {
764 let start = convert;
765 let node = "try_expr";
766 let start_range = convert.start_node(node)?;
767 convert.update(start_range);
768
769 let mut expr: Option<Expression> = None;
770 loop {
771 if let Ok(range) = convert.end_node(node) {
772 convert.update(range);
773 break;
774 } else if let Ok((range, val)) =
775 Expression::from_meta_data(file, source, "expr", convert, ignored)
776 {
777 convert.update(range);
778 expr = Some(val);
779 } else {
780 let range = convert.ignore();
781 convert.update(range);
782 ignored.push(range);
783 }
784 }
785
786 let expr = expr.ok_or(())?;
787 Ok((
788 convert.subtract(start),
789 TryExpr {
790 expr,
791 source_range: convert.source(start).unwrap(),
792 },
793 ))
794 }
795
796 fn get_locals(
797 &mut self,
798 relative: usize,
799 stack: &mut Vec<Option<Arc<String>>>,
800 closure_stack: &mut Vec<usize>,
801 module: &Module,
802 use_lookup: &UseLookup,
803 ) {
804 self.expr.get_locals(relative, stack, closure_stack, module, use_lookup)
805 }
806}
807
808#[derive(Debug, Clone, PartialEq)]
810pub enum Lazy {
811 Variable(Variable),
813 UnwrapOk,
815 UnwrapErr,
817 UnwrapSome,
819}
820
821unsafe impl Sync for Lazy {}
825
826#[derive(Debug, Clone)]
828pub struct Arg {
829 pub name: Arc<String>,
831 pub lifetime: Option<Arc<String>>,
833 pub ty: Type,
835 pub source_range: Range,
837 pub mutable: bool,
839}
840
841impl Arg {
842 pub fn from_meta_data(
844 file: &Arc<String>,
845 source: &Arc<String>,
846 mut convert: Convert,
847 ignored: &mut Vec<Range>,
848 ) -> Result<(Range, Arg, Vec<Lazy>), ()> {
849 let start = convert;
850 let node = "arg";
851 let start_range = convert.start_node(node)?;
852 convert.update(start_range);
853
854 let mut name: Option<Arc<String>> = None;
855 let mut lifetime: Option<Arc<String>> = None;
856 let mut ty: Option<Type> = None;
857 let mut mutable = false;
858 let mut lazy: Vec<Lazy> = vec![];
859 loop {
860 if let Ok(range) = convert.end_node(node) {
861 convert.update(range);
862 break;
863 } else if let Ok((range, val)) = convert.meta_bool("mut") {
864 convert.update(range);
865 mutable = val;
866 } else if let Ok((range, val)) = convert.meta_string("name") {
867 convert.update(range);
868 name = Some(val);
869 } else if let Ok((range, val)) = convert.meta_string("lifetime") {
870 convert.update(range);
871 lifetime = Some(val);
872 } else if let Ok((range, val)) = Type::from_meta_data("type", convert, ignored) {
873 convert.update(range);
874 ty = Some(val);
875 } else if let Ok((range, val)) = Grab::from_meta_data(file, source, convert, ignored) {
876 convert.update(range);
877 if let Some(val) = val.precompute() {
878 lazy.push(Lazy::Variable(val));
879 } else {
880 return Err(());
881 }
882 } else if let Ok((range, _)) = convert.meta_bool("ok(_)") {
883 convert.update(range);
884 lazy.push(Lazy::UnwrapOk);
885 } else if let Ok((range, _)) = convert.meta_bool("err(_)") {
886 convert.update(range);
887 lazy.push(Lazy::UnwrapErr);
888 } else if let Ok((range, _)) = convert.meta_bool("some(_)") {
889 convert.update(range);
890 lazy.push(Lazy::UnwrapSome);
891 } else {
892 let range = convert.ignore();
893 convert.update(range);
894 ignored.push(range);
895 }
896 }
897
898 let name = name.ok_or(())?;
899 let ty = match ty {
900 None => Type::Any,
901 Some(ty) => ty,
902 };
903 Ok((
904 convert.subtract(start),
905 Arg {
906 name,
907 lifetime,
908 ty,
909 source_range: convert.source(start).unwrap(),
910 mutable,
911 },
912 lazy,
913 ))
914 }
915}
916
917#[derive(Debug, Clone)]
921pub struct Current {
922 pub name: Arc<String>,
924 pub source_range: Range,
926 pub mutable: bool,
928}
929
930impl Current {
931 pub fn from_meta_data(
933 mut convert: Convert,
934 ignored: &mut Vec<Range>,
935 ) -> Result<(Range, Current), ()> {
936 let start = convert;
937 let node = "current";
938 let start_range = convert.start_node(node)?;
939 convert.update(start_range);
940
941 let mut name: Option<Arc<String>> = None;
942 let mut mutable = false;
943 loop {
944 if let Ok(range) = convert.end_node(node) {
945 convert.update(range);
946 break;
947 } else if let Ok((range, val)) = convert.meta_bool("mut") {
948 convert.update(range);
949 mutable = val;
950 } else if let Ok((range, val)) = convert.meta_string("name") {
951 convert.update(range);
952 name = Some(val);
953 } else if let Ok((range, _)) = Type::from_meta_data("type", convert, ignored) {
954 convert.update(range);
955 } else {
957 let range = convert.ignore();
958 convert.update(range);
959 ignored.push(range);
960 }
961 }
962
963 let name = name.ok_or(())?;
964 Ok((
965 convert.subtract(start),
966 Current {
967 name,
968 source_range: convert.source(start).unwrap(),
969 mutable,
970 },
971 ))
972 }
973}
974
975#[derive(Debug, Clone)]
977pub struct Block {
978 pub expressions: Vec<Expression>,
980 pub source_range: Range,
982}
983
984impl Block {
985 pub fn from_meta_data(
987 file: &Arc<String>,
988 source: &Arc<String>,
989 node: &str,
990 mut convert: Convert,
991 ignored: &mut Vec<Range>,
992 ) -> Result<(Range, Block), ()> {
993 let start = convert;
994 let start_range = convert.start_node(node)?;
995 convert.update(start_range);
996
997 let mut expressions = vec![];
998 loop {
999 if let Ok(range) = convert.end_node(node) {
1000 convert.update(range);
1001 break;
1002 } else if let Ok((range, val)) =
1003 Expression::from_meta_data(file, source, "expr", convert, ignored)
1004 {
1005 convert.update(range);
1006 expressions.push(val);
1007 } else {
1008 let range = convert.ignore();
1009 convert.update(range);
1010 ignored.push(range);
1011 }
1012 }
1013
1014 Ok((
1015 convert.subtract(start),
1016 Block {
1017 expressions,
1018 source_range: convert.source(start).unwrap(),
1019 },
1020 ))
1021 }
1022
1023 fn get_locals(
1024 &mut self,
1025 relative: usize,
1026 stack: &mut Vec<Option<Arc<String>>>,
1027 closure_stack: &mut Vec<usize>,
1028 module: &Module,
1029 use_lookup: &UseLookup,
1030 ) {
1031 let st = stack.len();
1032 for expr in &mut self.expressions {
1033 expr.get_locals(relative, stack, closure_stack, module, use_lookup);
1034 }
1035 stack.truncate(st);
1036 }
1037}
1038
1039#[derive(Debug, Clone)]
1041pub enum Expression {
1042 Link(Box<Link>),
1044 Object(Box<Object>),
1046 Array(Box<Array>),
1048 ArrayFill(Box<ArrayFill>),
1050 Return(Box<Expression>),
1052 ReturnVoid(Box<Range>),
1054 Break(Box<Break>),
1056 Continue(Box<Continue>),
1058 Block(Box<Block>),
1060 Go(Box<Go>),
1062 Call(Box<Call>),
1064 CallVoid(Box<CallVoid>),
1066 CallReturn(Box<CallReturn>),
1068 CallLazy(Box<CallLazy>),
1070 CallLoaded(Box<CallLoaded>),
1072 CallBinOp(Box<CallBinOp>),
1074 CallUnOp(Box<CallUnOp>),
1076 Item(Box<Item>),
1078 Assign(Box<Assign>),
1080 Vec4(Box<Vec4>),
1082 Mat4(Box<Mat4>),
1084 For(Box<For>),
1086 ForN(Box<ForN>),
1088 ForIn(Box<ForIn>),
1090 Sum(Box<ForN>),
1092 SumIn(Box<ForIn>),
1094 SumVec4(Box<ForN>),
1096 Prod(Box<ForN>),
1098 ProdIn(Box<ForIn>),
1100 ProdVec4(Box<ForN>),
1102 Min(Box<ForN>),
1104 MinIn(Box<ForIn>),
1106 Max(Box<ForN>),
1108 MaxIn(Box<ForIn>),
1110 Sift(Box<ForN>),
1112 SiftIn(Box<ForIn>),
1114 Any(Box<ForN>),
1116 AnyIn(Box<ForIn>),
1118 All(Box<ForN>),
1120 AllIn(Box<ForIn>),
1122 LinkFor(Box<ForN>),
1124 LinkIn(Box<ForIn>),
1126 If(Box<If>),
1128 Variable(Box<(Range, Variable)>),
1132 Try(Box<Expression>),
1134 Swizzle(Box<Swizzle>),
1136 Closure(Arc<Closure>),
1138 CallClosure(Box<CallClosure>),
1140 Grab(Box<Grab>),
1142 TryExpr(Box<TryExpr>),
1144 In(Box<In>),
1146}
1147
1148unsafe impl Sync for Expression {}
1150
1151impl Expression {
1152 pub fn from_meta_data(
1154 file: &Arc<String>,
1155 source: &Arc<String>,
1156 node: &str,
1157 mut convert: Convert,
1158 ignored: &mut Vec<Range>,
1159 ) -> Result<(Range, Expression), ()> {
1160 let start = convert;
1161 let start_range = convert.start_node(node)?;
1162 convert.update(start_range);
1163
1164 let mut result: Option<Expression> = None;
1165 loop {
1166 if let Ok(range) = convert.end_node(node) {
1167 convert.update(range);
1168 break;
1169 } else if let Ok((range, _)) = convert.meta_bool("mut") {
1170 convert.update(range);
1172 } else if let Ok((range, val)) = Link::from_meta_data(file, source, convert, ignored) {
1173 convert.update(range);
1174 result = Some(Expression::Link(Box::new(val)));
1175 } else if let Ok((range, val)) = Object::from_meta_data(file, source, convert, ignored)
1176 {
1177 convert.update(range);
1178 result = Some(Expression::Object(Box::new(val)));
1179 } else if let Ok((range, val)) = Array::from_meta_data(file, source, convert, ignored) {
1180 convert.update(range);
1181 result = Some(Expression::Array(Box::new(val)));
1182 } else if let Ok((range, val)) =
1183 ArrayFill::from_meta_data(file, source, convert, ignored)
1184 {
1185 convert.update(range);
1186 result = Some(Expression::ArrayFill(Box::new(val)));
1187 } else if let Ok((range, val)) =
1188 Expression::from_meta_data(file, source, "return", convert, ignored)
1189 {
1190 convert.update(range);
1191 result = Some(Expression::Return(Box::new(val)));
1192 } else if let Ok((range, _)) = convert.meta_bool("return_void") {
1193 convert.update(range);
1194 result = Some(Expression::ReturnVoid(Box::new(
1195 convert.source(start).unwrap(),
1196 )));
1197 } else if let Ok((range, val)) = Break::from_meta_data(convert, ignored) {
1198 convert.update(range);
1199 result = Some(Expression::Break(Box::new(val)));
1200 } else if let Ok((range, val)) = Continue::from_meta_data(convert, ignored) {
1201 convert.update(range);
1202 result = Some(Expression::Continue(Box::new(val)));
1203 } else if let Ok((range, val)) =
1204 Block::from_meta_data(file, source, "block", convert, ignored)
1205 {
1206 convert.update(range);
1207 result = Some(Expression::Block(Box::new(val)));
1208 } else if let Ok((range, val)) =
1209 BinOpSeq::from_meta_data(file, source, "add", convert, ignored)
1210 {
1211 convert.update(range);
1212 result = Some(val.into_expression());
1213 } else if let Ok((range, val)) =
1214 UnOpExpression::from_meta_data("not", file, source, convert, ignored)
1215 {
1216 convert.update(range);
1217 result = Some(val);
1218 } else if let Ok((range, val)) =
1219 BinOpSeq::from_meta_data(file, source, "mul", convert, ignored)
1220 {
1221 convert.update(range);
1222 result = Some(val.into_expression());
1223 } else if let Ok((range, val)) =
1224 BinOpSeq::from_meta_data(file, source, "compare", convert, ignored)
1225 {
1226 convert.update(range);
1227 result = Some(val.into_expression());
1228 } else if let Ok((range, val)) = Item::from_meta_data(file, source, convert, ignored) {
1229 convert.update(range);
1230 result = Some(Expression::Item(Box::new(val)));
1231 } else if let Ok((range, val)) = Norm::from_meta_data(file, source, convert, ignored) {
1232 convert.update(range);
1233 result = Some(val.into_call_expr());
1234 } else if let Ok((range, val)) = convert.meta_string("text") {
1235 convert.update(range);
1236 result = Some(Expression::Variable(Box::new((
1237 convert.source(start).unwrap(),
1238 Variable::Str(val),
1239 ))));
1240 } else if let Ok((range, val)) = convert.meta_f64("num") {
1241 convert.update(range);
1242 result = Some(Expression::Variable(Box::new((
1243 convert.source(start).unwrap(),
1244 Variable::f64(val),
1245 ))));
1246 } else if let Ok((range, val)) = Vec4::from_meta_data(file, source, convert, ignored) {
1247 convert.update(range);
1248 result = Some(Expression::Vec4(Box::new(val)));
1249 } else if let Ok((range, val)) = Mat4::from_meta_data(file, source, convert, ignored) {
1250 convert.update(range);
1251 result = Some(Expression::Mat4(Box::new(val)));
1252 } else if let Ok((range, val)) =
1253 Vec4UnLoop::from_meta_data(file, source, convert, ignored)
1254 {
1255 convert.update(range);
1256 result = Some(val.into_expression());
1257 } else if let Ok((range, val)) = convert.meta_bool("bool") {
1258 convert.update(range);
1259 result = Some(Expression::Variable(Box::new((
1260 convert.source(start).unwrap(),
1261 Variable::bool(val),
1262 ))));
1263 } else if let Ok((range, val)) = convert.meta_string("color") {
1264 convert.update(range);
1265 if let Some((rgb, a)) = read_color::rgb_maybe_a(&mut val.chars()) {
1266 let v = [
1267 f32::from(rgb[0]) / 255.0,
1268 f32::from(rgb[1]) / 255.0,
1269 f32::from(rgb[2]) / 255.0,
1270 f32::from(a.unwrap_or(255)) / 255.0,
1271 ];
1272 result = Some(Expression::Variable(Box::new((range, Variable::Vec4(v)))));
1273 } else {
1274 return Err(());
1275 }
1276 } else if let Ok((range, val)) = Go::from_meta_data(file, source, convert, ignored) {
1277 convert.update(range);
1278 result = Some(Expression::Go(Box::new(val)));
1279 } else if let Ok((range, val)) = Call::from_meta_data(file, source, convert, ignored) {
1280 convert.update(range);
1281 result = Some(Expression::Call(Box::new(val)));
1282 } else if let Ok((range, val)) =
1283 Call::named_from_meta_data(file, source, convert, ignored)
1284 {
1285 convert.update(range);
1286 result = Some(Expression::Call(Box::new(val)));
1287 } else if let Ok((range, val)) = Assign::from_meta_data(file, source, convert, ignored)
1288 {
1289 convert.update(range);
1290 result = Some(Expression::Assign(Box::new(val)));
1291 } else if let Ok((range, val)) = For::from_meta_data(file, source, convert, ignored) {
1292 convert.update(range);
1293 result = Some(Expression::For(Box::new(val)));
1294 } else if let Ok((range, val)) =
1295 ForN::from_meta_data(file, source, "for_n", convert, ignored)
1296 {
1297 convert.update(range);
1298 result = Some(Expression::ForN(Box::new(val)));
1299 } else if let Ok((range, val)) =
1300 ForN::from_meta_data(file, source, "sum", convert, ignored)
1301 {
1302 convert.update(range);
1303 result = Some(Expression::Sum(Box::new(val)));
1304 } else if let Ok((range, val)) =
1305 ForN::from_meta_data(file, source, "sum_vec4", convert, ignored)
1306 {
1307 convert.update(range);
1308 result = Some(Expression::SumVec4(Box::new(val)));
1309 } else if let Ok((range, val)) =
1310 ForN::from_meta_data(file, source, "prod", convert, ignored)
1311 {
1312 convert.update(range);
1313 result = Some(Expression::Prod(Box::new(val)));
1314 } else if let Ok((range, val)) =
1315 ForN::from_meta_data(file, source, "prod_vec4", convert, ignored)
1316 {
1317 convert.update(range);
1318 result = Some(Expression::ProdVec4(Box::new(val)));
1319 } else if let Ok((range, val)) =
1320 ForN::from_meta_data(file, source, "min", convert, ignored)
1321 {
1322 convert.update(range);
1323 result = Some(Expression::Min(Box::new(val)));
1324 } else if let Ok((range, val)) =
1325 ForN::from_meta_data(file, source, "max", convert, ignored)
1326 {
1327 convert.update(range);
1328 result = Some(Expression::Max(Box::new(val)));
1329 } else if let Ok((range, val)) =
1330 ForN::from_meta_data(file, source, "sift", convert, ignored)
1331 {
1332 convert.update(range);
1333 result = Some(Expression::Sift(Box::new(val)));
1334 } else if let Ok((range, val)) =
1335 ForN::from_meta_data(file, source, "any", convert, ignored)
1336 {
1337 convert.update(range);
1338 result = Some(Expression::Any(Box::new(val)));
1339 } else if let Ok((range, val)) =
1340 ForN::from_meta_data(file, source, "all", convert, ignored)
1341 {
1342 convert.update(range);
1343 result = Some(Expression::All(Box::new(val)));
1344 } else if let Ok((range, val)) =
1345 ForN::from_meta_data(file, source, "link_for", convert, ignored)
1346 {
1347 convert.update(range);
1348 result = Some(Expression::LinkFor(Box::new(val)));
1349 } else if let Ok((range, val)) = Loop::from_meta_data(file, source, convert, ignored) {
1350 convert.update(range);
1351 result = Some(val.into_expression());
1352 } else if let Ok((range, val)) = If::from_meta_data(file, source, convert, ignored) {
1353 convert.update(range);
1354 result = Some(Expression::If(Box::new(val)));
1355 } else if let Ok((range, _)) = convert.meta_bool("try") {
1356 convert.update(range);
1357 result = Some(Expression::Try(Box::new(result.unwrap())));
1358 } else if let Ok((range, val)) = Swizzle::from_meta_data(file, source, convert, ignored)
1359 {
1360 convert.update(range);
1361 result = Some(Expression::Swizzle(Box::new(val)));
1362 } else if let Ok((range, val)) =
1363 Closure::from_meta_data(file, source, "closure", convert, ignored)
1364 {
1365 convert.update(range);
1366 result = Some(Expression::Closure(Arc::new(val)));
1367 } else if let Ok((range, val)) =
1368 CallClosure::from_meta_data(file, source, convert, ignored)
1369 {
1370 convert.update(range);
1371 result = Some(Expression::CallClosure(Box::new(val)));
1372 } else if let Ok((range, val)) =
1373 CallClosure::named_from_meta_data(file, source, convert, ignored)
1374 {
1375 convert.update(range);
1376 result = Some(Expression::CallClosure(Box::new(val)));
1377 } else if let Ok((range, val)) = Grab::from_meta_data(file, source, convert, ignored) {
1378 convert.update(range);
1379 if let Some(v) = val.precompute() {
1380 result = Some(Expression::Variable(Box::new((val.source_range, v))));
1381 } else {
1382 result = Some(Expression::Grab(Box::new(val)));
1383 }
1384 } else if let Ok((range, val)) = TryExpr::from_meta_data(file, source, convert, ignored)
1385 {
1386 convert.update(range);
1387 result = Some(Expression::TryExpr(Box::new(val)));
1388 } else if let Ok((range, val)) = In::from_meta_data("in", convert, ignored) {
1389 convert.update(range);
1390 result = Some(Expression::In(Box::new(val)));
1391 } else if let Ok((range, val)) =
1392 ForIn::from_meta_data(file, source, "for_in", convert, ignored)
1393 {
1394 convert.update(range);
1395 result = Some(Expression::ForIn(Box::new(val)));
1396 } else if let Ok((range, val)) =
1397 ForIn::from_meta_data(file, source, "sum_in", convert, ignored)
1398 {
1399 convert.update(range);
1400 result = Some(Expression::SumIn(Box::new(val)));
1401 } else if let Ok((range, val)) =
1402 ForIn::from_meta_data(file, source, "prod_in", convert, ignored)
1403 {
1404 convert.update(range);
1405 result = Some(Expression::ProdIn(Box::new(val)));
1406 } else if let Ok((range, val)) =
1407 ForIn::from_meta_data(file, source, "min_in", convert, ignored)
1408 {
1409 convert.update(range);
1410 result = Some(Expression::MinIn(Box::new(val)));
1411 } else if let Ok((range, val)) =
1412 ForIn::from_meta_data(file, source, "max_in", convert, ignored)
1413 {
1414 convert.update(range);
1415 result = Some(Expression::MaxIn(Box::new(val)));
1416 } else if let Ok((range, val)) =
1417 ForIn::from_meta_data(file, source, "sift_in", convert, ignored)
1418 {
1419 convert.update(range);
1420 result = Some(Expression::SiftIn(Box::new(val)));
1421 } else if let Ok((range, val)) =
1422 ForIn::from_meta_data(file, source, "any_in", convert, ignored)
1423 {
1424 convert.update(range);
1425 result = Some(Expression::AnyIn(Box::new(val)));
1426 } else if let Ok((range, val)) =
1427 ForIn::from_meta_data(file, source, "all_in", convert, ignored)
1428 {
1429 convert.update(range);
1430 result = Some(Expression::AllIn(Box::new(val)));
1431 } else if let Ok((range, val)) =
1432 ForIn::from_meta_data(file, source, "link_in", convert, ignored)
1433 {
1434 convert.update(range);
1435 result = Some(Expression::LinkIn(Box::new(val)));
1436 } else {
1437 let range = convert.ignore();
1438 convert.update(range);
1439 ignored.push(range);
1440 }
1441 }
1442
1443 let result = result.ok_or(())?;
1444 Ok((convert.subtract(start), result))
1445 }
1446
1447 fn precompute(&self) -> Option<Variable> {
1448 use self::Expression::*;
1449
1450 match *self {
1451 ArrayFill(ref array_fill) => array_fill.precompute(),
1452 Array(ref array) => array.precompute(),
1453 Object(ref obj) => obj.precompute(),
1454 Vec4(ref vec4) => vec4.precompute(),
1455 Link(ref link) => link.precompute(),
1456 Variable(ref range_var) => Some(range_var.1.clone()),
1457 _ => None,
1458 }
1459 }
1460
1461 pub fn source_range(&self) -> Range {
1463 use self::Expression::*;
1464
1465 match *self {
1466 Link(ref link) => link.source_range,
1467 Object(ref obj) => obj.source_range,
1468 Array(ref arr) => arr.source_range,
1469 ArrayFill(ref arr_fill) => arr_fill.source_range,
1470 Return(ref expr) => expr.source_range(),
1471 ReturnVoid(ref range) => **range,
1472 Break(ref br) => br.source_range,
1473 Continue(ref c) => c.source_range,
1474 Block(ref bl) => bl.source_range,
1475 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1476 Go(ref go) => go.source_range,
1477 #[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
1478 Go(ref go) => match **go {},
1479 Call(ref call) => call.info.source_range,
1480 CallVoid(ref call) => call.info.source_range,
1481 CallReturn(ref call) => call.info.source_range,
1482 CallBinOp(ref call) => call.info.source_range,
1483 CallUnOp(ref call) => call.info.source_range,
1484 CallLazy(ref call) => call.info.source_range,
1485 CallLoaded(ref call) => call.info.source_range,
1486 Item(ref it) => it.source_range,
1487 Assign(ref assign) => assign.source_range,
1488 Vec4(ref vec4) => vec4.source_range,
1489 Mat4(ref mat4) => mat4.source_range,
1490 For(ref for_expr) => for_expr.source_range,
1491 ForN(ref for_n_expr) => for_n_expr.source_range,
1492 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1493 ForIn(ref for_in_expr) => for_in_expr.source_range,
1494 #[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
1495 ForIn(ref for_in_expr) |
1496 SumIn(ref for_in_expr) |
1497 ProdIn(ref for_in_expr) |
1498 MinIn(ref for_in_expr) |
1499 MaxIn(ref for_in_expr) |
1500 SiftIn(ref for_in_expr) |
1501 AnyIn(ref for_in_expr) |
1502 AllIn(ref for_in_expr) |
1503 LinkIn(ref for_in_expr) => match **for_in_expr {},
1504 Sum(ref for_n_expr) => for_n_expr.source_range,
1505 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1506 SumIn(ref for_in_expr) => for_in_expr.source_range,
1507 SumVec4(ref for_n_expr) => for_n_expr.source_range,
1508 Prod(ref for_n_expr) => for_n_expr.source_range,
1509 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1510 ProdIn(ref for_in_expr) => for_in_expr.source_range,
1511 ProdVec4(ref for_n_expr) => for_n_expr.source_range,
1512 Min(ref for_n_expr) => for_n_expr.source_range,
1513 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1514 MinIn(ref for_in_expr) => for_in_expr.source_range,
1515 Max(ref for_n_expr) => for_n_expr.source_range,
1516 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1517 MaxIn(ref for_in_expr) => for_in_expr.source_range,
1518 Sift(ref for_n_expr) => for_n_expr.source_range,
1519 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1520 SiftIn(ref for_in_expr) => for_in_expr.source_range,
1521 Any(ref for_n_expr) => for_n_expr.source_range,
1522 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1523 AnyIn(ref for_in_expr) => for_in_expr.source_range,
1524 All(ref for_n_expr) => for_n_expr.source_range,
1525 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1526 AllIn(ref for_in_expr) => for_in_expr.source_range,
1527 LinkFor(ref for_n_expr) => for_n_expr.source_range,
1528 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1529 LinkIn(ref for_in_expr) => for_in_expr.source_range,
1530 If(ref if_expr) => if_expr.source_range,
1531 Variable(ref range_var) => range_var.0,
1532 Try(ref expr) => expr.source_range(),
1533 Swizzle(ref swizzle) => swizzle.source_range,
1534 Closure(ref closure) => closure.source_range,
1535 CallClosure(ref call) => call.source_range,
1536 Grab(ref grab) => grab.source_range,
1537 TryExpr(ref try_expr) => try_expr.source_range,
1538 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
1539 In(ref in_expr) => in_expr.source_range,
1540 #[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
1541 In(ref in_expr) => match **in_expr {},
1542 }
1543 }
1544
1545 fn get_locals(
1546 &mut self,
1547 relative: usize,
1548 stack: &mut Vec<Option<Arc<String>>>,
1549 closure_stack: &mut Vec<usize>,
1550 module: &Module,
1551 use_lookup: &UseLookup,
1552 ) {
1553 use self::Expression::*;
1554
1555 match *self {
1556 Link(ref mut link) =>
1557 link.get_locals(relative, stack, closure_stack, module, use_lookup),
1558 Object(ref mut obj) =>
1559 obj.get_locals(relative, stack, closure_stack, module, use_lookup),
1560 Array(ref mut arr) =>
1561 arr.get_locals(relative, stack, closure_stack, module, use_lookup),
1562 ArrayFill(ref mut arr_fill) =>
1563 arr_fill.get_locals(relative, stack, closure_stack, module, use_lookup),
1564 Return(ref mut expr) => {
1565 let st = stack.len();
1566 expr.get_locals(relative, stack, closure_stack, module, use_lookup);
1567 stack.truncate(st);
1568 }
1569 ReturnVoid(_) => {}
1570 Break(_) => {}
1571 Continue(_) => {}
1572 Block(ref mut bl) =>
1573 bl.get_locals(relative, stack, closure_stack, module, use_lookup),
1574 Go(ref mut go) => go.get_locals(relative, stack, closure_stack, module, use_lookup),
1575 Call(ref mut call) => {
1576 call.get_locals(relative, stack, closure_stack, module, use_lookup);
1577 match call.f_index {
1578 FnIndex::Void(f) => {
1579 *self = Expression::CallVoid(Box::new(self::CallVoid {
1580 args: call.args.clone(),
1581 fun: f,
1582 info: call.info.clone(),
1583 }))
1584 }
1585 FnIndex::Return(f) => {
1586 *self = Expression::CallReturn(Box::new(self::CallReturn {
1587 args: call.args.clone(),
1588 fun: f,
1589 info: call.info.clone(),
1590 }))
1591 }
1592 FnIndex::BinOp(f) => {
1593 *self = Expression::CallBinOp(Box::new(self::CallBinOp {
1594 left: call.args[0].clone(),
1595 right: call.args[1].clone(),
1596 fun: f,
1597 info: call.info.clone(),
1598 }))
1599 }
1600 FnIndex::UnOp(f) => {
1601 *self = Expression::CallUnOp(Box::new(self::CallUnOp {
1602 arg: call.args[0].clone(),
1603 fun: f,
1604 info: call.info.clone(),
1605 }))
1606 }
1607 FnIndex::Lazy(f, lazy_inv) => {
1608 *self = Expression::CallLazy(Box::new(self::CallLazy {
1609 args: call.args.clone(),
1610 fun: f,
1611 lazy_inv,
1612 info: call.info.clone(),
1613 }))
1614 }
1615 FnIndex::Loaded(f) => {
1616 *self = Expression::CallLoaded(Box::new(self::CallLoaded {
1617 args: call.args.clone(),
1618 custom_source: call.custom_source.clone(),
1619 fun: f,
1620 info: call.info.clone(),
1621 }))
1622 }
1623 FnIndex::None => {}
1624 }
1625 }
1626 CallVoid(_) => unimplemented!("`CallVoid` is transformed from `Call`"),
1627 CallReturn(_) => unimplemented!("`CallReturn` is transformed from `Call`"),
1628 CallLazy(_) => unimplemented!("`CallLazy` is transformed from `Call`"),
1629 CallLoaded(_) => unimplemented!("`CallLoaded` is transformed from `Call`"),
1630 CallBinOp(_) => unimplemented!("`CallBinOp` is transformed from `Call`"),
1631 CallUnOp(_) => unimplemented!("`CallUnOp` is transformed from `Call`"),
1632 Item(ref mut it) =>
1633 it.get_locals(relative, stack, closure_stack, module, use_lookup),
1634 Assign(ref mut assign) =>
1635 assign.get_locals(relative, stack, closure_stack, module, use_lookup),
1636 Vec4(ref mut vec4) =>
1637 vec4.get_locals(relative, stack, closure_stack, module, use_lookup),
1638 Mat4(ref mut mat4) =>
1639 mat4.get_locals(relative, stack, closure_stack, module, use_lookup),
1640 For(ref mut for_expr) =>
1641 for_expr.get_locals(relative, stack, closure_stack, module, use_lookup),
1642 ForN(ref mut for_n_expr) =>
1643 for_n_expr.get_locals(relative, stack, closure_stack, module, use_lookup),
1644 ForIn(ref mut for_n_expr) |
1645 SumIn(ref mut for_n_expr) |
1646 ProdIn(ref mut for_n_expr) |
1647 MinIn(ref mut for_n_expr) |
1648 MaxIn(ref mut for_n_expr) |
1649 SiftIn(ref mut for_n_expr) |
1650 AnyIn(ref mut for_n_expr) |
1651 AllIn(ref mut for_n_expr) |
1652 LinkIn(ref mut for_n_expr) => {
1653 for_n_expr.get_locals(relative, stack, closure_stack, module, use_lookup)
1654 }
1655 Sum(ref mut for_n_expr) |
1656 SumVec4(ref mut for_n_expr) |
1657 Prod(ref mut for_n_expr) |
1658 ProdVec4(ref mut for_n_expr) |
1659 Min(ref mut for_n_expr) |
1660 Max(ref mut for_n_expr) |
1661 Sift(ref mut for_n_expr) |
1662 Any(ref mut for_n_expr) |
1663 All(ref mut for_n_expr) |
1664 LinkFor(ref mut for_n_expr) =>
1665 for_n_expr.get_locals(relative, stack, closure_stack, module, use_lookup),
1666 If(ref mut if_expr) =>
1667 if_expr.get_locals(relative, stack, closure_stack, module, use_lookup),
1668 Variable(_) => {}
1669 Try(ref mut expr) =>
1670 expr.get_locals(relative, stack, closure_stack, module, use_lookup),
1671 Swizzle(ref mut swizzle) =>
1672 swizzle.expr.get_locals(relative, stack, closure_stack, module, use_lookup),
1673 Closure(ref mut closure) => Arc::make_mut(closure).get_locals(
1674 relative,
1675 stack,
1676 closure_stack,
1677 module,
1678 use_lookup,
1679 ),
1680 CallClosure(ref mut call) =>
1681 call.get_locals(relative, stack, closure_stack, module, use_lookup),
1682 Grab(ref mut grab) =>
1683 grab.get_locals(relative, stack, closure_stack, module, use_lookup),
1684 TryExpr(ref mut try_expr) =>
1685 try_expr.get_locals(relative, stack, closure_stack, module, use_lookup),
1686 In(ref mut in_expr) => in_expr.get_locals(relative, module, use_lookup),
1687 }
1688 }
1689}
1690
1691#[derive(Debug, Clone)]
1693pub struct Link {
1694 pub items: Vec<Expression>,
1696 pub source_range: Range,
1698}
1699
1700impl Link {
1701 pub fn from_meta_data(
1703 file: &Arc<String>,
1704 source: &Arc<String>,
1705 mut convert: Convert,
1706 ignored: &mut Vec<Range>,
1707 ) -> Result<(Range, Link), ()> {
1708 let start = convert;
1709 let node = "link";
1710 let start_range = convert.start_node(node)?;
1711 convert.update(start_range);
1712
1713 let mut items: Vec<Expression> = vec![];
1714 loop {
1715 if let Ok(range) = convert.end_node(node) {
1716 convert.update(range);
1717 break;
1718 } else if let Ok((range, val)) =
1719 Expression::from_meta_data(file, source, "link_item", convert, ignored)
1720 {
1721 convert.update(range);
1722 items.push(val);
1723 } else {
1724 let range = convert.ignore();
1725 convert.update(range);
1726 ignored.push(range);
1727 }
1728 }
1729
1730 Ok((
1731 convert.subtract(start),
1732 Link {
1733 items,
1734 source_range: convert.source(start).unwrap(),
1735 },
1736 ))
1737 }
1738
1739 fn precompute(&self) -> Option<Variable> {
1740 let mut link = crate::link::Link::new();
1741 for it in &self.items {
1742 if let Some(v) = it.precompute() {
1743 if link.push(&v).is_err() {
1744 return None;
1745 };
1746 } else {
1747 return None;
1748 }
1749 }
1750 Some(Variable::Link(Box::new(link)))
1751 }
1752
1753 fn get_locals(
1754 &mut self,
1755 relative: usize,
1756 stack: &mut Vec<Option<Arc<String>>>,
1757 closure_stack: &mut Vec<usize>,
1758 module: &Module,
1759 use_lookup: &UseLookup,
1760 ) {
1761 let st = stack.len();
1762 for expr in &mut self.items {
1763 expr.get_locals(relative, stack, closure_stack, module, use_lookup);
1764 }
1765 stack.truncate(st);
1766 }
1767}
1768
1769#[derive(Debug, Clone)]
1771pub struct Object {
1772 pub key_values: Vec<(Arc<String>, Expression)>,
1774 pub source_range: Range,
1776}
1777
1778impl Object {
1779 pub fn from_meta_data(
1781 file: &Arc<String>,
1782 source: &Arc<String>,
1783 mut convert: Convert,
1784 ignored: &mut Vec<Range>,
1785 ) -> Result<(Range, Object), ()> {
1786 let start = convert;
1787 let node = "object";
1788 let start_range = convert.start_node(node)?;
1789 convert.update(start_range);
1790
1791 let mut key_values = vec![];
1792 loop {
1793 if let Ok(range) = convert.end_node(node) {
1794 convert.update(range);
1795 break;
1796 } else if let Ok((range, val)) =
1797 Object::key_value_from_meta_data(file, source, convert, ignored)
1798 {
1799 convert.update(range);
1800 key_values.push(val);
1801 } else {
1802 let range = convert.ignore();
1803 convert.update(range);
1804 ignored.push(range);
1805 }
1806 }
1807
1808 Ok((
1809 convert.subtract(start),
1810 Object {
1811 key_values,
1812 source_range: convert.source(start).unwrap(),
1813 },
1814 ))
1815 }
1816
1817 fn precompute(&self) -> Option<Variable> {
1818 let mut object: HashMap<_, _> = HashMap::new();
1819 for &(ref key, ref value) in &self.key_values {
1820 if let Some(v) = value.precompute() {
1821 object.insert(key.clone(), v);
1822 } else {
1823 return None;
1824 }
1825 }
1826 Some(Variable::Object(Arc::new(object)))
1827 }
1828
1829 fn key_value_from_meta_data(
1830 file: &Arc<String>,
1831 source: &Arc<String>,
1832 mut convert: Convert,
1833 ignored: &mut Vec<Range>,
1834 ) -> Result<(Range, (Arc<String>, Expression)), ()> {
1835 let start = convert;
1836 let node = "key_value";
1837 let start_range = convert.start_node(node)?;
1838 convert.update(start_range);
1839
1840 let mut key: Option<Arc<String>> = None;
1841 let mut value: Option<Expression> = None;
1842 loop {
1843 if let Ok(range) = convert.end_node(node) {
1844 convert.update(range);
1845 break;
1846 } else if let Ok((range, val)) = convert.meta_string("key") {
1847 convert.update(range);
1848 key = Some(val);
1849 } else if let Ok((range, val)) =
1850 Expression::from_meta_data(file, source, "val", convert, ignored)
1851 {
1852 convert.update(range);
1853 value = Some(val);
1854 } else {
1855 let range = convert.ignore();
1856 convert.update(range);
1857 ignored.push(range);
1858 }
1859 }
1860
1861 let key = key.ok_or(())?;
1862 let value = value.ok_or(())?;
1863 Ok((convert.subtract(start), (key, value)))
1864 }
1865
1866 fn get_locals(
1867 &mut self,
1868 relative: usize,
1869 stack: &mut Vec<Option<Arc<String>>>,
1870 closure_stack: &mut Vec<usize>,
1871 module: &Module,
1872 use_lookup: &UseLookup,
1873 ) {
1874 let st = stack.len();
1875 for &mut (_, ref mut expr) in &mut self.key_values {
1876 expr.get_locals(relative, stack, closure_stack, module, use_lookup);
1877 stack.truncate(st);
1878 }
1879 }
1880}
1881
1882#[derive(Debug, Clone)]
1884pub struct Array {
1885 pub items: Vec<Expression>,
1887 pub source_range: Range,
1889}
1890
1891impl Array {
1892 pub fn from_meta_data(
1894 file: &Arc<String>,
1895 source: &Arc<String>,
1896 mut convert: Convert,
1897 ignored: &mut Vec<Range>,
1898 ) -> Result<(Range, Array), ()> {
1899 let start = convert;
1900 let node = "array";
1901 let start_range = convert.start_node(node)?;
1902 convert.update(start_range);
1903
1904 let mut items = vec![];
1905 loop {
1906 if let Ok(range) = convert.end_node(node) {
1907 convert.update(range);
1908 break;
1909 } else if let Ok((range, val)) =
1910 Expression::from_meta_data(file, source, "array_item", convert, ignored)
1911 {
1912 convert.update(range);
1913 items.push(val);
1914 } else {
1915 let range = convert.ignore();
1916 convert.update(range);
1917 ignored.push(range);
1918 }
1919 }
1920
1921 Ok((
1922 convert.subtract(start),
1923 Array {
1924 items,
1925 source_range: convert.source(start).unwrap(),
1926 },
1927 ))
1928 }
1929
1930 fn precompute(&self) -> Option<Variable> {
1931 let mut res = Vec::with_capacity(self.items.len());
1932 for item in &self.items {
1933 if let Some(v) = item.precompute() {
1934 res.push(v);
1935 } else {
1936 return None;
1937 }
1938 }
1939 Some(Variable::Array(Arc::new(res)))
1940 }
1941
1942 fn get_locals(
1943 &mut self,
1944 relative: usize,
1945 stack: &mut Vec<Option<Arc<String>>>,
1946 closure_stack: &mut Vec<usize>,
1947 module: &Module,
1948 use_lookup: &UseLookup,
1949 ) {
1950 let st = stack.len();
1951 for item in &mut self.items {
1952 item.get_locals(relative, stack, closure_stack, module, use_lookup);
1953 stack.truncate(st);
1954 }
1955 }
1956}
1957
1958#[derive(Debug, Clone)]
1960pub struct ArrayFill {
1961 pub fill: Expression,
1963 pub n: Expression,
1965 pub source_range: Range,
1967}
1968
1969impl ArrayFill {
1970 pub fn from_meta_data(
1972 file: &Arc<String>,
1973 source: &Arc<String>,
1974 mut convert: Convert,
1975 ignored: &mut Vec<Range>,
1976 ) -> Result<(Range, ArrayFill), ()> {
1977 let start = convert;
1978 let node = "array_fill";
1979 let start_range = convert.start_node(node)?;
1980 convert.update(start_range);
1981
1982 let mut fill: Option<Expression> = None;
1983 let mut n: Option<Expression> = None;
1984 loop {
1985 if let Ok(range) = convert.end_node(node) {
1986 convert.update(range);
1987 break;
1988 } else if let Ok((range, val)) =
1989 Expression::from_meta_data(file, source, "fill", convert, ignored)
1990 {
1991 convert.update(range);
1992 fill = Some(val);
1993 } else if let Ok((range, val)) =
1994 Expression::from_meta_data(file, source, "n", convert, ignored)
1995 {
1996 convert.update(range);
1997 n = Some(val);
1998 } else {
1999 let range = convert.ignore();
2000 convert.update(range);
2001 ignored.push(range);
2002 }
2003 }
2004
2005 let fill = fill.ok_or(())?;
2006 let n = n.ok_or(())?;
2007 Ok((
2008 convert.subtract(start),
2009 ArrayFill {
2010 fill,
2011 n,
2012 source_range: convert.source(start).unwrap(),
2013 },
2014 ))
2015 }
2016
2017 fn precompute(&self) -> Option<Variable> {
2018 if let Expression::Variable(ref range_var) = self.n {
2019 if let (_, Variable::F64(n, _)) = **range_var {
2020 if let Expression::Variable(ref x) = self.fill {
2021 return Some(Variable::Array(Arc::new(vec![x.1.clone(); n as usize])));
2022 }
2023 }
2024 }
2025 None
2026 }
2027
2028 fn get_locals(
2029 &mut self,
2030 relative: usize,
2031 stack: &mut Vec<Option<Arc<String>>>,
2032 closure_stack: &mut Vec<usize>,
2033 module: &Module,
2034 use_lookup: &UseLookup,
2035 ) {
2036 let st = stack.len();
2037 self.fill.get_locals(relative, stack, closure_stack, module, use_lookup);
2038 stack.truncate(st);
2039 self.n.get_locals(relative, stack, closure_stack, module, use_lookup);
2040 stack.truncate(st);
2041 }
2042}
2043
2044#[derive(Debug, Clone)]
2046pub struct BinOpSeq {
2047 pub items: Vec<Expression>,
2049 pub ops: Vec<BinOp>,
2051 pub source_range: Range,
2053}
2054
2055impl BinOpSeq {
2056 pub fn from_meta_data(
2058 file: &Arc<String>,
2059 source: &Arc<String>,
2060 node: &str,
2061 mut convert: Convert,
2062 ignored: &mut Vec<Range>,
2063 ) -> Result<(Range, BinOpSeq), ()> {
2064 let start = convert;
2065 let start_range = convert.start_node(node)?;
2066 convert.update(start_range);
2067
2068 let mut items = vec![];
2069 let mut ops = vec![];
2070 loop {
2071 if let Ok(range) = convert.end_node(node) {
2072 convert.update(range);
2073 break;
2074 } else if let Ok((range, val)) =
2075 UnOpExpression::from_meta_data("neg", file, source, convert, ignored)
2076 {
2077 convert.update(range);
2078 items.push(val);
2079 } else if let Ok((range, val)) =
2080 BinOpSeq::from_meta_data(file, source, "pow", convert, ignored)
2081 {
2082 convert.update(range);
2083 items.push(val.into_expression());
2084 } else if let Ok((range, val)) =
2085 Expression::from_meta_data(file, source, "expr", convert, ignored)
2086 {
2087 convert.update(range);
2088 items.push(val);
2089 } else if let Ok((range, _)) = convert.meta_bool("*.") {
2090 convert.update(range);
2091 ops.push(BinOp::Dot);
2092 } else if let Ok((range, _)) = convert.meta_bool("x") {
2093 convert.update(range);
2094 ops.push(BinOp::Cross);
2095 } else if let Ok((range, _)) = convert.meta_bool("*") {
2096 convert.update(range);
2097 ops.push(BinOp::Mul);
2098 } else if let Ok((range, _)) = convert.meta_bool("/") {
2099 convert.update(range);
2100 ops.push(BinOp::Div);
2101 } else if let Ok((range, _)) = convert.meta_bool("%") {
2102 convert.update(range);
2103 ops.push(BinOp::Rem);
2104 } else if let Ok((range, _)) = convert.meta_bool("+") {
2105 convert.update(range);
2106 ops.push(BinOp::Add);
2107 } else if let Ok((range, _)) = convert.meta_bool("-") {
2108 convert.update(range);
2109 ops.push(BinOp::Sub);
2110 } else if let Ok((range, _)) = convert.meta_bool("||") {
2111 convert.update(range);
2112 ops.push(BinOp::OrElse);
2113 } else if let Ok((range, _)) = convert.meta_bool("^") {
2114 convert.update(range);
2115 ops.push(BinOp::Pow);
2116 } else if let Ok((range, _)) = convert.meta_bool("&&") {
2117 convert.update(range);
2118 ops.push(BinOp::AndAlso);
2119 } else if let Ok((range, _)) = convert.meta_bool("<") {
2120 convert.update(range);
2121 ops.push(BinOp::Less);
2122 } else if let Ok((range, _)) = convert.meta_bool("<=") {
2123 convert.update(range);
2124 ops.push(BinOp::LessOrEqual);
2125 } else if let Ok((range, _)) = convert.meta_bool(">") {
2126 convert.update(range);
2127 ops.push(BinOp::Greater);
2128 } else if let Ok((range, _)) = convert.meta_bool(">=") {
2129 convert.update(range);
2130 ops.push(BinOp::GreaterOrEqual);
2131 } else if let Ok((range, _)) = convert.meta_bool("==") {
2132 convert.update(range);
2133 ops.push(BinOp::Equal);
2134 } else if let Ok((range, _)) = convert.meta_bool("!=") {
2135 convert.update(range);
2136 ops.push(BinOp::NotEqual);
2137 } else {
2138 let range = convert.ignore();
2139 convert.update(range);
2140 ignored.push(range);
2141 }
2142 }
2143
2144 if items.is_empty() {
2145 return Err(());
2146 }
2147 Ok((
2148 convert.subtract(start),
2149 BinOpSeq {
2150 items,
2151 ops,
2152 source_range: convert.source(start).unwrap(),
2153 },
2154 ))
2155 }
2156
2157 fn into_expression(mut self) -> Expression {
2158 if self.items.len() == 1 {
2159 self.items[0].clone()
2160 } else {
2161 let op = self.ops.pop().expect("Expected a binary operation");
2162 let last = self.items.pop().expect("Expected argument");
2163 let source_range = self.source_range;
2164 BinOpExpression {
2165 op,
2166 left: self.into_expression(),
2167 right: last,
2168 source_range,
2169 }
2170 .into_expression()
2171 }
2172 }
2173}
2174
2175#[derive(Debug, Copy, Clone)]
2177pub enum BinOp {
2178 Add,
2180 Sub,
2182 Mul,
2184 Dot,
2186 Cross,
2188 Div,
2190 Rem,
2192 Pow,
2194 OrElse,
2196 AndAlso,
2198 Less,
2200 LessOrEqual,
2202 Greater,
2204 GreaterOrEqual,
2206 Equal,
2208 NotEqual,
2210}
2211
2212pub(crate) const BINOP_PREC_POW: u8 = 3;
2213pub(crate) const BINOP_PREC_MUL: u8 = 2;
2214pub(crate) const BINOP_PREC_ADD: u8 = 1;
2215pub(crate) const BINOP_PREC_EQ: u8 = 0;
2216
2217impl BinOp {
2218 pub fn symbol(self) -> &'static str {
2220 match self {
2221 BinOp::Add => "+",
2222 BinOp::Sub => "-",
2223 BinOp::Mul => "*",
2224 BinOp::Dot => "*.",
2225 BinOp::Cross => "x",
2226 BinOp::Div => "/",
2227 BinOp::Rem => "%",
2228 BinOp::Pow => "^",
2229 BinOp::OrElse => "||",
2230 BinOp::AndAlso => "&&",
2231 BinOp::Less => "<",
2232 BinOp::LessOrEqual => "<=",
2233 BinOp::Greater => ">",
2234 BinOp::GreaterOrEqual => ">=",
2235 BinOp::Equal => "==",
2236 BinOp::NotEqual => "!=",
2237 }
2238 }
2239
2240 pub fn symbol_bool(self) -> &'static str {
2242 match self {
2243 BinOp::Add => "or",
2244 BinOp::Mul => "and",
2245 _ => self.symbol(),
2246 }
2247 }
2248
2249 pub fn precedence(self) -> u8 {
2252 match self {
2253 BinOp::Less
2254 | BinOp::LessOrEqual
2255 | BinOp::Greater
2256 | BinOp::GreaterOrEqual
2257 | BinOp::Equal
2258 | BinOp::NotEqual => BINOP_PREC_EQ,
2259 BinOp::OrElse => BINOP_PREC_ADD,
2260 BinOp::AndAlso => BINOP_PREC_MUL,
2261 BinOp::Add | BinOp::Sub => BINOP_PREC_ADD,
2262 BinOp::Mul | BinOp::Dot | BinOp::Cross | BinOp::Div | BinOp::Rem => BINOP_PREC_MUL,
2263 BinOp::Pow => BINOP_PREC_POW,
2264 }
2265 }
2266}
2267
2268#[derive(Debug, Clone)]
2272pub enum Id {
2273 String(Range, Arc<String>),
2275 F64(Range, f64),
2277 Expression(Expression),
2279}
2280
2281impl Id {
2282 pub fn source_range(&self) -> Range {
2284 match *self {
2285 Id::String(range, _) => range,
2286 Id::F64(range, _) => range,
2287 Id::Expression(ref expr) => expr.source_range(),
2288 }
2289 }
2290
2291 fn get_locals(
2292 &mut self,
2293 relative: usize,
2294 stack: &mut Vec<Option<Arc<String>>>,
2295 closure_stack: &mut Vec<usize>,
2296 module: &Module,
2297 use_lookup: &UseLookup,
2298 ) -> bool {
2299 match *self {
2300 Id::String(_, _) => false,
2301 Id::F64(_, _) => false,
2302 Id::Expression(ref mut expr) => {
2303 let st = stack.len();
2304 expr.get_locals(relative, stack, closure_stack, module, use_lookup);
2305 stack.truncate(st);
2306 true
2307 }
2308 }
2309 }
2310}
2311
2312#[derive(Debug, Clone)]
2314pub struct Item {
2315 pub name: Arc<String>,
2317 pub stack_id: Cell<Option<usize>>,
2322 pub static_stack_id: Cell<Option<usize>>,
2326 pub current: bool,
2328 pub try_flag: bool,
2330 pub ids: Vec<Id>,
2332 pub try_ids: Vec<usize>,
2334 pub source_range: Range,
2336}
2337
2338impl Item {
2339 pub fn from_variable(name: Arc<String>, source_range: Range) -> Item {
2341 Item {
2342 name,
2343 current: false,
2344 stack_id: Cell::new(None),
2345 static_stack_id: Cell::new(None),
2346 try_flag: false,
2347 ids: vec![],
2348 try_ids: vec![],
2349 source_range,
2350 }
2351 }
2352
2353 fn trunc(&self, n: usize) -> Item {
2355 Item {
2356 name: self.name.clone(),
2357 current: self.current,
2358 stack_id: Cell::new(None),
2359 static_stack_id: Cell::new(None),
2360 try_flag: self.try_flag,
2361 ids: self.ids.iter().take(n).cloned().collect(),
2362 try_ids: {
2363 let mut try_ids = vec![];
2364 for &ind in &self.try_ids {
2365 if ind >= n {
2366 break;
2367 }
2368 try_ids.push(ind);
2369 }
2370 try_ids
2371 },
2372 source_range: self.source_range,
2373 }
2374 }
2375
2376 pub fn from_meta_data(
2378 file: &Arc<String>,
2379 source: &Arc<String>,
2380 mut convert: Convert,
2381 ignored: &mut Vec<Range>,
2382 ) -> Result<(Range, Item), ()> {
2383 let start = convert;
2384 let node = "item";
2385 let start_range = convert.start_node(node)?;
2386 convert.update(start_range);
2387
2388 let mut name: Option<Arc<String>> = None;
2389 let mut current = false;
2390 let mut ids = vec![];
2391 let mut try_ids = vec![];
2392 let mut try_flag = false;
2393 loop {
2394 if let Ok(range) = convert.end_node(node) {
2395 convert.update(range);
2396 break;
2397 } else if let Ok((range, val)) = convert.meta_string("name") {
2398 convert.update(range);
2399 name = Some(val);
2400 } else if let Ok((range, _)) = convert.meta_bool("current") {
2401 convert.update(range);
2402 current = true;
2403 } else if let Ok((range, _)) = convert.meta_bool("try_item") {
2404 convert.update(range);
2405 try_flag = true;
2406 } else if let Ok(range) = convert.start_node("item_extra") {
2408 convert.update(range);
2409 } else if let Ok(range) = convert.end_node("item_extra") {
2410 convert.update(range);
2411 } else if let Ok((range, val)) = convert.meta_string("id") {
2412 let start_id = convert;
2413 convert.update(range);
2414 ids.push(Id::String(convert.source(start_id).unwrap(), val));
2415 } else if let Ok((range, val)) = convert.meta_f64("id") {
2416 let start_id = convert;
2417 convert.update(range);
2418 ids.push(Id::F64(convert.source(start_id).unwrap(), val));
2419 } else if let Ok((range, val)) =
2420 Expression::from_meta_data(file, source, "id", convert, ignored)
2421 {
2422 convert.update(range);
2423 ids.push(Id::Expression(val));
2424 } else if let Ok((range, _)) = convert.meta_bool("try_id") {
2425 convert.update(range);
2426 try_ids.push(ids.len() - 1);
2428 } else {
2429 let range = convert.ignore();
2430 convert.update(range);
2431 ignored.push(range);
2432 }
2433 }
2434
2435 let name = name.ok_or(())?;
2436 Ok((
2437 convert.subtract(start),
2438 Item {
2439 name,
2440 stack_id: Cell::new(None),
2441 static_stack_id: Cell::new(None),
2442 current,
2443 try_flag,
2444 ids,
2445 try_ids,
2446 source_range: convert.source(start).unwrap(),
2447 },
2448 ))
2449 }
2450
2451 fn get_locals(
2452 &mut self,
2453 relative: usize,
2454 stack: &mut Vec<Option<Arc<String>>>,
2455 closure_stack: &mut Vec<usize>,
2456 module: &Module,
2457 use_lookup: &UseLookup,
2458 ) {
2459 let st = stack.len();
2460 for (i, n) in stack.iter().rev().enumerate() {
2461 if let Some(ref n) = *n {
2462 if **n == **self.name {
2463 self.static_stack_id.set(Some(i + 1));
2464 break;
2465 }
2466 }
2467 }
2468 for id in &mut self.ids {
2469 if id.get_locals(relative, stack, closure_stack, module, use_lookup) {
2470 stack.push(None);
2471 }
2472 }
2473 stack.truncate(st);
2474 }
2475}
2476
2477#[cfg(all(not(target_family = "wasm"), feature = "threading"))]
2479#[derive(Debug, Clone)]
2480pub struct Go {
2481 pub call: Call,
2483 pub source_range: Range,
2485}
2486
2487#[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
2489#[derive(Debug, Clone)]
2490pub enum Go {}
2491
2492impl Go {
2493 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
2494 pub fn from_meta_data(
2496 file: &Arc<String>,
2497 source: &Arc<String>,
2498 mut convert: Convert,
2499 ignored: &mut Vec<Range>,
2500 ) -> Result<(Range, Go), ()> {
2501 let start = convert;
2502 let node = "go";
2503 let start_range = convert.start_node(node)?;
2504 convert.update(start_range);
2505
2506 let mut call: Option<Call> = None;
2507 loop {
2508 if let Ok(range) = convert.end_node(node) {
2509 convert.update(range);
2510 break;
2511 } else if let Ok((range, val)) = Call::from_meta_data(file, source, convert, ignored) {
2512 convert.update(range);
2513 call = Some(val);
2514 } else if let Ok((range, val)) =
2515 Call::named_from_meta_data(file, source, convert, ignored)
2516 {
2517 convert.update(range);
2518 call = Some(val);
2519 } else {
2520 let range = convert.ignore();
2521 convert.update(range);
2522 ignored.push(range);
2523 }
2524 }
2525
2526 let call = call.ok_or(())?;
2527 Ok((
2528 convert.subtract(start),
2529 Go {
2530 call,
2531 source_range: convert.source(start).unwrap(),
2532 },
2533 ))
2534 }
2535
2536 #[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
2537 pub fn from_meta_data(
2539 _file: &Arc<String>,
2540 _source: &Arc<String>,
2541 _convert: Convert,
2542 _ignored: &mut Vec<Range>,
2543 ) -> Result<(Range, Go), ()> {
2544 Err(())
2545 }
2546
2547 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
2548 fn get_locals(
2549 &mut self,
2550 relative: usize,
2551 stack: &mut Vec<Option<Arc<String>>>,
2552 closure_stack: &mut Vec<usize>,
2553 module: &Module,
2554 use_lookup: &UseLookup,
2555 ) {
2556 let st = stack.len();
2557 for arg in &mut self.call.args {
2558 let st = stack.len();
2559 arg.get_locals(relative, stack, closure_stack, module, use_lookup);
2560 stack.truncate(st);
2561 }
2562 stack.truncate(st);
2563 }
2564
2565 #[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
2566 fn get_locals(
2567 &mut self,
2568 _relative: usize,
2569 _stack: &mut Vec<Option<Arc<String>>>,
2570 _closure_stack: &mut Vec<usize>,
2571 _module: &Module,
2572 _use_lookup: &UseLookup,
2573 ) {}
2574}
2575
2576#[derive(Debug, Clone)]
2578pub struct CallInfo {
2579 pub name: Arc<String>,
2581 pub alias: Option<Arc<String>>,
2583 pub source_range: Range,
2585}
2586
2587#[derive(Debug, Clone)]
2589pub struct CallLoaded {
2590 pub args: Vec<Expression>,
2592 pub fun: isize,
2594 pub info: Box<CallInfo>,
2596 pub custom_source: Option<Arc<String>>,
2598}
2599
2600#[derive(Debug, Clone)]
2602pub struct CallLazy {
2603 pub args: Vec<Expression>,
2605 pub fun: crate::FnReturnRef,
2607 pub lazy_inv: crate::LazyInvariant,
2609 pub info: Box<CallInfo>,
2611}
2612
2613#[derive(Debug, Clone)]
2615pub struct CallBinOp {
2616 pub left: Expression,
2618 pub right: Expression,
2620 pub fun: crate::FnBinOpRef,
2622 pub info: Box<CallInfo>,
2624}
2625
2626#[derive(Debug, Clone)]
2628pub struct CallUnOp {
2629 pub arg: Expression,
2631 pub fun: crate::FnUnOpRef,
2633 pub info: Box<CallInfo>,
2635}
2636
2637#[derive(Debug, Clone)]
2639pub struct CallReturn {
2640 pub args: Vec<Expression>,
2642 pub fun: crate::FnReturnRef,
2644 pub info: Box<CallInfo>,
2646}
2647
2648#[derive(Debug, Clone)]
2650pub struct CallVoid {
2651 pub args: Vec<Expression>,
2653 pub fun: crate::FnVoidRef,
2655 pub info: Box<CallInfo>,
2657}
2658
2659#[derive(Debug, Clone)]
2661pub struct Call {
2662 pub args: Vec<Expression>,
2664 pub f_index: FnIndex,
2666 pub info: Box<CallInfo>,
2668 pub custom_source: Option<Arc<String>>,
2670}
2671
2672impl Call {
2673 pub fn from_meta_data(
2675 file: &Arc<String>,
2676 source: &Arc<String>,
2677 mut convert: Convert,
2678 ignored: &mut Vec<Range>,
2679 ) -> Result<(Range, Call), ()> {
2680 let start = convert;
2681 let node = "call";
2682 let start_range = convert.start_node(node)?;
2683 convert.update(start_range);
2684
2685 let mut alias: Option<Arc<String>> = None;
2686 let mut name: Option<Arc<String>> = None;
2687 let mut args = vec![];
2688 let mut mutable: Vec<bool> = vec![];
2689 loop {
2690 if let Ok(range) = convert.end_node(node) {
2691 convert.update(range);
2692 break;
2693 } else if let Ok((range, val)) = convert.meta_string("alias") {
2694 convert.update(range);
2695 alias = Some(val);
2696 } else if let Ok((range, val)) = convert.meta_string("name") {
2697 convert.update(range);
2698 name = Some(val);
2699 } else if let Ok((range, val)) =
2700 Expression::from_meta_data(file, source, "call_arg", convert, ignored)
2701 {
2702 let mut peek = convert;
2703 mutable.push(match peek.start_node("call_arg") {
2704 Ok(r) => {
2705 peek.update(r);
2706 peek.meta_bool("mut").is_ok()
2707 }
2708 _ => unreachable!(),
2709 });
2710 convert.update(range);
2711 args.push(val);
2712 } else {
2713 let range = convert.ignore();
2714 convert.update(range);
2715 ignored.push(range);
2716 }
2717 }
2718
2719 let mut name = name.ok_or(())?;
2720
2721 if mutable.iter().any(|&arg| arg) {
2723 let mut name_plus_args = String::from(&**name);
2724 name_plus_args.push('(');
2725 let mut first = true;
2726 for &arg in &mutable {
2727 if !first {
2728 name_plus_args.push(',');
2729 }
2730 name_plus_args.push_str(if arg { "mut" } else { "_" });
2731 first = false;
2732 }
2733 name_plus_args.push(')');
2734 name = Arc::new(name_plus_args);
2735 }
2736
2737 Ok((
2738 convert.subtract(start),
2739 Call {
2740 args,
2741 f_index: FnIndex::None,
2742 custom_source: None,
2743 info: Box::new(CallInfo {
2744 alias,
2745 name,
2746 source_range: convert.source(start).unwrap(),
2747 }),
2748 },
2749 ))
2750 }
2751
2752 pub fn named_from_meta_data(
2754 file: &Arc<String>,
2755 source: &Arc<String>,
2756 mut convert: Convert,
2757 ignored: &mut Vec<Range>,
2758 ) -> Result<(Range, Call), ()> {
2759 let start = convert;
2760 let node = "named_call";
2761 let start_range = convert.start_node(node)?;
2762 convert.update(start_range);
2763
2764 let mut alias: Option<Arc<String>> = None;
2765 let mut name = String::new();
2766 let mut args = vec![];
2767 let mut mutable: Vec<bool> = vec![];
2768 loop {
2769 if let Ok(range) = convert.end_node(node) {
2770 convert.update(range);
2771 break;
2772 } else if let Ok((range, val)) = convert.meta_string("alias") {
2773 convert.update(range);
2774 alias = Some(val);
2775 } else if let Ok((range, val)) = convert.meta_string("word") {
2776 convert.update(range);
2777 if !name.is_empty() {
2778 name.push('_');
2779 name.push_str(&val);
2780 } else {
2781 name.push_str(&val);
2782 name.push('_');
2783 }
2784 } else if let Ok((range, val)) =
2785 Expression::from_meta_data(file, source, "call_arg", convert, ignored)
2786 {
2787 let mut peek = convert;
2788 mutable.push(match peek.start_node("call_arg") {
2789 Ok(r) => {
2790 peek.update(r);
2791 peek.meta_bool("mut").is_ok()
2792 }
2793 _ => unreachable!(),
2794 });
2795 convert.update(range);
2796 args.push(val);
2797 } else {
2798 let range = convert.ignore();
2799 convert.update(range);
2800 ignored.push(range);
2801 }
2802 }
2803
2804 if mutable.iter().any(|&arg| arg) {
2806 name.push('(');
2807 let mut first = true;
2808 for &arg in &mutable {
2809 if !first {
2810 name.push(',');
2811 }
2812 name.push_str(if arg { "mut" } else { "_" });
2813 first = false;
2814 }
2815 name.push(')');
2816 }
2817
2818 Ok((
2819 convert.subtract(start),
2820 Call {
2821 args,
2822 f_index: FnIndex::None,
2823 custom_source: None,
2824 info: Box::new(CallInfo {
2825 alias,
2826 name: Arc::new(name),
2827 source_range: convert.source(start).unwrap(),
2828 }),
2829 },
2830 ))
2831 }
2832
2833 fn get_locals(
2834 &mut self,
2835 relative: usize,
2836 stack: &mut Vec<Option<Arc<String>>>,
2837 closure_stack: &mut Vec<usize>,
2838 module: &Module,
2839 use_lookup: &UseLookup,
2840 ) {
2841 use crate::{
2842 FnBinOpRef,
2843 FnExt,
2844 FnReturnRef,
2845 FnUnOpRef,
2846 FnVoidRef,
2847 };
2848
2849 let st = stack.len();
2850 let f_index = if let Some(ref alias) = self.info.alias {
2851 if let Some(&i) = use_lookup
2852 .aliases
2853 .get(alias)
2854 .and_then(|map| map.get(&self.info.name))
2855 {
2856 match i {
2857 FnAlias::Loaded(i) => FnIndex::Loaded(i as isize - relative as isize),
2858 FnAlias::External(i) => {
2859 let f = &module.ext_prelude[i];
2860 match f.f {
2861 FnExt::Void(ff) => FnIndex::Void(FnVoidRef(ff)),
2862 FnExt::Return(ff) => FnIndex::Return(FnReturnRef(ff)),
2863 FnExt::BinOp(ff) => FnIndex::BinOp(FnBinOpRef(ff)),
2864 FnExt::UnOp(ff) => FnIndex::UnOp(FnUnOpRef(ff)),
2865 }
2866 }
2867 }
2868 } else {
2869 FnIndex::None
2870 }
2871 } else {
2872 module.find_function(&self.info.name, relative)
2873 };
2874 self.f_index = f_index;
2875 match f_index {
2876 FnIndex::Loaded(f_index) => {
2877 let index = (f_index + relative as isize) as usize;
2878 if module.functions[index].returns() {
2879 stack.push(None);
2880 }
2881 }
2882 FnIndex::Void(_)
2883 | FnIndex::Return(_)
2884 | FnIndex::Lazy(_, _)
2885 | FnIndex::BinOp(_)
2886 | FnIndex::UnOp(_) => {
2887 }
2890 FnIndex::None => {}
2891 }
2892 for arg in &mut self.args {
2893 let arg_st = stack.len();
2894 arg.get_locals(relative, stack, closure_stack, module, use_lookup);
2895 stack.truncate(arg_st);
2896 if let FnIndex::BinOp(_) = f_index {
2897 } else {
2898 match *arg {
2899 Expression::Swizzle(ref swizzle) => {
2900 for _ in 0..swizzle.len() {
2901 stack.push(None);
2902 }
2903 }
2904 _ => {
2905 stack.push(None);
2906 }
2907 }
2908 }
2909 }
2910 stack.truncate(st);
2911 }
2912
2913 pub fn arg_len(&self) -> usize {
2915 let mut sum = 0;
2916 for arg in &self.args {
2917 match *arg {
2918 Expression::Swizzle(ref swizzle) => {
2919 sum += swizzle.len();
2920 }
2921 _ => {
2922 sum += 1;
2923 }
2924 }
2925 }
2926 sum
2927 }
2928}
2929
2930#[derive(Debug, Clone)]
2932pub struct CallClosure {
2933 pub item: Item,
2935 pub args: Vec<Expression>,
2937 pub source_range: Range,
2939}
2940
2941impl CallClosure {
2942 pub fn from_meta_data(
2944 file: &Arc<String>,
2945 source: &Arc<String>,
2946 mut convert: Convert,
2947 ignored: &mut Vec<Range>,
2948 ) -> Result<(Range, CallClosure), ()> {
2949 let start = convert;
2950 let node = "call_closure";
2951 let start_range = convert.start_node(node)?;
2952 convert.update(start_range);
2953
2954 let mut item: Option<Item> = None;
2955 let mut args = vec![];
2956 let mut mutable: Vec<bool> = vec![];
2957 loop {
2958 if let Ok(range) = convert.end_node(node) {
2959 convert.update(range);
2960 break;
2961 } else if let Ok((range, val)) = Item::from_meta_data(file, source, convert, ignored) {
2962 convert.update(range);
2963 item = Some(val);
2964 } else if let Ok((range, val)) =
2965 Expression::from_meta_data(file, source, "call_arg", convert, ignored)
2966 {
2967 let mut peek = convert;
2968 mutable.push(match peek.start_node("call_arg") {
2969 Ok(r) => {
2970 peek.update(r);
2971 peek.meta_bool("mut").is_ok()
2972 }
2973 _ => unreachable!(),
2974 });
2975 convert.update(range);
2976 args.push(val);
2977 } else {
2978 let range = convert.ignore();
2979 convert.update(range);
2980 ignored.push(range);
2981 }
2982 }
2983
2984 let item = item.ok_or(())?;
2985 Ok((
2986 convert.subtract(start),
2987 CallClosure {
2988 item,
2989 args,
2990 source_range: convert.source(start).unwrap(),
2991 },
2992 ))
2993 }
2994
2995 pub fn named_from_meta_data(
2997 file: &Arc<String>,
2998 source: &Arc<String>,
2999 mut convert: Convert,
3000 ignored: &mut Vec<Range>,
3001 ) -> Result<(Range, CallClosure), ()> {
3002 let start = convert;
3003 let node = "named_call_closure";
3004 let start_range = convert.start_node(node)?;
3005 convert.update(start_range);
3006
3007 let mut item: Option<Item> = None;
3008 let mut name = String::new();
3009 let mut args = vec![];
3010 let mut mutable: Vec<bool> = vec![];
3011 loop {
3012 if let Ok(range) = convert.end_node(node) {
3013 convert.update(range);
3014 break;
3015 } else if let Ok((range, val)) = Item::from_meta_data(file, source, convert, ignored) {
3016 convert.update(range);
3017 item = Some(val);
3018 } else if let Ok((range, val)) = convert.meta_string("word") {
3019 convert.update(range);
3020 if !name.is_empty() {
3021 name.push('_');
3022 }
3023 name.push_str(&val);
3024 } else if let Ok((range, val)) =
3025 Expression::from_meta_data(file, source, "call_arg", convert, ignored)
3026 {
3027 let mut peek = convert;
3028 mutable.push(match peek.start_node("call_arg") {
3029 Ok(r) => {
3030 peek.update(r);
3031 peek.meta_bool("mut").is_ok()
3032 }
3033 _ => unreachable!(),
3034 });
3035 convert.update(range);
3036 args.push(val);
3037 } else {
3038 let range = convert.ignore();
3039 convert.update(range);
3040 ignored.push(range);
3041 }
3042 }
3043
3044 let mut item = item.ok_or(())?;
3045 {
3046 if item.ids.is_empty() {
3047 let n = Arc::make_mut(&mut item.name);
3049 n.push_str("__");
3050 n.push_str(&name);
3051 } else {
3052 let last = item.ids.len() - 1;
3053 if let Id::String(_, ref mut n) = item.ids[last] {
3054 let n = Arc::make_mut(n);
3056 n.push_str("__");
3057 n.push_str(&name);
3058 }
3059 }
3060 }
3061 Ok((
3062 convert.subtract(start),
3063 CallClosure {
3064 item,
3065 args,
3066 source_range: convert.source(start).unwrap(),
3067 },
3068 ))
3069 }
3070
3071 fn get_locals(
3072 &mut self,
3073 relative: usize,
3074 stack: &mut Vec<Option<Arc<String>>>,
3075 closure_stack: &mut Vec<usize>,
3076 module: &Module,
3077 use_lookup: &UseLookup,
3078 ) {
3079 let st = stack.len();
3080 self.item.get_locals(relative, stack, closure_stack, module, use_lookup);
3081 stack.push(Some(crate::runtime::RETURN_TYPE.clone()));
3084 for arg in &mut self.args {
3085 let arg_st = stack.len();
3086 arg.get_locals(relative, stack, closure_stack, module, use_lookup);
3087 stack.truncate(arg_st);
3088 match *arg {
3089 Expression::Swizzle(ref swizzle) => {
3090 for _ in 0..swizzle.len() {
3091 stack.push(None);
3092 }
3093 }
3094 _ => {
3095 stack.push(None);
3096 }
3097 }
3098 }
3099 stack.truncate(st);
3100 }
3101
3102 pub fn arg_len(&self) -> usize {
3104 let mut sum = 0;
3105 for arg in &self.args {
3106 match *arg {
3107 Expression::Swizzle(ref swizzle) => {
3108 sum += swizzle.len();
3109 }
3110 _ => {
3111 sum += 1;
3112 }
3113 }
3114 }
3115 sum
3116 }
3117}
3118
3119#[derive(Debug, Clone)]
3121pub struct Norm {
3122 pub expr: Expression,
3124 pub source_range: Range,
3126}
3127
3128impl Norm {
3129 pub fn from_meta_data(
3131 file: &Arc<String>,
3132 source: &Arc<String>,
3133 mut convert: Convert,
3134 ignored: &mut Vec<Range>,
3135 ) -> Result<(Range, Norm), ()> {
3136 let start = convert;
3137 let node = "norm";
3138 let start_range = convert.start_node(node)?;
3139 convert.update(start_range);
3140
3141 let mut expr: Option<Expression> = None;
3142 loop {
3143 if let Ok(range) = convert.end_node(node) {
3144 convert.update(range);
3145 break;
3146 } else if let Ok((range, val)) =
3147 Expression::from_meta_data(file, source, "expr", convert, ignored)
3148 {
3149 convert.update(range);
3150 expr = Some(val);
3151 } else {
3152 let range = convert.ignore();
3153 convert.update(range);
3154 ignored.push(range);
3155 }
3156 }
3157
3158 let expr = expr.ok_or(())?;
3159 Ok((
3160 convert.subtract(start),
3161 Norm {
3162 expr,
3163 source_range: convert.source(start).unwrap(),
3164 },
3165 ))
3166 }
3167
3168 fn into_call_expr(self) -> Expression {
3169 Expression::Call(Box::new(Call {
3170 args: vec![self.expr],
3171 custom_source: None,
3172 f_index: FnIndex::None,
3173 info: Box::new(CallInfo {
3174 alias: None,
3175 name: crate::NORM.clone(),
3176 source_range: self.source_range,
3177 }),
3178 }))
3179 }
3180}
3181
3182#[derive(Debug, Clone)]
3184pub struct BinOpExpression {
3185 pub op: BinOp,
3187 pub left: Expression,
3189 pub right: Expression,
3191 pub source_range: Range,
3193}
3194
3195impl BinOpExpression {
3196 fn into_expression(self) -> Expression {
3197 use self::BinOp::*;
3198
3199 Expression::Call(Box::new(Call {
3200 args: vec![self.left, self.right],
3201 custom_source: None,
3202 f_index: FnIndex::None,
3203 info: Box::new(CallInfo {
3204 alias: None,
3205 name: match self.op {
3206 Add => crate::ADD.clone(),
3207 Sub => crate::SUB.clone(),
3208 Mul => crate::MUL.clone(),
3209 Div => crate::DIV.clone(),
3210 Rem => crate::REM.clone(),
3211 Pow => crate::POW.clone(),
3212 Dot => crate::DOT.clone(),
3213 Cross => crate::CROSS.clone(),
3214 AndAlso => crate::AND_ALSO.clone(),
3215 OrElse => crate::OR_ELSE.clone(),
3216 Less => crate::LESS.clone(),
3217 LessOrEqual => crate::LESS_OR_EQUAL.clone(),
3218 Greater => crate::GREATER.clone(),
3219 GreaterOrEqual => crate::GREATER_OR_EQUAL.clone(),
3220 Equal => crate::EQUAL.clone(),
3221 NotEqual => crate::NOT_EQUAL.clone(),
3222 },
3223 source_range: self.source_range,
3224 }),
3225 }))
3226 }
3227}
3228
3229pub struct UnOpExpression;
3231
3232impl UnOpExpression {
3233 pub fn from_meta_data(
3235 node: &str,
3236 file: &Arc<String>,
3237 source: &Arc<String>,
3238 mut convert: Convert,
3239 ignored: &mut Vec<Range>,
3240 ) -> Result<(Range, Expression), ()> {
3241 let start = convert;
3242 let start_range = convert.start_node(node)?;
3243 convert.update(start_range);
3244
3245 let mut expr: Option<Expression> = None;
3246 loop {
3247 if let Ok(range) = convert.end_node(node) {
3248 convert.update(range);
3249 break;
3250 } else if let Ok((range, val)) =
3251 Expression::from_meta_data(file, source, "expr", convert, ignored)
3252 {
3253 convert.update(range);
3254 expr = Some(val);
3255 } else {
3256 let range = convert.ignore();
3257 convert.update(range);
3258 ignored.push(range);
3259 }
3260 }
3261
3262 let expr = expr.ok_or(())?;
3263 Ok((convert.subtract(start), {
3264 let name = match node {
3265 "not" => crate::NOT.clone(),
3266 "neg" => crate::NEG.clone(),
3267 _ => return Err(()),
3268 };
3269 Expression::Call(Box::new(Call {
3270 args: vec![expr],
3271 custom_source: None,
3272 f_index: FnIndex::None,
3273 info: Box::new(CallInfo {
3274 alias: None,
3275 name,
3276 source_range: convert.source(start).unwrap(),
3277 }),
3278 }))
3279 }))
3280 }
3281}
3282
3283#[derive(Debug, Clone)]
3285pub struct Assign {
3286 pub op: AssignOp,
3288 pub left: Expression,
3290 pub right: Expression,
3292 pub source_range: Range,
3294}
3295
3296impl Assign {
3297 pub fn from_meta_data(
3299 file: &Arc<String>,
3300 source: &Arc<String>,
3301 mut convert: Convert,
3302 ignored: &mut Vec<Range>,
3303 ) -> Result<(Range, Assign), ()> {
3304 let start = convert;
3305 let node = "assign";
3306 let start_range = convert.start_node(node)?;
3307 convert.update(start_range);
3308
3309 let mut op: Option<AssignOp> = None;
3310 let mut left: Option<Expression> = None;
3311 let mut right: Option<Expression> = None;
3312 loop {
3313 if let Ok(range) = convert.end_node(node) {
3314 convert.update(range);
3315 break;
3316 } else if let Ok((range, _)) = convert.meta_bool(":=") {
3317 convert.update(range);
3318 op = Some(AssignOp::Assign);
3319 } else if let Ok((range, _)) = convert.meta_bool("=") {
3320 convert.update(range);
3321 op = Some(AssignOp::Set);
3322 } else if let Ok((range, _)) = convert.meta_bool("+=") {
3323 convert.update(range);
3324 op = Some(AssignOp::Add);
3325 } else if let Ok((range, _)) = convert.meta_bool("-=") {
3326 convert.update(range);
3327 op = Some(AssignOp::Sub);
3328 } else if let Ok((range, _)) = convert.meta_bool("*=") {
3329 convert.update(range);
3330 op = Some(AssignOp::Mul);
3331 } else if let Ok((range, _)) = convert.meta_bool("/=") {
3332 convert.update(range);
3333 op = Some(AssignOp::Div);
3334 } else if let Ok((range, _)) = convert.meta_bool("%=") {
3335 convert.update(range);
3336 op = Some(AssignOp::Rem);
3337 } else if let Ok((range, _)) = convert.meta_bool("^=") {
3338 convert.update(range);
3339 op = Some(AssignOp::Pow);
3340 } else if let Ok((range, val)) =
3341 Expression::from_meta_data(file, source, "left", convert, ignored)
3342 {
3343 convert.update(range);
3344 left = Some(val);
3345 } else if let Ok((range, val)) =
3346 Expression::from_meta_data(file, source, "right", convert, ignored)
3347 {
3348 convert.update(range);
3349 right = Some(val);
3350 } else {
3351 let range = convert.ignore();
3352 convert.update(range);
3353 ignored.push(range);
3354 }
3355 }
3356
3357 let op = op.ok_or(())?;
3358 let left = left.ok_or(())?;
3359 let right = right.ok_or(())?;
3360 Ok((
3361 convert.subtract(start),
3362 Assign {
3363 op,
3364 left,
3365 right,
3366 source_range: convert.source(start).unwrap(),
3367 },
3368 ))
3369 }
3370
3371 fn get_locals(
3372 &mut self,
3373 relative: usize,
3374 stack: &mut Vec<Option<Arc<String>>>,
3375 closure_stack: &mut Vec<usize>,
3376 module: &Module,
3377 use_lookup: &UseLookup,
3378 ) {
3379 let st = stack.len();
3381 self.right.get_locals(relative, stack, closure_stack, module, use_lookup);
3382 stack.truncate(st);
3383
3384 if let Expression::Item(ref item) = self.left {
3386 if item.ids.is_empty() && self.op == AssignOp::Assign {
3387 stack.push(Some(item.name.clone()));
3388 return;
3389 }
3390 }
3391
3392 self.left.get_locals(relative, stack, closure_stack, module, use_lookup);
3393 stack.truncate(st);
3394 }
3395}
3396
3397#[derive(Debug, Copy, Clone, PartialEq, Eq)]
3399pub enum AssignOp {
3400 Assign,
3402 Set,
3404 Add,
3406 Sub,
3408 Mul,
3410 Div,
3412 Rem,
3414 Pow,
3416}
3417
3418impl AssignOp {
3419 pub fn symbol(self) -> &'static str {
3421 use self::AssignOp::*;
3422
3423 match self {
3424 Assign => ":=",
3425 Set => "=",
3426 Add => "+=",
3427 Sub => "-=",
3428 Mul => "*=",
3429 Div => "/=",
3430 Rem => "%=",
3431 Pow => "^=",
3432 }
3433 }
3434}
3435
3436#[derive(Debug, Clone)]
3438pub struct Mat4 {
3439 pub args: Vec<Expression>,
3441 pub source_range: Range,
3443}
3444
3445impl Mat4 {
3446 pub fn from_meta_data(
3448 file: &Arc<String>,
3449 source: &Arc<String>,
3450 mut convert: Convert,
3451 ignored: &mut Vec<Range>,
3452 ) -> Result<(Range, Mat4), ()> {
3453 let start = convert;
3454 let node = "mat4";
3455 let start_range = convert.start_node(node)?;
3456 convert.update(start_range);
3457
3458 let mut x: Option<Expression> = None;
3459 let mut y: Option<Expression> = None;
3460 let mut z: Option<Expression> = None;
3461 let mut w: Option<Expression> = None;
3462 loop {
3463 if let Ok(range) = convert.end_node(node) {
3464 convert.update(range);
3465 break;
3466 } else if let Ok((range, val)) =
3467 Expression::from_meta_data(file, source, "ex", convert, ignored)
3468 {
3469 convert.update(range);
3470 x = Some(val);
3471 } else if let Ok((range, val)) =
3472 Expression::from_meta_data(file, source, "ey", convert, ignored)
3473 {
3474 convert.update(range);
3475 y = Some(val);
3476 } else if let Ok((range, val)) =
3477 Expression::from_meta_data(file, source, "ez", convert, ignored)
3478 {
3479 convert.update(range);
3480 z = Some(val);
3481 } else if let Ok((range, val)) =
3482 Expression::from_meta_data(file, source, "ew", convert, ignored)
3483 {
3484 convert.update(range);
3485 w = Some(val);
3486 } else {
3487 let range = convert.ignore();
3488 convert.update(range);
3489 ignored.push(range);
3490 }
3491 }
3492
3493 let x = x.ok_or(())?;
3494 let y = y.unwrap_or_else(|| {
3495 Expression::Variable(Box::new((
3496 Range::empty(0),
3497 Variable::Vec4([0.0, 1.0, 0.0, 0.0]),
3498 )))
3499 });
3500 let z = z.unwrap_or_else(|| {
3501 Expression::Variable(Box::new((
3502 Range::empty(0),
3503 Variable::Vec4([0.0, 0.0, 1.0, 0.0]),
3504 )))
3505 });
3506 let w = w.unwrap_or_else(|| {
3507 Expression::Variable(Box::new((
3508 Range::empty(0),
3509 Variable::Vec4([0.0, 0.0, 0.0, 1.0]),
3510 )))
3511 });
3512 Ok((
3513 convert.subtract(start),
3514 Mat4 {
3515 args: vec![x, y, z, w],
3516 source_range: convert.source(start).unwrap(),
3517 },
3518 ))
3519 }
3520
3521 fn get_locals(
3522 &mut self,
3523 relative: usize,
3524 stack: &mut Vec<Option<Arc<String>>>,
3525 closure_stack: &mut Vec<usize>,
3526 module: &Module,
3527 use_lookup: &UseLookup,
3528 ) {
3529 let st = stack.len();
3530 for arg in &mut self.args {
3531 let arg_st = stack.len();
3532 arg.get_locals(relative, stack, closure_stack, module, use_lookup);
3533 stack.truncate(arg_st);
3534 stack.push(None);
3535 }
3536 stack.truncate(st);
3537 }
3538}
3539
3540#[derive(Debug, Clone)]
3542pub struct Vec4 {
3543 pub args: Vec<Expression>,
3545 pub source_range: Range,
3547}
3548
3549impl Vec4 {
3550 pub fn from_meta_data(
3552 file: &Arc<String>,
3553 source: &Arc<String>,
3554 mut convert: Convert,
3555 ignored: &mut Vec<Range>,
3556 ) -> Result<(Range, Vec4), ()> {
3557 let start = convert;
3558 let node = "vec4";
3559 let start_range = convert.start_node(node)?;
3560 convert.update(start_range);
3561
3562 let mut x: Option<Expression> = None;
3563 let mut y: Option<Expression> = None;
3564 let mut z: Option<Expression> = None;
3565 let mut w: Option<Expression> = None;
3566 loop {
3567 if let Ok(range) = convert.end_node(node) {
3568 convert.update(range);
3569 break;
3570 } else if let Ok((range, val)) =
3571 Expression::from_meta_data(file, source, "x", convert, ignored)
3572 {
3573 convert.update(range);
3574 x = Some(val);
3575 } else if let Ok((range, val)) =
3576 Expression::from_meta_data(file, source, "y", convert, ignored)
3577 {
3578 convert.update(range);
3579 y = Some(val);
3580 } else if let Ok((range, val)) =
3581 Expression::from_meta_data(file, source, "z", convert, ignored)
3582 {
3583 convert.update(range);
3584 z = Some(val);
3585 } else if let Ok((range, val)) =
3586 Expression::from_meta_data(file, source, "w", convert, ignored)
3587 {
3588 convert.update(range);
3589 w = Some(val);
3590 } else {
3591 let range = convert.ignore();
3592 convert.update(range);
3593 ignored.push(range);
3594 }
3595 }
3596
3597 let x = x.ok_or(())?;
3598 let y = y.unwrap_or_else(|| {
3599 Expression::Variable(Box::new((Range::empty(0), Variable::f64(0.0))))
3600 });
3601 let z = z.unwrap_or_else(|| {
3602 Expression::Variable(Box::new((Range::empty(0), Variable::f64(0.0))))
3603 });
3604 let w = w.unwrap_or_else(|| {
3605 Expression::Variable(Box::new((Range::empty(0), Variable::f64(0.0))))
3606 });
3607 Ok((
3608 convert.subtract(start),
3609 Vec4 {
3610 args: vec![x, y, z, w],
3611 source_range: convert.source(start).unwrap(),
3612 },
3613 ))
3614 }
3615
3616 fn precompute(&self) -> Option<Variable> {
3617 let mut v: [f32; 4] = [0.0; 4];
3618 for i in 0..self.args.len().min(4) {
3619 if let Some(val) = self.args[i].precompute() {
3620 if let Variable::F64(val, _) = val {
3621 v[i] = val as f32;
3622 } else {
3623 return None;
3624 }
3625 } else {
3626 return None;
3627 }
3628 }
3629 Some(Variable::Vec4(v))
3630 }
3631
3632 fn get_locals(
3633 &mut self,
3634 relative: usize,
3635 stack: &mut Vec<Option<Arc<String>>>,
3636 closure_stack: &mut Vec<usize>,
3637 module: &Module,
3638 use_lookup: &UseLookup,
3639 ) {
3640 let st = stack.len();
3641 for arg in &mut self.args {
3642 let arg_st = stack.len();
3643 arg.get_locals(relative, stack, closure_stack, module, use_lookup);
3644 stack.truncate(arg_st);
3645 match *arg {
3646 Expression::Swizzle(ref swizzle) => {
3647 for _ in 0..swizzle.len() {
3648 stack.push(None);
3649 }
3650 }
3651 _ => {
3652 stack.push(None);
3653 }
3654 }
3655 }
3656 stack.truncate(st);
3657 }
3658}
3659
3660#[derive(Debug, Clone)]
3662pub struct Vec4UnLoop {
3663 pub name: Arc<String>,
3665 pub expr: Expression,
3667 pub len: u8,
3669 pub source_range: Range,
3671}
3672
3673impl Vec4UnLoop {
3674 pub fn from_meta_data(
3676 file: &Arc<String>,
3677 source: &Arc<String>,
3678 mut convert: Convert,
3679 ignored: &mut Vec<Range>,
3680 ) -> Result<(Range, Vec4UnLoop), ()> {
3681 let start = convert;
3682 let node = "vec4_un_loop";
3683 let start_range = convert.start_node(node)?;
3684 convert.update(start_range);
3685
3686 let mut name: Option<Arc<String>> = None;
3687 let mut expr: Option<Expression> = None;
3688 let mut len: u8 = 4;
3689 loop {
3690 if let Ok(range) = convert.end_node(node) {
3691 convert.update(range);
3692 break;
3693 } else if let Ok((range, _)) = convert.meta_bool("4") {
3694 convert.update(range);
3695 len = 4;
3696 } else if let Ok((range, _)) = convert.meta_bool("3") {
3697 convert.update(range);
3698 len = 3;
3699 } else if let Ok((range, _)) = convert.meta_bool("2") {
3700 convert.update(range);
3701 len = 2;
3702 } else if let Ok((range, val)) = convert.meta_string("name") {
3703 convert.update(range);
3704 name = Some(val);
3705 } else if let Ok((range, val)) =
3706 Expression::from_meta_data(file, source, "expr", convert, ignored)
3707 {
3708 convert.update(range);
3709 expr = Some(val);
3710 } else {
3711 let range = convert.ignore();
3712 convert.update(range);
3713 ignored.push(range);
3714 }
3715 }
3716
3717 let name = name.ok_or(())?;
3718 let expr = expr.ok_or(())?;
3719 Ok((
3720 convert.subtract(start),
3721 Vec4UnLoop {
3722 name,
3723 expr,
3724 len,
3725 source_range: convert.source(start).unwrap(),
3726 },
3727 ))
3728 }
3729
3730 fn into_expression(self) -> Expression {
3731 let source_range = self.source_range;
3732
3733 let zero = || Expression::Variable(Box::new((source_range, Variable::f64(0.0))));
3734
3735 let replace_0 = replace::number(&self.expr, &self.name, 0.0);
3736 let replace_1 = replace::number(&self.expr, &self.name, 1.0);
3737 let replace_2 = if self.len > 2 {
3738 replace::number(&self.expr, &self.name, 2.0)
3739 } else {
3740 zero()
3741 };
3742 let replace_3 = if self.len > 3 {
3743 replace::number(&self.expr, &self.name, 3.0)
3744 } else {
3745 zero()
3746 };
3747
3748 Expression::Vec4(Box::new(Vec4 {
3749 args: vec![replace_0, replace_1, replace_2, replace_3],
3750 source_range,
3751 }))
3752 }
3753}
3754
3755#[derive(Debug, Clone)]
3757pub struct Swizzle {
3758 pub sw0: usize,
3760 pub sw1: usize,
3762 pub sw2: Option<usize>,
3764 pub sw3: Option<usize>,
3766 pub expr: Expression,
3768 pub source_range: Range,
3770}
3771
3772impl Swizzle {
3773 pub fn from_meta_data(
3775 file: &Arc<String>,
3776 source: &Arc<String>,
3777 mut convert: Convert,
3778 ignored: &mut Vec<Range>,
3779 ) -> Result<(Range, Swizzle), ()> {
3780 let start = convert;
3781 let node = "swizzle";
3782 let start_range = convert.start_node(node)?;
3783 convert.update(start_range);
3784
3785 let mut sw0: Option<usize> = None;
3786 let mut sw1: Option<usize> = None;
3787 let mut sw2: Option<usize> = None;
3788 let mut sw3: Option<usize> = None;
3789 let mut expr: Option<Expression> = None;
3790 loop {
3791 if let Ok(range) = convert.end_node(node) {
3792 convert.update(range);
3793 break;
3794 } else if let Ok((range, val)) = Sw::from_meta_data("sw0", convert, ignored) {
3795 convert.update(range);
3796 sw0 = Some(val.ind);
3797 } else if let Ok((range, val)) = Sw::from_meta_data("sw1", convert, ignored) {
3798 convert.update(range);
3799 sw1 = Some(val.ind);
3800 } else if let Ok((range, val)) = Sw::from_meta_data("sw2", convert, ignored) {
3801 convert.update(range);
3802 sw2 = Some(val.ind);
3803 } else if let Ok((range, val)) = Sw::from_meta_data("sw3", convert, ignored) {
3804 convert.update(range);
3805 sw3 = Some(val.ind);
3806 } else if let Ok((range, val)) =
3807 Expression::from_meta_data(file, source, "expr", convert, ignored)
3808 {
3809 convert.update(range);
3810 expr = Some(val);
3811 } else {
3812 let range = convert.ignore();
3813 convert.update(range);
3814 ignored.push(range);
3815 }
3816 }
3817
3818 let sw0 = sw0.ok_or(())?;
3819 let sw1 = sw1.ok_or(())?;
3820 let expr = expr.ok_or(())?;
3821 Ok((
3822 convert.subtract(start),
3823 Swizzle {
3824 sw0,
3825 sw1,
3826 sw2,
3827 sw3,
3828 expr,
3829 source_range: convert.source(start).unwrap(),
3830 },
3831 ))
3832 }
3833
3834 fn len(&self) -> usize {
3835 2 + if self.sw2.is_some() { 1 } else { 0 } + if self.sw3.is_some() { 1 } else { 0 }
3836 }
3837}
3838
3839#[derive(Debug, Clone)]
3841pub struct Sw {
3842 pub ind: usize,
3844 pub source_range: Range,
3846}
3847
3848impl Sw {
3849 pub fn from_meta_data(
3851 node: &str,
3852 mut convert: Convert,
3853 ignored: &mut Vec<Range>,
3854 ) -> Result<(Range, Sw), ()> {
3855 let start = convert;
3856 let start_range = convert.start_node(node)?;
3857 convert.update(start_range);
3858
3859 let mut ind: Option<usize> = None;
3860 loop {
3861 if let Ok(range) = convert.end_node(node) {
3862 convert.update(range);
3863 break;
3864 } else if let Ok((range, _)) = convert.meta_bool("x") {
3865 convert.update(range);
3866 ind = Some(0);
3867 } else if let Ok((range, _)) = convert.meta_bool("y") {
3868 convert.update(range);
3869 ind = Some(1);
3870 } else if let Ok((range, _)) = convert.meta_bool("z") {
3871 convert.update(range);
3872 ind = Some(2);
3873 } else if let Ok((range, _)) = convert.meta_bool("w") {
3874 convert.update(range);
3875 ind = Some(3);
3876 } else {
3877 let range = convert.ignore();
3878 convert.update(range);
3879 ignored.push(range);
3880 }
3881 }
3882
3883 let ind = ind.ok_or(())?;
3884 Ok((
3885 convert.subtract(start),
3886 Sw {
3887 ind,
3888 source_range: convert.source(start).unwrap(),
3889 },
3890 ))
3891 }
3892}
3893
3894#[derive(Debug, Clone)]
3896pub struct For {
3897 pub init: Expression,
3899 pub cond: Expression,
3901 pub step: Expression,
3903 pub block: Block,
3905 pub label: Option<Arc<String>>,
3907 pub source_range: Range,
3909}
3910
3911impl For {
3912 pub fn from_meta_data(
3914 file: &Arc<String>,
3915 source: &Arc<String>,
3916 mut convert: Convert,
3917 ignored: &mut Vec<Range>,
3918 ) -> Result<(Range, For), ()> {
3919 let start = convert;
3920 let node = "for";
3921 let start_range = convert.start_node(node)?;
3922 convert.update(start_range);
3923
3924 let mut init: Option<Expression> = None;
3925 let mut cond: Option<Expression> = None;
3926 let mut step: Option<Expression> = None;
3927 let mut block: Option<Block> = None;
3928 let mut label: Option<Arc<String>> = None;
3929 loop {
3930 if let Ok(range) = convert.end_node(node) {
3931 convert.update(range);
3932 break;
3933 } else if let Ok((range, val)) =
3934 Expression::from_meta_data(file, source, "init", convert, ignored)
3935 {
3936 convert.update(range);
3937 init = Some(val);
3938 } else if let Ok((range, val)) =
3939 Expression::from_meta_data(file, source, "cond", convert, ignored)
3940 {
3941 convert.update(range);
3942 cond = Some(val);
3943 } else if let Ok((range, val)) =
3944 Expression::from_meta_data(file, source, "step", convert, ignored)
3945 {
3946 convert.update(range);
3947 step = Some(val);
3948 } else if let Ok((range, val)) =
3949 Block::from_meta_data(file, source, "block", convert, ignored)
3950 {
3951 convert.update(range);
3952 block = Some(val);
3953 } else if let Ok((range, val)) = convert.meta_string("label") {
3954 convert.update(range);
3955 label = Some(val);
3956 } else {
3957 let range = convert.ignore();
3958 convert.update(range);
3959 ignored.push(range);
3960 }
3961 }
3962
3963 let init = init.ok_or(())?;
3964 let cond = cond.ok_or(())?;
3965 let step = step.ok_or(())?;
3966 let block = block.ok_or(())?;
3967 Ok((
3968 convert.subtract(start),
3969 For {
3970 init,
3971 cond,
3972 step,
3973 block,
3974 label,
3975 source_range: convert.source(start).unwrap(),
3976 },
3977 ))
3978 }
3979
3980 fn get_locals(
3981 &mut self,
3982 relative: usize,
3983 stack: &mut Vec<Option<Arc<String>>>,
3984 closure_stack: &mut Vec<usize>,
3985 module: &Module,
3986 use_lookup: &UseLookup,
3987 ) {
3988 let st = stack.len();
3989 self.init.get_locals(relative, stack, closure_stack, module, use_lookup);
3990 let after_init = stack.len();
3991 self.cond.get_locals(relative, stack, closure_stack, module, use_lookup);
3992 stack.truncate(after_init);
3993 self.step.get_locals(relative, stack, closure_stack, module, use_lookup);
3994 stack.truncate(after_init);
3995 self.block.get_locals(relative, stack, closure_stack, module, use_lookup);
3996 stack.truncate(st);
3997 }
3998}
3999
4000#[derive(Debug, Clone)]
4002#[cfg(all(not(target_family = "wasm"), feature = "threading"))]
4003pub struct ForIn {
4004 pub name: Arc<String>,
4006 pub iter: Expression,
4008 pub block: Block,
4010 pub label: Option<Arc<String>>,
4012 pub source_range: Range,
4014}
4015
4016#[derive(Debug, Clone)]
4018#[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
4019pub enum ForIn {}
4020
4021impl ForIn {
4022 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
4024 pub fn from_meta_data(
4025 file: &Arc<String>,
4026 source: &Arc<String>,
4027 node: &str,
4028 mut convert: Convert,
4029 ignored: &mut Vec<Range>,
4030 ) -> Result<(Range, ForIn), ()> {
4031 let start = convert;
4032 let start_range = convert.start_node(node)?;
4033 convert.update(start_range);
4034
4035 let mut name: Option<Arc<String>> = None;
4036 let mut iter: Option<Expression> = None;
4037 let mut block: Option<Block> = None;
4038 let mut label: Option<Arc<String>> = None;
4039 loop {
4040 if let Ok(range) = convert.end_node(node) {
4041 convert.update(range);
4042 break;
4043 } else if let Ok((range, val)) = convert.meta_string("name") {
4044 convert.update(range);
4045 name = Some(val);
4046 } else if let Ok((range, val)) =
4047 Expression::from_meta_data(file, source, "iter", convert, ignored)
4048 {
4049 convert.update(range);
4050 iter = Some(val);
4051 } else if let Ok((range, val)) =
4052 Block::from_meta_data(file, source, "block", convert, ignored)
4053 {
4054 convert.update(range);
4055 block = Some(val);
4056 } else if let Ok((range, val)) = convert.meta_string("label") {
4057 convert.update(range);
4058 label = Some(val);
4059 } else {
4060 let range = convert.ignore();
4061 convert.update(range);
4062 ignored.push(range);
4063 }
4064 }
4065
4066 let name = name.ok_or(())?;
4067 let iter = iter.ok_or(())?;
4068 let block = block.ok_or(())?;
4069 Ok((
4070 convert.subtract(start),
4071 ForIn {
4072 name,
4073 iter,
4074 block,
4075 label,
4076 source_range: convert.source(start).unwrap(),
4077 },
4078 ))
4079 }
4080
4081 #[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
4083 pub fn from_meta_data(
4084 _file: &Arc<String>,
4085 _source: &Arc<String>,
4086 _node: &str,
4087 _convert: Convert,
4088 _ignored: &mut Vec<Range>,
4089 ) -> Result<(Range, ForIn), ()> {
4090 Err(())
4091 }
4092
4093 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
4094 fn get_locals(
4095 &mut self,
4096 relative: usize,
4097 stack: &mut Vec<Option<Arc<String>>>,
4098 closure_stack: &mut Vec<usize>,
4099 module: &Module,
4100 use_lookup: &UseLookup,
4101 ) {
4102 let st = stack.len();
4103 self.iter.get_locals(relative, stack, closure_stack, module, use_lookup);
4104 stack.truncate(st);
4105 stack.push(Some(self.name.clone()));
4106 self.block.get_locals(relative, stack, closure_stack, module, use_lookup);
4107 stack.truncate(st);
4108 }
4109
4110 #[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
4111 fn get_locals(
4112 &mut self,
4113 _relative: usize,
4114 _stack: &mut Vec<Option<Arc<String>>>,
4115 _closure_stack: &mut Vec<usize>,
4116 _module: &Module,
4117 _use_lookup: &UseLookup,
4118 ) {}
4119}
4120
4121#[derive(Debug, Clone)]
4123pub struct ForN {
4124 pub name: Arc<String>,
4126 pub start: Option<Expression>,
4130 pub end: Expression,
4134 pub block: Block,
4136 pub label: Option<Arc<String>>,
4138 pub source_range: Range,
4140}
4141
4142impl ForN {
4143 pub fn from_meta_data(
4145 file: &Arc<String>,
4146 source: &Arc<String>,
4147 node: &str,
4148 mut convert: Convert,
4149 ignored: &mut Vec<Range>,
4150 ) -> Result<(Range, ForN), ()> {
4151 let start = convert;
4152 let start_range = convert.start_node(node)?;
4153 convert.update(start_range);
4154
4155 let mut indices: Vec<(Arc<String>, Option<Expression>, Option<Expression>)> = vec![];
4156 let mut block: Option<Block> = None;
4157 let mut label: Option<Arc<String>> = None;
4158 loop {
4159 if let Ok(range) = convert.end_node(node) {
4160 convert.update(range);
4161 break;
4162 } else if let Ok((range, val)) =
4163 Block::from_meta_data(file, source, "block", convert, ignored)
4164 {
4165 convert.update(range);
4166 block = Some(val);
4167 } else if let Ok((range, val)) = convert.meta_string("label") {
4168 convert.update(range);
4169 label = Some(val);
4170 } else if let Ok((range, val)) = convert.meta_string("name") {
4171 convert.update(range);
4172 let mut start_expr: Option<Expression> = None;
4173 let mut end_expr: Option<Expression> = None;
4174 if let Ok((range, val)) =
4175 Expression::from_meta_data(file, source, "start", convert, ignored)
4176 {
4177 convert.update(range);
4178 start_expr = Some(val);
4179 }
4180 if let Ok((range, val)) =
4181 Expression::from_meta_data(file, source, "end", convert, ignored)
4182 {
4183 convert.update(range);
4184 end_expr = Some(val);
4185 }
4186 indices.push((val, start_expr, end_expr));
4187 } else {
4188 let range = convert.ignore();
4189 convert.update(range);
4190 ignored.push(range);
4191 }
4192 }
4193
4194 ForN::create(
4195 node,
4196 convert.subtract(start),
4197 convert.source(start).unwrap(),
4198 label,
4199 &indices,
4200 block,
4201 )
4202 }
4203
4204 fn create(
4205 node: &str,
4206 range: Range,
4207 source_range: Range,
4208 label: Option<Arc<String>>,
4209 indices: &[(Arc<String>, Option<Expression>, Option<Expression>)],
4210 mut block: Option<Block>,
4211 ) -> Result<(Range, ForN), ()> {
4212 if indices.is_empty() {
4213 return Err(());
4214 }
4215
4216 let name: Arc<String> = indices[0].0.clone();
4217 let start_expr = indices[0].1.clone();
4218 let mut end_expr = indices[0].2.clone();
4219
4220 if indices.len() > 1 {
4221 let (_, new_for_n) =
4222 ForN::create(node, range, source_range, None, &indices[1..], block)?;
4223 block = Some(Block {
4224 source_range,
4225 expressions: vec![match node {
4226 "for_n" => Expression::ForN(Box::new(new_for_n)),
4227 "sum" => Expression::Sum(Box::new(new_for_n)),
4228 "sum_vec4" => Expression::SumVec4(Box::new(new_for_n)),
4229 "prod" => Expression::Prod(Box::new(new_for_n)),
4230 "prod_vec4" => Expression::ProdVec4(Box::new(new_for_n)),
4231 "any" => Expression::Any(Box::new(new_for_n)),
4232 "all" => Expression::All(Box::new(new_for_n)),
4233 "min" => Expression::Min(Box::new(new_for_n)),
4234 "max" => Expression::Max(Box::new(new_for_n)),
4235 "sift" => Expression::Sift(Box::new(new_for_n)),
4236 "link_for" => Expression::LinkFor(Box::new(new_for_n)),
4237 _ => return Err(()),
4238 }],
4239 });
4240 }
4241
4242 let block = block.ok_or(())?;
4243
4244 if end_expr.is_none() {
4246 end_expr = infer_len::infer(&block, &name);
4247 }
4248
4249 let end_expr = end_expr.ok_or(())?;
4250 Ok((
4251 range,
4252 ForN {
4253 name,
4254 start: start_expr,
4255 end: end_expr,
4256 block,
4257 label,
4258 source_range,
4259 },
4260 ))
4261 }
4262
4263 fn get_locals(
4264 &mut self,
4265 relative: usize,
4266 stack: &mut Vec<Option<Arc<String>>>,
4267 closure_stack: &mut Vec<usize>,
4268 module: &Module,
4269 use_lookup: &UseLookup,
4270 ) {
4271 let st = stack.len();
4272 if let Some(ref mut start) = self.start {
4273 start.get_locals(relative, stack, closure_stack, module, use_lookup);
4274 stack.truncate(st);
4275 }
4276 self.end.get_locals(relative, stack, closure_stack, module, use_lookup);
4277 stack.truncate(st);
4278 stack.push(Some(self.name.clone()));
4279 self.block.get_locals(relative, stack, closure_stack, module, use_lookup);
4280 stack.truncate(st);
4281 }
4282}
4283
4284#[derive(Debug, Clone)]
4286pub struct Loop {
4287 pub block: Block,
4289 pub label: Option<Arc<String>>,
4291 pub source_range: Range,
4293}
4294
4295impl Loop {
4296 pub fn from_meta_data(
4298 file: &Arc<String>,
4299 source: &Arc<String>,
4300 mut convert: Convert,
4301 ignored: &mut Vec<Range>,
4302 ) -> Result<(Range, Loop), ()> {
4303 let start = convert;
4304 let node = "loop";
4305 let start_range = convert.start_node(node)?;
4306 convert.update(start_range);
4307
4308 let mut block: Option<Block> = None;
4309 let mut label: Option<Arc<String>> = None;
4310 loop {
4311 if let Ok(range) = convert.end_node(node) {
4312 convert.update(range);
4313 break;
4314 } else if let Ok((range, val)) =
4315 Block::from_meta_data(file, source, "block", convert, ignored)
4316 {
4317 convert.update(range);
4318 block = Some(val);
4319 } else if let Ok((range, val)) = convert.meta_string("label") {
4320 convert.update(range);
4321 label = Some(val);
4322 } else {
4323 let range = convert.ignore();
4324 convert.update(range);
4325 ignored.push(range);
4326 }
4327 }
4328
4329 let block = block.ok_or(())?;
4330 Ok((
4331 convert.subtract(start),
4332 Loop {
4333 block,
4334 label,
4335 source_range: convert.source(start).unwrap(),
4336 },
4337 ))
4338 }
4339
4340 fn into_expression(self) -> Expression {
4341 let source_range = self.source_range;
4342 Expression::For(Box::new(For {
4343 block: self.block,
4344 label: self.label,
4345 init: Expression::Block(Box::new(Block {
4346 expressions: vec![],
4347 source_range,
4348 })),
4349 step: Expression::Block(Box::new(Block {
4350 expressions: vec![],
4351 source_range,
4352 })),
4353 cond: Expression::Variable(Box::new((source_range, Variable::bool(true)))),
4354 source_range,
4355 }))
4356 }
4357}
4358
4359#[derive(Debug, Clone)]
4361pub struct Break {
4362 pub label: Option<Arc<String>>,
4364 pub source_range: Range,
4366}
4367
4368impl Break {
4369 pub fn from_meta_data(
4371 mut convert: Convert,
4372 ignored: &mut Vec<Range>,
4373 ) -> Result<(Range, Break), ()> {
4374 let start = convert;
4375 let node = "break";
4376 let start_range = convert.start_node(node)?;
4377 convert.update(start_range);
4378
4379 let mut label: Option<Arc<String>> = None;
4380 loop {
4381 if let Ok(range) = convert.end_node(node) {
4382 convert.update(range);
4383 break;
4384 } else if let Ok((range, val)) = convert.meta_string("label") {
4385 convert.update(range);
4386 label = Some(val);
4387 } else {
4388 let range = convert.ignore();
4389 convert.update(range);
4390 ignored.push(range);
4391 }
4392 }
4393
4394 Ok((
4395 convert.subtract(start),
4396 Break {
4397 label,
4398 source_range: convert.source(start).unwrap(),
4399 },
4400 ))
4401 }
4402}
4403
4404#[derive(Debug, Clone)]
4406pub struct Continue {
4407 pub label: Option<Arc<String>>,
4409 pub source_range: Range,
4411}
4412
4413impl Continue {
4414 pub fn from_meta_data(
4416 mut convert: Convert,
4417 ignored: &mut Vec<Range>,
4418 ) -> Result<(Range, Continue), ()> {
4419 let start = convert;
4420 let node = "continue";
4421 let start_range = convert.start_node(node)?;
4422 convert.update(start_range);
4423
4424 let mut label: Option<Arc<String>> = None;
4425 loop {
4426 if let Ok(range) = convert.end_node(node) {
4427 convert.update(range);
4428 break;
4429 } else if let Ok((range, val)) = convert.meta_string("label") {
4430 convert.update(range);
4431 label = Some(val);
4432 } else {
4433 let range = convert.ignore();
4434 convert.update(range);
4435 ignored.push(range);
4436 }
4437 }
4438
4439 Ok((
4440 convert.subtract(start),
4441 Continue {
4442 label,
4443 source_range: convert.source(start).unwrap(),
4444 },
4445 ))
4446 }
4447}
4448
4449#[derive(Debug, Clone)]
4451pub struct If {
4452 pub cond: Expression,
4454 pub true_block: Block,
4456 pub else_if_conds: Vec<Expression>,
4458 pub else_if_blocks: Vec<Block>,
4460 pub else_block: Option<Block>,
4462 pub source_range: Range,
4464}
4465
4466impl If {
4467 pub fn from_meta_data(
4469 file: &Arc<String>,
4470 source: &Arc<String>,
4471 mut convert: Convert,
4472 ignored: &mut Vec<Range>,
4473 ) -> Result<(Range, If), ()> {
4474 let start = convert;
4475 let node = "if";
4476 let start_range = convert.start_node(node)?;
4477 convert.update(start_range);
4478
4479 let mut cond: Option<Expression> = None;
4480 let mut true_block: Option<Block> = None;
4481 let mut else_if_conds: Vec<Expression> = vec![];
4482 let mut else_if_blocks: Vec<Block> = vec![];
4483 let mut else_block: Option<Block> = None;
4484 loop {
4485 if let Ok(range) = convert.end_node(node) {
4486 convert.update(range);
4487 break;
4488 } else if let Ok((range, val)) =
4489 Expression::from_meta_data(file, source, "cond", convert, ignored)
4490 {
4491 convert.update(range);
4492 cond = Some(val);
4493 } else if let Ok((range, val)) =
4494 Block::from_meta_data(file, source, "true_block", convert, ignored)
4495 {
4496 convert.update(range);
4497 true_block = Some(val);
4498 } else if let Ok((range, val)) =
4499 Expression::from_meta_data(file, source, "else_if_cond", convert, ignored)
4500 {
4501 convert.update(range);
4502 else_if_conds.push(val);
4503 } else if let Ok((range, val)) =
4504 Block::from_meta_data(file, source, "else_if_block", convert, ignored)
4505 {
4506 convert.update(range);
4507 else_if_blocks.push(val);
4508 } else if let Ok((range, val)) =
4509 Block::from_meta_data(file, source, "else_block", convert, ignored)
4510 {
4511 convert.update(range);
4512 else_block = Some(val);
4513 } else {
4514 let range = convert.ignore();
4515 convert.update(range);
4516 ignored.push(range);
4517 }
4518 }
4519
4520 let cond = cond.ok_or(())?;
4521 let true_block = true_block.ok_or(())?;
4522 Ok((
4523 convert.subtract(start),
4524 If {
4525 cond,
4526 true_block,
4527 else_if_conds,
4528 else_if_blocks,
4529 else_block,
4530 source_range: convert.source(start).unwrap(),
4531 },
4532 ))
4533 }
4534
4535 fn get_locals(
4536 &mut self,
4537 relative: usize,
4538 stack: &mut Vec<Option<Arc<String>>>,
4539 closure_stack: &mut Vec<usize>,
4540 module: &Module,
4541 use_lookup: &UseLookup,
4542 ) {
4543 let st = stack.len();
4544 self.cond.get_locals(relative, stack, closure_stack, module, use_lookup);
4545 stack.truncate(st);
4546 self.true_block.get_locals(relative, stack, closure_stack, module, use_lookup);
4547 stack.truncate(st);
4548 for else_if_cond in &mut self.else_if_conds {
4551 else_if_cond.get_locals(relative, stack, closure_stack, module, use_lookup);
4552 stack.truncate(st);
4553 }
4554 for else_if_block in &mut self.else_if_blocks {
4555 else_if_block.get_locals(relative, stack, closure_stack, module, use_lookup);
4556 stack.truncate(st);
4557 }
4558 if let Some(ref mut else_block) = self.else_block {
4559 else_block.get_locals(relative, stack, closure_stack, module, use_lookup);
4560 stack.truncate(st);
4561 }
4562 }
4563}
4564
4565#[derive(Debug, Clone)]
4567#[cfg(all(not(target_family = "wasm"), feature = "threading"))]
4568pub struct In {
4569 pub alias: Option<Arc<String>>,
4571 pub name: Arc<String>,
4573 pub f_index: Cell<FnIndex>,
4575 pub source_range: Range,
4577}
4578
4579#[derive(Debug, Clone)]
4581#[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
4582pub enum In {}
4583
4584impl In {
4585 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
4587 pub fn from_meta_data(
4588 node: &'static str,
4589 mut convert: Convert,
4590 ignored: &mut Vec<Range>,
4591 ) -> Result<(Range, In), ()> {
4592 let start = convert;
4593 let start_range = convert.start_node(node)?;
4594 convert.update(start_range);
4595
4596 let mut name: Option<Arc<String>> = None;
4597 let mut alias: Option<Arc<String>> = None;
4598 loop {
4599 if let Ok(range) = convert.end_node(node) {
4600 convert.update(range);
4601 break;
4602 } else if let Ok((range, val)) = convert.meta_string("alias") {
4603 convert.update(range);
4604 alias = Some(val);
4605 } else if let Ok((range, val)) = convert.meta_string("name") {
4606 convert.update(range);
4607 name = Some(val);
4608 } else {
4609 let range = convert.ignore();
4610 convert.update(range);
4611 ignored.push(range);
4612 }
4613 }
4614
4615 let name = name.ok_or(())?;
4616 Ok((
4617 convert.subtract(start),
4618 In {
4619 alias,
4620 name,
4621 f_index: Cell::new(FnIndex::None),
4622 source_range: convert.source(start).unwrap(),
4623 },
4624 ))
4625 }
4626
4627 #[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
4629 pub fn from_meta_data(
4630 _node: &'static str,
4631 _convert: Convert,
4632 _ignored: &mut Vec<Range>,
4633 ) -> Result<(Range, In), ()> {
4634 Err(())
4635 }
4636
4637 #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
4638 fn get_locals(&mut self, relative: usize, module: &Module, use_lookup: &UseLookup) {
4639 use crate::{
4640 FnBinOpRef,
4641 FnExt,
4642 FnReturnRef,
4643 FnUnOpRef,
4644 FnVoidRef,
4645 };
4646
4647 let f_index = if let Some(ref alias) = self.alias {
4648 if let Some(&i) = use_lookup
4649 .aliases
4650 .get(alias)
4651 .and_then(|map| map.get(&self.name))
4652 {
4653 match i {
4654 FnAlias::Loaded(i) => FnIndex::Loaded(i as isize - relative as isize),
4655 FnAlias::External(i) => {
4656 let f = &module.ext_prelude[i];
4657 match f.f {
4658 FnExt::Void(ff) => FnIndex::Void(FnVoidRef(ff)),
4659 FnExt::Return(ff) => FnIndex::Return(FnReturnRef(ff)),
4660 FnExt::BinOp(ff) => FnIndex::BinOp(FnBinOpRef(ff)),
4661 FnExt::UnOp(ff) => FnIndex::UnOp(FnUnOpRef(ff)),
4662 }
4663 }
4664 }
4665 } else {
4666 FnIndex::None
4667 }
4668 } else {
4669 module.find_function(&self.name, relative)
4670 };
4671 self.f_index.set(f_index);
4672 }
4673
4674 #[cfg(not(all(not(target_family = "wasm"), feature = "threading")))]
4675 fn get_locals(&mut self, _relative: usize, _module: &Module, _use_lookup: &UseLookup) {}
4676}