geo_aid_script/
parser.rs

1//! Parses `GeoScript`'s tokens into a structured representation. Most of this module's
2//! functionality is autogenerated through macros.
3
4use geo_aid_derive::Parse;
5use num_traits::Zero;
6
7use crate::token::number::ProcNum;
8use crate::unroll::library;
9use std::fmt::Formatter;
10use std::ops::Deref;
11use std::{
12    fmt::{Debug, Display},
13    iter::Peekable,
14    marker::PhantomData,
15};
16
17use crate::span;
18
19use super::{
20    token::{
21        number::CompExponent, Ampersant, Asterisk, At, Caret, Colon, Comma, Dollar, Dot, Eq,
22        Exclamation, Gt, Gteq, Ident, LBrace, LParen, LSquare, Let, Lt, Lteq, Minus, NamedIdent,
23        NumberLit, Plus, Question, RBrace, RParen, RSquare, Semi, Slash, Span, StrLit, TokInteger,
24        Token,
25    },
26    unit, ComplexUnit, Error,
27};
28
29/// The main trait for parsing tokens.
30pub trait Parse {
31    /// The first token of a structure.
32    type FirstToken: CheckParses;
33
34    /// Parse the tokens into `Self`.
35    ///
36    /// # Errors
37    /// Returns an error if parsing was unsuccessful.
38    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
39        input: &mut InputStream<'t, I>,
40    ) -> Result<Self, Error>
41    where
42        Self: Sized;
43
44    /// Get the span of this node.
45    fn get_span(&self) -> Span;
46}
47
48/// Check if `Self` would parse given the tokens.
49pub trait CheckParses {
50    /// Check if `Self` would parse given the tokens.
51    fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
52        input: &InputStream<'t, I>,
53    ) -> Option<bool>;
54}
55
56impl<T: Parse> CheckParses for T {
57    fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
58        input: &InputStream<'t, I>,
59    ) -> Option<bool> {
60        Some(input.clone().parse::<Self>().is_ok())
61    }
62}
63
64/// A simple token alternative for use with `FirstToken`
65#[derive(Debug)]
66pub struct TokenOr<T, U> {
67    phantom_t: PhantomData<T>,
68    phantom_u: PhantomData<U>,
69}
70
71impl<T: CheckParses, U: CheckParses> CheckParses for TokenOr<T, U> {
72    fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
73        input: &InputStream<'t, I>,
74    ) -> Option<bool> {
75        T::check_parses(input).or_else(|| U::check_parses(input))
76    }
77}
78
79/// A simple token option for use with `FirstToken`
80#[derive(Debug)]
81pub struct Maybe<T> {
82    phantom_t: PhantomData<T>,
83}
84
85impl<T: CheckParses> CheckParses for Maybe<T> {
86    fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
87        input: &InputStream<'t, I>,
88    ) -> Option<bool> {
89        T::check_parses(input).and_then(|x| if x { Some(x) } else { None })
90    }
91}
92
93impl<T: Parse> Parse for Vec<T> {
94    type FirstToken = Maybe<T::FirstToken>;
95
96    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
97        input: &mut InputStream<'t, I>,
98    ) -> Result<Self, Error>
99    where
100        Self: Sized,
101    {
102        let mut parsed = Self::new();
103
104        while let Ok(Some(v)) = input.parse() {
105            parsed.push(v);
106        }
107
108        Ok(parsed)
109    }
110
111    fn get_span(&self) -> Span {
112        self.first().map_or(Span::empty(), |x| {
113            x.get_span().join(self.last().unwrap().get_span())
114        })
115    }
116}
117
118/// Vector with at least one element.
119pub struct AtLeastOne<T>(Vec<T>);
120
121impl<T: Debug> Debug for AtLeastOne<T> {
122    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123        write!(f, "{:?}", self.0)
124    }
125}
126
127impl<T> Deref for AtLeastOne<T> {
128    type Target = Vec<T>;
129
130    fn deref(&self) -> &Self::Target {
131        &self.0
132    }
133}
134
135impl<T: Parse> Parse for AtLeastOne<T> {
136    type FirstToken = T::FirstToken;
137
138    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
139        input: &mut InputStream<'t, I>,
140    ) -> Result<Self, Error>
141    where
142        Self: Sized,
143    {
144        let mut parsed = Vec::new();
145
146        // First element is forced.
147        if let Ok(v) = input.parse() {
148            parsed.push(v);
149        }
150
151        while let Ok(Some(v)) = input.parse() {
152            parsed.push(v);
153        }
154
155        Ok(Self(parsed))
156    }
157
158    fn get_span(&self) -> Span {
159        self.first().map_or(Span::empty(), |x| {
160            x.get_span().join(self.last().unwrap().get_span())
161        })
162    }
163}
164
165impl<T: Parse, U: Parse> Parse for (T, U) {
166    type FirstToken = T::FirstToken;
167
168    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
169        input: &mut InputStream<'t, I>,
170    ) -> Result<Self, Error>
171    where
172        Self: Sized,
173    {
174        Ok((input.parse()?, input.parse()?))
175    }
176
177    fn get_span(&self) -> Span {
178        self.0.get_span().join(self.1.get_span())
179    }
180}
181
182impl<T: Parse> Parse for Option<T> {
183    type FirstToken = Maybe<T::FirstToken>;
184
185    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
186        input: &mut InputStream<'t, I>,
187    ) -> Result<Self, Error>
188    where
189        Self: Sized,
190    {
191        let mut branch = input.clone();
192
193        if let Ok(v) = branch.parse() {
194            *input = branch;
195            Ok(Some(v))
196        } else {
197            Ok(None)
198        }
199    }
200
201    fn get_span(&self) -> Span {
202        match self {
203            Some(v) => v.get_span(),
204            None => span!(0, 0, 0, 0),
205        }
206    }
207}
208
209/// The stream (peekable iterator) of input tokens
210#[derive(Debug, Clone)]
211pub struct InputStream<'t, I: Iterator<Item = &'t Token> + Clone> {
212    /// The underlying iterator.
213    it: Peekable<I>,
214}
215
216impl<'t, I: Iterator<Item = &'t Token> + Clone> InputStream<'t, I> {
217    /// Create a new stream from an iterator over tokens.
218    #[must_use]
219    pub fn new<It: IntoIterator<IntoIter = I>>(it: It) -> Self {
220        Self {
221            it: it.into_iter().peekable(),
222        }
223    }
224
225    /// Parse tokens as a node.
226    ///
227    /// # Errors
228    /// Returns an error if failed to parse
229    pub fn parse<P: Parse>(&mut self) -> Result<P, Error> {
230        P::parse(self)
231    }
232
233    /// Get the next token
234    ///
235    /// # Errors
236    /// Returns an EOF error if there is no next token.
237    pub fn get_token(&mut self) -> Result<&'t Token, Error> {
238        self.it.next().ok_or(Error::EndOfInput)
239    }
240
241    /// Expect there to be a token. Does not advance the stream.
242    ///
243    /// # Errors
244    /// Returns an EOF error if there is no next token.
245    pub fn expect_token(&mut self) -> Result<(), Error> {
246        if self.eof() {
247            Err(Error::EndOfInput)
248        } else {
249            Ok(())
250        }
251    }
252
253    /// Check if this is the end of input.
254    #[must_use]
255    pub fn eof(&mut self) -> bool {
256        self.it.peek().is_none()
257    }
258}
259
260/// A binary operator, like `+`, `-`, `*` or `/`.
261#[derive(Debug, Parse)]
262pub enum BinaryOperator {
263    /// Addition
264    Add(Plus),
265    /// Subtraction
266    Sub(Minus),
267    /// Multiplication
268    Mul(Asterisk),
269    /// Division
270    Div(Slash),
271}
272
273impl Display for BinaryOperator {
274    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
275        match self {
276            BinaryOperator::Add(_) => write!(f, "+"),
277            BinaryOperator::Sub(_) => write!(f, "-"),
278            BinaryOperator::Mul(_) => write!(f, "*"),
279            BinaryOperator::Div(_) => write!(f, "/"),
280        }
281    }
282}
283
284/// `&(point, ...)` - a point collection constructor allowing the creation of
285/// of a point collection from individual point expressions.
286#[derive(Debug, Parse)]
287#[parse(first_token = Ampersant)]
288pub struct PointCollectionConstructor {
289    pub ampersant: Ampersant,
290    pub left_paren: LParen,
291    pub points: Punctuated<Expression<false>, Comma>,
292    pub right_paren: RParen,
293}
294
295/// Punctuated expressions.
296#[derive(Debug)]
297pub struct ImplicitIterator<const ITER: bool> {
298    pub exprs: Punctuated<SimpleExpression, Comma>,
299}
300
301impl<const ITER: bool> ImplicitIterator<ITER> {
302    /// Get the expression at given index.
303    #[must_use]
304    pub fn get(&self, index: usize) -> Option<&SimpleExpression> {
305        if ITER {
306            self.exprs.get(index)
307        } else {
308            Some(&self.exprs.first)
309        }
310    }
311}
312
313impl<const ITER: bool> Parse for ImplicitIterator<ITER> {
314    type FirstToken = <SimpleExpression as Parse>::FirstToken;
315
316    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
317        input: &mut InputStream<'t, I>,
318    ) -> Result<Self, Error>
319    where
320        Self: Sized,
321    {
322        if ITER {
323            Ok(Self {
324                exprs: input.parse()?,
325            })
326        } else {
327            Ok(Self {
328                exprs: Punctuated {
329                    first: input.parse()?,
330                    collection: Vec::new(),
331                },
332            })
333        }
334    }
335
336    fn get_span(&self) -> Span {
337        self.exprs.get_span()
338    }
339}
340
341/// `$id(a, b, ...)` - an explicit iterator with an id.
342#[derive(Debug)]
343pub struct ExplicitIterator {
344    pub dollar: Dollar,
345    pub id_token: TokInteger,
346    pub id: u8,
347    pub left_paren: LParen,
348    pub exprs: Punctuated<Expression<false>, Comma>,
349    pub right_paren: RParen,
350}
351
352impl ExplicitIterator {
353    /// Get the expression at given index.
354    #[must_use]
355    pub fn get(&self, index: usize) -> Option<&Expression<false>> {
356        self.exprs.get(index)
357    }
358}
359
360impl Parse for ExplicitIterator {
361    type FirstToken = Dollar;
362
363    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
364        input: &mut InputStream<'r, I>,
365    ) -> Result<Self, Error> {
366        let mut parsed = Self {
367            dollar: input.parse()?,
368            id_token: input.parse()?,
369            id: 0,
370            left_paren: input.parse()?,
371            exprs: input.parse()?,
372            right_paren: input.parse()?,
373        };
374
375        parsed.id = parsed
376            .id_token
377            .parsed
378            .parse()
379            .map_err(|_| Error::NumberTooLarge {
380                error_span: parsed.id_token.get_span(),
381            })?;
382
383        if parsed.exprs.len() == 1 {
384            return Err(Error::SingleVariantExplicitIterator {
385                error_span: parsed.dollar.span.join(parsed.right_paren.span),
386            });
387        }
388
389        Ok(parsed)
390    }
391
392    fn get_span(&self) -> Span {
393        self.dollar.span.join(self.right_paren.span)
394    }
395}
396
397/// A parsed expression. Either an implicit iterator or a binary operation.
398#[derive(Debug)]
399pub enum Expression<const ITER: bool> {
400    /// Simple values separated by a comma.
401    ImplicitIterator(ImplicitIterator<ITER>),
402    /// A binary operator expression.
403    Binop(ExprBinop<ITER>),
404}
405
406impl<const ITER: bool> Parse for Expression<ITER> {
407    type FirstToken = <SimpleExpression as Parse>::FirstToken;
408
409    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
410        input: &mut InputStream<'r, I>,
411    ) -> Result<Self, Error> {
412        let mut expr = Expression::ImplicitIterator(input.parse()?);
413
414        while let Ok(Some(op)) = input.parse() {
415            let rhs = Expression::ImplicitIterator(input.parse()?);
416
417            expr = dispatch_order(expr, op, rhs);
418        }
419
420        Ok(expr)
421    }
422
423    fn get_span(&self) -> Span {
424        match self {
425            Expression::ImplicitIterator(it) => it.get_span(),
426            Expression::Binop(e) => e.lhs.get_span().join(e.rhs.get_span()),
427        }
428    }
429}
430
431/// A rational exponent of form `(a/b)`, where `a` and `b` are integer tokens.
432#[derive(Debug)]
433pub struct RationalExponent {
434    pub lparen: LParen,
435    pub num: TokInteger,
436    pub slash: Slash,
437    pub denum: TokInteger,
438    pub rparen: RParen,
439}
440
441impl Parse for RationalExponent {
442    type FirstToken = LParen;
443
444    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
445        input: &mut InputStream<'r, I>,
446    ) -> Result<Self, Error> {
447        let parsed = Self {
448            lparen: input.parse()?,
449            num: input.parse()?,
450            slash: input.parse()?,
451            denum: input.parse()?,
452            rparen: input.parse()?,
453        };
454
455        if parsed.denum.parsed.is_zero() {
456            return Err(Error::ZeroDenominator {
457                error_span: parsed.denum.span,
458            });
459        }
460
461        Ok(parsed)
462    }
463
464    fn get_span(&self) -> Span {
465        self.lparen.span.join(self.rparen.span)
466    }
467}
468
469/// An integer or a ratio. Used for exponents in exponentiation.
470#[derive(Debug, Parse)]
471pub enum Exponent {
472    Simple(TokInteger),
473    Parenthesized(RationalExponent),
474}
475
476impl Exponent {
477    /// Converts this exponent into a rational number.
478    ///
479    /// # Errors
480    /// Returns an error if the numbers can't fit.
481    pub fn as_comp(&self) -> Result<CompExponent, Error> {
482        match self {
483            Self::Simple(i) => Ok(CompExponent::new(
484                i.parsed
485                    .parse()
486                    .map_err(|_| Error::NumberTooLarge { error_span: i.span })?,
487                1,
488            )),
489            Self::Parenthesized(exp) => Ok(CompExponent::new(
490                exp.num.parsed.parse().map_err(|_| Error::NumberTooLarge {
491                    error_span: exp.num.span,
492                })?,
493                exp.denum
494                    .parsed
495                    .parse()
496                    .map_err(|_| Error::NumberTooLarge {
497                        error_span: exp.denum.span,
498                    })?,
499            )),
500        }
501    }
502}
503
504/// A value being raised to a rational power `v^exp`.
505#[derive(Debug, Parse)]
506pub struct Exponentiation {
507    /// Caret token
508    pub caret: Caret,
509    /// Possible negation of the exponent
510    pub minus: Option<Minus>,
511    /// The exponent.
512    pub exponent: Exponent,
513}
514
515/// A field access on a value `value.field`
516#[derive(Debug, Parse)]
517pub struct FieldIndex {
518    /// The indexed thing
519    pub name: Box<Name>,
520    /// The dot
521    pub dot: Dot,
522    /// The field
523    pub field: Ident,
524}
525
526/// A name (field, method or variable).
527#[derive(Debug)]
528pub enum Name {
529    // Variant order matters, as it defines the parsing priority
530    /// A function call.
531    Call(ExprCall),
532    FieldIndex(FieldIndex),
533    Ident(Ident),
534    Expression(ExprParenthesised),
535}
536
537impl Parse for Name {
538    type FirstToken = TokenOr<Maybe<Ident>, LParen>;
539
540    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
541        input: &mut InputStream<'t, I>,
542    ) -> Result<Self, Error>
543    where
544        Self: Sized,
545    {
546        let mut name = if let Some(expr) = input.parse()? {
547            Self::Expression(expr)
548        } else {
549            Self::Ident(input.parse()?)
550        };
551
552        loop {
553            name = if let Some(dot) = input.parse::<Option<Dot>>()? {
554                Self::FieldIndex(FieldIndex {
555                    name: Box::new(name),
556                    dot,
557                    field: input.parse()?,
558                })
559            } else if let Some(lparen) = input.parse::<Option<LParen>>()? {
560                Self::Call(ExprCall {
561                    name: Box::new(name),
562                    lparen,
563                    params: input.parse()?,
564                    rparen: input.parse()?,
565                })
566            } else {
567                break Ok(name);
568            };
569        }
570    }
571
572    fn get_span(&self) -> Span {
573        match self {
574            Self::Call(v) => v.get_span(),
575            Self::FieldIndex(v) => v.get_span(),
576            Self::Expression(v) => v.get_span(),
577            Self::Ident(v) => v.get_span(),
578        }
579    }
580}
581
582/// A parsed simple expression.
583#[derive(Debug, Parse)]
584pub struct SimpleExpression {
585    /// Possible minus for negation.
586    pub minus: Option<Minus>,
587    /// The kind of the expression.
588    pub kind: SimpleExpressionKind,
589    /// Possible exponentiation.
590    pub exponent: Option<Exponentiation>,
591    /// The additional display information.
592    pub display: Option<DisplayProperties>,
593}
594
595/// A parsed simple expression.
596#[derive(Debug, Parse)]
597pub enum SimpleExpressionKind {
598    /// A named (variable, field or function call)
599    Name(Name),
600    /// A raw number
601    Number(NumberLit),
602    /// An explicit iterator.
603    ExplicitIterator(ExplicitIterator),
604    /// A point collection construction
605    PointCollection(PointCollectionConstructor),
606}
607
608/// A parsed function call
609#[derive(Debug, Parse)]
610pub struct ExprCall {
611    /// The called thing.
612    pub name: Box<Name>,
613    /// The `(` token.
614    pub lparen: LParen,
615    /// Punctuated params. `None` if no params are given.
616    pub params: Option<Punctuated<Expression<false>, Comma>>,
617    /// The `)` token.
618    pub rparen: RParen,
619}
620
621/// A parsed parenthesised expression
622#[derive(Debug, Parse)]
623pub struct ExprParenthesised {
624    /// The `(` token.
625    pub lparen: LParen,
626    /// The contained `Expression`.
627    pub content: Box<Expression<true>>,
628    /// The `)` token.
629    pub rparen: RParen,
630}
631
632/// A parsed binary operator expression.
633#[derive(Debug, Parse)]
634pub struct ExprBinop<const ITER: bool> {
635    /// Left hand side
636    pub lhs: Box<Expression<ITER>>,
637    /// The operator
638    pub operator: BinaryOperator,
639    /// Right hand side.
640    pub rhs: Box<Expression<ITER>>,
641}
642
643impl BinaryOperator {
644    fn index(&self) -> u8 {
645        match self {
646            BinaryOperator::Add(_) | BinaryOperator::Sub(_) => 1,
647            BinaryOperator::Mul(_) | BinaryOperator::Div(_) => 2,
648        }
649    }
650}
651
652/// Inserts an operator with an rhs into an operator series, considering the order of operations.
653fn dispatch_order<const ITER: bool>(
654    lhs: Expression<ITER>,
655    op: BinaryOperator,
656    rhs: Expression<ITER>, // We have to trust, that it is a valid expression.
657) -> Expression<ITER> {
658    match lhs {
659        // if lhs is simple, there is no order to consider.
660        lhs @ Expression::ImplicitIterator(_) => Expression::Binop(ExprBinop {
661            lhs: Box::new(lhs),
662            operator: op,
663            rhs: Box::new(rhs),
664        }),
665        // Otherwise we compare indices of the operators and act accordingly.
666        Expression::Binop(lhs) => {
667            if op.index() > lhs.operator.index() {
668                Expression::Binop(ExprBinop {
669                    lhs: lhs.lhs,
670                    operator: lhs.operator,
671                    rhs: Box::new(dispatch_order(*lhs.rhs, op, rhs)),
672                })
673            } else {
674                Expression::Binop(ExprBinop {
675                    lhs: Box::new(Expression::Binop(lhs)),
676                    operator: op,
677                    rhs: Box::new(rhs),
678                })
679            }
680        }
681    }
682}
683
684/// A builtin rule operator
685#[derive(Debug, Parse)]
686pub enum PredefinedRuleOperator {
687    /// Equality
688    Eq(Eq),
689    /// Less than
690    Lt(Lt),
691    /// Greater than
692    Gt(Gt),
693    /// Less than or equal
694    Lteq(Lteq),
695    /// Greater than or equal
696    Gteq(Gteq),
697}
698
699/// A rule operator.
700#[derive(Debug, Parse)]
701pub enum RuleOperator {
702    /// An inverted rule operator (!op)
703    Inverted(InvertedRuleOperator),
704    Predefined(PredefinedRuleOperator),
705    Defined(NamedIdent),
706}
707
708/// An inverted rule operator.
709#[derive(Debug, Parse)]
710#[parse(first_token = Exclamation)]
711pub struct InvertedRuleOperator {
712    /// The `!` token
713    pub exclamation: Exclamation,
714    /// The operator.
715    pub operator: Box<RuleOperator>,
716}
717
718/// Defines the first half of a flag statement.
719#[derive(Debug, Parse)]
720pub struct FlagName {
721    pub at: At,
722    pub name: Punctuated<NamedIdent, Dot>,
723    pub colon: Colon,
724}
725
726/// A set of flags.
727#[derive(Debug, Parse)]
728#[parse(first_token = LBrace)]
729pub struct FlagSet {
730    pub lbrace: LBrace,
731    pub flags: Vec<FlagStatement>,
732    pub rbrace: RBrace,
733}
734
735/// Defines the second half of a flag statement.
736#[derive(Debug, Parse)]
737pub enum FlagValue {
738    Ident(NamedIdent),
739    Set(FlagSet),
740    Number(NumberLit),
741}
742
743/// Defines a compiler flag or flagset.
744#[derive(Debug, Parse)]
745pub struct FlagStatement {
746    pub name: FlagName,
747    pub value: FlagValue,
748}
749
750/// A single variable definition. Contains its name and optional display properties
751#[derive(Debug, Clone, Parse)]
752pub struct VariableDefinition {
753    /// Name of the variable.
754    pub name: Ident,
755    /// Display properties.
756    pub display_properties: Option<DisplayProperties>,
757}
758
759/// `let <something> = <something else>`.
760/// Defines variables and possibly adds rules to them.
761#[derive(Debug, Parse)]
762pub struct LetStatement {
763    /// The `let` token.
764    pub let_token: Let,
765    /// The lhs ident iterator.
766    pub ident: Punctuated<VariableDefinition, Comma>,
767    /// The `=` token.
768    pub eq: Eq,
769    /// The rhs expression.
770    pub expr: Expression<true>,
771    /// The rule after the rhs expression.
772    pub rule: Option<(RuleOperator, Expression<true>)>,
773    /// The ending semicolon.
774    pub semi: Semi,
775}
776
777/// `lhs ruleop rhs`.
778/// Defines a rule.
779#[derive(Debug, Parse)]
780pub struct RuleStatement {
781    /// Left hand side
782    pub first: Expression<true>,
783    /// The rules themselves.
784    pub rules: AtLeastOne<(RuleOperator, Expression<true>)>,
785    /// The ending semicolon.
786    pub semi: Semi,
787}
788
789/// `?expr`. Used for displaying and biases.
790#[derive(Debug, Parse)]
791pub struct RefStatement {
792    /// The starting question mark.
793    pub question: Question,
794    /// Operand.
795    pub operand: Expression<true>,
796    /// The ending semicolon.
797    pub semi: Semi,
798}
799
800/// A general statement. A rule, `let` or a ref
801#[derive(Debug)]
802pub enum Statement {
803    /// No operation
804    Noop(Semi),
805    /// let
806    Let(Displayed<LetStatement>),
807    /// Flag
808    Flag(FlagStatement),
809    /// Reference
810    Ref(Displayed<RefStatement>),
811    /// rule
812    Rule(Displayed<RuleStatement>),
813}
814
815impl Parse for Statement {
816    type FirstToken = TokenOr<
817        LSquare,
818        TokenOr<
819            Semi,
820            TokenOr<At, TokenOr<Question, TokenOr<Let, <SimpleExpression as Parse>::FirstToken>>>,
821        >,
822    >;
823
824    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
825        input: &mut InputStream<'t, I>,
826    ) -> Result<Self, Error>
827    where
828        Self: Sized,
829    {
830        let props = input.parse()?;
831        input.expect_token()?;
832
833        let tok = input.it.peek().cloned().unwrap();
834
835        match tok {
836            Token::Let(_) => Ok(Self::Let(Displayed {
837                properties: props,
838                statement: input.parse()?,
839            })),
840            Token::Semi(_) => {
841                if props.is_some() {
842                    Err(Error::UnexpectedProperties {
843                        error_span: props.get_span(),
844                    })
845                } else {
846                    Ok(Self::Noop(input.parse()?))
847                }
848            }
849            Token::At(_) => {
850                if props.is_some() {
851                    Err(Error::UnexpectedProperties {
852                        error_span: props.get_span(),
853                    })
854                } else {
855                    Ok(Self::Flag(input.parse()?))
856                }
857            }
858            Token::Question(_) => Ok(Self::Ref(Displayed {
859                properties: props,
860                statement: input.parse()?,
861            })),
862            _ => Ok(Self::Rule(Displayed {
863                properties: props,
864                statement: input.parse()?,
865            })),
866        }
867    }
868
869    fn get_span(&self) -> Span {
870        todo!()
871    }
872}
873
874impl Statement {
875    #[must_use]
876    pub fn as_flag(&self) -> Option<&FlagStatement> {
877        if let Self::Flag(v) = self {
878            Some(v)
879        } else {
880            None
881        }
882    }
883}
884
885/// Generic structure for statements that accept display options.
886#[derive(Debug, Parse)]
887pub struct Displayed<T: Parse> {
888    /// The properties
889    pub properties: Option<DisplayProperties>,
890    /// The statement itself
891    pub statement: T,
892}
893
894/// A utility struct for collections of parsed items with punctuators between them.
895#[derive(Debug, Clone, Parse)]
896pub struct Punctuated<T: Parse, P: Parse> {
897    /// The first parsed item.
898    pub first: Box<T>,
899    /// The next items with punctuators.
900    pub collection: Vec<(P, T)>,
901}
902
903impl<T: Parse, P: Parse> Punctuated<T, P> {
904    /// Creates a new instance of `Punctuated`.
905    #[must_use]
906    pub fn new(first: T) -> Punctuated<T, P> {
907        Self {
908            first: Box::new(first),
909            collection: Vec::new(),
910        }
911    }
912
913    /// Turns the punctuated into an iterator on the items.
914    pub fn iter(&self) -> impl Iterator<Item = &T> {
915        vec![self.first.as_ref()]
916            .into_iter()
917            .chain(self.collection.iter().map(|x| &x.1))
918    }
919
920    /// Turns the punctuated into an iterator on the items.
921    pub fn into_parsed_iter(self) -> impl Iterator<Item = T> {
922        vec![*self.first]
923            .into_iter()
924            .chain(self.collection.into_iter().map(|x| x.1))
925    }
926
927    /// Gets the item count.
928    #[must_use]
929    pub fn len(&self) -> usize {
930        self.collection.len() + 1
931    }
932
933    /// Checks if there are no items (always false).
934    #[must_use]
935    pub fn is_empty(&self) -> bool {
936        false
937    }
938
939    /// Tries to get the element on `index`.
940    #[must_use]
941    pub fn get(&self, index: usize) -> Option<&T> {
942        match index {
943            0 => Some(&self.first),
944            _ => self.collection.get(index - 1).map(|x| &x.1),
945        }
946    }
947}
948
949impl Parse for TokInteger {
950    type FirstToken = NumberLit;
951
952    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
953        input: &mut InputStream<'r, I>,
954    ) -> Result<Self, Error> {
955        match input.get_token()? {
956            Token::NumberLit(NumberLit::Integer(tok)) => Ok(tok.clone()),
957            t => Err(Error::InvalidToken { token: t.clone() }),
958        }
959    }
960
961    fn get_span(&self) -> Span {
962        self.span
963    }
964}
965
966impl Parse for NamedIdent {
967    type FirstToken = Ident;
968
969    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
970        input: &mut InputStream<'r, I>,
971    ) -> Result<Self, Error> {
972        match input.get_token()? {
973            Token::Ident(Ident::Named(named)) => Ok(named.clone()),
974            t => Err(Error::InvalidToken { token: t.clone() }),
975        }
976    }
977
978    fn get_span(&self) -> Span {
979        self.span
980    }
981}
982
983impl<T: Parse> Parse for Box<T> {
984    type FirstToken = T::FirstToken;
985
986    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
987        input: &mut InputStream<'r, I>,
988    ) -> Result<Self, Error> {
989        Ok(Box::new(input.parse()?))
990    }
991
992    fn get_span(&self) -> Span {
993        (**self).get_span()
994    }
995}
996
997/// A builtin type.
998#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
999pub enum Type {
1000    /// A point
1001    Point,
1002    /// A line
1003    Line,
1004    /// A number with a certain unit.
1005    Number(Option<ComplexUnit>),
1006    /// A point collection.
1007    PointCollection(usize),
1008    /// A circle
1009    Circle,
1010    /// A derived type.
1011    Derived(&'static str),
1012    /// Marks unknown type. Unknown type pretends to be valid, but isn't really.
1013    Unknown,
1014}
1015
1016impl Type {
1017    #[must_use]
1018    pub fn as_number(&self) -> Option<&Option<ComplexUnit>> {
1019        if let Self::Number(v) = self {
1020            Some(v)
1021        } else {
1022            None
1023        }
1024    }
1025}
1026
1027/// A user-defined type.
1028pub struct DefinedType {
1029    /// The type's name.
1030    pub name: String,
1031}
1032
1033impl Display for Type {
1034    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1035        match self {
1036            Self::Point => write!(f, "Point"),
1037            Self::Line => write!(f, "Line"),
1038            Self::Number(unit) => match unit {
1039                Some(unit) => write!(f, "Number ({unit})"),
1040                None => write!(f, "Number (no unit)"),
1041            },
1042            Self::PointCollection(l) => write!(f, "Point collection ({l})"),
1043            Self::Circle => write!(f, "Circle"),
1044            Self::Derived(name) => write!(f, "{name}"),
1045            Type::Unknown => write!(f, "undefined"),
1046        }
1047    }
1048}
1049
1050impl Type {
1051    /// Whether `self` can be cast to `into`.
1052    #[must_use]
1053    pub fn can_cast(&self, into: &Type) -> bool {
1054        match self {
1055            // A point can only be cast into another point or a point collection with length one.
1056            Type::Point => matches!(into, Type::Point | Type::PointCollection(1)),
1057            // A line can only be cast into another line.
1058            Type::Line => matches!(into, Type::Line),
1059            // A number with a defined unit can only be cast into another number with the same unit.
1060            Type::Number(Some(unit1)) => {
1061                if let Type::Number(Some(unit2)) = into {
1062                    unit1 == unit2
1063                } else {
1064                    false
1065                }
1066            }
1067            // A number with no defined unit can be cast into any other number, except angle.
1068            Type::Number(None) => match into {
1069                Type::Number(unit) => match unit {
1070                    Some(unit) => unit.0[1].is_zero(), // no angle
1071                    None => true,
1072                },
1073                _ => false,
1074            },
1075            Type::PointCollection(l) => match into {
1076                Type::Point => *l == 1,
1077                Type::Line => *l == 2,
1078                Type::Number(Some(u)) => *u == unit::DISTANCE && *l == 2,
1079                Type::PointCollection(v) => v == l || *v == 0,
1080                _ => false,
1081            },
1082            Type::Circle => matches!(into, Type::Circle),
1083            Type::Derived(name) => {
1084                if into == self {
1085                    true
1086                } else if let Type::PointCollection(count) = into {
1087                    library::get_derived_pc(name) == *count
1088                } else {
1089                    false
1090                }
1091            }
1092            Type::Unknown => true,
1093        }
1094    }
1095}
1096
1097/// A property
1098#[derive(Debug, Clone, Parse)]
1099pub struct Property {
1100    /// Property name.
1101    pub name: NamedIdent,
1102    /// '='
1103    pub eq: Eq,
1104    /// Property value.
1105    pub value: PropertyValue,
1106}
1107
1108/// A property's value
1109#[derive(Debug, Clone, Parse)]
1110pub enum PropertyValue {
1111    Number(NumberLit),
1112    Ident(Ident),
1113    RawString(RawString),
1114    String(StrLit),
1115}
1116
1117impl Display for PropertyValue {
1118    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1119        match self {
1120            Self::Number(n) => write!(f, "{n}"),
1121            Self::Ident(i) => write!(f, "{i}"),
1122            Self::RawString(s) => write!(f, "!{}", s.lit),
1123            Self::String(s) => write!(f, "{s}"),
1124        }
1125    }
1126}
1127
1128/// A raw string line `!"Hello, World!"`. Does not parse any special characters.
1129#[derive(Debug, Clone, Parse)]
1130pub struct RawString {
1131    pub excl: Exclamation,
1132    /// The string contents.
1133    pub lit: StrLit,
1134}
1135
1136/// Trait for conversion of properties into actual types.
1137pub trait FromProperty: Sized {
1138    /// Try to convert the property value into `Self`.
1139    ///
1140    /// # Errors
1141    /// Causes an error if the value is not properly convertible.
1142    fn from_property(property: PropertyValue) -> Result<Self, Error>;
1143}
1144
1145impl<T: FromProperty> FromProperty for Result<T, Error> {
1146    fn from_property(property: PropertyValue) -> Result<Self, Error> {
1147        Ok(T::from_property(property))
1148    }
1149}
1150
1151impl FromProperty for bool {
1152    fn from_property(property: PropertyValue) -> Result<Self, Error> {
1153        match property {
1154            PropertyValue::Ident(ident) => match ident {
1155                Ident::Named(ident) => match ident.ident.as_str() {
1156                    "enabled" | "on" | "true" | "yes" => Ok(true),
1157                    "disabled" | "off" | "false" | "no" => Ok(false),
1158                    _ => Err(Error::BooleanExpected {
1159                        error_span: ident.get_span(),
1160                    }),
1161                },
1162                Ident::Collection(_) => Err(Error::BooleanExpected {
1163                    error_span: ident.get_span(),
1164                }),
1165            },
1166            PropertyValue::Number(num) => match num {
1167                NumberLit::Integer(i) => match i.parsed.parse::<u8>() {
1168                    Ok(0) => Ok(false),
1169                    Ok(1) => Ok(true),
1170                    _ => Err(Error::BooleanExpected { error_span: i.span }),
1171                },
1172                NumberLit::Float(f) => Err(Error::BooleanExpected { error_span: f.span }),
1173            },
1174            PropertyValue::String(s) => match s.content.as_str() {
1175                "enabled" | "on" | "true" | "yes" => Ok(true),
1176                "disabled" | "off" | "false" | "no" => Ok(false),
1177                _ => Err(Error::BooleanExpected {
1178                    error_span: s.get_span(),
1179                }),
1180            },
1181            PropertyValue::RawString(s) => Err(Error::BooleanExpected {
1182                error_span: s.get_span(),
1183            }),
1184        }
1185    }
1186}
1187
1188impl FromProperty for String {
1189    fn from_property(property: PropertyValue) -> Result<String, Error> {
1190        match property {
1191            PropertyValue::Ident(ident) => Ok(ident.to_string()),
1192            PropertyValue::Number(num) => Err(Error::StringExpected {
1193                error_span: num.get_span(),
1194            }),
1195            PropertyValue::RawString(s) => Ok(s.lit.content),
1196            PropertyValue::String(s) => Ok(s.content),
1197        }
1198    }
1199}
1200
1201impl FromProperty for ProcNum {
1202    fn from_property(property: PropertyValue) -> Result<Self, Error> {
1203        match property {
1204            PropertyValue::Number(num) => Ok(ProcNum::from(&num)),
1205            PropertyValue::RawString(s) => Err(Error::NumberExpected {
1206                error_span: s.get_span(),
1207            }),
1208            PropertyValue::String(s) => Err(Error::NumberExpected {
1209                error_span: s.get_span(),
1210            }),
1211            PropertyValue::Ident(ident) => Err(Error::NumberExpected {
1212                error_span: ident.get_span(),
1213            }),
1214        }
1215    }
1216}
1217
1218/// Properties usually related to displaying things.
1219#[derive(Debug, Clone, Parse)]
1220pub struct DisplayProperties {
1221    /// '['
1222    pub lsquare: LSquare,
1223    /// Properties
1224    pub properties: Punctuated<Property, Semi>,
1225    /// ']'
1226    pub rsquare: RSquare,
1227}