1use std::{collections::HashMap, fmt::Display, ops::{Deref, DerefMut}, rc::Rc};
4use crate::{RantProgramInfo, InternalString, RantValue, RantValueType};
5
6pub(crate) const PIPE_VALUE_NAME: &str = "~PIPE";
7
8#[repr(u8)]
10#[derive(Debug, Copy, Clone, PartialEq)]
11pub enum PrintFlag {
12  None,
14  Hint,
16  Sink
18}
19
20#[derive(Debug, Clone, Eq, PartialEq, Hash)]
23pub struct Identifier(InternalString);
24
25impl Identifier {
26  pub fn new(idstr: InternalString) -> Self {
27    Self(idstr)
28  }
29}
30
31impl From<&'static str> for Identifier {
32  fn from(s: &'static str) -> Self {
33    Self::new(InternalString::from(s))
34  }
35}
36
37impl std::borrow::Borrow<str> for Identifier {
38  fn borrow(&self) -> &str {
39    self.0.as_str()
40  }
41}
42
43impl Deref for Identifier {
44  type Target = InternalString;
45  fn deref(&self) -> &Self::Target {
46    &self.0
47  }
48}
49
50impl Display for Identifier {
51  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52    write!(f, "{}", self.0)
53  }
54}
55
56pub(crate) fn is_valid_ident(name: &str) -> bool {
58  if name.is_empty() { return false }
59  let mut has_non_digit = false;
60  let is_valid_chars = name.chars().all(|c| {
61    has_non_digit |= !c.is_ascii_digit();
62    c.is_alphanumeric() || matches!(c, '_' | '-')
63  });
64  has_non_digit && is_valid_chars
65}
66
67#[derive(Debug, Clone)]
69pub enum SliceIndex {
70  Static(i64),
72  Dynamic(Rc<Sequence>)
74}
75
76impl Display for SliceIndex {
77  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78    match self {
79      SliceIndex::Static(i) => write!(f, "{}", i),
80      SliceIndex::Dynamic(_expr) => write!(f, "{{...}}"),
81    }
82  }
83}
84
85#[derive(Debug, Clone)]
87pub enum SliceExpr {
88  Full,
90  From(SliceIndex),
92  To(SliceIndex),
94  Between(SliceIndex, SliceIndex),
96}
97
98impl SliceExpr {
99  pub(crate) fn as_static_slice<F: FnMut(&Rc<Sequence>) -> RantValue>(&self, mut index_converter: F) -> Result<Slice, RantValueType> {
103    macro_rules! convert_index {
104      ($index:expr) => {
105        match $index {
106          SliceIndex::Static(i) => *i,
107          SliceIndex::Dynamic(expr) => {
108            match index_converter(expr) {
109              RantValue::Int(i) => i,
110              other => return Err(other.get_type())
111            }
112          }
113        }
114      }
115    }
116
117    Ok(match self {
118      SliceExpr::Full => Slice::Full,
119      SliceExpr::From(from) => Slice::From(convert_index!(from)),
120      SliceExpr::To(to) => Slice::To(convert_index!(to)),
121      SliceExpr::Between(from, to) => Slice::Between(convert_index!(from), convert_index!(to)),
122    })
123  }
124}
125
126impl Display for SliceExpr {
127  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128    match self {
129      SliceExpr::Full => write!(f, ":"),
130      SliceExpr::From(i) => write!(f, "{}:", i),
131      SliceExpr::To(i) => write!(f, ":{}", i),
132      SliceExpr::Between(l, r) => write!(f, "{}:{}", l, r),
133    }
134  }
135}
136
137#[derive(Debug)]
139pub enum Slice {
140  Full,
142  From(i64),
144  To(i64),
146  Between(i64, i64),
148}
149
150#[derive(Debug, Clone)]
152pub enum AccessPathComponent {
153  Name(Identifier),
155  Index(i64),
157  Slice(SliceExpr),
159  Expression(Rc<Sequence>),
161  PipeValue,
163}
164
165impl Display for AccessPathComponent {
166  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167    match self {
168      Self::Name(name) => write!(f, "{name}"),
169      Self::Index(i) => write!(f, "{i}"),
170      Self::Slice(slice_expr) => write!(f, "{slice_expr}"),
171      Self::Expression(expr) => write!(f, "({}...)", expr.name().map(|name| name.as_str()).unwrap_or("")),
172      Self::PipeValue => write!(f, "[]"),
173    }
174  }
175}
176
177#[derive(Debug, Copy, Clone, PartialEq)]
179pub enum VarAccessMode {
180  Local,
182  ExplicitGlobal,
184  Descope(usize),
186}
187
188impl VarAccessMode {
189  pub fn descope_count(&self) -> usize {
191    match self {
192      VarAccessMode::Local | VarAccessMode::ExplicitGlobal => 0,
193      VarAccessMode::Descope(n) => *n
194    }
195  }
196
197  #[inline]
199  pub fn is_local(&self) -> bool {
200    matches!(self, Self::Local)
201  }
202}
203
204#[derive(Debug, Clone)]
206pub struct AccessPath {
207  path: Vec<AccessPathComponent>,
208  mode: VarAccessMode,
209}
210
211impl AccessPath {
212  #[inline]
213  pub fn new(path: Vec<AccessPathComponent>, kind: VarAccessMode) -> Self {
214    Self {
215      path,
216      mode: kind
217    }
218  }
219
220  #[inline]
222  pub fn add_descope(self, n: usize) -> Self {
223    Self {
224      mode: match self.mode {
225        VarAccessMode::Local => VarAccessMode::Descope(n),
226        VarAccessMode::Descope(d) => VarAccessMode::Descope(d + n),
227        VarAccessMode::ExplicitGlobal => VarAccessMode::ExplicitGlobal,
228      },
229      .. self
230    }
231  }
232
233  #[inline]
235  pub fn is_explicit_global(&self) -> bool {
236    matches!(self.mode, VarAccessMode::ExplicitGlobal)
237  }
238
239  #[inline]
241  pub fn is_anonymous(&self) -> bool {
242    matches!(self.first(), Some(AccessPathComponent::Expression(..) | AccessPathComponent::PipeValue))
243  }
244
245  #[inline]
247  pub fn is_variable_target(&self) -> bool {
248    self.len() == 1 && matches!(self.first(), Some(AccessPathComponent::Name(..) | AccessPathComponent::Expression(..) | AccessPathComponent::PipeValue))
249  }
250
251  #[inline]
253  pub fn is_anonymous_target(&self) -> bool {
254    self.len() == 1 && matches!(self.first(), Some(AccessPathComponent::Expression(..) | AccessPathComponent::PipeValue))
255  }
256
257  #[inline]
259  pub fn mode(&self) -> VarAccessMode {
260    self.mode
261  }
262
263  #[inline]
265  pub fn dynamic_exprs(&self) -> Vec<Rc<Sequence>> {
266    use AccessPathComponent::*;
267    let mut exprs = vec![];
268    for component in self.iter() {
269      match component {
270        Expression(expr) => exprs.push(Rc::clone(expr)),
271        Slice(SliceExpr::From(SliceIndex::Dynamic(expr)))
272        | Slice(SliceExpr::To(SliceIndex::Dynamic(expr))) 
273        | Slice(SliceExpr::Between(SliceIndex::Static(_), SliceIndex::Dynamic(expr)))
274        | Slice(SliceExpr::Between(SliceIndex::Dynamic(expr), SliceIndex::Static(_))) => exprs.push(Rc::clone(expr)),
275        Slice(SliceExpr::Between(SliceIndex::Dynamic(expr_from), SliceIndex::Dynamic(expr_to))) => {
276          exprs.push(Rc::clone(expr_from));
277          exprs.push(Rc::clone(expr_to));
278        },
279        _ => {}
280      }
281    }
282    exprs
283  }
284
285  #[inline]
287  pub fn var_name(&self) -> Option<Identifier> {
288    if let Some(first) = self.first() {
289      return Some(match first {
290        AccessPathComponent::Name(id) => id.clone(),
291        AccessPathComponent::PipeValue => Identifier::from(PIPE_VALUE_NAME),
292        _ => return None
293      })
294    }
295    None
296  }
297}
298
299impl Deref for AccessPath {
300  type Target = Vec<AccessPathComponent>;
301  fn deref(&self) -> &Self::Target {
302    &self.path
303  }
304}
305
306impl DerefMut for AccessPath {
307  fn deref_mut(&mut self) -> &mut Self::Target {
308    &mut self.path
309  }
310}
311
312impl Display for AccessPath {
313  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
314    write!(f, "{}", self.iter().map(|part| part.to_string()).collect::<Vec<String>>().join("/"))
315  }
316}
317
318#[derive(Debug)]
320pub struct Sequence {
321  elements: Vec<Rc<Expression>>,
322  pub name: Option<InternalString>,
324  pub origin: Rc<RantProgramInfo>,
326}
327
328impl Sequence {
329  #[inline]
331  pub fn new(seq: Vec<Rc<Expression>>, origin: &Rc<RantProgramInfo>) -> Self {
332    Self {
333      elements: seq,
334      name: None,
335      origin: Rc::clone(origin),
336    }
337  }
338  
339  #[inline]
341  pub fn one(rst: Expression, origin: &Rc<RantProgramInfo>) -> Self {
342    Self {
343      elements: vec![Rc::new(rst)],
344      name: None,
345      origin: Rc::clone(origin),
346    }
347  }
348  
349  pub fn empty(origin: &Rc<RantProgramInfo>) -> Self {
351    Self::new(vec![], origin)
352  }
353
354  #[inline(always)]
356  pub fn with_name(mut self, name: InternalString) -> Self {
357    self.name = Some(name);
358    self
359  }
360
361  #[inline(always)]
363  pub fn with_name_str(mut self, name: &str) -> Self {
364    self.name = Some(InternalString::from(name));
365    self
366  }
367
368  pub fn name(&self) -> Option<&InternalString> {
370    self.name.as_ref()
371  }
372}
373
374impl Deref for Sequence {
375  type Target = Vec<Rc<Expression>>;
376  fn deref(&self) -> &Self::Target {
377    &self.elements
378  }
379}
380
381impl DerefMut for Sequence {
382  fn deref_mut(&mut self) -> &mut Self::Target {
383    &mut self.elements
384  }
385}
386
387#[derive(Debug)]
389pub struct Block {
390  pub is_weighted: bool,
392  pub protection: Option<BlockProtection>,
394  pub elements: Rc<Vec<Rc<BlockElement>>>
396}
397
398impl Block {
399  pub fn new(is_weighted: bool, protection: Option<BlockProtection>, elements: Vec<Rc<BlockElement>>) -> Self {
401    Block {
402      is_weighted,
403      protection,
404      elements: Rc::new(elements),
405    }
406  }
407  
408  #[inline]
410  pub fn len(&self) -> usize {
411    self.elements.len()
412  }
413}
414
415#[derive(Debug, Copy, Clone, PartialEq)]
416pub enum BlockProtection {
417  Outer,
418}
419
420#[derive(Debug)]
422pub struct BlockElement {
423  pub main: Rc<Sequence>,
425  pub weight: Option<BlockWeight>,
427  pub output_modifier: Option<OutputModifierSig>,
429}
430
431impl Clone for BlockElement {
432  #[inline]
433  fn clone(&self) -> Self {
434    Self {
435      main: Rc::clone(&self.main),
436      weight: self.weight.clone(),
437      output_modifier: self.output_modifier.clone(),
438    }
439  }
440}
441
442#[derive(Debug)]
444pub enum BlockWeight {
445  Dynamic(Rc<Sequence>),
447  Constant(f64),
449}
450
451impl Clone for BlockWeight {
452  #[inline]
453  fn clone(&self) -> Self {
454    match self {
455      BlockWeight::Dynamic(s) => Self::Dynamic(Rc::clone(s)),
456      BlockWeight::Constant(c) => Self::Constant(*c),
457    }
458  }
459}
460
461#[derive(Debug, Clone)]
463pub struct OutputModifierSig {
464  pub input_var: Option<Identifier>
465}
466
467#[derive(Debug, Copy, Clone)]
469pub enum Varity {
470  Required,
472  Optional,
474  VariadicStar,
476  VariadicPlus,
478}
479
480impl Varity {
481  pub fn is_valid_order(first: Varity, second: Varity) -> bool {
483    use Varity::*;
484    matches!((first, second), 
485      (Required, Required) |
486      (Required, Optional) |
487      (Required, VariadicStar) |
488      (Required, VariadicPlus) |
489      (Optional, Optional) |
490      (Optional, VariadicStar)
491    )
492  }
493
494  pub fn is_variadic(&self) -> bool {
496    use Varity::*;
497    matches!(self, VariadicStar | VariadicPlus)
498  }
499}
500
501impl Display for Varity {
502  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
503    use Varity::*;
504    match self {
505      Required => write!(f, "required parameter"),
506      Optional => write!(f, "optional parameter"),
507      VariadicStar => write!(f, "optional variadic parameter"),
508      VariadicPlus => write!(f, "required variadic parameter"),
509    }
510  }
511}
512
513#[derive(Debug, Copy, Clone)]
515pub enum ArgumentSpreadMode {
516  NoSpread,
518  Parametric,
520  Temporal { label: usize, is_complex: bool },
528}
529
530#[derive(Debug)]
532pub struct ArgumentExpr {
533  pub expr: Rc<Sequence>,
535  pub spread_mode: ArgumentSpreadMode,
537}
538
539#[derive(Debug)]
541pub enum FunctionCallTarget {
542  Path(Rc<AccessPath>),
545}
546
547#[derive(Debug)]
549pub struct FunctionCall {
550  pub target: FunctionCallTarget,
552  pub arguments: Rc<Vec<ArgumentExpr>>,
554  pub is_temporal: bool,
556}
557
558#[derive(Debug)]
560pub struct PipedCall {
561  pub steps: Rc<Vec<FunctionCall>>,
563  pub assignment_pipe: Option<Rc<AssignmentPipeTarget>>,
565  pub is_temporal: bool,
567}
568
569#[derive(Debug)]
571pub enum AssignmentPipeTarget {
572  Set(Rc<AccessPath>),
574  Def { ident: Identifier, is_const: bool, access_mode: VarAccessMode },
576}
577
578#[derive(Debug)]
580pub struct TemporalSpreadState {
581  counters: Vec<(usize, usize)>,
583  arg_labels: HashMap<usize, usize>,
585}
586
587impl TemporalSpreadState {
588  #[inline]
590  pub fn new(arg_exprs: &[ArgumentExpr], args: &[RantValue]) -> Self {
591    let mut counters = Vec::with_capacity(args.len());
592    let mut arg_labels: HashMap<usize, usize> = Default::default();
593    for (i, expr) in arg_exprs.iter().enumerate() {
594      if let ArgumentSpreadMode::Temporal { label, .. } = expr.spread_mode {
595        arg_labels.insert(i, label);
596        let arg = &args[i];
599        if label >= counters.len() {
600          let counter_size = if arg.is_indexable() {
601            arg.len()
602          } else {
603            0
604          };
605          counters.push((0, counter_size));
606        } else {
607          if arg.is_indexable() {
610            let (_, n) = &mut counters[label];
611            *n = arg.len().min(*n);
612          }
613        }
614      }
615    }
616    Self {
617      counters,
618      arg_labels,
619    }
620  }
621
622  #[inline]
624  pub fn len(&self) -> usize {
625    self.counters.len()
626  }
627
628  #[inline]
630  pub fn is_empty(&self) -> bool {
631    self.counters.is_empty() || self.counters.iter().all(|(.., n)| *n == 0)
632  }
633
634  #[inline]
636  pub fn get(&self, arg_index: usize) -> Option<usize> {
637    self.arg_labels.get(&arg_index).map(|i| self.counters[*i].0)
638  }
639
640  #[inline]
643  pub fn increment(&mut self) -> bool {
644    let mut success = false;
645    for (c, n) in self.counters.iter_mut() {
646      *c += 1;
647      if c >= n {
649        *c = 0;
650      } else {
651        success = true;
652        break
653      }
654    }
655    success
656  }
657}
658
659#[derive(Debug, Clone)]
661pub struct FunctionDef {
662  pub path: Rc<AccessPath>,
664  pub is_const: bool, pub params: Rc<Vec<Parameter>>,
668  pub capture_vars: Rc<Vec<Identifier>>,
670  pub body: Rc<Sequence>,
672}
673
674#[derive(Debug, Clone)]
676pub struct LambdaExpr {
677  pub body: Rc<Sequence>,
679  pub params: Rc<Vec<Parameter>>,
681  pub capture_vars: Rc<Vec<Identifier>>,
683}
684
685#[derive(Debug)]
687pub struct Parameter {
688  pub name: Identifier,
690  pub varity: Varity,
692  pub default_value_expr: Option<Rc<Sequence>>,
694}
695
696impl Parameter {
697  #[inline]
699  pub fn is_required(&self) -> bool {
700    use Varity::*;
701    matches!(self.varity, Required | VariadicPlus)
702  }
703
704  #[inline]
705  pub fn is_optional(&self) -> bool {
706    use Varity::*;
707    matches!(self.varity, Optional)
708  }
709}
710
711#[derive(Debug)]
713pub enum MapKeyExpr {
714  Dynamic(Rc<Sequence>),
716  Static(InternalString),
718}
719
720#[derive(Debug)]
722pub struct Getter {
723  pub path: Rc<AccessPath>,
725  pub fallback: Option<Rc<Sequence>>,
727}
728
729#[derive(Debug)]
731pub struct Setter {
732  pub path: Rc<AccessPath>,
734  pub value: Rc<Sequence>,
736}
737
738#[derive(Debug, Copy, Clone)]
740pub enum CompAssignOp {
741  Add,
743  Subtract,
745  Multiply,
747  Divide,
749  Modulo,
751  Power,
753  And,
755  Or,
757  Xor,
759  Nand,
761  Nor,
763}
764
765#[derive(Debug)]
767pub struct Definition {
768  pub name: Identifier,
770  pub is_const: bool,
772  pub access_mode: VarAccessMode,
774  pub value: Option<Rc<Sequence>>,
776}
777
778#[derive(Debug)]
780pub enum Expression {
781  Nop,
783  Sequence(Rc<Sequence>),
785  Block(Rc<Block>),
787  ListInit(Rc<Vec<Rc<Sequence>>>),
789  TupleInit(Rc<Vec<Rc<Sequence>>>),
791  MapInit(Rc<Vec<(MapKeyExpr, Rc<Sequence>)>>),
793  Lambda(LambdaExpr),
795  FuncCall(FunctionCall),
797  PipedCall(PipedCall),
799  FuncDef(FunctionDef),
801  Define(Definition),
803  Get(Getter),
805  Set(Setter),
807  PipeValue,
809  Fragment(InternalString),
811  Whitespace(InternalString),
813  Integer(i64),
815  Float(f64),
817  Boolean(bool),
819  NothingVal,
821  Return(Option<Rc<Sequence>>),
823  Continue(Option<Rc<Sequence>>),
825  Break(Option<Rc<Sequence>>),
827  LogicNot(Rc<Sequence>),
829  Negate(Rc<Sequence>),
831  Power(Rc<Sequence>, Rc<Sequence>),
833  Multiply(Rc<Sequence>, Rc<Sequence>),
835  Divide(Rc<Sequence>, Rc<Sequence>),
837  Modulo(Rc<Sequence>, Rc<Sequence>),
839  Add(Rc<Sequence>, Rc<Sequence>),
841  Subtract(Rc<Sequence>, Rc<Sequence>),
843  Less(Rc<Sequence>, Rc<Sequence>),
845  LessOrEqual(Rc<Sequence>, Rc<Sequence>),
847  Greater(Rc<Sequence>, Rc<Sequence>),
849  GreaterOrEqual(Rc<Sequence>, Rc<Sequence>),
851  Equals(Rc<Sequence>, Rc<Sequence>),
853  NotEquals(Rc<Sequence>, Rc<Sequence>),
855  LogicAnd(Rc<Sequence>, Rc<Sequence>),
857  LogicXor(Rc<Sequence>, Rc<Sequence>),
859  LogicOr(Rc<Sequence>, Rc<Sequence>),
861  Conditional { conditions: Rc<Vec<(Rc<Sequence>, Rc<Block>)>>, fallback: Option<Rc<Block>> },
863  DebugCursor(DebugInfo),
865  Require { alias: Option<InternalString>, path: InternalString },
867}
868
869impl Expression {
870  pub fn display_name(&self) -> &'static str {
872    match self {
873      Self::Sequence(_) =>                     "sequence",
874      Self::Block(..) =>                       "block",
875      Self::ListInit(_) =>                     "list",
876      Self::TupleInit(_) =>                    "tuple",
877      Self::MapInit(_) =>                      "map",
878      Self::Lambda(_) =>                       "lambda",
879      Self::FuncCall(_) =>                     "call function",
880      Self::FuncDef(_) =>                      "define function",
881      Self::Fragment(_) =>                     "fragment",
882      Self::Whitespace(_) =>                   "whitespace",
883      Self::Integer(_) =>                      "integer",
884      Self::Float(_) =>                        "float",
885      Self::Boolean(_) =>                      "bool",
886      Self::NothingVal =>                      "nothing_val",
887      Self::Nop =>                             "no-op",
888      Self::Define(..) =>                      "definition",
889      Self::Get(..) =>                         "getter",
890      Self::Set(..) =>                         "setter",
891      Self::PipedCall(_) =>                    "piped call",
892      Self::PipeValue =>                       "pipeval",
893      Self::Return(_) =>                       "return",
894      Self::Continue(_) =>                     "continue",
895      Self::Break(_) =>                        "break",
896      Self::LogicNot(_) =>                     "not",
897      Self::Negate(_) =>                       "negate",
898      Self::Power(_, _) =>                     "power",
899      Self::Multiply(_, _) =>                  "multiply",
900      Self::Divide(_, _) =>                    "divide",
901      Self::Modulo(_, _) =>                    "modulo",
902      Self::Add(_, _) =>                       "add",
903      Self::Subtract(_, _) =>                  "subtract",
904      Self::Less(_, _) =>                      "less than",
905      Self::LessOrEqual(_, _) =>               "less than or equal",
906      Self::Greater(_, _) =>                   "greater than",
907      Self::GreaterOrEqual(_, _) =>            "greater than or equal",
908      Self::Equals(_, _) =>                    "equals",
909      Self::NotEquals(_, _) =>                 "not equals",
910      Self::LogicAnd(_, _) =>                  "and",
911      Self::LogicXor(_, _) =>                  "xor",
912      Self::LogicOr(_, _) =>                   "or",
913      Self::DebugCursor(_) =>                  "debug cursor",
914      Self::Conditional { .. } =>              "conditional",
915      Self::Require { .. } =>                  "require",
916    }
917  }
918}
919
920impl Display for Expression {
921  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
922    write!(f, "{}", self.display_name())
923  }
924}
925
926#[derive(Debug)]
928pub enum DebugInfo {
929  Location { line: usize, col: usize },
931}