1use crate::{parser, span};
9use flags::FlagSetConstructor;
10use geo_aid_derive::CloneWithNode;
11use geo_aid_figure::Style;
12use num_traits::{One, Zero};
13use std::any::Any;
14use std::fmt::Formatter;
15use std::mem;
16use std::{
17 collections::{hash_map::Entry, HashMap},
18 fmt::{Debug, Display},
19 hash::Hash,
20 ops::{Deref, DerefMut},
21 rc::Rc,
22 write,
23};
24
25use crate::figure::SpannedMathString;
26use crate::ty;
27use library::macros::index;
28
29use self::context::CompileContext;
30use self::figure::{
31 AnyExprNode, CircleNode, CollectionNode, EmptyNode, FromExpr, HierarchyNode, LineNode,
32 LineType, MaybeUnset, Node, NumberNode, PCNode, PointNode,
33};
34use self::library::Library;
35
36use super::parser::{
37 ExprBinop, ExprCall, FromProperty, InputStream, Name, PointCollectionConstructor, RefStatement,
38};
39use super::token::number::{CompExponent, ProcNum};
40use super::token::NumberLit;
41use super::{
42 parser::{
43 BinaryOperator, DisplayProperties, ExplicitIterator, Expression, ImplicitIterator,
44 LetStatement, Parse, PredefinedRuleOperator, PropertyValue, Punctuated, RuleOperator,
45 RuleStatement, SimpleExpression, SimpleExpressionKind, Statement, Type,
46 },
47 token::{self, Ident, NamedIdent, PointCollection as PCToken, Span},
48 unit, ComplexUnit, Error,
49};
50
51pub mod context;
52pub mod figure;
53pub mod flags;
54pub mod library;
55
56trait Unroll<T = AnyExpr> {
58 fn unroll(
59 &self,
60 context: &mut CompileContext,
61 library: &Library,
62 it_index: &HashMap<u8, usize>,
63 display: Properties,
64 ) -> T;
65}
66
67#[derive(Debug)]
69pub struct RuleOperatorDefinition {
70 pub name: String,
72}
73
74#[derive(Debug)]
76pub struct Variable<T: Displayed> {
77 pub name: String,
79 pub definition_span: Span,
81 pub definition: Expr<T>,
83}
84
85#[derive(Debug)]
87pub struct IterTree {
88 pub variants: Vec<IterNode>,
90 pub id: u8,
92 pub span: Span,
94}
95
96#[derive(Debug)]
99pub struct IterNode(Vec<IterTree>);
100
101impl Deref for IterNode {
102 type Target = Vec<IterTree>;
103
104 fn deref(&self) -> &Self::Target {
105 &self.0
106 }
107}
108
109impl DerefMut for IterNode {
110 fn deref_mut(&mut self) -> &mut Self::Target {
111 &mut self.0
112 }
113}
114
115impl<const ITER: bool> From<&Expression<ITER>> for IterNode {
116 fn from(value: &Expression<ITER>) -> Self {
117 match value {
118 Expression::ImplicitIterator(it) => it.into(),
119 Expression::Binop(binop) => Self::from2(binop.lhs.as_ref(), binop.rhs.as_ref()),
120 }
121 }
122}
123
124impl From<&SimpleExpressionKind> for IterNode {
125 fn from(value: &SimpleExpressionKind) -> Self {
126 match value {
127 SimpleExpressionKind::Number(_) => IterNode::new(Vec::new()),
128 SimpleExpressionKind::Name(name) => name.into(),
129 SimpleExpressionKind::ExplicitIterator(it) => IterNode::new(vec![it.into()]),
130 SimpleExpressionKind::PointCollection(col) => IterNode::new(
131 col.points
132 .iter()
133 .flat_map(|v| IterNode::from(v).0.into_iter())
134 .collect(),
135 ),
136 }
137 }
138}
139
140impl From<&Name> for IterNode {
141 fn from(value: &Name) -> Self {
142 match value {
143 Name::Ident(_) => IterNode::new(Vec::new()),
144 Name::FieldIndex(f) => f.name.as_ref().into(),
145 Name::Call(expr) => IterNode::new(
146 IterNode::from(expr.name.as_ref())
147 .0
148 .into_iter()
149 .chain(
150 expr.params
151 .as_ref()
152 .into_iter()
153 .flat_map(|params| params.iter().flat_map(|v| IterNode::from(v).0)),
154 )
155 .collect(),
156 ),
157 Name::Expression(expr) => expr.content.as_ref().into(),
158 }
159 }
160}
161
162impl<const ITER: bool> From<&ImplicitIterator<ITER>> for IterNode {
163 fn from(value: &ImplicitIterator<ITER>) -> Self {
164 if value.exprs.collection.is_empty() {
165 (&value.exprs.first.as_ref().kind).into()
166 } else {
167 IterNode::new(vec![value.into()])
168 }
169 }
170}
171
172impl<const ITER: bool> From<&ImplicitIterator<ITER>> for IterTree {
173 fn from(value: &ImplicitIterator<ITER>) -> Self {
174 Self {
175 id: 0, variants: value.exprs.iter().map(|v| (&v.kind).into()).collect(),
177 span: value.get_span(),
178 }
179 }
180}
181
182impl From<&ExplicitIterator> for IterTree {
183 fn from(value: &ExplicitIterator) -> Self {
184 Self {
185 id: value.id,
186 variants: value.exprs.iter().map(IterNode::from).collect(),
187 span: value.get_span(),
188 }
189 }
190}
191
192impl IterTree {
193 pub fn get_iter_lengths(
199 &self,
200 lengths: &mut HashMap<u8, (usize, Span, Option<Span>)>,
201 full_span: Span,
202 ) -> Result<(), Error> {
203 for variant in &self.variants {
204 variant.get_iter_lengths(lengths, full_span)?;
205 }
206
207 Ok(())
208 }
209}
210
211impl IterNode {
212 #[must_use]
214 pub fn new(content: Vec<IterTree>) -> Self {
215 Self(content)
216 }
217
218 #[must_use]
220 pub fn from2<const ITER1: bool, const ITER2: bool>(
221 e1: &Expression<ITER1>,
222 e2: &Expression<ITER2>,
223 ) -> Self {
224 let mut node = Self::from(e1);
225 node.extend(Self::from(e2).0);
226 node
227 }
228
229 pub fn get_iter_lengths(
238 &self,
239 lengths: &mut HashMap<u8, (usize, Span, Option<Span>)>,
240 full_span: Span,
241 ) -> Result<(), Error> {
242 for iter in &self.0 {
243 match lengths.entry(iter.id) {
244 Entry::Vacant(entry) => {
245 entry.insert((iter.variants.len(), iter.span, Some(iter.span)));
246 }
247 Entry::Occupied(mut entry) => {
248 if entry.get().0 != iter.variants.len() {
249 return Err(Error::InconsistentIterators {
250 first_span: entry.get().1,
251 first_length: entry.get().0,
252 occurred_span: iter.span,
253 occurred_length: iter.variants.len(),
254 error_span: full_span,
255 });
256 } else if let Some(parent) = entry.get().2 {
257 return Err(Error::IteratorWithSameIdIterator {
258 error_span: full_span,
259 parent_span: parent,
260 contained_span: iter.span,
261 });
262 }
263
264 entry.get_mut().2 = Some(iter.span);
265 }
266 }
267
268 iter.get_iter_lengths(lengths, full_span)?;
269 lengths.get_mut(&iter.id).unwrap().2 = None;
270 }
271
272 Ok(())
273 }
274}
275
276#[derive(Debug)]
279pub struct MultiRangeIterator {
280 maxes: Vec<usize>,
283 currents: Vec<usize>,
285}
286
287impl MultiRangeIterator {
288 #[must_use]
290 pub fn new(maxes: Vec<usize>) -> Self {
291 let l = maxes.len();
292
293 Self {
294 maxes,
295 currents: [0].repeat(l),
296 }
297 }
298
299 pub fn increment(&mut self) -> Option<&Vec<usize>> {
301 self.increment_place(self.currents.len() - 1)
302 }
303
304 fn increment_place(&mut self, at: usize) -> Option<&Vec<usize>> {
306 self.currents[at] += 1;
307
308 if self.currents[at] == self.maxes[at] {
309 self.currents[at] = 0;
310 if at == 0 {
311 None
312 } else {
313 self.increment_place(at - 1)
314 }
315 } else {
316 Some(&self.currents)
317 }
318 }
319
320 #[must_use]
322 pub fn get_currents(&self) -> &Vec<usize> {
323 &self.currents
324 }
325}
326
327#[derive(Debug)]
329pub struct IterTreeIterator<'r> {
330 steps: Vec<(Vec<(&'r IterTree, usize)>, MultiRangeIterator)>,
332 currents: Option<HashMap<u8, usize>>,
334}
335
336impl<'r> IterTreeIterator<'r> {
337 #[must_use]
339 pub fn new(tree: &'r IterNode) -> Self {
340 let mut this = Self {
341 steps: Vec::new(),
342 currents: Some(HashMap::new()),
343 };
344
345 this.add_node(tree);
346
347 this
348 }
349
350 fn add_node(&mut self, node: &'r IterNode) {
352 if node.len() > 0 {
353 let mut visited = Vec::new();
354 let mut lengths = Vec::new();
355
356 for tree in node.iter() {
357 if !visited.contains(&tree.id) {
358 visited.push(tree.id);
359 lengths.push(tree.variants.len());
360 }
361 }
362
363 self.steps.push((
364 node.iter()
366 .map(|v| {
367 (
368 v,
369 visited
370 .iter()
371 .enumerate()
372 .find(|(_, x)| **x == v.id)
373 .unwrap()
374 .0,
375 )
376 })
377 .collect(),
378 MultiRangeIterator::new(lengths),
379 ));
380 self.update_currents();
381
382 self.update_iterators();
383 }
384 }
385
386 fn update_iterators(&mut self) {
388 let nodes = if let Some(node) = self.steps.last() {
389 node.0
390 .iter()
391 .map(|iter| &iter.0.variants[node.1.get_currents()[iter.1]])
392 .collect()
393 } else {
394 Vec::new()
395 };
396
397 for node in nodes {
398 self.add_node(node);
399 }
400 }
401
402 fn update_currents(&mut self) {
404 let node = self.steps.last().unwrap();
405 let currents = node.1.get_currents();
406
407 for v in &node.0 {
408 self.currents
409 .as_mut()
410 .unwrap()
411 .entry(v.0.id)
412 .and_modify(|x| *x = currents[v.1])
413 .or_insert(currents[v.1]);
414 }
415 }
416
417 pub fn next(&mut self) {
419 while let Some(node) = self.steps.last_mut() {
420 if node.1.increment().is_some() {
421 self.update_currents();
422 self.update_iterators();
423 return;
424 }
425
426 self.steps.pop();
427 }
428
429 self.currents = None;
430 }
431
432 #[must_use]
434 pub fn get_currents(&self) -> Option<&HashMap<u8, usize>> {
435 self.currents.as_ref()
436 }
437}
438
439#[derive(Debug)]
441pub enum UnrolledRuleKind {
442 PointEq(Expr<Point>, Expr<Point>),
444 NumberEq(Expr<Number>, Expr<Number>),
446 Gt(Expr<Number>, Expr<Number>),
448 Alternative(Vec<UnrolledRule>),
450 Bias(AnyExpr),
452}
453
454pub trait ConvertFrom<T>: Displayed {
456 fn convert_from(value: T, context: &CompileContext) -> Expr<Self>;
461
462 fn can_convert_from(value: &T) -> bool;
464}
465
466pub trait Convert
469where
470 Self: Sized,
471{
472 fn convert<T: ConvertFrom<Self>>(self, context: &CompileContext) -> Expr<T>;
477
478 fn can_convert<T: ConvertFrom<Self>>(&self) -> bool;
483}
484
485impl<T> Convert for T {
486 fn convert<U: ConvertFrom<Self>>(self, context: &CompileContext) -> Expr<U> {
487 U::convert_from(self, context)
488 }
489
490 fn can_convert<U: ConvertFrom<Self>>(&self) -> bool {
491 U::can_convert_from(self)
492 }
493}
494
495pub trait GetValueType {
497 fn get_value_type(&self) -> Type;
498}
499
500pub trait GeoType: From<Expr<Self::Target>> {
502 type Target: ConvertFrom<AnyExpr>;
504
505 fn get_type() -> Type;
506}
507
508macro_rules! impl_x_from_x {
509 ($what:ident) => {
510 impl ConvertFrom<Expr<$what>> for $what {
511 fn convert_from(value: Expr<$what>, _context: &CompileContext) -> Expr<Self> {
512 value
513 }
514
515 fn can_convert_from(_value: &Expr<$what>) -> bool {
516 true
517 }
518 }
519 };
520}
521
522macro_rules! impl_from_any {
523 ($what:ident) => {
524 impl ConvertFrom<AnyExpr> for $what {
525 fn convert_from(value: AnyExpr, context: &CompileContext) -> Expr<Self> {
526 match value {
527 AnyExpr::Point(v) => v.convert(context),
528 AnyExpr::Line(v) => v.convert(context),
529 AnyExpr::Number(v) => v.convert(context),
530 AnyExpr::Circle(v) => v.convert(context),
531 AnyExpr::PointCollection(v) => v.convert(context),
532 AnyExpr::Derived(v) => v.convert(context),
533 AnyExpr::Unknown(v) => v.convert(context),
534 }
535 }
536
537 fn can_convert_from(value: &AnyExpr) -> bool {
538 match value {
539 AnyExpr::Point(v) => Self::can_convert_from(v),
540 AnyExpr::Line(v) => Self::can_convert_from(v),
541 AnyExpr::Number(v) => Self::can_convert_from(v),
542 AnyExpr::Circle(v) => Self::can_convert_from(v),
543 AnyExpr::PointCollection(v) => Self::can_convert_from(v),
544 AnyExpr::Derived(v) => Self::can_convert_from(v),
545 AnyExpr::Unknown(v) => Self::can_convert_from(v),
546 }
547 }
548 }
549 };
550}
551
552macro_rules! convert_err {
553 ($from:ident($v:expr) -> $to:ident with $context:ident) => {{
554 let v = $v;
555
556 $context.push_error(Error::ImplicitConversionDoesNotExist {
557 error_span: v.span,
558 from: v.data.get_value_type(),
559 to: Self::get_type(),
560 });
561
562 Expr {
563 span: v.span,
564 data: Rc::new($to::dummy()),
565 node: None,
566 }
567 }};
568}
569
570macro_rules! impl_convert_err {
571 ($from:ident -> $to:ident) => {
572 impl ConvertFrom<Expr<$from>> for $to {
573 fn convert_from(value: Expr<$from>, context: &CompileContext) -> Expr<Self> {
574 convert_err!($from(value) -> $to with context)
575 }
576
577 fn can_convert_from(_value: &Expr<$from>) -> bool {
578 false
579 }
580 }
581 }
582}
583
584macro_rules! impl_from_unknown {
585 {$what:ident} => {
586 impl ConvertFrom<Expr<Unknown>> for $what {
587 fn convert_from(value: Expr<Unknown>, _context: &CompileContext) -> Expr<Self> {
588 Expr {
589 span: value.span,
590 data: Rc::new($what::dummy()),
591 node: None
592 }
593 }
594
595 fn can_convert_from(_value: &Expr<Unknown>) -> bool {
596 true
597 }
598 }
599 }
600}
601
602macro_rules! impl_make_variable {
603 ($what:ident) => {
604 impl Expr<$what> {
605 #[must_use]
606 pub fn make_variable(self, name: String) -> Self {
607 let sp = self.span;
608
609 Expr {
610 span: sp,
611 data: Rc::new($what::Generic(Generic::VariableAccess(Rc::new(Variable {
612 name,
613 definition: self,
614 definition_span: sp,
615 })))),
616 node: None, }
618 }
619 }
620 };
621 ($what:ident { other: $other:ident, data: $data:ident }) => {
622 impl Expr<$what> {
623 #[must_use]
624 pub fn make_variable(self, name: String) -> Self {
625 let sp = self.span;
626
627 Expr {
628 span: sp,
629 data: Rc::new($what {
630 $other: self.data.$other,
631 data: $data::Generic(Generic::VariableAccess(Rc::new(Variable {
632 name,
633 definition: self,
634 definition_span: sp,
635 }))),
636 }),
637 node: None, }
639 }
640 }
641 };
642}
643
644macro_rules! impl_any_from_x {
645 ($what:ident) => {
646 impl From<Expr<$what>> for AnyExpr {
647 fn from(value: Expr<$what>) -> Self {
648 AnyExpr::$what(value)
649 }
650 }
651 };
652}
653
654#[derive(Debug, CloneWithNode)]
656pub enum Generic<T>
657where
658 T: Displayed,
659{
660 VariableAccess(Rc<Variable<T>>),
662 Boxed(Expr<T>),
664 Dummy,
667}
668
669impl<T: Display + Displayed> Display for Generic<T> {
670 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
671 match self {
672 Self::VariableAccess(name) => write!(f, "{}", name.name),
673 Self::Boxed(expr) => {
674 write!(f, "{expr}")
675 }
676 Self::Dummy => write!(f, "invalid (dummy)"),
677 }
678 }
679}
680
681#[derive(Debug, CloneWithNode)]
683pub enum Point {
684 Generic(Generic<Self>),
686 Average(ClonedVec<Expr<Point>>),
688 LineLineIntersection(Expr<Line>, Expr<Line>),
690 CircleCenter(Expr<Circle>),
692 Free,
694 FromComplex(Expr<Number>),
696}
697
698impl Point {
699 #[must_use]
700 pub fn get_type() -> Type {
701 Type::Point
702 }
703}
704
705impl Dummy for Point {
706 fn dummy() -> Self {
707 Self::Generic(Generic::Dummy)
708 }
709
710 fn is_dummy(&self) -> bool {
711 matches!(self, Self::Generic(Generic::Dummy))
712 }
713}
714
715impl Displayed for Point {
716 type Node = PointNode;
717}
718
719impl GetData for Point {
720 fn get_data(&self) -> &Self {
721 match self {
722 Point::Generic(v) => match v {
723 Generic::Boxed(v) => v.get_data(),
724 Generic::VariableAccess(v) => v.definition.get_data(),
725 Generic::Dummy => self,
726 },
727 _ => self,
728 }
729 }
730}
731
732impl Expr<Point> {
733 #[must_use]
735 pub fn boxed(mut self, span: Span) -> Self {
736 let node = self.node.take();
737
738 Self {
739 span,
740 data: Rc::new(Point::Generic(Generic::Boxed(self))),
741 node,
742 }
743 }
744
745 #[must_use]
747 pub fn x(self, span: Span, display: Properties, context: &CompileContext) -> Expr<Number> {
748 let mut expr = Expr {
749 span,
750 node: None,
751 data: Rc::new(Number {
752 unit: Some(unit::DISTANCE),
753 data: NumberData::PointX(self),
754 }),
755 };
756
757 expr.node = Some(HierarchyNode::from_expr(&expr, display, context));
758 expr
759 }
760
761 #[must_use]
763 pub fn y(self, span: Span, display: Properties, context: &CompileContext) -> Expr<Number> {
764 let mut expr = Expr {
765 span,
766 node: None,
767 data: Rc::new(Number {
768 unit: Some(unit::DISTANCE),
769 data: NumberData::PointY(self),
770 }),
771 };
772
773 expr.node = Some(HierarchyNode::from_expr(&expr, display, context));
774 expr
775 }
776}
777
778impl GeoType for Expr<Point> {
779 type Target = Point;
780
781 fn get_type() -> Type {
782 ty::POINT
783 }
784}
785
786impl GetValueType for Point {
787 fn get_value_type(&self) -> Type {
788 ty::POINT
789 }
790}
791
792impl Display for Point {
793 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
794 match self {
795 Self::Generic(v) => write!(f, "{v}"),
796 Self::Average(exprs) => write!(
797 f,
798 "average({})",
799 exprs
800 .iter()
801 .map(|v| format!("{v}"))
802 .collect::<Vec<String>>()
803 .join(", ")
804 ),
805 Self::LineLineIntersection(l1, l2) => {
806 write!(f, "intersection({l1}, {l2})")
807 }
808 Self::CircleCenter(circle) => {
809 write!(f, "{circle}.center")
810 }
811 Self::Free => write!(f, "Free point"),
812 Self::FromComplex(number) => write!(f, "to_point({number})"),
813 }
814 }
815}
816
817impl_x_from_x! {Point}
818impl_from_any! {Point}
819impl_from_unknown! {Point}
820impl_convert_err! {Circle -> Point}
821impl_convert_err! {Line -> Point}
822impl_convert_err! {Derived -> Point}
823impl_convert_err! {Number -> Point}
824
825impl_make_variable! {Point}
826
827impl ConvertFrom<Expr<PointCollection>> for Point {
828 fn convert_from(mut value: Expr<PointCollection>, context: &CompileContext) -> Expr<Self> {
829 if value.data.length == 1 {
830 let mut expr = index!(node value, 0);
831
832 if let Some(pc_node) = value.node {
833 if let Some(mut props) = pc_node.root.props {
834 if let Some(pt_node) = &mut expr.node {
835 pt_node.children = pc_node.children;
836 pt_node.root.display = pc_node.root.display;
837
838 pt_node.root.display_label = props.get("display_label").maybe_unset(true);
839 pt_node.root.label = props
840 .get("label")
841 .maybe_unset(SpannedMathString::new(span!(0, 0, 0, 0)));
842 pt_node.root.display_dot = props.get("display_dot").maybe_unset(true);
843 pt_node.root.default_label = props
844 .get("default-label")
845 .ok_or(SpannedMathString::new(span!(0, 0, 0, 0)));
846 }
847
848 props.ignore("default-label");
849 props.finish(context);
850 }
851 }
852
853 expr
854 } else {
855 convert_err!(PointCollection(value) -> Point with context)
856 }
857 }
858
859 fn can_convert_from(value: &Expr<PointCollection>) -> bool {
860 value.data.length == 1
861 }
862}
863
864#[derive(Debug, CloneWithNode)]
866pub enum Circle {
867 Generic(Generic<Self>),
869 Circle(Expr<Point>, Expr<Number>),
871}
872
873impl_x_from_x! {Circle}
874impl_from_any! {Circle}
875impl_from_unknown! {Circle}
876
877impl_convert_err! {Point -> Circle}
878impl_convert_err! {Line -> Circle}
879impl_convert_err! {Derived -> Circle}
880impl_convert_err! {Number -> Circle}
881impl_convert_err! {PointCollection -> Circle}
882
883impl_make_variable! {Circle}
884
885impl Circle {
886 #[must_use]
887 pub fn get_type() -> Type {
888 ty::CIRCLE
889 }
890}
891
892impl Dummy for Circle {
893 fn dummy() -> Self {
894 Self::Generic(Generic::Dummy)
895 }
896
897 fn is_dummy(&self) -> bool {
898 matches!(self, Self::Generic(Generic::Dummy))
899 }
900}
901
902impl Displayed for Circle {
903 type Node = CircleNode;
904}
905
906impl GetData for Circle {
907 fn get_data(&self) -> &Self {
908 match self {
909 Circle::Generic(v) => match v {
910 Generic::Boxed(v) => v.get_data(),
911 Generic::VariableAccess(v) => v.definition.get_data(),
912 Generic::Dummy => self,
913 },
914 Circle::Circle(..) => self,
915 }
916 }
917}
918
919impl Expr<Circle> {
920 #[must_use]
922 pub fn boxed(mut self, span: Span) -> Self {
923 let node = self.node.take();
924
925 Self {
926 span,
927 data: Rc::new(Circle::Generic(Generic::Boxed(self))),
928 node,
929 }
930 }
931
932 #[must_use]
934 pub fn center(self, span: Span, display: Properties, context: &CompileContext) -> Expr<Point> {
935 let mut expr = Expr {
936 span,
937 node: None,
938 data: Rc::new(Point::CircleCenter(self)),
939 };
940
941 expr.node = Some(HierarchyNode::from_expr(&expr, display, context));
942 expr
943 }
944
945 #[must_use]
947 pub fn radius(self, span: Span, display: Properties, context: &CompileContext) -> Expr<Number> {
948 let mut expr = Expr {
949 span,
950 node: None,
951 data: Rc::new(Number {
952 unit: Some(unit::DISTANCE),
953 data: NumberData::CircleRadius(self),
954 }),
955 };
956
957 expr.node = Some(HierarchyNode::from_expr(&expr, display, context));
958 expr
959 }
960}
961
962impl GetValueType for Circle {
963 fn get_value_type(&self) -> Type {
964 ty::CIRCLE
965 }
966}
967
968impl Display for Circle {
969 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
970 match self {
971 Self::Generic(v) => write!(f, "{v}"),
972 Self::Circle(center, radius) => {
973 write!(f, "circle({center}, {radius})")
974 }
975 }
976 }
977}
978
979impl GeoType for Expr<Circle> {
980 type Target = Circle;
981
982 fn get_type() -> Type {
983 ty::CIRCLE
984 }
985}
986#[derive(Debug, CloneWithNode)]
988pub enum Line {
989 Generic(Generic<Self>),
991 LineFromPoints(Expr<Point>, Expr<Point>),
993 AngleBisector(Expr<Point>, Expr<Point>, Expr<Point>),
995 PerpendicularThrough(Expr<Line>, Expr<Point>),
997 ParallelThrough(Expr<Line>, Expr<Point>),
999 PointVector(Expr<Point>, Expr<Number>),
1001}
1002
1003impl Line {
1004 #[must_use]
1005 pub fn get_type() -> Type {
1006 ty::LINE
1007 }
1008}
1009
1010impl Dummy for Line {
1011 fn dummy() -> Self {
1012 Self::Generic(Generic::Dummy)
1013 }
1014
1015 fn is_dummy(&self) -> bool {
1016 matches!(self, Self::Generic(Generic::Dummy))
1017 }
1018}
1019
1020impl Displayed for Line {
1021 type Node = LineNode;
1022}
1023
1024impl GetData for Line {
1025 fn get_data(&self) -> &Self {
1026 match self {
1027 Line::Generic(v) => match v {
1028 Generic::Boxed(v) => v.get_data(),
1029 Generic::VariableAccess(v) => v.definition.get_data(),
1030 Generic::Dummy => self,
1031 },
1032 _ => self,
1033 }
1034 }
1035}
1036
1037impl Expr<Line> {
1038 #[must_use]
1040 pub fn boxed(mut self, span: Span) -> Self {
1041 let node = self.node.take();
1042
1043 Self {
1044 span,
1045 data: Rc::new(Line::Generic(Generic::Boxed(self))),
1046 node,
1047 }
1048 }
1049}
1050
1051impl_x_from_x! {Line}
1052impl_from_any! {Line}
1053impl_from_unknown! {Line}
1054impl_convert_err! {Derived -> Line}
1055impl_convert_err! {Circle -> Line}
1056impl_convert_err! {Point -> Line}
1057impl_convert_err! {Number -> Line}
1058
1059impl_make_variable! {Line}
1060
1061impl ConvertFrom<Expr<PointCollection>> for Line {
1062 fn convert_from(mut value: Expr<PointCollection>, context: &CompileContext) -> Expr<Self> {
1063 if value.data.length == 2 {
1064 let mut expr = context.line(index!(node value, 0), index!(node value, 1));
1065 if let Some(pc_node) = value.node {
1066 if let Some(mut props) = pc_node.root.props {
1067 if let Some(ln_node) = &mut expr.node {
1068 ln_node.children = pc_node.children;
1069 ln_node.root.display = pc_node.root.display;
1070
1071 ln_node.root.display_label = props.get("display_label").maybe_unset(true);
1072 ln_node.root.label = props
1073 .get("label")
1074 .maybe_unset(SpannedMathString::new(span!(0, 0, 0, 0)));
1075 ln_node.root.default_label = props
1076 .get("default-label")
1077 .get_or(SpannedMathString::new(span!(0, 0, 0, 0)));
1078 ln_node.root.style = props.get("style").maybe_unset(Style::default());
1079 ln_node.root.line_type = props.get("type").maybe_unset(LineType::default());
1080 }
1081
1082 props.finish(context);
1083 }
1084 }
1085
1086 expr
1087 } else {
1088 convert_err!(PointCollection(value) -> Line with context)
1089 }
1090 }
1091
1092 fn can_convert_from(value: &Expr<PointCollection>) -> bool {
1093 value.data.length == 2
1094 }
1095}
1096
1097impl GetValueType for Line {
1098 fn get_value_type(&self) -> Type {
1099 ty::LINE
1100 }
1101}
1102
1103impl Display for Line {
1104 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1105 match self {
1106 Self::Generic(v) => write!(f, "{v}"),
1107 Self::LineFromPoints(e1, e2) => write!(f, "line({e1}, {e2})"),
1108 Self::AngleBisector(e1, e2, e3) => {
1109 write!(f, "angle-bisector({e1}, {e2}, {e3})")
1110 }
1111 Self::PerpendicularThrough(l, p) => {
1112 write!(f, "perpendicular-through({l}, {p})")
1113 }
1114 Self::ParallelThrough(l, p) => {
1115 write!(f, "parallel-through({l}, {p})")
1116 }
1117 Self::PointVector(p, v) => write!(f, "point-vector({p}, {v})"),
1118 }
1119 }
1120}
1121
1122impl GeoType for Expr<Line> {
1123 type Target = Line;
1124
1125 fn get_type() -> Type {
1126 ty::LINE
1127 }
1128}
1129
1130#[derive(Debug, CloneWithNode)]
1132pub enum NumberData {
1133 Generic(Generic<Number>),
1135 Number(ProcNum),
1137 DstLiteral(ProcNum),
1139 SetUnit(Expr<Number>, ComplexUnit),
1141 PointPointDistance(Expr<Point>, Expr<Point>),
1143 PointLineDistance(Expr<Point>, Expr<Line>),
1145 Negate(Expr<Number>),
1147 Add(Expr<Number>, Expr<Number>),
1149 Subtract(Expr<Number>, Expr<Number>),
1151 Multiply(Expr<Number>, Expr<Number>),
1153 Divide(Expr<Number>, Expr<Number>),
1155 ThreePointAngle(Expr<Point>, Expr<Point>, Expr<Point>),
1157 ThreePointAngleDir(Expr<Point>, Expr<Point>, Expr<Point>),
1159 TwoLineAngle(Expr<Line>, Expr<Line>),
1161 Average(ClonedVec<Expr<Number>>),
1163 CircleRadius(Expr<Circle>),
1165 Pow(Expr<Number>, CompExponent),
1167 PointX(Expr<Point>),
1169 PointY(Expr<Point>),
1171 Free,
1173 FromPoint(Expr<Point>),
1175 Real(Expr<Number>),
1177 Imaginary(Expr<Number>),
1179 Log(Expr<Number>),
1181 Exp(Expr<Number>),
1183 Sin(Expr<Number>),
1185 Cos(Expr<Number>),
1187 Atan2(Expr<Number>, Expr<Number>),
1189 Direction(Expr<Line>),
1191}
1192
1193impl Display for NumberData {
1194 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1195 match self {
1196 Self::Generic(v) => write!(f, "{v}"),
1197 Self::Average(exprs) => write!(
1198 f,
1199 "average({})",
1200 exprs
1201 .iter()
1202 .map(|v| format!("{v}"))
1203 .collect::<Vec<String>>()
1204 .join(", ")
1205 ),
1206 Self::Number(num) => write!(f, "{num}"),
1207 Self::DstLiteral(dst) => write!(f, "={dst}"),
1208 Self::SetUnit(expr, _) => {
1209 write!(f, "{expr}")
1210 }
1211 Self::PointPointDistance(e1, e2) => write!(f, "dst({e1}, {e2})"),
1212 Self::PointLineDistance(e1, e2) => write!(f, "dst({e1}, {e2})"),
1213 Self::Negate(e) => write!(f, "-{e}"),
1214 Self::Add(e1, e2) => write!(f, "{e1} + {e2}"),
1215 Self::Multiply(e1, e2) => write!(f, "{e1} * {e2}"),
1216 Self::Divide(e1, e2) => write!(f, "{e1} / {e2}"),
1217 Self::Subtract(e1, e2) => write!(f, "{e1} - {e2}"),
1218 Self::ThreePointAngle(e1, e2, e3) => {
1219 write!(f, "angle({e1}, {e2}, {e3})")
1220 }
1221 Self::ThreePointAngleDir(e1, e2, e3) => {
1222 write!(f, "dir_angle({e1}, {e2}, {e3})")
1223 }
1224 Self::TwoLineAngle(e1, e2) => write!(f, "angle({e1}, {e2})"),
1225 Self::CircleRadius(circle) => {
1226 write!(f, "{circle}.radius")
1227 }
1228 Self::Pow(base, exponent) => write!(f, "({base})^{exponent}"),
1229 Self::PointX(expr) => write!(f, "{expr}.x"),
1230 Self::PointY(expr) => write!(f, "{expr}.y"),
1231 Self::Free => write!(f, "Free scalar"),
1232 Self::FromPoint(point) => write!(f, "to_complex({point})"),
1233 Self::Real(number) => write!(f, "Re({number})"),
1234 Self::Imaginary(number) => write!(f, "Im({number})"),
1235 Self::Log(number) => write!(f, "log({number})"),
1236 Self::Exp(number) => write!(f, "exp({number})"),
1237 Self::Sin(v) => write!(f, "sin({v})"),
1238 Self::Cos(v) => write!(f, "cos({v})"),
1239 Self::Atan2(y, x) => write!(f, "atan2({y}, {x})"),
1240 Self::Direction(line) => write!(f, "dir({line})"),
1241 }
1242 }
1243}
1244
1245#[derive(Debug, CloneWithNode)]
1247pub struct Number {
1248 pub unit: Option<ComplexUnit>,
1249 pub data: NumberData,
1250}
1251
1252impl_x_from_x! {Number}
1253impl_from_any! {Number}
1254impl_from_unknown! {Number}
1255
1256impl_convert_err! {Point -> Number}
1257impl_convert_err! {Circle -> Number}
1258impl_convert_err! {Line -> Number}
1259impl_convert_err! {Derived -> Number}
1260
1261impl_make_variable! {Number {other: unit, data: NumberData}}
1262
1263impl Dummy for Number {
1264 fn dummy() -> Self {
1265 Self {
1266 unit: None,
1267 data: NumberData::Generic(Generic::Dummy),
1268 }
1269 }
1270
1271 fn is_dummy(&self) -> bool {
1272 matches!(self.data, NumberData::Generic(Generic::Dummy))
1273 }
1274}
1275
1276impl Displayed for Number {
1277 type Node = NumberNode;
1278}
1279
1280impl ConvertFrom<Expr<PointCollection>> for Number {
1281 fn convert_from(mut value: Expr<PointCollection>, context: &CompileContext) -> Expr<Self> {
1282 if value.data.length == 2 {
1283 let display = value
1286 .node
1287 .as_mut()
1288 .and_then(|x| x.root.props.take())
1289 .unwrap_or_default();
1290
1291 let mut expr = library::dst::distance_function_pp(
1292 index!(node value, 0),
1293 index!(node value, 1),
1294 context,
1295 display,
1296 );
1297
1298 if let Some(pc_node) = value.node {
1299 if let Some(sc_node) = &mut expr.node {
1300 sc_node.children = pc_node.children;
1301 sc_node.root.display = pc_node.root.display;
1302 }
1303 }
1304
1305 expr.0
1306 } else {
1307 convert_err!(PointCollection(value) -> Number with context)
1308 }
1309 }
1310
1311 fn can_convert_from(value: &Expr<PointCollection>) -> bool {
1312 value.data.length == 2
1313 }
1314}
1315
1316impl Number {
1317 #[must_use]
1318 pub fn get_type() -> Type {
1319 ty::SCALAR
1320 }
1321}
1322
1323impl GetData for Number {
1324 fn get_data(&self) -> &Self {
1325 match &self.data {
1326 NumberData::Generic(v) => match v {
1327 Generic::Boxed(v) => v.get_data(),
1328 Generic::VariableAccess(v) => v.definition.get_data(),
1329 Generic::Dummy => self,
1330 },
1331 _ => self,
1332 }
1333 }
1334}
1335
1336impl Expr<Number> {
1337 #[must_use]
1339 pub fn boxed(mut self, span: Span) -> Self {
1340 let node = self.node.take();
1341
1342 Self {
1343 span,
1344 data: Rc::new(Number {
1345 unit: self.data.unit,
1346 data: NumberData::Generic(Generic::Boxed(self)),
1347 }),
1348 node,
1349 }
1350 }
1351
1352 #[must_use]
1359 pub fn convert_unit(mut self, unit: Option<ComplexUnit>, context: &CompileContext) -> Self {
1360 let err = Error::ImplicitConversionDoesNotExist {
1361 error_span: self.span,
1362 from: self.get_value_type(),
1363 to: Type::Number(unit),
1364 };
1365
1366 if self.data.unit == unit {
1367 self
1368 } else if unit.is_none() || self.data.unit.is_some() && self.data.unit != unit {
1369 context.push_error(err);
1370
1371 Expr {
1373 span: self.span,
1374 data: Rc::new(Number {
1375 unit,
1376 data: self.data.data.clone_without_node(),
1377 }),
1378 node: self.node.take(),
1379 }
1380 } else {
1381 Self {
1383 data: Rc::new(Number {
1384 unit,
1385 data: match &self.data.data {
1386 NumberData::Generic(generic) => match generic {
1387 Generic::VariableAccess(_) => unreachable!(), Generic::Boxed(v) => NumberData::Generic(Generic::Boxed(
1389 v.clone_without_node().convert_unit(unit, context),
1390 )),
1391 Generic::Dummy => NumberData::Generic(Generic::Dummy),
1392 },
1393 v @ NumberData::Number(_) => v.clone_without_node(),
1394 NumberData::Free => {
1395 NumberData::SetUnit(self.clone_without_node(), unit.unwrap_or_default())
1396 }
1397 NumberData::DstLiteral(_)
1398 | NumberData::PointPointDistance(_, _)
1399 | NumberData::PointLineDistance(_, _)
1400 | NumberData::ThreePointAngle(_, _, _)
1401 | NumberData::ThreePointAngleDir(_, _, _)
1402 | NumberData::TwoLineAngle(_, _)
1403 | NumberData::CircleRadius(_)
1404 | NumberData::PointX(_)
1405 | NumberData::PointY(_)
1406 | NumberData::Log(_)
1407 | NumberData::Exp(_)
1408 | NumberData::Sin(_)
1409 | NumberData::Cos(_)
1410 | NumberData::Atan2(_, _)
1411 | NumberData::Direction(_)
1412 | NumberData::FromPoint(_)
1413 | NumberData::SetUnit(_, _) => unreachable!(), NumberData::Negate(v) => {
1415 NumberData::Negate(v.clone_without_node().convert_unit(unit, context))
1416 }
1417 NumberData::Add(a, b) => {
1418 NumberData::Add(
1420 a.clone_without_node().convert_unit(unit, context),
1421 b.clone_without_node().convert_unit(unit, context),
1422 )
1423 }
1424 NumberData::Subtract(a, b) => {
1425 NumberData::Subtract(
1427 a.clone_without_node().convert_unit(unit, context),
1428 b.clone_without_node().convert_unit(unit, context),
1429 )
1430 }
1431 NumberData::Multiply(a, b) => {
1432 NumberData::Multiply(
1434 a.clone_without_node().convert_unit(unit, context),
1435 b.clone_without_node()
1436 .convert_unit(Some(unit::SCALAR), context),
1437 )
1438 }
1439 NumberData::Divide(a, b) => {
1440 NumberData::Divide(
1442 a.clone_without_node().convert_unit(unit, context),
1443 b.clone_without_node()
1444 .convert_unit(Some(unit::SCALAR), context),
1445 )
1446 }
1447 NumberData::Average(exprs) => {
1448 NumberData::Average(
1450 exprs
1451 .iter()
1452 .map(|v| v.clone_without_node().convert_unit(unit, context))
1453 .collect::<Vec<_>>()
1454 .into(),
1455 )
1456 }
1457 NumberData::Pow(base, exponent) => NumberData::Pow(
1458 base.clone_without_node()
1459 .convert_unit(unit.map(|x| x.pow(exponent.recip())), context),
1460 *exponent,
1461 ),
1462 NumberData::Real(number) => NumberData::Real(
1463 number.clone_without_node().convert_unit(unit, context),
1464 ),
1465 NumberData::Imaginary(number) => NumberData::Imaginary(
1466 number.clone_without_node().convert_unit(unit, context),
1467 ),
1468 },
1469 }),
1470 ..self
1471 }
1472 }
1473 }
1474
1475 #[must_use]
1477 pub fn can_convert_unit(&self, unit: Option<ComplexUnit>) -> bool {
1478 !(unit.is_none() || self.data.unit.is_some() && self.data.unit != unit)
1479 }
1480
1481 #[must_use]
1487 pub fn specify_unit(self, context: &CompileContext) -> Self {
1488 if self.data.unit.is_none() {
1489 self.convert_unit(Some(unit::SCALAR), context)
1490 } else {
1491 self
1492 }
1493 }
1494}
1495
1496impl GetValueType for Number {
1497 fn get_value_type(&self) -> Type {
1498 Type::Number(self.unit)
1499 }
1500}
1501
1502impl Display for Number {
1503 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1504 write!(f, "{}", self.data)
1505 }
1506}
1507
1508#[derive(Debug, CloneWithNode)]
1510pub enum PointCollectionData {
1511 Generic(Generic<PointCollection>),
1513 PointCollection(ClonedVec<Expr<Point>>),
1515}
1516
1517impl PointCollectionData {
1518 #[must_use]
1519 pub fn as_collection(&self) -> Option<&ClonedVec<Expr<Point>>> {
1520 match self {
1521 PointCollectionData::PointCollection(v) => Some(v),
1522 PointCollectionData::Generic(_) => None,
1523 }
1524 }
1525
1526 #[must_use]
1527 pub fn as_collection_mut(&mut self) -> Option<&mut ClonedVec<Expr<Point>>> {
1528 match self {
1529 PointCollectionData::PointCollection(v) => Some(v),
1530 PointCollectionData::Generic(_) => None,
1531 }
1532 }
1533
1534 #[must_use]
1539 pub fn index(&self, index: usize) -> Expr<Point> {
1540 match self {
1541 PointCollectionData::Generic(generic) => match generic {
1542 Generic::VariableAccess(var) => var.definition.index_without_node(index),
1543 Generic::Boxed(expr) => expr.index_without_node(index),
1544 Generic::Dummy => Expr::new_spanless(Point::Generic(Generic::Dummy)),
1545 },
1546 PointCollectionData::PointCollection(col) => col.get(index).map_or_else(
1547 || Expr::new_spanless(Point::dummy()),
1548 CloneWithNode::clone_without_node,
1549 ),
1550 }
1551 }
1552}
1553
1554impl Display for PointCollectionData {
1555 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1556 match self {
1557 Self::Generic(v) => write!(f, "{v}"),
1558 Self::PointCollection(col) => write!(
1559 f,
1560 "col({})",
1561 col.iter()
1562 .map(|v| format!("{v}"))
1563 .collect::<Vec<String>>()
1564 .join(", ")
1565 ),
1566 }
1567 }
1568}
1569
1570#[derive(Debug, CloneWithNode)]
1572pub struct PointCollection {
1573 pub length: usize,
1575 pub data: PointCollectionData,
1577}
1578
1579impl_from_any! {PointCollection}
1580impl_from_unknown! {PointCollection}
1581
1582impl_convert_err! {Circle -> PointCollection}
1583impl_convert_err! {Line -> PointCollection}
1584impl_convert_err! {Number -> PointCollection}
1585impl_convert_err! {Derived -> PointCollection}
1586
1587impl_make_variable! {PointCollection {other: length, data: PointCollectionData}}
1588
1589impl Displayed for PointCollection {
1590 type Node = PCNode;
1591}
1592
1593impl Dummy for PointCollection {
1594 fn dummy() -> Self {
1595 Self {
1596 length: 0,
1597 data: PointCollectionData::Generic(Generic::Dummy),
1598 }
1599 }
1600
1601 fn is_dummy(&self) -> bool {
1602 matches!(self.data, PointCollectionData::Generic(Generic::Dummy))
1603 }
1604}
1605
1606impl GetData for PointCollection {
1607 fn get_data(&self) -> &Self {
1608 match &self.data {
1609 PointCollectionData::Generic(v) => match v {
1610 Generic::Boxed(v) => v.get_data(),
1611 Generic::VariableAccess(v) => v.definition.get_data(),
1612 Generic::Dummy => self,
1613 },
1614 PointCollectionData::PointCollection(_) => self,
1615 }
1616 }
1617}
1618
1619impl ConvertFrom<Expr<Point>> for PointCollection {
1620 fn convert_from(mut value: Expr<Point>, _context: &CompileContext) -> Expr<Self> {
1621 let value_node = value.take_node();
1622 let mut expr = Expr {
1623 span: value.span,
1624 data: Rc::new(PointCollection {
1625 length: 1,
1626 data: PointCollectionData::PointCollection(vec![value].into()),
1627 }),
1628 node: None,
1629 };
1630 let mut node = PCNode::new(expr.clone_without_node());
1631 node.push(value_node);
1632 expr.node = Some(HierarchyNode::new(node));
1633
1634 expr
1635 }
1636
1637 fn can_convert_from(_value: &Expr<Point>) -> bool {
1638 true
1639 }
1640}
1641
1642impl ConvertFrom<Expr<PointCollection>> for PointCollection {
1643 fn convert_from(mut value: Expr<PointCollection>, context: &CompileContext) -> Expr<Self> {
1644 if let Some(node) = &mut value.node {
1645 if let Some(props) = node.root.props.take() {
1646 props.finish(context);
1647 }
1648 }
1649
1650 value
1651 }
1652
1653 fn can_convert_from(_value: &Expr<PointCollection>) -> bool {
1654 true
1655 }
1656}
1657
1658impl PointCollection {
1659 #[must_use]
1662 pub fn get_type() -> Type {
1663 ty::collection(0)
1664 }
1665}
1666
1667impl Expr<PointCollection> {
1668 #[must_use]
1670 pub fn boxed(mut self, span: Span) -> Self {
1671 let node = self.node.take();
1672
1673 Self {
1674 span,
1675 data: Rc::new(PointCollection {
1676 length: self.data.length,
1677 data: PointCollectionData::Generic(Generic::Boxed(self)),
1678 }),
1679 node,
1680 }
1681 }
1682
1683 #[must_use]
1689 pub fn check_len(self, length: usize, context: &CompileContext) -> Self {
1690 if self.data.length == length
1691 || length == 0
1692 || matches!(self.data.data, PointCollectionData::Generic(Generic::Dummy))
1693 {
1694 self
1695 } else {
1696 context.push_error(Error::ImplicitConversionDoesNotExist {
1697 error_span: self.span,
1698 from: self.get_value_type(),
1699 to: ty::collection(length),
1700 });
1701
1702 Self {
1703 data: Rc::new(PointCollection::dummy()),
1704 ..self
1705 }
1706 }
1707 }
1708
1709 #[must_use]
1711 pub fn index_without_node(&self, index: usize) -> Expr<Point> {
1712 self.data.data.index(index)
1713 }
1714
1715 #[must_use]
1717 pub fn index_with_node(&mut self, index: usize) -> Expr<Point> {
1718 let mut point = self.data.data.index(index);
1719 point.node = self
1720 .node
1721 .as_mut()
1722 .and_then(|x| x.root.children[index].take());
1723
1724 point
1725 }
1726}
1727
1728impl GetValueType for PointCollection {
1729 fn get_value_type(&self) -> Type {
1730 ty::collection(self.length)
1731 }
1732}
1733
1734impl Display for PointCollection {
1735 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1736 write!(f, "{}", self.data)
1737 }
1738}
1739
1740#[derive(Debug, CloneWithNode)]
1742pub enum DerivedData {
1743 Generic(Generic<Derived>),
1745 Data(Rc<dyn DerivedType>),
1747}
1748
1749impl Display for DerivedData {
1750 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1751 match self {
1752 Self::Generic(v) => write!(f, "{v}"),
1753 Self::Data(v) => write!(f, "{v}"),
1754 }
1755 }
1756}
1757
1758pub trait DerivedType: Debug + Display + 'static {
1760 fn as_any(&self) -> &dyn Any;
1762}
1763
1764#[derive(Debug, CloneWithNode)]
1767pub struct Derived {
1768 pub name: &'static str,
1770 pub data: DerivedData,
1772}
1773
1774impl_x_from_x! {Derived}
1775impl_from_any! {Derived}
1776impl_from_unknown! {Derived}
1777
1778impl_convert_err! {Point -> Derived}
1779impl_convert_err! {Line -> Derived}
1780impl_convert_err! {Circle -> Derived}
1781impl_convert_err! {Number -> Derived}
1782impl_convert_err! {PointCollection -> Derived}
1783
1784impl_make_variable! {Derived {other: name, data: DerivedData}}
1785
1786impl Derived {
1787 #[must_use]
1789 pub fn get_type() -> Type {
1790 ty::derived("{}")
1791 }
1792}
1793
1794impl Displayed for Derived {
1795 type Node = dyn Node;
1796}
1797
1798impl Dummy for Derived {
1799 fn dummy() -> Self {
1800 Self {
1801 name: "dummy",
1802 data: DerivedData::Generic(Generic::Dummy),
1803 }
1804 }
1805
1806 fn is_dummy(&self) -> bool {
1807 matches!(self.data, DerivedData::Generic(Generic::Dummy))
1808 }
1809}
1810
1811impl Expr<Derived> {
1812 #[must_use]
1814 pub fn boxed(mut self, span: Span) -> Self {
1815 let node = self.node.take();
1816
1817 Self {
1818 span,
1819 data: Rc::new(Derived {
1820 name: self.data.name,
1821 data: DerivedData::Generic(Generic::Boxed(self)),
1822 }),
1823 node,
1824 }
1825 }
1826
1827 #[must_use]
1832 pub fn check_name(self, name: &'static str, context: &CompileContext) -> Self {
1833 if self.data.name == name || matches!(self.data.data, DerivedData::Generic(Generic::Dummy))
1834 {
1835 self
1836 } else {
1837 context.push_error(Error::ImplicitConversionDoesNotExist {
1838 error_span: self.span,
1839 from: self.get_value_type(),
1840 to: ty::derived(name),
1841 });
1842
1843 Self {
1844 data: Rc::new(Derived::dummy()),
1845 ..self
1846 }
1847 }
1848 }
1849}
1850
1851impl GetData for Derived {
1852 fn get_data(&self) -> &Self {
1853 match &self.data {
1854 DerivedData::Generic(v) => match v {
1855 Generic::VariableAccess(var) => var.definition.get_data(),
1856 Generic::Boxed(v) => v.get_data(),
1857 Generic::Dummy => self,
1858 },
1859 _ => self,
1860 }
1861 }
1862}
1863
1864impl GetValueType for Derived {
1865 fn get_value_type(&self) -> Type {
1866 ty::derived(self.name)
1867 }
1868}
1869
1870impl Display for Derived {
1871 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1872 write!(f, "{} {}", self.name, self.data)
1873 }
1874}
1875
1876#[derive(Debug, CloneWithNode)]
1878pub enum Unknown {
1879 Generic(Generic<Unknown>),
1881}
1882
1883impl_make_variable! {Unknown}
1884
1885impl Dummy for Unknown {
1886 fn dummy() -> Self {
1887 Self::Generic(Generic::Dummy)
1888 }
1889
1890 fn is_dummy(&self) -> bool {
1891 true
1892 }
1893}
1894
1895impl Display for Unknown {
1896 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1897 match self {
1898 Self::Generic(v) => write!(f, "{v}"),
1899 }
1900 }
1901}
1902
1903impl Displayed for Unknown {
1904 type Node = EmptyNode;
1905}
1906
1907impl GetValueType for Unknown {
1908 fn get_value_type(&self) -> Type {
1909 Type::Unknown
1910 }
1911}
1912
1913impl Expr<Unknown> {
1914 #[must_use]
1916 pub fn boxed(mut self, span: Span) -> Self {
1917 let node = self.take_node();
1918
1919 Self {
1920 data: Rc::new(Unknown::Generic(Generic::Boxed(self))),
1921 span,
1922 node,
1923 }
1924 }
1925}
1926
1927#[derive(Debug, CloneWithNode)]
1929pub enum AnyExpr {
1930 Point(Expr<Point>),
1931 Line(Expr<Line>),
1932 Number(Expr<Number>),
1933 Circle(Expr<Circle>),
1934 PointCollection(Expr<PointCollection>),
1935 Derived(Expr<Derived>),
1936 Unknown(Expr<Unknown>),
1937}
1938
1939impl_any_from_x! {Point}
1940impl_any_from_x! {Line}
1941impl_any_from_x! {Number}
1942impl_any_from_x! {Circle}
1943impl_any_from_x! {PointCollection}
1944impl_any_from_x! {Derived}
1945impl_any_from_x! {Unknown}
1946
1947impl AnyExpr {
1948 #[must_use]
1950 pub fn get_span_mut(&mut self) -> &mut Span {
1951 match self {
1952 Self::Point(v) => &mut v.span,
1953 Self::Line(v) => &mut v.span,
1954 Self::Number(v) => &mut v.span,
1955 Self::Circle(v) => &mut v.span,
1956 Self::PointCollection(v) => &mut v.span,
1957 Self::Derived(v) => &mut v.span,
1958 Self::Unknown(v) => &mut v.span,
1959 }
1960 }
1961
1962 #[must_use]
1964 pub fn get_span(&self) -> Span {
1965 match self {
1966 Self::Point(v) => v.span,
1967 Self::Line(v) => v.span,
1968 Self::Number(v) => v.span,
1969 Self::Circle(v) => v.span,
1970 Self::PointCollection(v) => v.span,
1971 Self::Derived(v) => v.span,
1972 Self::Unknown(v) => v.span,
1973 }
1974 }
1975
1976 pub fn replace_node(&mut self, with: Option<AnyExprNode>) -> Option<AnyExprNode> {
1978 Some(match self {
1979 Self::Point(v) => {
1980 AnyExprNode::Point(mem::replace(&mut v.node, with.map(AnyExprNode::to_point))?)
1981 }
1982 Self::Line(v) => {
1983 AnyExprNode::Line(mem::replace(&mut v.node, with.map(AnyExprNode::to_line))?)
1984 }
1985 Self::Number(v) => {
1986 AnyExprNode::Number(mem::replace(&mut v.node, with.map(AnyExprNode::to_scalar))?)
1987 }
1988 Self::Circle(v) => {
1989 AnyExprNode::Circle(mem::replace(&mut v.node, with.map(AnyExprNode::to_circle))?)
1990 }
1991 Self::PointCollection(v) => AnyExprNode::PointCollection(mem::replace(
1992 &mut v.node,
1993 with.map(AnyExprNode::to_point_collection),
1994 )?),
1995 Self::Derived(v) => AnyExprNode::Derived(mem::replace(
1996 &mut v.node,
1997 with.map(AnyExprNode::to_derived),
1998 )?),
1999 Self::Unknown(v) => AnyExprNode::Unknown(mem::replace(
2000 &mut v.node,
2001 with.map(AnyExprNode::to_unknown),
2002 )?),
2003 })
2004 }
2005
2006 #[must_use]
2008 pub fn get_node(&self) -> Option<&dyn Node> {
2009 match self {
2010 Self::Point(x) => x.node.as_ref().map(|c| c as &dyn Node),
2011 Self::Line(x) => x.node.as_ref().map(|c| c as &dyn Node),
2012 Self::Number(x) => x.node.as_ref().map(|c| c as &dyn Node),
2013 Self::Circle(x) => x.node.as_ref().map(|c| c as &dyn Node),
2014 Self::PointCollection(x) => x.node.as_ref().map(|c| c as &dyn Node),
2015 Self::Derived(x) => x.node.as_ref().map(|c| c as &dyn Node),
2016 Self::Unknown(x) => x.node.as_ref().map(|c| c as &dyn Node),
2017 }
2018 }
2019
2020 #[must_use]
2021 pub fn to_scalar(self) -> Option<Expr<Number>> {
2022 match self {
2023 Self::Number(v) => Some(v),
2024 _ => None,
2025 }
2026 }
2027
2028 #[must_use]
2029 pub fn as_point(&self) -> Option<&Expr<Point>> {
2030 match self {
2031 Self::Point(v) => Some(v),
2032 _ => None,
2033 }
2034 }
2035
2036 #[must_use]
2038 pub fn get_type(&self) -> Type {
2039 match self {
2040 AnyExpr::Point(v) => v.get_value_type(),
2041 AnyExpr::Line(v) => v.get_value_type(),
2042 AnyExpr::Number(v) => v.get_value_type(),
2043 AnyExpr::Circle(v) => v.get_value_type(),
2044 AnyExpr::PointCollection(v) => v.get_value_type(),
2045 AnyExpr::Derived(v) => v.get_value_type(),
2046 AnyExpr::Unknown(v) => v.get_value_type(),
2047 }
2048 }
2049
2050 #[must_use]
2055 pub fn convert_to(self, to: Type, context: &CompileContext) -> Self {
2056 match to {
2057 Type::Point => Self::Point(self.convert(context)),
2058 Type::Line => Self::Line(self.convert(context)),
2059 Type::Number(unit) => Self::Number(self.convert(context).convert_unit(unit, context)),
2060 Type::PointCollection(len) => {
2061 Self::PointCollection(self.convert(context).check_len(len, context))
2062 }
2063 Type::Circle => Self::Circle(self.convert(context)),
2064 Type::Derived(name) => Self::Derived(self.convert(context).check_name(name, context)),
2065 Type::Unknown => Self::Unknown(Expr::dummy()),
2066 }
2067 }
2068
2069 #[must_use]
2071 pub fn can_convert_to(&self, to: Type) -> bool {
2072 match to {
2073 Type::Point => self.can_convert::<Point>(),
2074 Type::Line => self.can_convert::<Line>(),
2075 Type::Number(unit) => self.can_convert_to_scalar(unit).is_some(),
2076 Type::PointCollection(len) => self.can_convert_to_collection(len).is_some(),
2077 Type::Circle => self.can_convert::<Circle>(),
2078 Type::Derived(name) => self.can_convert_to_derived(name),
2079 Type::Unknown => true,
2080 }
2081 }
2082
2083 #[must_use]
2089 pub fn can_convert_to_scalar(&self, unit: Option<ComplexUnit>) -> Option<Option<ComplexUnit>> {
2090 match self {
2091 Self::Line(_) | Self::Derived(_) | Self::Circle(_) | Self::Point(_) => None,
2092 Self::PointCollection(v) => (v.data.length == 2
2093 && (unit == Some(unit::DISTANCE) || unit.is_none()))
2094 .then_some(Some(unit::DISTANCE)),
2095 Self::Number(u) => (u.data.unit == unit || u.data.unit.is_none() || unit.is_none())
2096 .then_some(u.data.unit.or(unit)),
2097 Self::Unknown(_) => Some(unit),
2098 }
2099 }
2100
2101 #[must_use]
2103 pub fn can_convert_to_collection(&self, len: usize) -> Option<usize> {
2104 match self {
2105 Self::Line(_) | Self::Derived(_) | Self::Circle(_) | Self::Number(_) => None,
2106 Self::PointCollection(v) => (v.data.length == len || len == 0).then_some(v.data.length),
2107 Self::Point(_) => (len == 1 || len == 0).then_some(1),
2108 Self::Unknown(_) => Some(0),
2109 }
2110 }
2111
2112 #[must_use]
2114 pub fn can_convert_to_derived(&self, name: &str) -> bool {
2115 match self {
2116 Self::Derived(derived) => derived.data.name == name,
2117 Self::Unknown(_) => true,
2118 _ => false,
2119 }
2120 }
2121
2122 #[must_use]
2124 pub fn boxed(self, span: Span) -> Self {
2125 match self {
2126 Self::Point(v) => Self::Point(v.boxed(span)),
2127 Self::Line(v) => Self::Line(v.boxed(span)),
2128 Self::Number(v) => Self::Number(v.boxed(span)),
2129 Self::Circle(v) => Self::Circle(v.boxed(span)),
2130 Self::PointCollection(v) => Self::PointCollection(v.boxed(span)),
2131 Self::Derived(v) => Self::Derived(v.boxed(span)),
2132 Self::Unknown(v) => Self::Unknown(v.boxed(span)),
2133 }
2134 }
2135
2136 #[must_use]
2141 pub fn get_variable_span(&self) -> Span {
2142 match self {
2143 Self::Point(v) => match v.data.as_ref() {
2144 Point::Generic(Generic::VariableAccess(var)) => var.definition_span,
2145 _ => panic!("not a variable"),
2146 },
2147 Self::Line(v) => match v.data.as_ref() {
2148 Line::Generic(Generic::VariableAccess(var)) => var.definition_span,
2149 _ => panic!("not a variable"),
2150 },
2151 Self::Number(v) => match &v.data.data {
2152 NumberData::Generic(Generic::VariableAccess(var)) => var.definition_span,
2153 _ => panic!("not a variable"),
2154 },
2155 Self::Circle(v) => match v.data.as_ref() {
2156 Circle::Generic(Generic::VariableAccess(var)) => var.definition_span,
2157 _ => panic!("not a variable"),
2158 },
2159 Self::PointCollection(v) => match &v.data.data {
2160 PointCollectionData::Generic(Generic::VariableAccess(var)) => var.definition_span,
2161 _ => panic!("not a variable"),
2162 },
2163 Self::Derived(v) => match &v.data.data {
2164 DerivedData::Generic(Generic::VariableAccess(var)) => var.definition_span,
2165 _ => panic!("not a variable"),
2166 },
2167 Self::Unknown(v) => match v.data.as_ref() {
2168 Unknown::Generic(Generic::VariableAccess(var)) => var.definition_span,
2169 Unknown::Generic(_) => panic!("not a variable"),
2170 },
2171 }
2172 }
2173
2174 #[must_use]
2176 pub fn make_variable(self, name: String) -> Self {
2177 match self {
2178 Self::Point(v) => Self::Point(v.make_variable(name)),
2179 Self::Line(v) => Self::Line(v.make_variable(name)),
2180 Self::Number(v) => Self::Number(v.make_variable(name)),
2181 Self::Circle(v) => Self::Circle(v.make_variable(name)),
2182 Self::PointCollection(v) => Self::PointCollection(v.make_variable(name)),
2183 Self::Derived(v) => Self::Derived(v.make_variable(name)),
2184 Self::Unknown(v) => Self::Unknown(v.make_variable(name)),
2185 }
2186 }
2187
2188 #[must_use]
2189 pub fn as_derived(&self) -> Option<&Expr<Derived>> {
2190 if let Self::Derived(v) = self {
2191 Some(v)
2192 } else {
2193 None
2194 }
2195 }
2196
2197 pub fn try_into_derived(self) -> Result<Expr<Derived>, Self> {
2198 if let Self::Derived(v) = self {
2199 Ok(v)
2200 } else {
2201 Err(self)
2202 }
2203 }
2204
2205 #[must_use]
2206 pub fn as_number(&self) -> Option<&Expr<Number>> {
2207 if let Self::Number(v) = self {
2208 Some(v)
2209 } else {
2210 None
2211 }
2212 }
2213}
2214
2215impl Dummy for AnyExpr {
2216 fn dummy() -> Self {
2217 Self::Unknown(Expr::dummy())
2218 }
2219
2220 fn is_dummy(&self) -> bool {
2221 match self {
2222 Self::Point(v) => v.is_dummy(),
2223 Self::Line(v) => v.is_dummy(),
2224 Self::Number(v) => v.is_dummy(),
2225 Self::Circle(v) => v.is_dummy(),
2226 Self::PointCollection(v) => v.is_dummy(),
2227 Self::Derived(v) => v.is_dummy(),
2228 Self::Unknown(v) => v.is_dummy(),
2229 }
2230 }
2231}
2232
2233impl Display for AnyExpr {
2234 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2235 match self {
2236 Self::Point(v) => write!(f, "{v}"),
2237 Self::Line(v) => write!(f, "{v}"),
2238 Self::Number(v) => write!(f, "{v}"),
2239 Self::Circle(v) => write!(f, "{v}"),
2240 Self::PointCollection(v) => write!(f, "{v}"),
2241 Self::Derived(v) => write!(f, "{v}"),
2242 Self::Unknown(v) => write!(f, "{v}"),
2243 }
2244 }
2245}
2246
2247pub fn display_vec<T: Display>(v: &[T]) -> String {
2249 v.iter()
2250 .map(|x| format!("{x}"))
2251 .collect::<Vec<String>>()
2252 .join(", ")
2253}
2254
2255pub trait Dummy {
2257 #[must_use]
2259 fn dummy() -> Self;
2260
2261 #[must_use]
2263 fn is_dummy(&self) -> bool;
2264}
2265
2266pub trait Displayed: Sized {
2268 type Node: Node + ?Sized;
2270}
2271
2272pub trait GetData {
2274 #[must_use]
2276 fn get_data(&self) -> &Self;
2277}
2278
2279pub trait CloneWithNode {
2282 #[must_use]
2284 fn clone_with_node(&mut self) -> Self;
2285
2286 #[must_use]
2288 fn clone_without_node(&self) -> Self;
2289}
2290
2291#[derive(Debug)]
2293pub struct ClonedVec<T>(pub Vec<T>);
2294
2295impl<T> From<Vec<T>> for ClonedVec<T> {
2296 fn from(value: Vec<T>) -> Self {
2297 Self(value)
2298 }
2299}
2300
2301impl<T> Deref for ClonedVec<T> {
2302 type Target = Vec<T>;
2303
2304 fn deref(&self) -> &Self::Target {
2305 &self.0
2306 }
2307}
2308
2309impl<T> DerefMut for ClonedVec<T> {
2310 fn deref_mut(&mut self) -> &mut Self::Target {
2311 &mut self.0
2312 }
2313}
2314
2315#[derive(Debug)]
2317pub struct ClonedMap<K, V>(pub HashMap<K, V>);
2318
2319impl<K, V> From<HashMap<K, V>> for ClonedMap<K, V> {
2320 fn from(value: HashMap<K, V>) -> Self {
2321 Self(value)
2322 }
2323}
2324
2325impl<K, V> Deref for ClonedMap<K, V> {
2326 type Target = HashMap<K, V>;
2327
2328 fn deref(&self) -> &Self::Target {
2329 &self.0
2330 }
2331}
2332
2333impl<K, V> DerefMut for ClonedMap<K, V> {
2334 fn deref_mut(&mut self) -> &mut Self::Target {
2335 &mut self.0
2336 }
2337}
2338
2339impl<T: Clone> CloneWithNode for T {
2340 fn clone_with_node(&mut self) -> Self {
2341 self.clone()
2342 }
2343
2344 fn clone_without_node(&self) -> Self {
2345 self.clone()
2346 }
2347}
2348
2349impl<T: CloneWithNode> CloneWithNode for ClonedVec<T> {
2350 fn clone_with_node(&mut self) -> Self {
2351 self.iter_mut()
2352 .map(CloneWithNode::clone_with_node)
2353 .collect::<Vec<_>>()
2354 .into()
2355 }
2356
2357 fn clone_without_node(&self) -> Self {
2358 self.iter()
2359 .map(CloneWithNode::clone_without_node)
2360 .collect::<Vec<_>>()
2361 .into()
2362 }
2363}
2364
2365impl<K: Hash + CloneWithNode + Eq, V: CloneWithNode> CloneWithNode for ClonedMap<K, V> {
2366 fn clone_with_node(&mut self) -> Self {
2367 self.iter_mut()
2368 .map(|(k, v)| (k.clone_without_node(), v.clone_with_node()))
2369 .collect::<HashMap<_, _>>()
2370 .into()
2371 }
2372
2373 fn clone_without_node(&self) -> Self {
2374 self.iter()
2375 .map(|(k, v)| (k.clone_without_node(), v.clone_without_node()))
2376 .collect::<HashMap<_, _>>()
2377 .into()
2378 }
2379}
2380
2381#[derive(Debug)]
2383pub struct Expr<T: Displayed> {
2384 pub data: Rc<T>,
2386 pub span: Span,
2388 pub node: Option<HierarchyNode<T::Node>>,
2390}
2391
2392impl<T: GetData + Displayed> Expr<T> {
2393 #[must_use]
2395 pub fn get_data(&self) -> &T {
2396 self.data.get_data()
2397 }
2398}
2399
2400impl<T: Displayed> CloneWithNode for Expr<T> {
2401 fn clone_with_node(&mut self) -> Self {
2402 Self {
2403 data: Rc::clone(&self.data),
2404 span: self.span,
2405 node: self.node.take(),
2406 }
2407 }
2408
2409 fn clone_without_node(&self) -> Self {
2410 Self {
2411 data: Rc::clone(&self.data),
2412 span: self.span,
2413 node: None,
2414 }
2415 }
2416}
2417
2418impl<T: GetValueType + Displayed> GetValueType for Expr<T> {
2419 fn get_value_type(&self) -> Type {
2420 self.data.get_value_type()
2421 }
2422}
2423
2424impl<T: Display + Displayed> Display for Expr<T> {
2425 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2426 write!(f, "{}", self.data)
2427 }
2428}
2429
2430impl<T: Displayed> Expr<T> {
2431 #[must_use]
2433 pub fn new_spanless(data: T) -> Self {
2434 Self {
2435 span: span!(0, 0, 0, 0),
2436 data: Rc::new(data),
2437 node: None,
2438 }
2439 }
2440
2441 pub fn take_node(&mut self) -> Option<HierarchyNode<T::Node>> {
2443 self.node.take()
2444 }
2445}
2446
2447impl<T: Displayed + Dummy> Dummy for Expr<T> {
2448 fn dummy() -> Self {
2449 Self::new_spanless(T::dummy())
2450 }
2451
2452 fn is_dummy(&self) -> bool {
2453 self.data.is_dummy()
2454 }
2455}
2456
2457#[derive(Debug)]
2459pub struct UnrolledRule {
2460 pub kind: UnrolledRuleKind,
2462 pub inverted: bool,
2464 pub weight: ProcNum,
2466}
2467
2468impl Display for UnrolledRule {
2469 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2470 let inv = if self.inverted { "!" } else { "" };
2471
2472 match &self.kind {
2473 UnrolledRuleKind::PointEq(a, b) => write!(f, "{a} {inv}= {b}"),
2474 UnrolledRuleKind::NumberEq(a, b) => write!(f, "{a} {inv}= {b}"),
2475 UnrolledRuleKind::Gt(a, b) => {
2476 write!(f, "{a} {} {b}", if self.inverted { "<=" } else { ">" })
2477 }
2478 UnrolledRuleKind::Alternative(v) => {
2479 write!(
2480 f,
2481 "{}",
2482 v.iter()
2483 .map(|x| format!("{x}"))
2484 .collect::<Vec<String>>()
2485 .join(" || ")
2486 )
2487 }
2488 UnrolledRuleKind::Bias(v) => write!(f, "bias {v}"),
2489 }
2490 }
2491}
2492
2493#[must_use]
2500pub fn construct_point_name(letter: char, primes: u8) -> String {
2501 String::from(letter) + &"'".repeat(primes as usize)
2502}
2503
2504fn fetch_variable(context: &CompileContext, name: &str, variable_span: Span) -> AnyExpr {
2506 let mut var = if let Some(var) = context.variables.get(name) {
2507 var.clone_without_node()
2508 } else {
2509 let suggested = most_similar(context.variables.keys(), name);
2510
2511 context.push_error(Error::UndefinedVariable {
2512 error_span: variable_span,
2513 variable_name: name.to_string(),
2514 suggested: suggested.cloned(),
2515 suggest_complex: name == "i",
2516 });
2517
2518 Expr::new_spanless(Unknown::dummy())
2519 .make_variable(name.to_string())
2520 .into()
2521 };
2522
2523 *var.get_span_mut() = variable_span;
2524 var
2525}
2526
2527impl Unroll for SimpleExpression {
2528 fn unroll(
2529 &self,
2530 context: &mut CompileContext,
2531 library: &Library,
2532 it_index: &HashMap<u8, usize>,
2533 display: Properties,
2534 ) -> AnyExpr {
2535 let display = Properties::from(self.display.clone()).merge_with(display);
2536
2537 let unrolled = self.kind.unroll(context, library, it_index, display);
2538 let unrolled = if let Some(exponent) = &self.exponent {
2539 let mut unrolled: Expr<Number> = unrolled.convert(context);
2540 let node = unrolled.node.take();
2541
2542 let exponent = match exponent.exponent.as_comp() {
2543 Ok(v) => {
2544 if self.minus.is_some() {
2545 -v
2546 } else {
2547 v
2548 }
2549 }
2550 Err(err) => {
2551 context.push_error(err);
2552 CompExponent::one()
2553 }
2554 };
2555
2556 AnyExpr::Number(Expr {
2557 span: self.get_span(),
2558 data: Rc::new(Number {
2559 unit: unrolled.data.unit.map(|v| v.pow(exponent)),
2560 data: NumberData::Pow(unrolled, exponent),
2561 }),
2562 node,
2563 })
2564 } else {
2565 unrolled
2566 };
2567
2568 if self.minus.is_some() {
2569 let mut unrolled: Expr<Number> = unrolled.convert(context);
2570 let node = unrolled.node.take();
2571
2572 AnyExpr::Number(Expr {
2573 span: self.get_span(),
2574 data: Rc::new(Number {
2575 unit: unrolled.data.unit,
2576 data: NumberData::Negate(unrolled),
2577 }),
2578 node,
2579 })
2580 } else {
2581 unrolled
2582 }
2583 }
2584}
2585
2586#[derive(Debug)]
2588pub enum FuncRef {
2589 Function(String),
2590 Method(String, AnyExpr),
2592 Invalid,
2594}
2595
2596impl Unroll for Ident {
2597 fn unroll(
2598 &self,
2599 context: &mut CompileContext,
2600 _library: &Library,
2601 _it_index: &HashMap<u8, usize>,
2602 display: Properties,
2603 ) -> AnyExpr {
2604 match self {
2605 Ident::Named(named) => {
2606 display.finish(context);
2608
2609 fetch_variable(context, &named.ident, named.span)
2610 }
2611 Ident::Collection(col) => {
2612 let mut display = display;
2613 let display_pc = display.get("display").maybe_unset(true);
2614
2615 let mut pc_children = Vec::new();
2616 pc_children.resize_with(col.collection.len(), || None);
2617
2618 let mut expr = Expr {
2620 data: Rc::new(PointCollection {
2621 length: col.collection.len(),
2622 data: PointCollectionData::PointCollection(
2623 col.collection
2624 .iter()
2625 .map(|item| {
2626 fetch_variable(context, &format!("{item}"), col.span)
2627 .convert::<Point>(context)
2628 })
2629 .collect::<Vec<_>>()
2630 .into(),
2631 ),
2632 }),
2633 span: col.span,
2634 node: None,
2635 };
2636 expr.node = Some(HierarchyNode::new(PCNode {
2637 display: display_pc,
2638 children: pc_children,
2639 props: Some(display),
2640 expr: expr.clone_without_node(),
2641 }));
2642 AnyExpr::PointCollection(expr)
2643 }
2644 }
2645 }
2646}
2647
2648impl Unroll for ExprCall {
2649 fn unroll(
2650 &self,
2651 context: &mut CompileContext,
2652 library: &Library,
2653 it_index: &HashMap<u8, usize>,
2654 mut display: Properties,
2655 ) -> AnyExpr {
2656 let name = self
2657 .name
2658 .unroll(context, library, it_index, Properties::default());
2659
2660 let (func_name, self_param) = match name {
2661 FuncRef::Function(x) => (x, None),
2662 FuncRef::Method(x, y) => (x, Some(y)),
2663 FuncRef::Invalid => {
2664 display.ignore_all();
2665 display.finish(context);
2666 return AnyExpr::Unknown(Expr::new_spanless(Unknown::dummy()));
2667 }
2668 };
2669
2670 let self_type = self_param.as_ref().map(AnyExpr::get_type);
2671
2672 let mut params = Vec::new();
2673 params.extend(self_param);
2674
2675 if let Some(parsed) = &self.params {
2676 for p in parsed.iter() {
2677 params.push(p.unroll(context, library, it_index, Properties::default()));
2678 }
2679 }
2680
2681 let func = match self_type {
2682 Some(t) => library.get_method(t, &func_name),
2683 None => library.get_function(&func_name),
2684 };
2685
2686 let res = match func {
2687 Ok(func) => {
2688 if let Some(overload) = func.get_overload(¶ms) {
2689 let ret = overload.unroll(params, context, display);
2690
2691 return ret.boxed(self.get_span());
2692 }
2693
2694 context.push_error(Error::OverloadNotFound {
2695 error_span: self.get_span(),
2696 function_name: func_name.clone(),
2697 params: params.iter().map(AnyExpr::get_type).collect(),
2698 });
2699
2700 Expr {
2701 data: Rc::new(Unknown::dummy()),
2702 span: self.get_span(),
2703 node: None,
2704 }
2705 .into()
2706 }
2707 Err(suggested) => {
2708 if let Some(self_type) = self_type {
2709 context.push_error(Error::UndefinedMethod {
2710 error_span: self.name.get_span(),
2711 function_name: func_name,
2712 on_type: self_type,
2713 suggested,
2714 });
2715 } else {
2716 context.push_error(Error::UndefinedFunction {
2717 error_span: self.name.get_span(),
2718 function_name: func_name.clone(),
2719 suggested,
2720 });
2721 }
2722
2723 Expr::new_spanless(Unknown::dummy()).into()
2724 }
2725 };
2726
2727 for mut param in params {
2728 if let Some(AnyExprNode::PointCollection(mut pc)) = param.replace_node(None) {
2729 if let Some(props) = pc.root.props.take() {
2730 props.finish(context);
2731 }
2732 }
2733 }
2734
2735 display.ignore_all();
2736 display.finish(context);
2737
2738 res
2739 }
2740}
2741
2742impl Unroll for Name {
2743 fn unroll(
2744 &self,
2745 context: &mut CompileContext,
2746 library: &Library,
2747 it_index: &HashMap<u8, usize>,
2748 display: Properties,
2749 ) -> AnyExpr {
2750 match self {
2751 Self::Ident(i) => i.unroll(context, library, it_index, display),
2752 Self::Call(expr) => expr.unroll(context, library, it_index, display),
2753 Self::Expression(v) => v.content.unroll(context, library, it_index, display),
2754 Self::FieldIndex(_) => {
2755 context.push_error(Error::FieldAccess {
2756 error_span: self.get_span(),
2757 });
2758
2759 Expr::new_spanless(Unknown::dummy()).into()
2760 }
2761 }
2762 }
2763}
2764
2765impl Unroll<FuncRef> for Name {
2766 fn unroll(
2767 &self,
2768 context: &mut CompileContext,
2769 library: &Library,
2770 it_index: &HashMap<u8, usize>,
2771 display: Properties,
2772 ) -> FuncRef {
2773 display.finish(context);
2774
2775 match self {
2776 Self::Ident(Ident::Named(n)) => FuncRef::Function(n.ident.clone()),
2777 Self::FieldIndex(f) => {
2778 let self_param: AnyExpr =
2779 f.name
2780 .unroll(context, library, it_index, Properties::default());
2781 let name = match &f.field {
2782 Ident::Named(n) => n.ident.clone(),
2783 Ident::Collection(_) => {
2784 context.push_error(Error::ExpectedFunction {
2785 error_span: self.get_span(),
2786 });
2787
2788 return FuncRef::Invalid;
2789 }
2790 };
2791
2792 match self_param {
2793 AnyExpr::Unknown(_) => FuncRef::Invalid,
2794 self_param => FuncRef::Method(name, self_param),
2795 }
2796 }
2797 _ => {
2798 context.push_error(Error::ExpectedFunction {
2799 error_span: self.get_span(),
2800 });
2801
2802 FuncRef::Invalid
2803 }
2804 }
2805 }
2806}
2807
2808impl Unroll for NumberLit {
2809 fn unroll(
2810 &self,
2811 context: &mut CompileContext,
2812 _library: &Library,
2813 _it_index: &HashMap<u8, usize>,
2814 display: Properties,
2815 ) -> AnyExpr {
2816 display.finish(context);
2817
2818 AnyExpr::Number(Expr {
2819 data: Rc::new(Number {
2820 unit: None,
2821 data: NumberData::Number(self.into()),
2822 }),
2823 span: self.get_span(),
2824 node: None,
2825 })
2826 }
2827}
2828
2829impl Unroll for ExplicitIterator {
2830 fn unroll(
2831 &self,
2832 context: &mut CompileContext,
2833 library: &Library,
2834 it_index: &HashMap<u8, usize>,
2835 display: Properties,
2836 ) -> AnyExpr {
2837 self.get(it_index[&self.id])
2838 .unwrap()
2839 .unroll(context, library, it_index, display)
2840 }
2841}
2842
2843impl Unroll for PointCollectionConstructor {
2844 fn unroll(
2845 &self,
2846 context: &mut CompileContext,
2847 library: &Library,
2848 it_index: &HashMap<u8, usize>,
2849 mut display: Properties,
2850 ) -> AnyExpr {
2851 let display_pc = display.get("display").maybe_unset(true);
2852
2853 let mut pc_children = Vec::new();
2854 pc_children.resize_with(self.points.len(), || None);
2855
2856 let mut expr = Expr {
2857 span: self.get_span(),
2858 data: Rc::new(PointCollection {
2859 length: self.points.len(),
2860 data: PointCollectionData::PointCollection({
2861 let mut points = Vec::new();
2862
2863 for expr in self.points.iter() {
2864 let mut unrolled =
2865 expr.unroll(context, library, it_index, Properties::default());
2866
2867 if unrolled.can_convert_to(ty::POINT) {
2868 points.push(unrolled.convert(context));
2869 } else {
2870 context.push_error(Error::NonPointInPointCollection {
2871 error_span: self.get_span(),
2872 received: (expr.get_span(), unrolled.get_type()), });
2874
2875 points.push(Expr {
2877 span: unrolled.get_span(),
2878 data: Rc::new(Point::dummy()),
2879 node: unrolled.replace_node(None).map(AnyExprNode::to_point),
2880 });
2881 }
2882 }
2883
2884 for pt in &mut points {
2885 pc_children.push(pt.take_node());
2886 }
2887
2888 points.into()
2889 }),
2890 }),
2891 node: None,
2892 };
2893
2894 expr.node = Some(HierarchyNode::new(PCNode {
2895 display: display_pc,
2896 children: pc_children,
2897 props: Some(display),
2898 expr: expr.clone_without_node(),
2899 }));
2900
2901 AnyExpr::PointCollection(expr)
2902 }
2903}
2904
2905impl Unroll for SimpleExpressionKind {
2906 fn unroll(
2907 &self,
2908 context: &mut CompileContext,
2909 library: &Library,
2910 it_index: &HashMap<u8, usize>,
2911 display: Properties,
2912 ) -> AnyExpr {
2913 match self {
2914 Self::Name(name) => name.unroll(context, library, it_index, display),
2915 Self::Number(num) => num.unroll(context, library, it_index, display),
2916 Self::ExplicitIterator(it) => it.unroll(context, library, it_index, display),
2917 Self::PointCollection(col) => col.unroll(context, library, it_index, display),
2918 }
2919 }
2920}
2921
2922impl<const ITER: bool> Unroll for ExprBinop<ITER> {
2923 fn unroll(
2924 &self,
2925 context: &mut CompileContext,
2926 library: &Library,
2927 it_index: &HashMap<u8, usize>,
2928 display: Properties,
2929 ) -> AnyExpr {
2930 let lhs = self
2931 .lhs
2932 .unroll(context, library, it_index, Properties::default());
2933 let rhs = self
2934 .rhs
2935 .unroll(context, library, it_index, Properties::default());
2936
2937 let mut lhs = if lhs.can_convert_to(ty::SCALAR_UNKNOWN) {
2938 lhs.convert::<Number>(context)
2939 } else {
2940 context.push_error(Error::InvalidOperandType {
2941 error_span: Box::new(self.get_span()),
2942 got: (lhs.get_type(), Box::new(lhs.get_span())),
2943 op: self.operator.to_string(),
2944 });
2945
2946 Expr {
2947 span: lhs.get_span(),
2948 data: Rc::new(Number::dummy()),
2949 node: None,
2950 }
2951 };
2952
2953 let mut rhs = if rhs.can_convert_to(ty::SCALAR_UNKNOWN) {
2954 rhs.convert::<Number>(context)
2955 } else {
2956 context.push_error(Error::InvalidOperandType {
2957 error_span: Box::new(self.get_span()),
2958 got: (rhs.get_type(), Box::new(rhs.get_span())),
2959 op: self.operator.to_string(),
2960 });
2961
2962 Expr {
2963 span: rhs.get_span(),
2964 data: Rc::new(Number::dummy()),
2965 node: None,
2966 }
2967 };
2968
2969 let lhs_node = lhs.take_node();
2971 let rhs_node = rhs.take_node();
2972
2973 match &self.operator {
2974 BinaryOperator::Add(_) | BinaryOperator::Sub(_) => {
2975 let lhs = if lhs.data.unit.is_none() {
2976 lhs.convert_unit(rhs.data.unit, context)
2977 } else {
2978 lhs
2979 };
2980
2981 let rhs = rhs.convert_unit(lhs.data.unit, context);
2982 let mut expr = Expr {
2983 span: self.get_span(),
2984 data: Rc::new(Number {
2985 unit: rhs.data.unit,
2986 data: match &self.operator {
2987 BinaryOperator::Add(_) => NumberData::Add(lhs, rhs),
2988 BinaryOperator::Sub(_) => NumberData::Subtract(lhs, rhs),
2989 _ => unreachable!(),
2990 },
2991 }),
2992 node: None,
2993 };
2994
2995 let mut node = HierarchyNode::new(NumberNode::from_expr(&expr, display, context));
2996 node.extend_children(lhs_node);
2997 node.extend_children(rhs_node);
2998
2999 expr.node = Some(node);
3000
3001 AnyExpr::Number(expr)
3002 }
3003 BinaryOperator::Mul(_) | BinaryOperator::Div(_) => {
3004 let lhs = lhs.specify_unit(context);
3005
3006 let rhs = rhs.specify_unit(context);
3007 let mut expr = Expr {
3008 span: self.get_span(),
3009 data: Rc::new(Number {
3010 unit: Some(lhs.data.unit.unwrap() * rhs.data.unit.as_ref().unwrap()),
3011 data: match &self.operator {
3012 BinaryOperator::Mul(_) => NumberData::Multiply(lhs, rhs),
3013 BinaryOperator::Div(_) => NumberData::Divide(lhs, rhs),
3014 _ => unreachable!(),
3015 },
3016 }),
3017 node: None,
3018 };
3019
3020 let mut node = HierarchyNode::new(NumberNode::from_expr(&expr, display, context));
3021 node.extend_children(lhs_node);
3022 node.extend_children(rhs_node);
3023
3024 expr.node = Some(node);
3025
3026 AnyExpr::Number(expr)
3027 }
3028 }
3029 }
3030}
3031
3032impl<const ITER: bool> Unroll for ImplicitIterator<ITER> {
3033 fn unroll(
3034 &self,
3035 context: &mut CompileContext,
3036 library: &Library,
3037 it_index: &HashMap<u8, usize>,
3038 display: Properties,
3039 ) -> AnyExpr {
3040 if self.exprs.collection.is_empty() {
3041 self.exprs.first.as_ref()
3042 } else {
3043 self.get(it_index[&0]).unwrap()
3045 }
3046 .unroll(context, library, it_index, display)
3047 }
3048}
3049
3050impl<const ITER: bool> Unroll for Expression<ITER> {
3051 fn unroll(
3052 &self,
3053 context: &mut CompileContext,
3054 library: &Library,
3055 it_index: &HashMap<u8, usize>,
3056 display: Properties,
3057 ) -> AnyExpr {
3058 match self {
3059 Expression::ImplicitIterator(it) => it.unroll(context, library, it_index, display),
3060 Expression::Binop(op) => op.unroll(context, library, it_index, display),
3061 }
3062 }
3063}
3064
3065pub fn most_similar<'r, I: IntoIterator<Item = &'r T>, T: AsRef<str> + ?Sized + 'r>(
3091 expected: I,
3092 received: &str,
3093) -> Option<&'r T> {
3094 #[allow(clippy::cast_possible_truncation)]
3095 expected
3096 .into_iter()
3097 .map(|v| {
3098 (
3099 v,
3100 (strsim::jaro(v.as_ref(), received) * 1000.0).floor() as i64,
3101 )
3102 })
3103 .filter(|v| v.1 > 600)
3104 .max_by_key(|v| v.1)
3105 .map(|v| v.0)
3106}
3107
3108#[derive(Debug)]
3110pub struct Properties {
3111 props: HashMap<String, (Span, String, PropertyValue)>,
3113 finished: bool,
3115 errors: Vec<Error>,
3117 expected: Vec<&'static str>,
3120}
3121
3122impl Display for Properties {
3123 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
3124 write!(f, "[")?;
3125
3126 for (k, v) in &self.props {
3127 write!(f, "{k} = {}, ", v.1)?;
3128 }
3129
3130 write!(f, "]")
3131 }
3132}
3133
3134impl Clone for Properties {
3135 fn clone(&self) -> Self {
3136 Self {
3137 props: self.props.clone(),
3138 finished: false,
3139 errors: Vec::new(),
3140 expected: Vec::new(),
3141 }
3142 }
3143}
3144
3145#[allow(clippy::derivable_impls)]
3147impl Default for Properties {
3148 fn default() -> Self {
3149 Self {
3150 props: HashMap::new(),
3151 finished: false,
3152 errors: Vec::new(),
3153 expected: Vec::new(),
3154 }
3155 }
3156}
3157
3158impl Properties {
3159 fn normalize(property: &str) -> String {
3160 property
3161 .chars()
3162 .filter(|c| *c != '_')
3163 .map(|c| c.to_ascii_lowercase())
3164 .collect()
3165 }
3166
3167 pub fn finish(mut self, context: &CompileContext) {
3169 self.finished = true;
3170
3171 let props = mem::take(&mut self.props);
3172 let expected = mem::take(&mut self.expected);
3173
3174 self.errors.extend(props.into_values().map(|value| {
3175 let suggested = most_similar(expected.iter().copied(), &value.1);
3176
3177 Error::UnexpectedDisplayOption {
3178 error_span: value.0,
3179 option: value.1,
3180 suggested,
3181 }
3182 }));
3183
3184 context.extend_errors(mem::take(&mut self.errors));
3185 }
3186
3187 #[must_use]
3189 pub fn get<T: FromProperty>(&mut self, property: &'static str) -> Property<T> {
3190 let norm = Self::normalize(property);
3191 if let Some((_, _, prop)) = self.props.remove(&norm) {
3192 let prop_span = prop.get_span();
3193
3194 Property {
3195 value: match T::from_property(prop) {
3196 Ok(v) => Some(v),
3197 Err(err) => {
3198 self.errors.push(err);
3199 None
3200 }
3201 },
3202 span: Some(prop_span),
3203 }
3204 } else {
3205 self.expected.push(property);
3206
3207 Property {
3208 value: None,
3209 span: None,
3210 }
3211 }
3212 }
3213
3214 pub fn ignore(&mut self, property: &'static str) {
3216 self.props.remove(&Self::normalize(property));
3217 }
3218
3219 pub fn add_if_not_present(
3221 &mut self,
3222 property: &'static str,
3223 (key_span, value): (Span, PropertyValue),
3224 ) {
3225 self.props.entry(Self::normalize(property)).or_insert((
3226 key_span,
3227 property.to_string(),
3228 value,
3229 ));
3230 }
3231
3232 #[must_use]
3235 pub fn merge_with(mut self, mut other: Properties) -> Self {
3236 self.errors.extend(mem::take(&mut other.errors));
3237
3238 for (k, v) in mem::take(&mut other.props) {
3239 self.props.insert(k, v);
3240 }
3241
3242 other.finished = true;
3244
3245 self
3246 }
3247
3248 fn ignore_all(&mut self) {
3250 self.props.clear();
3251 }
3252}
3253
3254impl From<Option<DisplayProperties>> for Properties {
3255 fn from(value: Option<DisplayProperties>) -> Self {
3256 Self {
3257 props: value
3258 .into_iter()
3259 .flat_map(|x| x.properties.into_parsed_iter())
3260 .map(|v| {
3261 (
3262 Self::normalize(&v.name.ident),
3263 (v.name.span, v.name.ident.clone(), v.value.clone()),
3264 )
3265 })
3266 .collect(),
3267 finished: false,
3268 errors: Vec::new(),
3269 expected: Vec::new(),
3270 }
3271 }
3272}
3273
3274impl Drop for Properties {
3275 fn drop(&mut self) {
3276 if !self.finished {
3277 eprintln!(
3278 "Properties dropped before finishing parsing: {:#?}. Please report this error.",
3279 self.props
3280 );
3281 }
3282 }
3283}
3284
3285#[derive(Debug, Clone)]
3287pub struct Property<T> {
3288 value: Option<T>,
3289 span: Option<Span>,
3290}
3291
3292impl<T> Property<T> {
3293 #[must_use]
3295 pub fn get(self) -> Option<T> {
3296 self.value
3297 }
3298
3299 #[must_use]
3301 pub fn get_or(self, default: T) -> T {
3302 self.value.unwrap_or(default)
3303 }
3304
3305 #[must_use]
3307 pub fn get_span(&self) -> Option<Span> {
3308 self.span
3309 }
3310
3311 #[must_use]
3313 pub fn maybe_unset(self, default: T) -> MaybeUnset<T> {
3314 let mut value = MaybeUnset::new(default);
3315 value.try_set(self.get());
3316
3317 value
3318 }
3319}
3320
3321impl<T> Property<Result<T, Error>> {
3322 #[must_use]
3324 pub fn ok_or(self, default: T) -> T {
3325 self.value.and_then(Result::ok).unwrap_or(default)
3326 }
3327}
3328
3329fn create_variable_named(
3331 stat: &LetStatement,
3332 context: &mut CompileContext,
3333 named: &NamedIdent,
3334 mut rhs_unrolled: AnyExpr,
3335 variable_nodes: &mut Vec<Box<dyn Node>>,
3336) -> Result<(), Error> {
3337 let convert = if let AnyExpr::PointCollection(pc) = &mut rhs_unrolled {
3338 if pc.data.length == 1 {
3339 true
3340 } else {
3341 if let Some(node) = &mut pc.node {
3342 if let Some(mut props) = node.root.props.take() {
3343 let _ = props.get::<Result<SpannedMathString, Error>>("default-label");
3344 props.finish(context);
3345 }
3346 }
3347
3348 context.push_error(Error::InvalidPC {
3351 error_span: stat.get_span(),
3352 });
3353 false
3354 }
3355 } else {
3356 false
3357 };
3358
3359 if convert {
3360 rhs_unrolled = rhs_unrolled.convert_to(Type::Point, context);
3361 }
3362
3363 match context.variables.entry(named.ident.clone()) {
3364 Entry::Occupied(entry) => Err(Error::RedefinedVariable {
3366 defined_at: entry.get().get_variable_span(),
3367 error_span: stat.get_span(),
3368 variable_name: entry.key().clone(),
3369 }),
3370 Entry::Vacant(entry) => {
3372 variable_nodes.extend(rhs_unrolled.replace_node(None).map(AnyExprNode::to_dyn));
3373
3374 let var = rhs_unrolled.make_variable(entry.key().clone());
3375 entry.insert(var);
3376
3377 Ok(())
3378 }
3379 }
3380}
3381
3382fn create_variable_collection(
3385 stat: &LetStatement,
3386 context: &mut CompileContext,
3387 col: &PCToken,
3388 rhs_unrolled: AnyExpr,
3389 variable_nodes: &mut Vec<Box<dyn Node>>,
3390) -> Result<(), Error> {
3391 let maybe_error = Error::CannotUnpack {
3394 error_span: rhs_unrolled.get_span(),
3395 ty: rhs_unrolled.get_type(),
3396 length: col.len(),
3397 };
3398
3399 let mut rhs = rhs_unrolled.convert::<PointCollection>(context);
3400
3401 if rhs.data.length != col.len()
3402 && !matches!(rhs.data.data, PointCollectionData::Generic(Generic::Dummy))
3403 {
3404 return Err(maybe_error);
3405 }
3406
3407 for (i, pt) in col.collection.iter().enumerate() {
3418 let id = format!("{pt}");
3419 let mut var = rhs.index_with_node(i);
3420 let mut pt_node = var
3421 .take_node()
3422 .unwrap_or(HierarchyNode::new(PointNode::from_expr(
3423 &var,
3424 Properties::default(),
3425 context,
3426 )));
3427
3428 match context.variables.entry(id.clone()) {
3429 Entry::Occupied(entry) => {
3431 return Err(Error::RedefinedVariable {
3432 defined_at: entry.get().get_variable_span(),
3433 error_span: stat.get_span(),
3434 variable_name: id,
3435 })
3436 }
3437 Entry::Vacant(entry) => {
3439 pt_node.root.default_label = SpannedMathString::from(pt.clone());
3440
3441 variable_nodes.push(Box::new(pt_node));
3442
3443 let var = var.make_variable(entry.key().clone());
3444
3445 let var = AnyExpr::Point(var);
3446 entry.insert(var);
3447 }
3448 }
3449 }
3450
3451 variable_nodes.extend(rhs.take_node().map(|n| Box::new(n) as Box<dyn Node>));
3452
3453 Ok(())
3454}
3455
3456fn create_variables(
3458 stat: &LetStatement,
3459 context: &mut CompileContext,
3460 library: &Library,
3461 external: Option<DisplayProperties>,
3462) -> Result<Vec<Box<dyn Node>>, Error> {
3463 let mut variable_nodes = Vec::new();
3464
3465 let tree = IterNode::from(&stat.expr);
3466
3467 let ind = if let Some(iter) = tree.first() {
3468 if stat.ident.len() == 1 {
3469 context.push_error(Error::LetStatUnexpectedIterator {
3470 var_span: stat.ident.get_span(),
3471 error_span: iter.span,
3472 });
3473
3474 }
3476
3477 for it in tree.iter() {
3478 if iter.id != it.id {
3479 context.push_error(Error::LetStatMoreThanOneIterator {
3480 error_span: stat.expr.get_span(),
3481 first_span: iter.span,
3482 second_span: it.span,
3483 });
3484
3485 }
3487
3488 for variant in &it.variants {
3489 if let Some(it2) = variant.first() {
3490 context.push_error(Error::LetStatMoreThanOneIterator {
3491 error_span: stat.expr.get_span(),
3492 first_span: iter.span,
3493 second_span: it2.span,
3494 });
3495
3496 }
3498 }
3499 }
3500
3501 let mut lengths = HashMap::new();
3502 tree.get_iter_lengths(&mut lengths, stat.expr.get_span())?;
3503 let entry = lengths.get(&iter.id).unwrap();
3504
3505 if entry.0 != stat.ident.len() {
3506 return Err(Error::InconsistentIterators {
3507 first_span: stat.ident.get_span(),
3508 first_length: stat.ident.len(),
3509 occurred_span: entry.1,
3510 occurred_length: entry.0,
3511 error_span: stat.get_span(),
3512 });
3513 }
3514
3515 None
3516 } else {
3517 Some(HashMap::new())
3518 };
3519
3520 let mut it_index = IterTreeIterator::new(&tree);
3521
3522 for def in stat.ident.iter() {
3524 let mut external = Properties::from(external.clone());
3525
3526 if def.name.is_named() {
3527 external.add_if_not_present(
3528 "default-label",
3529 (def.name.get_span(), PropertyValue::Ident(def.name.clone())),
3530 );
3531 }
3532
3533 let display = external.merge_with(Properties::from(def.display_properties.clone()));
3534
3535 let rhs_unrolled = stat.expr.unroll(
3536 context,
3537 library,
3538 ind.as_ref()
3539 .unwrap_or_else(|| it_index.get_currents().unwrap()),
3540 display,
3541 );
3542 it_index.next();
3543
3544 match &def.name {
3547 Ident::Named(named) => {
3548 create_variable_named(stat, context, named, rhs_unrolled, &mut variable_nodes)?;
3549 }
3550 Ident::Collection(col) => {
3551 create_variable_collection(stat, context, col, rhs_unrolled, &mut variable_nodes)?;
3552 }
3553 }
3554 }
3555
3556 Ok(variable_nodes)
3557}
3558
3559fn unroll_ref(
3561 stat: &parser::Displayed<RefStatement>,
3562 context: &mut CompileContext,
3563 library: &Library,
3564) -> Result<Vec<Box<dyn Node>>, Error> {
3565 let mut nodes = Vec::new();
3566 let tree = IterNode::from(&stat.statement.operand);
3567
3568 tree.get_iter_lengths(&mut HashMap::new(), stat.get_span())?;
3570
3571 let mut index = IterTreeIterator::new(&tree);
3573
3574 while let Some(it_index) = index.get_currents() {
3575 let mut display = Properties::from(stat.properties.clone());
3576 let weight = display.get("weight").get_or(ProcNum::zero());
3577
3578 let mut expr = stat
3579 .statement
3580 .operand
3581 .unroll(context, library, it_index, display);
3582
3583 if let AnyExpr::PointCollection(pc) = &mut expr {
3584 if let Some(node) = pc.node.take() {
3585 if let Some(props) = node.root.props {
3586 props.finish(context);
3587 }
3588 }
3589
3590 context.push_error(Error::InvalidPC {
3591 error_span: expr.get_span(),
3592 });
3593 }
3594
3595 let node = expr.replace_node(None).map(AnyExprNode::to_dyn);
3596 nodes.extend(node);
3597
3598 if !weight.is_zero() {
3600 context.push_rule(UnrolledRule {
3601 kind: UnrolledRuleKind::Bias(expr),
3602 inverted: false,
3603 weight,
3604 });
3605 }
3606
3607 index.next();
3608 }
3609
3610 Ok(nodes)
3611}
3612
3613fn unroll_let(
3615 stat: parser::Displayed<LetStatement>,
3616 context: &mut CompileContext,
3617 library: &Library,
3618) -> Result<Vec<Box<dyn Node>>, Error> {
3619 let parser::Displayed {
3620 properties,
3621 statement: mut stat,
3622 } = stat;
3623
3624 let lhs: Expression<true> = Expression::ImplicitIterator(ImplicitIterator {
3626 exprs: Punctuated {
3627 first: Box::new(SimpleExpression {
3628 minus: None,
3629 kind: SimpleExpressionKind::Name(Name::Ident(stat.ident.first.name.clone())),
3630 exponent: None,
3631 display: None,
3632 }),
3633 collection: stat
3634 .ident
3635 .collection
3636 .iter()
3637 .map(|(p, i)| {
3638 (
3639 *p,
3640 SimpleExpression {
3641 minus: None,
3642 kind: SimpleExpressionKind::Name(Name::Ident(i.name.clone())),
3643 exponent: None,
3644 display: None,
3645 },
3646 )
3647 })
3648 .collect(),
3649 },
3650 });
3651
3652 let stat_span = stat.get_span();
3653 let rule = mem::take(&mut stat.rule);
3654
3655 let mut nodes = create_variables(&stat, context, library, properties)?;
3656
3657 if let Some((rule, expr)) = rule {
3659 let tree = IterNode::from2(&lhs, &expr);
3660
3661 tree.get_iter_lengths(&mut HashMap::new(), stat_span)?;
3663
3664 let mut index = IterTreeIterator::new(&tree);
3666
3667 while let Some(it_index) = index.get_currents() {
3668 nodes.push(unroll_rule(
3669 (
3670 lhs.unroll(context, library, it_index, Properties::default()),
3671 &rule,
3672 expr.unroll(context, library, it_index, Properties::default()),
3673 ),
3674 context,
3675 library,
3676 stat_span,
3677 false,
3678 Properties::from(None),
3679 ));
3680
3681 index.next();
3682 }
3683 }
3684
3685 Ok(nodes)
3686}
3687
3688fn unroll_eq(
3690 lhs: AnyExpr,
3691 rhs: AnyExpr,
3692 context: &mut CompileContext,
3693 full_span: Span,
3694 inverted: bool,
3695 display: Properties,
3696) -> Box<dyn Node> {
3697 let lhs_type = lhs.get_type();
3698 let rhs_type = rhs.get_type();
3699
3700 if (lhs_type == ty::collection(2) && rhs_type == ty::collection(2))
3701 || (lhs_type == ty::collection(2) && rhs_type == ty::SCALAR_UNKNOWN)
3702 || (lhs_type == ty::SCALAR_UNKNOWN && rhs_type == ty::collection(2))
3703 {
3704 let lhs = lhs
3706 .convert(context)
3707 .convert_unit(Some(unit::DISTANCE), context);
3708 let rhs = rhs
3709 .convert(context)
3710 .convert_unit(Some(unit::DISTANCE), context);
3711 context.scalar_eq_display(lhs, rhs, inverted, display)
3712 } else if lhs_type == ty::collection(1) && rhs_type == ty::collection(1) {
3713 let lhs = lhs.convert(context);
3714 let rhs = rhs.convert(context);
3715
3716 context.point_eq_display(lhs, rhs, inverted, display)
3717 } else {
3718 let (lhs, rhs, new_type) = if rhs.can_convert_to(lhs_type) {
3720 (lhs, rhs.convert_to(lhs_type, context), lhs_type)
3721 } else if lhs.can_convert_to(rhs_type) {
3722 (lhs.convert_to(rhs_type, context), rhs, rhs_type)
3723 } else {
3724 context.push_error(Error::InconsistentTypes {
3725 expected: (lhs_type, Box::new(lhs.get_span())),
3726 got: (rhs_type, Box::new(rhs.get_span())),
3727 error_span: Box::new(full_span),
3728 });
3729
3730 (
3732 lhs,
3733 AnyExpr::Unknown(Expr {
3734 span: rhs.get_span(),
3735 data: Rc::new(Unknown::dummy()),
3736 node: None,
3737 })
3738 .convert_to(lhs_type, context),
3739 lhs_type,
3740 )
3741 };
3742
3743 match new_type {
3744 Type::Point => {
3745 let lhs = lhs.convert(context);
3746 let rhs = rhs.convert(context);
3747
3748 context.point_eq_display(lhs, rhs, inverted, display)
3749 }
3750 Type::Number(_) => {
3751 let lhs = lhs.convert(context);
3752 let rhs = rhs.convert(context);
3753
3754 context.scalar_eq_display(lhs, rhs, inverted, display)
3755 }
3756 ty => {
3757 if ty != Type::Unknown {
3758 context.push_error(Error::ComparisonDoesNotExist {
3759 error_span: full_span,
3760 ty,
3761 });
3762 }
3763
3764 context.scalar_eq_display(
3766 Expr::new_spanless(Number::dummy()),
3767 Expr::new_spanless(Number::dummy()),
3768 inverted,
3769 display,
3770 )
3771 }
3772 }
3773 }
3774}
3775
3776fn unroll_gt(
3778 lhs: Expr<Number>,
3779 rhs: Expr<Number>,
3780 context: &mut CompileContext,
3781 full_span: Span,
3782 inverted: bool,
3783 display: Properties,
3784) -> Box<dyn Node> {
3785 if lhs.data.unit.is_some() {
3786 let rhs = if rhs.can_convert_unit(lhs.data.unit) {
3787 rhs.convert_unit(lhs.data.unit, context)
3788 } else {
3789 context.push_error(Error::InconsistentTypes {
3790 expected: (lhs.get_value_type(), Box::new(lhs.span)),
3791 got: (rhs.get_value_type(), Box::new(rhs.span)),
3792 error_span: Box::new(full_span),
3793 });
3794
3795 Expr {
3796 span: rhs.span,
3797 node: rhs.node,
3798 data: Rc::new(Number::dummy()),
3799 }
3800 .convert_unit(lhs.data.unit, context)
3801 };
3802
3803 context.gt_display(lhs, rhs, inverted, display)
3804 } else if rhs.data.unit.is_some() {
3805 let lhs = lhs.convert_unit(rhs.data.unit, context);
3806 context.gt_display(lhs, rhs, inverted, display)
3807 } else {
3808 let lhs = lhs.convert_unit(Some(unit::SCALAR), context);
3809 let rhs = rhs.convert_unit(Some(unit::SCALAR), context);
3810 context.gt_display(lhs, rhs, inverted, display)
3811 }
3812}
3813
3814fn unroll_rule(
3816 (lhs, op, rhs): (AnyExpr, &RuleOperator, AnyExpr),
3817 context: &mut CompileContext,
3818 library: &Library,
3819 full_span: Span,
3820 inverted: bool,
3821 mut display: Properties,
3822) -> Box<dyn Node> {
3823 match op {
3824 RuleOperator::Predefined(pre) => match pre {
3825 PredefinedRuleOperator::Eq(_) => {
3826 unroll_eq(lhs, rhs, context, full_span, inverted, display)
3827 }
3828 PredefinedRuleOperator::Lt(_) => unroll_gt(
3829 rhs.convert(context),
3830 lhs.convert(context),
3831 context,
3832 full_span,
3833 inverted,
3834 display,
3835 ),
3836 PredefinedRuleOperator::Gt(_) => unroll_gt(
3837 lhs.convert(context),
3838 rhs.convert(context),
3839 context,
3840 full_span,
3841 inverted,
3842 display,
3843 ),
3844 PredefinedRuleOperator::Lteq(_) => unroll_gt(
3845 lhs.convert(context),
3846 rhs.convert(context),
3847 context,
3848 full_span,
3849 !inverted,
3850 display,
3851 ),
3852 PredefinedRuleOperator::Gteq(_) => unroll_gt(
3853 rhs.convert(context),
3854 lhs.convert(context),
3855 context,
3856 full_span,
3857 !inverted,
3858 display,
3859 ),
3860 },
3861 RuleOperator::Defined(op) => {
3862 let weight = display.get("weight").get_or(ProcNum::one());
3863
3864 let overload = match library.get_rule(op.ident.as_str()) {
3865 Ok(func) => {
3866 if let Some(overload) = func.get_overload(&lhs, &rhs) {
3867 overload
3868 } else {
3869 context.push_error(Error::OverloadNotFound {
3870 error_span: op.span,
3871 function_name: op.ident.clone(),
3872 params: vec![lhs.get_type(), rhs.get_type()],
3873 });
3874
3875 display.finish(context);
3877 return Box::new(EmptyNode);
3878 }
3879 }
3880 Err(suggested) => {
3881 context.push_error(Error::UndefinedFunction {
3882 error_span: op.span,
3883 function_name: op.ident.clone(),
3884 suggested,
3885 });
3886
3887 display.finish(context);
3889 return Box::new(EmptyNode);
3890 }
3891 };
3892
3893 overload.unroll(lhs, rhs, context, display, inverted, weight)
3894 }
3895 RuleOperator::Inverted(op) => unroll_rule(
3896 (lhs, &op.operator, rhs),
3897 context,
3898 library,
3899 full_span,
3900 !inverted,
3901 display,
3902 ),
3903 }
3904}
3905
3906fn unroll_rule_statement(
3908 rule: &parser::Displayed<RuleStatement>,
3909 context: &mut CompileContext,
3910 library: &Library,
3911) -> Result<Vec<Box<dyn Node>>, Error> {
3912 let mut nodes = Vec::new();
3913 let parser::Displayed {
3914 properties,
3915 statement: rule,
3916 } = rule;
3917
3918 let firsts = Some(&rule.first)
3919 .into_iter()
3920 .chain(rule.rules.iter().map(|v| &v.1));
3921
3922 for (lhs, op, rhs) in firsts
3923 .zip(rule.rules.iter())
3924 .map(|(lhs, (op, rhs))| (lhs, op, rhs))
3925 {
3926 let tree = IterNode::from2(lhs, rhs);
3927 let full_span = lhs.get_span().join(rhs.get_span());
3928 tree.get_iter_lengths(&mut HashMap::new(), full_span)?;
3929
3930 let mut it_index = IterTreeIterator::new(&tree);
3931
3932 while let Some(index) = it_index.get_currents() {
3933 nodes.push(unroll_rule(
3934 (
3935 lhs.unroll(context, library, index, Properties::default()),
3936 op,
3937 rhs.unroll(context, library, index, Properties::default()),
3938 ),
3939 context,
3940 library,
3941 full_span,
3942 false,
3943 Properties::from(properties.clone()),
3944 ));
3945
3946 it_index.next();
3947 }
3948 }
3949
3950 Ok(nodes)
3951}
3952
3953pub fn unroll(input: &str) -> Result<(CompileContext, CollectionNode), Vec<Error>> {
3958 let mut context = CompileContext::new();
3960 let library = Library::new();
3961
3962 let mut figure = CollectionNode::new();
3963
3964 let tokens = match token::tokenize(input) {
3965 Ok(v) => v,
3966 Err(err) => return Err(vec![err]),
3967 };
3968 let mut input = InputStream::new(&tokens);
3969
3970 let mut statements = Vec::new();
3971
3972 while !input.eof() {
3973 statements.push(match input.parse() {
3974 Ok(v) => v,
3975 Err(err) => return Err(vec![err]),
3976 });
3977 }
3978
3979 let mut flags = FlagSetConstructor::new()
3980 .add_set("optimizations", FlagSetConstructor::new())
3981 .add_set(
3982 "language",
3983 FlagSetConstructor::new().add_bool_def("complex_numbers", false),
3984 )
3985 .add_bool_def("point_inequalities", true)
3986 .finish();
3987
3988 for flag in statements.iter().filter_map(Statement::as_flag) {
3989 flags::set_flag(&mut flags, flag, &context);
3990 }
3991
3992 context.flags = flags;
3993
3994 let enable_complex = context.flags["language"].as_set().unwrap()["complex_numbers"]
3996 .kind
3997 .as_setting()
3998 .unwrap();
3999
4000 if enable_complex.get_value().unwrap().as_bool().unwrap() {
4001 context.variables.insert(
4002 String::from("i"),
4003 AnyExpr::Number(Expr {
4004 span: enable_complex.get_span().unwrap(),
4005 data: Rc::new(Number {
4006 unit: Some(unit::SCALAR),
4007 data: NumberData::Number(ProcNum::i()),
4008 }),
4009 node: None,
4010 }),
4011 );
4012 }
4013
4014 for stat in statements {
4015 match stat {
4017 Statement::Noop(_) | Statement::Flag(_) => (),
4018 Statement::Let(stat) => match unroll_let(stat, &mut context, &library) {
4019 Ok(nodes) => {
4020 for node in nodes {
4021 figure.push_boxed(node);
4022 }
4023 }
4024 Err(err) => context.push_error(err),
4025 },
4026 Statement::Rule(stat) => match unroll_rule_statement(&stat, &mut context, &library) {
4027 Ok(nodes) => {
4028 for node in nodes {
4029 figure.push_boxed(node);
4030 }
4031 }
4032 Err(err) => context.push_error(err),
4033 },
4034 Statement::Ref(stat) => match unroll_ref(&stat, &mut context, &library) {
4035 Ok(nodes) => {
4036 for node in nodes {
4037 figure.push_boxed(node);
4038 }
4039 }
4040 Err(err) => context.push_error(err),
4041 },
4042 }
4043 }
4044
4045 if context.valid() {
4050 Ok((context, figure))
4051 } else {
4052 Err(context.take_errors())
4053 }
4054}