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}