1mod clause;
55mod common;
56mod modal;
57mod noun;
58mod pragmatics;
59mod quantifier;
60mod question;
61mod verb;
62
63#[cfg(test)]
64mod tests;
65
66pub use clause::ClauseParsing;
67pub use modal::ModalParsing;
68pub use noun::NounParsing;
69pub use pragmatics::PragmaticsParsing;
70pub use quantifier::QuantifierParsing;
71pub use question::QuestionParsing;
72pub use verb::{LogicVerbParsing, ImperativeVerbParsing};
73
74use crate::analysis::TypeRegistry;
75use crate::arena_ctx::AstContext;
76use crate::ast::{AspectOperator, LogicExpr, NeoEventData, NumberKind, QuantifierKind, TemporalOperator, Term, ThematicRole, Stmt, Expr, Literal, TypeExpr, BinaryOpKind, MatchArm, OptFlag};
77use crate::ast::stmt::{ReadSource, Pattern};
78use std::collections::HashSet;
79use crate::drs::{Case, Gender, Number, ReferentSource};
80use crate::drs::{Drs, BoxType, WorldState};
81use crate::error::{ParseError, ParseErrorKind};
82use logicaffeine_base::{Interner, Symbol, SymbolEq};
83use crate::lexer::Lexer;
84use crate::lexicon::{self, Aspect, Definiteness, Time, VerbClass};
85use crate::token::{BlockType, FocusKind, Token, TokenType};
86
87pub(super) type ParseResult<T> = Result<T, ParseError>;
88
89use std::ops::{Deref, DerefMut};
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
93pub enum ParserMode {
94 #[default]
96 Declarative,
97 Imperative,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
106pub enum NegativeScopeMode {
107 #[default]
110 Narrow,
111 Wide,
114}
115
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
124pub enum ModalPreference {
125 #[default]
127 Default,
128 Epistemic,
130 Deontic,
132}
133
134#[derive(Debug, Clone, Copy)]
139pub enum ResolvedPronoun {
140 Variable(Symbol),
142 Constant(Symbol),
144}
145
146#[derive(Clone)]
147struct ParserCheckpoint {
148 pos: usize,
149 var_counter: usize,
150 bindings_len: usize,
151 island: u32,
152 time: Option<Time>,
153 negative_depth: u32,
154}
155
156pub struct ParserGuard<'p, 'a, 'ctx, 'int> {
189 parser: &'p mut Parser<'a, 'ctx, 'int>,
190 checkpoint: ParserCheckpoint,
191 committed: bool,
192}
193
194impl<'p, 'a, 'ctx, 'int> ParserGuard<'p, 'a, 'ctx, 'int> {
195 pub fn commit(mut self) {
197 self.committed = true;
198 }
199}
200
201impl<'p, 'a, 'ctx, 'int> Drop for ParserGuard<'p, 'a, 'ctx, 'int> {
202 fn drop(&mut self) {
203 if !self.committed {
204 self.parser.restore(self.checkpoint.clone());
205 }
206 }
207}
208
209impl<'p, 'a, 'ctx, 'int> Deref for ParserGuard<'p, 'a, 'ctx, 'int> {
210 type Target = Parser<'a, 'ctx, 'int>;
211 fn deref(&self) -> &Self::Target {
212 self.parser
213 }
214}
215
216impl<'p, 'a, 'ctx, 'int> DerefMut for ParserGuard<'p, 'a, 'ctx, 'int> {
217 fn deref_mut(&mut self) -> &mut Self::Target {
218 self.parser
219 }
220}
221
222#[derive(Clone, Debug)]
227pub struct EventTemplate<'a> {
228 pub verb: Symbol,
230 pub non_agent_roles: Vec<(ThematicRole, Term<'a>)>,
232 pub modifiers: Vec<Symbol>,
234}
235
236pub struct Parser<'a, 'ctx, 'int> {
253 pub(super) tokens: Vec<Token>,
255 pub(super) current: usize,
257 pub(super) var_counter: usize,
259 pub(super) pending_time: Option<Time>,
261 pub(super) donkey_bindings: Vec<(Symbol, Symbol, bool, bool)>,
263 pub(super) interner: &'int mut Interner,
265 pub(super) ctx: AstContext<'a>,
267 pub(super) current_island: u32,
269 pub(super) pp_attach_to_noun: bool,
271 pub(super) filler_gap: Option<Symbol>,
273 pub(super) negative_depth: u32,
275 pub(super) discourse_event_var: Option<Symbol>,
277 pub(super) last_event_template: Option<EventTemplate<'a>>,
279 pub(super) noun_priority_mode: bool,
281 pub(super) collective_mode: bool,
283 pub(super) pending_cardinal: Option<u32>,
285 pub(super) mode: ParserMode,
287 pub(super) type_registry: Option<TypeRegistry>,
289 pub(super) event_reading_mode: bool,
291 pub(super) drs: Drs,
293 pub(super) negative_scope_mode: NegativeScopeMode,
295 pub(super) modal_preference: ModalPreference,
297 pub(super) world_state: &'ctx mut WorldState,
299 pub(super) in_negative_quantifier: bool,
301}
302
303impl<'a, 'ctx, 'int> Parser<'a, 'ctx, 'int> {
304 pub fn new(
308 tokens: Vec<Token>,
309 world_state: &'ctx mut WorldState,
310 interner: &'int mut Interner,
311 ctx: AstContext<'a>,
312 types: TypeRegistry,
313 ) -> Self {
314 Parser {
315 tokens,
316 current: 0,
317 var_counter: 0,
318 pending_time: None,
319 donkey_bindings: Vec::new(),
320 interner,
321 ctx,
322 current_island: 0,
323 pp_attach_to_noun: false,
324 filler_gap: None,
325 negative_depth: 0,
326 discourse_event_var: None,
327 last_event_template: None,
328 noun_priority_mode: false,
329 collective_mode: false,
330 pending_cardinal: None,
331 mode: ParserMode::Declarative,
332 type_registry: Some(types),
333 event_reading_mode: false,
334 drs: Drs::new(), negative_scope_mode: NegativeScopeMode::default(),
336 modal_preference: ModalPreference::default(),
337 world_state,
338 in_negative_quantifier: false,
339 }
340 }
341
342 pub fn set_discourse_event_var(&mut self, var: Symbol) {
343 self.discourse_event_var = Some(var);
344 }
345
346 pub fn drs_mut(&mut self) -> &mut Drs {
348 &mut self.world_state.drs
349 }
350
351 pub fn drs_ref(&self) -> &Drs {
353 &self.world_state.drs
354 }
355
356 pub fn swap_drs_with_world_state(&mut self) {
360 std::mem::swap(&mut self.drs, &mut self.world_state.drs);
361 }
362
363 pub fn has_world_state(&self) -> bool {
365 true
366 }
367
368 pub fn mode(&self) -> ParserMode {
369 self.mode
370 }
371
372 pub fn is_known_type(&self, sym: Symbol) -> bool {
375 self.type_registry
376 .as_ref()
377 .map(|r| r.is_type(sym))
378 .unwrap_or(false)
379 }
380
381 pub fn is_generic_type(&self, sym: Symbol) -> bool {
384 self.type_registry
385 .as_ref()
386 .map(|r| r.is_generic(sym))
387 .unwrap_or(false)
388 }
389
390 fn get_generic_param_count(&self, sym: Symbol) -> Option<usize> {
392 use crate::analysis::TypeDef;
393 self.type_registry.as_ref().and_then(|r| {
394 match r.get(sym) {
395 Some(TypeDef::Generic { param_count }) => Some(*param_count),
396 _ => None,
397 }
398 })
399 }
400
401 fn find_variant(&self, sym: Symbol) -> Option<Symbol> {
403 self.type_registry
404 .as_ref()
405 .and_then(|r| r.find_variant(sym).map(|(enum_name, _)| enum_name))
406 }
407
408 fn consume_type_name(&mut self) -> ParseResult<Symbol> {
410 let t = self.advance().clone();
411 match t.kind {
412 TokenType::Noun(s) | TokenType::Adjective(s) => Ok(s),
413 TokenType::ProperName(s) => Ok(s),
414 TokenType::Verb { .. } => Ok(t.lexeme),
416 TokenType::Tally => Ok(self.interner.intern("Tally")),
418 TokenType::SharedSet => Ok(self.interner.intern("SharedSet")),
419 TokenType::SharedSequence => Ok(self.interner.intern("SharedSequence")),
420 TokenType::CollaborativeSequence => Ok(self.interner.intern("CollaborativeSequence")),
421 TokenType::SharedMap => Ok(self.interner.intern("SharedMap")),
422 TokenType::Divergent => Ok(self.interner.intern("Divergent")),
423 TokenType::Article(_) => Ok(t.lexeme),
425 other => Err(ParseError {
426 kind: ParseErrorKind::ExpectedContentWord { found: other },
427 span: self.current_span(),
428 }),
429 }
430 }
431
432 fn parse_type_expression(&mut self) -> ParseResult<TypeExpr<'a>> {
437 use noun::NounParsing;
438
439 if self.check_word("fn") {
441 if let Some(next) = self.tokens.get(self.current + 1) {
442 if matches!(next.kind, TokenType::LParen) {
443 self.advance(); self.advance(); let mut inputs = Vec::new();
448 if !self.check(&TokenType::RParen) {
449 inputs.push(self.parse_type_expression()?);
450 while self.check(&TokenType::Comma) {
451 self.advance(); inputs.push(self.parse_type_expression()?);
453 }
454 }
455
456 if !self.check(&TokenType::RParen) {
457 return Err(ParseError {
458 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
459 span: self.current_span(),
460 });
461 }
462 self.advance(); if !self.check(&TokenType::Arrow) {
466 return Err(ParseError {
467 kind: ParseErrorKind::ExpectedKeyword { keyword: "->".to_string() },
468 span: self.current_span(),
469 });
470 }
471 self.advance(); let output = self.parse_type_expression()?;
474 let output_ref = self.ctx.alloc_type_expr(output);
475 let inputs_ref = self.ctx.alloc_type_exprs(inputs);
476 return Ok(TypeExpr::Function { inputs: inputs_ref, output: output_ref });
477 }
478 }
479 }
480
481 if self.check(&TokenType::LParen) {
483 self.advance(); let inner = self.parse_type_expression()?;
485 if !self.check(&TokenType::RParen) {
486 return Err(ParseError {
487 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
488 span: self.current_span(),
489 });
490 }
491 self.advance(); return Ok(inner);
493 }
494
495 if self.check(&TokenType::Persistent) {
497 self.advance(); let inner = self.parse_type_expression()?;
499 let inner_ref = self.ctx.alloc_type_expr(inner);
500 return Ok(TypeExpr::Persistent { inner: inner_ref });
501 }
502
503 let mut base = self.consume_type_name()?;
505
506 let base_name = self.interner.resolve(base);
508 if base_name == "SharedSet" || base_name == "ORSet" {
509 if self.check(&TokenType::LParen) {
510 self.advance(); if self.check(&TokenType::RemoveWins) {
512 self.advance(); base = self.interner.intern("SharedSet_RemoveWins");
514 } else if self.check(&TokenType::AddWins) {
515 self.advance(); base = self.interner.intern("SharedSet_AddWins");
518 }
519 if !self.check(&TokenType::RParen) {
520 return Err(ParseError {
521 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
522 span: self.current_span(),
523 });
524 }
525 self.advance(); }
527 }
528
529 let base_name = self.interner.resolve(base);
531 if base_name == "SharedSequence" || base_name == "RGA" {
532 if self.check(&TokenType::LParen) {
533 self.advance(); if self.check(&TokenType::YATA) {
535 self.advance(); base = self.interner.intern("SharedSequence_YATA");
537 }
538 if !self.check(&TokenType::RParen) {
539 return Err(ParseError {
540 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
541 span: self.current_span(),
542 });
543 }
544 self.advance(); }
546 }
547
548 let base_type = if self.check(&TokenType::From) {
550 self.advance(); let module_name = self.consume_type_name()?;
552 let module_str = self.interner.resolve(module_name);
553 let base_str = self.interner.resolve(base);
554 let qualified = format!("{}::{}", module_str, base_str);
555 let qualified_sym = self.interner.intern(&qualified);
556 TypeExpr::Named(qualified_sym)
557 } else {
558 let base_name = self.interner.resolve(base);
560 let param_count = self.get_generic_param_count(base)
561 .or_else(|| match base_name {
562 "Result" => Some(2), "Option" | "Maybe" => Some(1), "Seq" | "List" | "Vec" => Some(1), "Set" | "HashSet" => Some(1), "Map" | "HashMap" => Some(2), "Pair" => Some(2), "Triple" => Some(3), "SharedSet" | "ORSet" | "SharedSet_AddWins" | "SharedSet_RemoveWins" => Some(1),
572 "SharedSequence" | "RGA" | "SharedSequence_YATA" | "CollaborativeSequence" => Some(1),
573 "SharedMap" | "ORMap" => Some(2), "Divergent" | "MVRegister" => Some(1), _ => None,
576 });
577
578 if let Some(count) = param_count {
580 let has_preposition = self.check_of_preposition() || self.check_preposition_is("from");
581 let maybe_direct = !has_preposition && base_name == "Maybe" && matches!(
583 self.peek().kind,
584 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) | TokenType::Verb { .. }
585 );
586 if has_preposition || maybe_direct {
587 if has_preposition {
588 self.advance(); }
590
591 let mut params = Vec::new();
592 for i in 0..count {
593 if i > 0 {
594 if self.check(&TokenType::And) || self.check_to_preposition() || self.check(&TokenType::Comma) {
596 self.advance();
597 }
598 }
599 let param = self.parse_type_expression()?;
600 params.push(param);
601 }
602
603 let params_slice = self.ctx.alloc_type_exprs(params);
604 TypeExpr::Generic { base, params: params_slice }
605 } else {
606 let is_primitive = self.type_registry.as_ref().map(|r| r.is_type(base)).unwrap_or(false)
608 || matches!(base_name, "Int" | "Nat" | "Text" | "Bool" | "Boolean" | "Real" | "Unit");
609 if is_primitive {
610 TypeExpr::Primitive(base)
611 } else {
612 TypeExpr::Named(base)
613 }
614 }
615 } else {
616 let is_primitive = self.type_registry.as_ref().map(|r| r.is_type(base)).unwrap_or(false)
618 || matches!(base_name, "Int" | "Nat" | "Text" | "Bool" | "Boolean" | "Real" | "Unit");
619 if is_primitive {
620 TypeExpr::Primitive(base)
621 } else {
622 TypeExpr::Named(base)
624 }
625 }
626 };
627
628 if self.check(&TokenType::Where) {
630 self.advance(); let predicate_expr = self.parse_condition()?;
634
635 let bound_var = self.extract_bound_var(&predicate_expr)
637 .unwrap_or_else(|| self.interner.intern("it"));
638
639 let predicate = self.expr_to_logic_predicate(&predicate_expr, bound_var)
641 .ok_or_else(|| ParseError {
642 kind: ParseErrorKind::InvalidRefinementPredicate,
643 span: self.peek().span,
644 })?;
645
646 let base_alloc = self.ctx.alloc_type_expr(base_type);
648
649 return Ok(TypeExpr::Refinement { base: base_alloc, var: bound_var, predicate });
650 }
651
652 Ok(base_type)
653 }
654
655 fn extract_bound_var(&self, expr: &Expr<'a>) -> Option<Symbol> {
657 match expr {
658 Expr::Identifier(sym) => Some(*sym),
659 Expr::BinaryOp { left, .. } => self.extract_bound_var(left),
660 _ => None,
661 }
662 }
663
664 fn expr_to_logic_predicate(&mut self, expr: &Expr<'a>, bound_var: Symbol) -> Option<&'a LogicExpr<'a>> {
667 match expr {
668 Expr::BinaryOp { op, left, right } => {
669 let pred_name = match op {
671 BinaryOpKind::Gt => "Greater",
672 BinaryOpKind::Lt => "Less",
673 BinaryOpKind::GtEq => "GreaterEqual",
674 BinaryOpKind::LtEq => "LessEqual",
675 BinaryOpKind::Eq => "Equal",
676 BinaryOpKind::NotEq => "NotEqual",
677 BinaryOpKind::And => {
678 let left_logic = self.expr_to_logic_predicate(left, bound_var)?;
680 let right_logic = self.expr_to_logic_predicate(right, bound_var)?;
681 return Some(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
682 left: left_logic,
683 op: TokenType::And,
684 right: right_logic,
685 }));
686 }
687 BinaryOpKind::Or => {
688 let left_logic = self.expr_to_logic_predicate(left, bound_var)?;
689 let right_logic = self.expr_to_logic_predicate(right, bound_var)?;
690 return Some(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
691 left: left_logic,
692 op: TokenType::Or,
693 right: right_logic,
694 }));
695 }
696 _ => return None, };
698 let pred_sym = self.interner.intern(pred_name);
699
700 let left_term = self.expr_to_term(left)?;
702 let right_term = self.expr_to_term(right)?;
703
704 let args = self.ctx.terms.alloc_slice([left_term, right_term]);
705 Some(self.ctx.exprs.alloc(LogicExpr::Predicate { name: pred_sym, args, world: None }))
706 }
707 _ => None,
708 }
709 }
710
711 fn expr_to_term(&mut self, expr: &Expr<'a>) -> Option<Term<'a>> {
713 match expr {
714 Expr::Identifier(sym) => Some(Term::Variable(*sym)),
715 Expr::Literal(lit) => {
716 match lit {
717 Literal::Number(n) => Some(Term::Value {
718 kind: NumberKind::Integer(*n),
719 unit: None,
720 dimension: None,
721 }),
722 Literal::Boolean(b) => {
723 let sym = self.interner.intern(if *b { "true" } else { "false" });
724 Some(Term::Constant(sym))
725 }
726 _ => None, }
728 }
729 _ => None,
730 }
731 }
732
733 pub fn process_block_headers(&mut self) {
734 use crate::token::BlockType;
735
736 while self.current < self.tokens.len() {
737 if let TokenType::BlockHeader { block_type } = &self.tokens[self.current].kind {
738 self.mode = match block_type {
739 BlockType::Main | BlockType::Function => ParserMode::Imperative,
740 BlockType::Theorem | BlockType::Definition | BlockType::Proof |
741 BlockType::Example | BlockType::Logic | BlockType::Note | BlockType::TypeDef |
742 BlockType::Policy | BlockType::Requires => ParserMode::Declarative,
743 BlockType::No => self.mode, };
745 self.current += 1;
746 } else {
747 break;
748 }
749 }
750 }
751
752 pub fn get_event_var(&mut self) -> Symbol {
753 self.discourse_event_var.unwrap_or_else(|| self.interner.intern("e"))
754 }
755
756 pub fn capture_event_template(&mut self, verb: Symbol, roles: &[(ThematicRole, Term<'a>)], modifiers: &[Symbol]) {
757 let non_agent_roles: Vec<_> = roles.iter()
758 .filter(|(role, _)| *role != ThematicRole::Agent)
759 .cloned()
760 .collect();
761 self.last_event_template = Some(EventTemplate {
762 verb,
763 non_agent_roles,
764 modifiers: modifiers.to_vec(),
765 });
766 }
767
768 fn parse_embedded_wh_clause(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
769 let var_name = self.interner.intern("x");
771 let var_term = Term::Variable(var_name);
772
773 if self.check_verb() {
774 let verb = self.consume_verb();
776 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
777 name: verb,
778 args: self.ctx.terms.alloc_slice([var_term]),
779 world: None,
780 });
781 return Ok(body);
782 }
783
784 if self.check_content_word() || self.check_article() {
785 let subject = self.parse_noun_phrase(true)?;
787 if self.check_verb() {
788 let verb = self.consume_verb();
789 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
790 name: verb,
791 args: self.ctx.terms.alloc_slice([
792 Term::Constant(subject.noun),
793 var_term,
794 ]),
795 world: None,
796 });
797 return Ok(body);
798 }
799 }
800
801 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(var_name)))
803 }
804
805 pub fn set_pp_attachment_mode(&mut self, attach_to_noun: bool) {
806 self.pp_attach_to_noun = attach_to_noun;
807 }
808
809 pub fn set_noun_priority_mode(&mut self, mode: bool) {
810 self.noun_priority_mode = mode;
811 }
812
813 pub fn set_collective_mode(&mut self, mode: bool) {
814 self.collective_mode = mode;
815 }
816
817 pub fn set_event_reading_mode(&mut self, mode: bool) {
818 self.event_reading_mode = mode;
819 }
820
821 pub fn set_negative_scope_mode(&mut self, mode: NegativeScopeMode) {
822 self.negative_scope_mode = mode;
823 }
824
825 pub fn set_modal_preference(&mut self, pref: ModalPreference) {
826 self.modal_preference = pref;
827 }
828
829 fn checkpoint(&self) -> ParserCheckpoint {
830 ParserCheckpoint {
831 pos: self.current,
832 var_counter: self.var_counter,
833 bindings_len: self.donkey_bindings.len(),
834 island: self.current_island,
835 time: self.pending_time,
836 negative_depth: self.negative_depth,
837 }
838 }
839
840 fn restore(&mut self, cp: ParserCheckpoint) {
841 self.current = cp.pos;
842 self.var_counter = cp.var_counter;
843 self.donkey_bindings.truncate(cp.bindings_len);
844 self.current_island = cp.island;
845 self.pending_time = cp.time;
846 self.negative_depth = cp.negative_depth;
847 }
848
849 fn is_negative_context(&self) -> bool {
850 self.negative_depth % 2 == 1
851 }
852
853 pub fn guard(&mut self) -> ParserGuard<'_, 'a, 'ctx, 'int> {
854 ParserGuard {
855 checkpoint: self.checkpoint(),
856 parser: self,
857 committed: false,
858 }
859 }
860
861 pub(super) fn try_parse<F, T>(&mut self, op: F) -> Option<T>
862 where
863 F: FnOnce(&mut Self) -> ParseResult<T>,
864 {
865 let cp = self.checkpoint();
866 match op(self) {
867 Ok(res) => Some(res),
868 Err(_) => {
869 self.restore(cp);
870 None
871 }
872 }
873 }
874
875 fn resolve_pronoun(&mut self, gender: Gender, number: Number) -> ParseResult<ResolvedPronoun> {
876 if self.world_state.in_discourse_mode() && self.world_state.has_prior_modal_context() {
881 if let Some(candidate) = self.world_state.resolve_via_telescope(gender) {
884 return Ok(ResolvedPronoun::Variable(candidate.variable));
885 }
886 let blocked_candidates: Vec<_> = self.world_state.telescope_candidates()
890 .iter()
891 .filter(|c| c.in_modal_scope)
892 .collect();
893 if !blocked_candidates.is_empty() {
894 let has_upcoming_modal = self.has_modal_subordination_ahead();
897 if has_upcoming_modal {
898 if let Some(candidate) = blocked_candidates.into_iter().find(|c| {
900 c.gender == gender || gender == Gender::Unknown || c.gender == Gender::Unknown
901 }) {
902 return Ok(ResolvedPronoun::Variable(candidate.variable));
903 }
904 }
905 return Err(ParseError {
907 kind: ParseErrorKind::ScopeViolation(
908 "Cannot access hypothetical entity from reality. Use modal subordination (e.g., 'would') to continue a hypothetical context.".to_string()
909 ),
910 span: self.current_span(),
911 });
912 }
913 }
915
916 let current_box = self.drs.current_box_index();
918 match self.drs.resolve_pronoun(current_box, gender, number) {
919 Ok(sym) => return Ok(ResolvedPronoun::Variable(sym)),
920 Err(crate::drs::ScopeError::InaccessibleReferent { gender: g, reason, .. }) => {
921 if self.world_state.in_discourse_mode() {
925 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
926 return Ok(ResolvedPronoun::Variable(candidate.variable));
927 }
928 }
929 return Err(ParseError {
931 kind: ParseErrorKind::ScopeViolation(reason),
932 span: self.current_span(),
933 });
934 }
935 Err(crate::drs::ScopeError::NoMatchingReferent { gender: g, number: n }) => {
936 if !self.world_state.has_prior_modal_context() {
938 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
939 return Ok(ResolvedPronoun::Variable(candidate.variable));
940 }
941 }
942
943 if self.world_state.in_discourse_mode() {
945 return Err(ParseError {
946 kind: ParseErrorKind::UnresolvedPronoun {
947 gender: g,
948 number: n,
949 },
950 span: self.current_span(),
951 });
952 }
953
954 let deictic_name = match (g, n) {
957 (Gender::Male, Number::Singular) => "Him",
958 (Gender::Female, Number::Singular) => "Her",
959 (Gender::Neuter, Number::Singular) => "It",
960 (Gender::Male, Number::Plural) | (Gender::Female, Number::Plural) => "Them",
961 (Gender::Neuter, Number::Plural) => "Them",
962 (Gender::Unknown, _) => "Someone",
963 };
964 let sym = self.interner.intern(deictic_name);
965 self.drs.introduce_referent(sym, sym, g, n);
967 return Ok(ResolvedPronoun::Constant(sym));
968 }
969 }
970 }
971
972 fn resolve_donkey_pronoun(&mut self, gender: Gender) -> Option<Symbol> {
973 for (noun_class, var_name, used, _wide_neg) in self.donkey_bindings.iter_mut().rev() {
974 let noun_str = self.interner.resolve(*noun_class);
975 let noun_gender = Self::infer_noun_gender(noun_str);
976 if noun_gender == gender || gender == Gender::Neuter || noun_gender == Gender::Unknown {
977 *used = true; return Some(*var_name);
979 }
980 }
981 None
982 }
983
984 fn infer_noun_gender(noun: &str) -> Gender {
985 let lower = noun.to_lowercase();
986 if lexicon::is_female_noun(&lower) {
987 Gender::Female
988 } else if lexicon::is_male_noun(&lower) {
989 Gender::Male
990 } else if lexicon::is_neuter_noun(&lower) {
991 Gender::Neuter
992 } else {
993 Gender::Unknown
994 }
995 }
996
997 fn is_plural_noun(noun: &str) -> bool {
998 let lower = noun.to_lowercase();
999 if lexicon::is_proper_name(&lower) {
1001 return false;
1002 }
1003 if lexicon::is_irregular_plural(&lower) {
1004 return true;
1005 }
1006 lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2
1007 }
1008
1009 fn singularize_noun(noun: &str) -> String {
1010 let lower = noun.to_lowercase();
1011 if let Some(singular) = lexicon::singularize(&lower) {
1012 return singular.to_string();
1013 }
1014 if lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2 {
1015 let base = &lower[..lower.len() - 1];
1016 let mut chars: Vec<char> = base.chars().collect();
1017 if !chars.is_empty() {
1018 chars[0] = chars[0].to_uppercase().next().unwrap();
1019 }
1020 return chars.into_iter().collect();
1021 }
1022 let mut chars: Vec<char> = lower.chars().collect();
1023 if !chars.is_empty() {
1024 chars[0] = chars[0].to_uppercase().next().unwrap();
1025 }
1026 chars.into_iter().collect()
1027 }
1028
1029 fn infer_gender(name: &str) -> Gender {
1030 let lower = name.to_lowercase();
1031 if lexicon::is_male_name(&lower) {
1032 Gender::Male
1033 } else if lexicon::is_female_name(&lower) {
1034 Gender::Female
1035 } else {
1036 Gender::Unknown
1037 }
1038 }
1039
1040
1041 fn next_var_name(&mut self) -> Symbol {
1042 const VARS: &[&str] = &["x", "y", "z", "w", "v", "u"];
1043 let idx = self.var_counter;
1044 self.var_counter += 1;
1045 if idx < VARS.len() {
1046 self.interner.intern(VARS[idx])
1047 } else {
1048 let name = format!("x{}", idx - VARS.len() + 1);
1049 self.interner.intern(&name)
1050 }
1051 }
1052
1053 pub fn parse(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
1070 let mut result = self.parse_sentence()?;
1071
1072 while self.check(&TokenType::Period) || self.check(&TokenType::Exclamation) {
1075 self.advance(); if !self.is_at_end() {
1077 let next = self.parse_sentence()?;
1078 result = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1079 left: result,
1080 op: TokenType::And,
1081 right: next,
1082 });
1083 }
1084 }
1085
1086 Ok(result)
1087 }
1088
1089 pub fn parse_program(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
1107 let mut statements = Vec::new();
1108 let mut in_definition_block = false;
1109 let mut pending_opt_flags: HashSet<OptFlag> = HashSet::new();
1110
1111 if self.mode == ParserMode::Declarative {
1113 }
1117
1118 while !self.is_at_end() {
1119 if let Some(Token { kind: TokenType::BlockHeader { block_type }, .. }) = self.tokens.get(self.current) {
1121 match block_type {
1122 BlockType::Definition => {
1123 in_definition_block = true;
1124 self.mode = ParserMode::Declarative;
1125 self.advance();
1126 continue;
1127 }
1128 BlockType::Main => {
1129 in_definition_block = false;
1130 self.mode = ParserMode::Imperative;
1131 self.advance();
1132 continue;
1133 }
1134 BlockType::No => {
1135 self.advance(); if let Some(token) = self.tokens.get(self.current) {
1140 let word = self.interner.resolve(token.lexeme).to_lowercase();
1141 match word.as_str() {
1142 "memo" => { pending_opt_flags.insert(OptFlag::NoMemo); }
1143 "tco" => { pending_opt_flags.insert(OptFlag::NoTCO); }
1144 "peephole" => { pending_opt_flags.insert(OptFlag::NoPeephole); }
1145 "borrow" => { pending_opt_flags.insert(OptFlag::NoBorrow); }
1146 "optimize" => {
1147 pending_opt_flags.insert(OptFlag::NoOptimize);
1148 pending_opt_flags.insert(OptFlag::NoMemo);
1149 pending_opt_flags.insert(OptFlag::NoTCO);
1150 pending_opt_flags.insert(OptFlag::NoPeephole);
1151 pending_opt_flags.insert(OptFlag::NoBorrow);
1152 }
1153 _ => {} }
1155 self.advance(); }
1157 while self.check(&TokenType::Newline) {
1159 self.advance();
1160 }
1161 continue;
1162 }
1163 BlockType::Function => {
1164 in_definition_block = false;
1165 self.mode = ParserMode::Imperative;
1166 self.advance();
1167 let flags = std::mem::take(&mut pending_opt_flags);
1169 let func_def = self.parse_function_def_with_flags(flags)?;
1170 statements.push(func_def);
1171 continue;
1172 }
1173 BlockType::TypeDef => {
1174 self.advance();
1177 self.skip_type_def_content();
1178 continue;
1179 }
1180 BlockType::Policy => {
1181 in_definition_block = true; self.mode = ParserMode::Declarative;
1185 self.advance();
1186 continue;
1187 }
1188 BlockType::Theorem => {
1189 in_definition_block = false;
1191 self.mode = ParserMode::Declarative;
1192 self.advance();
1193 let theorem = self.parse_theorem_block()?;
1194 statements.push(theorem);
1195 continue;
1196 }
1197 BlockType::Requires => {
1198 in_definition_block = false;
1199 self.mode = ParserMode::Declarative;
1200 self.advance();
1201 let deps = self.parse_requires_block()?;
1202 statements.extend(deps);
1203 continue;
1204 }
1205 _ => {
1206 in_definition_block = false;
1208 self.mode = ParserMode::Declarative;
1209 self.advance();
1210 continue;
1211 }
1212 }
1213 }
1214
1215 if in_definition_block {
1217 self.advance();
1218 continue;
1219 }
1220
1221 if self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) || self.check(&TokenType::Newline) {
1223 self.advance();
1224 continue;
1225 }
1226
1227 if self.mode == ParserMode::Imperative {
1229 let stmt = self.parse_statement()?;
1230 statements.push(stmt);
1231
1232 if self.check(&TokenType::Period) {
1233 self.advance();
1234 }
1235 } else {
1236 self.advance();
1238 }
1239 }
1240
1241 Ok(statements)
1242 }
1243
1244 fn parse_statement(&mut self) -> ParseResult<Stmt<'a>> {
1245 if self.check(&TokenType::To) || self.check_preposition_is("to") {
1248 return self.parse_function_def();
1249 }
1250 if self.check(&TokenType::Let) {
1251 return self.parse_let_statement();
1252 }
1253 if self.check(&TokenType::Mut) {
1256 return self.parse_equals_assignment(true);
1257 }
1258 if self.peek_equals_assignment() {
1261 return self.parse_equals_assignment(false);
1262 }
1263 if self.check(&TokenType::Set) {
1264 return self.parse_set_statement();
1265 }
1266 if self.check(&TokenType::Return) {
1267 return self.parse_return_statement();
1268 }
1269 if self.check(&TokenType::Break) {
1270 return self.parse_break_statement();
1271 }
1272 if self.check(&TokenType::If) {
1273 return self.parse_if_statement();
1274 }
1275 if self.check(&TokenType::Assert) {
1276 return self.parse_assert_statement();
1277 }
1278 if self.check(&TokenType::Trust) {
1280 return self.parse_trust_statement();
1281 }
1282 if self.check(&TokenType::Check) {
1284 return self.parse_check_statement();
1285 }
1286 if self.check(&TokenType::Listen) {
1288 return self.parse_listen_statement();
1289 }
1290 if self.check(&TokenType::NetConnect) {
1291 return self.parse_connect_statement();
1292 }
1293 if self.check(&TokenType::Sleep) {
1294 return self.parse_sleep_statement();
1295 }
1296 if self.check(&TokenType::Sync) {
1298 return self.parse_sync_statement();
1299 }
1300 if self.check(&TokenType::Mount) {
1302 return self.parse_mount_statement();
1303 }
1304 if self.check(&TokenType::While) {
1305 return self.parse_while_statement();
1306 }
1307 if self.check(&TokenType::Repeat) {
1308 return self.parse_repeat_statement();
1309 }
1310 if self.check(&TokenType::For) {
1312 return self.parse_for_statement();
1313 }
1314 if self.check(&TokenType::Call) {
1315 return self.parse_call_statement();
1316 }
1317 if self.check(&TokenType::Give) {
1318 return self.parse_give_statement();
1319 }
1320 if self.check(&TokenType::Show) {
1321 return self.parse_show_statement();
1322 }
1323 if self.check(&TokenType::Inspect) {
1325 return self.parse_inspect_statement();
1326 }
1327
1328 if self.check(&TokenType::Push) {
1330 return self.parse_push_statement();
1331 }
1332 if self.check(&TokenType::Pop) {
1333 return self.parse_pop_statement();
1334 }
1335 if self.check(&TokenType::Add) {
1337 return self.parse_add_statement();
1338 }
1339 if self.check(&TokenType::Remove) {
1340 return self.parse_remove_statement();
1341 }
1342
1343 if self.check(&TokenType::Inside) {
1345 return self.parse_zone_statement();
1346 }
1347
1348 if self.check(&TokenType::Attempt) {
1350 return self.parse_concurrent_block();
1351 }
1352 if self.check(&TokenType::Simultaneously) {
1353 return self.parse_parallel_block();
1354 }
1355
1356 if self.check(&TokenType::Read) {
1358 return self.parse_read_statement();
1359 }
1360 if self.check(&TokenType::Write) {
1361 return self.parse_write_statement();
1362 }
1363
1364 if self.check(&TokenType::Spawn) {
1366 return self.parse_spawn_statement();
1367 }
1368 if self.check(&TokenType::Send) {
1369 if self.lookahead_contains_into() {
1371 return self.parse_send_pipe_statement();
1372 }
1373 return self.parse_send_statement();
1374 }
1375 if self.check(&TokenType::Await) {
1376 if self.lookahead_is_first_of() {
1378 return self.parse_select_statement();
1379 }
1380 return self.parse_await_statement();
1381 }
1382
1383 if self.check(&TokenType::Merge) {
1385 return self.parse_merge_statement();
1386 }
1387 if self.check(&TokenType::Increase) {
1388 return self.parse_increase_statement();
1389 }
1390 if self.check(&TokenType::Decrease) {
1392 return self.parse_decrease_statement();
1393 }
1394 if self.check(&TokenType::Append) {
1395 return self.parse_append_statement();
1396 }
1397 if self.check(&TokenType::Resolve) {
1398 return self.parse_resolve_statement();
1399 }
1400
1401 if self.check(&TokenType::Launch) {
1403 return self.parse_launch_statement();
1404 }
1405 if self.check(&TokenType::Stop) {
1406 return self.parse_stop_statement();
1407 }
1408 if self.check(&TokenType::Try) {
1409 return self.parse_try_statement();
1410 }
1411 if self.check(&TokenType::Receive) {
1412 return self.parse_receive_pipe_statement();
1413 }
1414
1415 if self.check(&TokenType::Escape) {
1417 return self.parse_escape_statement();
1418 }
1419
1420 if self.tokens.get(self.current + 1)
1424 .map(|t| matches!(t.kind, TokenType::LParen))
1425 .unwrap_or(false)
1426 {
1427 let function = self.peek().lexeme;
1429 self.advance(); let expr = self.parse_call_expr(function)?;
1433 if let Expr::Call { function, args } = expr {
1434 return Ok(Stmt::Call { function: *function, args: args.clone() });
1435 }
1436 }
1437
1438 Err(ParseError {
1439 kind: ParseErrorKind::ExpectedStatement,
1440 span: self.current_span(),
1441 })
1442 }
1443
1444 fn parse_if_statement(&mut self) -> ParseResult<Stmt<'a>> {
1445 self.advance(); let cond = self.parse_condition()?;
1449
1450 if self.check(&TokenType::Then) {
1452 self.advance();
1453 }
1454
1455 if !self.check(&TokenType::Colon) {
1457 return Err(ParseError {
1458 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1459 span: self.current_span(),
1460 });
1461 }
1462 self.advance(); if !self.check(&TokenType::Indent) {
1466 return Err(ParseError {
1467 kind: ParseErrorKind::ExpectedStatement,
1468 span: self.current_span(),
1469 });
1470 }
1471 self.advance(); let mut then_stmts = Vec::new();
1475 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1476 let stmt = self.parse_statement()?;
1477 then_stmts.push(stmt);
1478 if self.check(&TokenType::Period) {
1479 self.advance();
1480 }
1481 }
1482
1483 if self.check(&TokenType::Dedent) {
1485 self.advance();
1486 }
1487
1488 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1490 .alloc_slice(then_stmts.into_iter());
1491
1492 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1494 self.advance(); if self.check(&TokenType::If) {
1498 let nested_if = self.parse_if_statement()?;
1500 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1501 .alloc_slice(std::iter::once(nested_if));
1502 Some(nested_slice)
1503 } else {
1504 if !self.check(&TokenType::Colon) {
1506 return Err(ParseError {
1507 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1508 span: self.current_span(),
1509 });
1510 }
1511 self.advance(); if !self.check(&TokenType::Indent) {
1514 return Err(ParseError {
1515 kind: ParseErrorKind::ExpectedStatement,
1516 span: self.current_span(),
1517 });
1518 }
1519 self.advance(); let mut else_stmts = Vec::new();
1522 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1523 let stmt = self.parse_statement()?;
1524 else_stmts.push(stmt);
1525 if self.check(&TokenType::Period) {
1526 self.advance();
1527 }
1528 }
1529
1530 if self.check(&TokenType::Dedent) {
1531 self.advance();
1532 }
1533
1534 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1535 .alloc_slice(else_stmts.into_iter()))
1536 }
1537 } else if self.check(&TokenType::Elif) {
1538 self.advance(); let nested_if = self.parse_elif_as_if()?;
1542 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1543 .alloc_slice(std::iter::once(nested_if));
1544 Some(nested_slice)
1545 } else {
1546 None
1547 };
1548
1549 Ok(Stmt::If {
1550 cond,
1551 then_block,
1552 else_block,
1553 })
1554 }
1555
1556 fn parse_elif_as_if(&mut self) -> ParseResult<Stmt<'a>> {
1559 let cond = self.parse_condition()?;
1561
1562 if !self.check(&TokenType::Colon) {
1564 return Err(ParseError {
1565 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1566 span: self.current_span(),
1567 });
1568 }
1569 self.advance(); if !self.check(&TokenType::Indent) {
1573 return Err(ParseError {
1574 kind: ParseErrorKind::ExpectedStatement,
1575 span: self.current_span(),
1576 });
1577 }
1578 self.advance(); let mut then_stmts = Vec::new();
1582 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1583 let stmt = self.parse_statement()?;
1584 then_stmts.push(stmt);
1585 if self.check(&TokenType::Period) {
1586 self.advance();
1587 }
1588 }
1589
1590 if self.check(&TokenType::Dedent) {
1592 self.advance();
1593 }
1594
1595 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1597 .alloc_slice(then_stmts.into_iter());
1598
1599 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1601 self.advance(); if self.check(&TokenType::If) {
1605 let nested_if = self.parse_if_statement()?;
1606 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1607 .alloc_slice(std::iter::once(nested_if));
1608 Some(nested_slice)
1609 } else {
1610 if !self.check(&TokenType::Colon) {
1612 return Err(ParseError {
1613 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1614 span: self.current_span(),
1615 });
1616 }
1617 self.advance(); if !self.check(&TokenType::Indent) {
1620 return Err(ParseError {
1621 kind: ParseErrorKind::ExpectedStatement,
1622 span: self.current_span(),
1623 });
1624 }
1625 self.advance(); let mut else_stmts = Vec::new();
1628 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1629 let stmt = self.parse_statement()?;
1630 else_stmts.push(stmt);
1631 if self.check(&TokenType::Period) {
1632 self.advance();
1633 }
1634 }
1635
1636 if self.check(&TokenType::Dedent) {
1637 self.advance();
1638 }
1639
1640 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1641 .alloc_slice(else_stmts.into_iter()))
1642 }
1643 } else if self.check(&TokenType::Elif) {
1644 self.advance(); let nested_if = self.parse_elif_as_if()?;
1646 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1647 .alloc_slice(std::iter::once(nested_if));
1648 Some(nested_slice)
1649 } else {
1650 None
1651 };
1652
1653 Ok(Stmt::If {
1654 cond,
1655 then_block,
1656 else_block,
1657 })
1658 }
1659
1660 fn parse_while_statement(&mut self) -> ParseResult<Stmt<'a>> {
1661 self.advance(); let cond = self.parse_condition()?;
1664
1665 let decreasing = if self.check(&TokenType::LParen) {
1667 self.advance(); if !self.check_word("decreasing") {
1671 return Err(ParseError {
1672 kind: ParseErrorKind::ExpectedKeyword { keyword: "decreasing".to_string() },
1673 span: self.current_span(),
1674 });
1675 }
1676 self.advance(); let variant = self.parse_imperative_expr()?;
1679
1680 if !self.check(&TokenType::RParen) {
1681 return Err(ParseError {
1682 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1683 span: self.current_span(),
1684 });
1685 }
1686 self.advance(); Some(variant)
1689 } else {
1690 None
1691 };
1692
1693 if !self.check(&TokenType::Colon) {
1694 return Err(ParseError {
1695 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1696 span: self.current_span(),
1697 });
1698 }
1699 self.advance(); if !self.check(&TokenType::Indent) {
1702 return Err(ParseError {
1703 kind: ParseErrorKind::ExpectedStatement,
1704 span: self.current_span(),
1705 });
1706 }
1707 self.advance(); let mut body_stmts = Vec::new();
1710 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1711 let stmt = self.parse_statement()?;
1712 body_stmts.push(stmt);
1713 if self.check(&TokenType::Period) {
1714 self.advance();
1715 }
1716 }
1717
1718 if self.check(&TokenType::Dedent) {
1719 self.advance();
1720 }
1721
1722 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1723 .alloc_slice(body_stmts.into_iter());
1724
1725 Ok(Stmt::While { cond, body, decreasing })
1726 }
1727
1728 fn parse_loop_pattern(&mut self) -> ParseResult<Pattern> {
1731 use crate::ast::stmt::Pattern;
1732
1733 if self.check(&TokenType::LParen) {
1735 self.advance(); let mut identifiers = Vec::new();
1738 loop {
1739 let id = self.expect_identifier()?;
1740 identifiers.push(id);
1741
1742 if self.check(&TokenType::Comma) {
1744 self.advance(); continue;
1746 }
1747 break;
1748 }
1749
1750 if !self.check(&TokenType::RParen) {
1752 return Err(ParseError {
1753 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1754 span: self.current_span(),
1755 });
1756 }
1757 self.advance(); Ok(Pattern::Tuple(identifiers))
1760 } else {
1761 let id = self.expect_identifier()?;
1763 Ok(Pattern::Identifier(id))
1764 }
1765 }
1766
1767 fn parse_repeat_statement(&mut self) -> ParseResult<Stmt<'a>> {
1768 self.advance(); if self.check(&TokenType::For) {
1772 self.advance();
1773 }
1774
1775 let pattern = self.parse_loop_pattern()?;
1777
1778 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1780 self.advance(); let start = self.parse_imperative_expr()?;
1782
1783 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1785 return Err(ParseError {
1786 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1787 span: self.current_span(),
1788 });
1789 }
1790 self.advance();
1791
1792 let end = self.parse_imperative_expr()?;
1793 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1794 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1795 self.advance(); self.parse_imperative_expr()?
1797 } else {
1798 return Err(ParseError {
1799 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1800 span: self.current_span(),
1801 });
1802 };
1803
1804 if !self.check(&TokenType::Colon) {
1806 return Err(ParseError {
1807 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1808 span: self.current_span(),
1809 });
1810 }
1811 self.advance();
1812
1813 if !self.check(&TokenType::Indent) {
1815 return Err(ParseError {
1816 kind: ParseErrorKind::ExpectedStatement,
1817 span: self.current_span(),
1818 });
1819 }
1820 self.advance();
1821
1822 let mut body_stmts = Vec::new();
1824 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1825 let stmt = self.parse_statement()?;
1826 body_stmts.push(stmt);
1827 if self.check(&TokenType::Period) {
1828 self.advance();
1829 }
1830 }
1831
1832 if self.check(&TokenType::Dedent) {
1833 self.advance();
1834 }
1835
1836 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1837 .alloc_slice(body_stmts.into_iter());
1838
1839 Ok(Stmt::Repeat { pattern, iterable, body })
1840 }
1841
1842 fn parse_for_statement(&mut self) -> ParseResult<Stmt<'a>> {
1845 self.advance(); let pattern = self.parse_loop_pattern()?;
1849
1850 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1852 self.advance(); let start = self.parse_imperative_expr()?;
1854
1855 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1857 return Err(ParseError {
1858 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1859 span: self.current_span(),
1860 });
1861 }
1862 self.advance();
1863
1864 let end = self.parse_imperative_expr()?;
1865 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1866 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1867 self.advance(); self.parse_imperative_expr()?
1869 } else {
1870 return Err(ParseError {
1871 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1872 span: self.current_span(),
1873 });
1874 };
1875
1876 if !self.check(&TokenType::Colon) {
1878 return Err(ParseError {
1879 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1880 span: self.current_span(),
1881 });
1882 }
1883 self.advance();
1884
1885 if !self.check(&TokenType::Indent) {
1887 return Err(ParseError {
1888 kind: ParseErrorKind::ExpectedStatement,
1889 span: self.current_span(),
1890 });
1891 }
1892 self.advance();
1893
1894 let mut body_stmts = Vec::new();
1896 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1897 let stmt = self.parse_statement()?;
1898 body_stmts.push(stmt);
1899 if self.check(&TokenType::Period) {
1900 self.advance();
1901 }
1902 }
1903
1904 if self.check(&TokenType::Dedent) {
1905 self.advance();
1906 }
1907
1908 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1909 .alloc_slice(body_stmts.into_iter());
1910
1911 Ok(Stmt::Repeat { pattern, iterable, body })
1912 }
1913
1914 fn parse_call_statement(&mut self) -> ParseResult<Stmt<'a>> {
1915 self.advance(); let function = match &self.peek().kind {
1921 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
1922 let s = *sym;
1923 self.advance();
1924 s
1925 }
1926 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
1927 let s = self.peek().lexeme;
1929 self.advance();
1930 s
1931 }
1932 _ => {
1933 return Err(ParseError {
1934 kind: ParseErrorKind::ExpectedIdentifier,
1935 span: self.current_span(),
1936 });
1937 }
1938 };
1939
1940 let args = if self.check_preposition_is("with") {
1942 self.advance(); self.parse_call_arguments()?
1944 } else {
1945 Vec::new()
1946 };
1947
1948 Ok(Stmt::Call { function, args })
1949 }
1950
1951 fn parse_call_arguments(&mut self) -> ParseResult<Vec<&'a Expr<'a>>> {
1952 let mut args = Vec::new();
1953
1954 let arg = self.parse_call_arg()?;
1956 args.push(arg);
1957
1958 while self.check(&TokenType::And) || self.check(&TokenType::Comma) {
1960 self.advance(); let arg = self.parse_call_arg()?;
1962 args.push(arg);
1963 }
1964
1965 Ok(args)
1966 }
1967
1968 fn parse_call_arg(&mut self) -> ParseResult<&'a Expr<'a>> {
1969 if self.check(&TokenType::Give) {
1971 self.advance(); let value = self.parse_comparison()?;
1973 return Ok(self.ctx.alloc_imperative_expr(Expr::Give { value }));
1974 }
1975
1976 self.parse_comparison()
1979 }
1980
1981 fn parse_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1982 self.parse_or_condition()
1985 }
1986
1987 fn parse_or_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1989 let mut left = self.parse_and_condition()?;
1990
1991 while self.check(&TokenType::Or) || self.check_word("or") {
1992 self.advance();
1993 let right = self.parse_and_condition()?;
1994 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
1995 op: BinaryOpKind::Or,
1996 left,
1997 right,
1998 });
1999 }
2000
2001 Ok(left)
2002 }
2003
2004 fn parse_and_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
2006 let mut left = self.parse_comparison()?;
2007
2008 while self.check(&TokenType::And) || self.check_word("and") {
2009 self.advance();
2010 let right = self.parse_comparison()?;
2011 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
2012 op: BinaryOpKind::And,
2013 left,
2014 right,
2015 });
2016 }
2017
2018 Ok(left)
2019 }
2020
2021 fn parse_comparison(&mut self) -> ParseResult<&'a Expr<'a>> {
2023 if self.check(&TokenType::Not) || self.check_word("not") {
2025 self.advance(); let operand = self.parse_comparison()?; return Ok(self.ctx.alloc_imperative_expr(Expr::Not { operand }));
2028 }
2029
2030 let left = self.parse_xor_expr()?;
2031
2032 let op = if self.check(&TokenType::Equals) {
2034 self.advance();
2035 Some(BinaryOpKind::Eq)
2036 } else if self.check(&TokenType::Identity) {
2037 self.advance();
2039 Some(BinaryOpKind::Eq)
2040 } else if self.check_word("is") {
2041 let saved_pos = self.current;
2043 self.advance(); if self.check_word("greater") {
2046 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
2048 self.advance(); Some(BinaryOpKind::Gt)
2050 } else {
2051 self.current = saved_pos;
2052 None
2053 }
2054 } else if self.check_word("less") {
2055 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
2057 self.advance(); Some(BinaryOpKind::Lt)
2059 } else {
2060 self.current = saved_pos;
2061 None
2062 }
2063 } else if self.check_word("at") {
2064 self.advance(); if self.check_word("least") {
2066 self.advance(); Some(BinaryOpKind::GtEq)
2068 } else if self.check_word("most") {
2069 self.advance(); Some(BinaryOpKind::LtEq)
2071 } else {
2072 self.current = saved_pos;
2073 None
2074 }
2075 } else if self.check_word("not") || self.check(&TokenType::Not) {
2076 self.advance(); Some(BinaryOpKind::NotEq)
2079 } else if self.check_word("equal") {
2080 self.advance(); if self.check_preposition_is("to") {
2083 self.advance(); Some(BinaryOpKind::Eq)
2085 } else {
2086 self.current = saved_pos;
2087 None
2088 }
2089 } else {
2090 self.current = saved_pos;
2091 None
2092 }
2093 } else if self.check(&TokenType::Lt) {
2094 self.advance();
2095 Some(BinaryOpKind::Lt)
2096 } else if self.check(&TokenType::Gt) {
2097 self.advance();
2098 Some(BinaryOpKind::Gt)
2099 } else if self.check(&TokenType::LtEq) {
2100 self.advance();
2101 Some(BinaryOpKind::LtEq)
2102 } else if self.check(&TokenType::GtEq) {
2103 self.advance();
2104 Some(BinaryOpKind::GtEq)
2105 } else if self.check(&TokenType::EqEq) || self.check(&TokenType::Assign) {
2106 self.advance();
2107 Some(BinaryOpKind::Eq)
2108 } else if self.check(&TokenType::NotEq) {
2109 self.advance();
2110 Some(BinaryOpKind::NotEq)
2111 } else {
2112 None
2113 };
2114
2115 if let Some(op) = op {
2116 let right = self.parse_xor_expr()?;
2117 Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp { op, left, right }))
2118 } else {
2119 Ok(left)
2120 }
2121 }
2122
2123 fn parse_let_statement(&mut self) -> ParseResult<Stmt<'a>> {
2124 self.advance(); let mutable = if self.check_mutable_keyword() {
2128 self.advance();
2129 true
2130 } else {
2131 false
2132 };
2133
2134 let var = self.expect_identifier()?;
2136
2137 let ty = if self.check(&TokenType::Colon) {
2139 self.advance(); let type_expr = self.parse_type_expression()?;
2141 Some(self.ctx.alloc_type_expr(type_expr))
2142 } else {
2143 None
2144 };
2145
2146 if !self.check(&TokenType::Be) && !self.check(&TokenType::Assign) {
2148 return Err(ParseError {
2149 kind: ParseErrorKind::ExpectedKeyword { keyword: "be or =".to_string() },
2150 span: self.current_span(),
2151 });
2152 }
2153 self.advance(); if self.check_word("mounted") {
2157 self.advance(); if !self.check(&TokenType::At) && !self.check_preposition_is("at") {
2159 return Err(ParseError {
2160 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2161 span: self.current_span(),
2162 });
2163 }
2164 self.advance(); let path = self.parse_imperative_expr()?;
2166 return Ok(Stmt::Mount { var, path });
2167 }
2168
2169 if self.check_article() {
2171 let saved_pos = self.current;
2172 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = self.peek().kind {
2176 let word = self.interner.resolve(sym).to_lowercase();
2177 if word == "peeragent" {
2178 self.advance(); if self.check(&TokenType::At) || self.check_preposition_is("at") {
2182 self.advance(); let address = self.parse_imperative_expr()?;
2186
2187 return Ok(Stmt::LetPeerAgent { var, address });
2188 }
2189 }
2190 }
2191 self.current = saved_pos;
2193 }
2194
2195 if self.check_article() {
2197 let saved_pos = self.current;
2198 self.advance(); if self.check(&TokenType::Pipe) {
2201 self.advance(); if !self.check_word("of") {
2205 return Err(ParseError {
2206 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
2207 span: self.current_span(),
2208 });
2209 }
2210 self.advance(); let element_type = self.expect_identifier()?;
2214
2215 return Ok(Stmt::CreatePipe { var, element_type, capacity: None });
2218 }
2219 self.current = saved_pos;
2221 }
2222
2223 if self.check(&TokenType::Launch) {
2225 self.advance(); if !self.check_article() {
2229 return Err(ParseError {
2230 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2231 span: self.current_span(),
2232 });
2233 }
2234 self.advance();
2235
2236 if !self.check(&TokenType::Task) {
2238 return Err(ParseError {
2239 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2240 span: self.current_span(),
2241 });
2242 }
2243 self.advance();
2244
2245 if !self.check(&TokenType::To) && !self.check_word("to") {
2247 return Err(ParseError {
2248 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2249 span: self.current_span(),
2250 });
2251 }
2252 self.advance();
2253
2254 let function = self.expect_identifier()?;
2256
2257 let args = if self.check_word("with") {
2259 self.advance();
2260 self.parse_call_arguments()?
2261 } else {
2262 vec![]
2263 };
2264
2265 return Ok(Stmt::LaunchTaskWithHandle { handle: var, function, args });
2266 }
2267
2268 let value = self.parse_imperative_expr()?;
2270
2271 if let Some(declared_ty) = &ty {
2273 if let Some(inferred) = self.infer_literal_type(value) {
2274 if !self.check_type_compatibility(declared_ty, inferred) {
2275 let expected = match declared_ty {
2276 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2277 self.interner.resolve(*sym).to_string()
2278 }
2279 _ => "unknown".to_string(),
2280 };
2281 return Err(ParseError {
2282 kind: ParseErrorKind::TypeMismatch {
2283 expected,
2284 found: inferred.to_string(),
2285 },
2286 span: self.current_span(),
2287 });
2288 }
2289 }
2290 }
2291
2292 let value = if self.check_word("with") {
2294 let saved = self.current;
2295 self.advance(); if self.check_word("capacity") {
2297 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2299 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2300 } else {
2301 self.current = saved; value
2303 }
2304 } else {
2305 value
2306 };
2307
2308 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2310
2311 Ok(Stmt::Let { var, ty, value, mutable })
2312 }
2313
2314 fn check_mutable_keyword(&self) -> bool {
2315 if matches!(self.peek().kind, TokenType::Mut) {
2317 return true;
2318 }
2319 if let TokenType::Noun(sym) | TokenType::Adjective(sym) = self.peek().kind {
2321 let word = self.interner.resolve(sym).to_lowercase();
2322 word == "mutable" || word == "mut"
2323 } else {
2324 false
2325 }
2326 }
2327
2328 fn infer_literal_type(&self, expr: &Expr<'_>) -> Option<&'static str> {
2330 match expr {
2331 Expr::Literal(lit) => match lit {
2332 crate::ast::Literal::Number(_) => Some("Int"),
2333 crate::ast::Literal::Float(_) => Some("Real"),
2334 crate::ast::Literal::Text(_) => Some("Text"),
2335 crate::ast::Literal::Boolean(_) => Some("Bool"),
2336 crate::ast::Literal::Nothing => Some("Unit"),
2337 crate::ast::Literal::Char(_) => Some("Char"),
2338 crate::ast::Literal::Duration(_) => Some("Duration"),
2339 crate::ast::Literal::Date(_) => Some("Date"),
2340 crate::ast::Literal::Moment(_) => Some("Moment"),
2341 crate::ast::Literal::Span { .. } => Some("Span"),
2342 crate::ast::Literal::Time(_) => Some("Time"),
2343 },
2344 _ => None, }
2346 }
2347
2348 fn check_type_compatibility(&self, declared: &TypeExpr<'_>, inferred: &str) -> bool {
2350 match declared {
2351 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2352 let declared_name = self.interner.resolve(*sym);
2353 declared_name.eq_ignore_ascii_case(inferred)
2355 || (declared_name.eq_ignore_ascii_case("Nat") && inferred == "Int")
2356 || (declared_name.eq_ignore_ascii_case("Byte") && inferred == "Int")
2357 }
2358 _ => true, }
2360 }
2361
2362 fn peek_equals_assignment(&self) -> bool {
2369 let is_identifier = matches!(
2373 self.peek().kind,
2374 TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Identifier
2375 | TokenType::Adjective(_) | TokenType::Verb { .. }
2376 | TokenType::Particle(_) | TokenType::Ambiguous { .. }
2377 | TokenType::Pronoun { .. }
2378 );
2379 if !is_identifier {
2380 return false;
2381 }
2382
2383 if self.current + 1 >= self.tokens.len() {
2385 return false;
2386 }
2387
2388 let next = &self.tokens[self.current + 1].kind;
2389
2390 if matches!(next, TokenType::Assign) {
2392 return true;
2393 }
2394
2395 if matches!(next, TokenType::Colon) {
2398 let mut offset = 2;
2399 while self.current + offset < self.tokens.len() {
2400 let tok = &self.tokens[self.current + offset].kind;
2401 if matches!(tok, TokenType::Assign) {
2402 return true;
2403 }
2404 if matches!(tok, TokenType::Period | TokenType::Newline | TokenType::EOF) {
2405 return false;
2406 }
2407 offset += 1;
2408 }
2409 }
2410
2411 false
2412 }
2413
2414 fn parse_equals_assignment(&mut self, explicit_mutable: bool) -> ParseResult<Stmt<'a>> {
2416 if explicit_mutable {
2418 self.advance(); }
2420
2421 let var = self.expect_identifier()?;
2423
2424 let ty = if self.check(&TokenType::Colon) {
2426 self.advance(); let type_expr = self.parse_type_expression()?;
2428 Some(self.ctx.alloc_type_expr(type_expr))
2429 } else {
2430 None
2431 };
2432
2433 if !self.check(&TokenType::Assign) {
2435 return Err(ParseError {
2436 kind: ParseErrorKind::ExpectedKeyword { keyword: "=".to_string() },
2437 span: self.current_span(),
2438 });
2439 }
2440 self.advance(); let value = self.parse_imperative_expr()?;
2444
2445 let value = if self.check_word("with") {
2447 let saved = self.current;
2448 self.advance(); if self.check_word("capacity") {
2450 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2452 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2453 } else {
2454 self.current = saved; value
2456 }
2457 } else {
2458 value
2459 };
2460
2461 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2463
2464 Ok(Stmt::Let { var, ty, value, mutable: explicit_mutable })
2465 }
2466
2467 fn parse_set_statement(&mut self) -> ParseResult<Stmt<'a>> {
2468 use crate::ast::Expr;
2469 self.advance(); let target_expr = self.parse_imperative_expr()?;
2473
2474 let target_expr = if self.check(&TokenType::At) {
2476 self.advance(); let key = self.parse_imperative_expr()?;
2478 self.ctx.alloc_imperative_expr(Expr::Index { collection: target_expr, index: key })
2479 } else {
2480 target_expr
2481 };
2482
2483 let is_to = self.check(&TokenType::To) || matches!(
2485 &self.peek().kind,
2486 TokenType::Preposition(sym) if self.interner.resolve(*sym) == "to"
2487 );
2488 if !is_to {
2489 return Err(ParseError {
2490 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2491 span: self.current_span(),
2492 });
2493 }
2494 self.advance(); let value = self.parse_imperative_expr()?;
2498
2499 match target_expr {
2502 Expr::FieldAccess { object, field } => {
2503 Ok(Stmt::SetField { object: *object, field: *field, value })
2504 }
2505 Expr::Identifier(target) => {
2506 Ok(Stmt::Set { target: *target, value })
2507 }
2508 Expr::Index { collection, index } => {
2509 Ok(Stmt::SetIndex { collection: *collection, index: *index, value })
2510 }
2511 _ => Err(ParseError {
2512 kind: ParseErrorKind::ExpectedIdentifier,
2513 span: self.current_span(),
2514 })
2515 }
2516 }
2517
2518 fn parse_return_statement(&mut self) -> ParseResult<Stmt<'a>> {
2519 self.advance(); if self.check(&TokenType::Period) || self.is_at_end() {
2523 return Ok(Stmt::Return { value: None });
2524 }
2525
2526 let value = self.parse_comparison()?;
2528 Ok(Stmt::Return { value: Some(value) })
2529 }
2530
2531 fn parse_break_statement(&mut self) -> ParseResult<Stmt<'a>> {
2532 self.advance(); Ok(Stmt::Break)
2534 }
2535
2536 fn parse_assert_statement(&mut self) -> ParseResult<Stmt<'a>> {
2537 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2541 self.advance();
2542 }
2543
2544 let condition = self.parse_condition()?;
2547
2548 Ok(Stmt::RuntimeAssert { condition })
2549 }
2550
2551 fn parse_trust_statement(&mut self) -> ParseResult<Stmt<'a>> {
2554 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2558 self.advance();
2559 }
2560
2561 let saved_mode = self.mode;
2563 self.mode = ParserMode::Declarative;
2564
2565 let proposition = self.parse()?;
2567
2568 self.mode = saved_mode;
2570
2571 if !self.check(&TokenType::Because) {
2573 return Err(ParseError {
2574 kind: ParseErrorKind::UnexpectedToken {
2575 expected: TokenType::Because,
2576 found: self.peek().kind.clone(),
2577 },
2578 span: self.current_span(),
2579 });
2580 }
2581 self.advance(); let justification = match &self.peek().kind {
2585 TokenType::StringLiteral(sym) => {
2586 let s = *sym;
2587 self.advance();
2588 s
2589 }
2590 _ => {
2591 return Err(ParseError {
2592 kind: ParseErrorKind::UnexpectedToken {
2593 expected: TokenType::StringLiteral(self.interner.intern("")),
2594 found: self.peek().kind.clone(),
2595 },
2596 span: self.current_span(),
2597 });
2598 }
2599 };
2600
2601 Ok(Stmt::Trust { proposition, justification })
2602 }
2603
2604 fn parse_check_statement(&mut self) -> ParseResult<Stmt<'a>> {
2608 let start_span = self.current_span();
2609 self.advance(); if self.check(&TokenType::That) {
2613 self.advance();
2614 }
2615
2616 if matches!(self.peek().kind, TokenType::Article(_)) {
2618 self.advance();
2619 }
2620
2621 let subject = match &self.peek().kind {
2623 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2624 let s = *sym;
2625 self.advance();
2626 s
2627 }
2628 _ => {
2629 let tok = self.peek();
2631 let s = tok.lexeme;
2632 self.advance();
2633 s
2634 }
2635 };
2636
2637 let is_capability;
2639 let predicate;
2640 let object;
2641
2642 if self.check(&TokenType::Is) || self.check(&TokenType::Are) {
2643 is_capability = false;
2645 self.advance(); predicate = match &self.peek().kind {
2649 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2650 let s = *sym;
2651 self.advance();
2652 s
2653 }
2654 _ => {
2655 let tok = self.peek();
2656 let s = tok.lexeme;
2657 self.advance();
2658 s
2659 }
2660 };
2661 object = None;
2662 } else if self.check(&TokenType::Can) {
2663 is_capability = true;
2665 self.advance(); predicate = match &self.peek().kind {
2669 TokenType::Verb { lemma, .. } => {
2670 let s = *lemma;
2671 self.advance();
2672 s
2673 }
2674 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2675 let s = *sym;
2676 self.advance();
2677 s
2678 }
2679 _ => {
2680 let tok = self.peek();
2681 let s = tok.lexeme;
2682 self.advance();
2683 s
2684 }
2685 };
2686
2687 if matches!(self.peek().kind, TokenType::Article(_)) {
2689 self.advance();
2690 }
2691
2692 let obj = match &self.peek().kind {
2694 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2695 let s = *sym;
2696 self.advance();
2697 s
2698 }
2699 _ => {
2700 let tok = self.peek();
2701 let s = tok.lexeme;
2702 self.advance();
2703 s
2704 }
2705 };
2706 object = Some(obj);
2707 } else {
2708 return Err(ParseError {
2709 kind: ParseErrorKind::ExpectedKeyword { keyword: "is/can".to_string() },
2710 span: self.current_span(),
2711 });
2712 }
2713
2714 let source_text = if is_capability {
2716 let obj_name = self.interner.resolve(object.unwrap());
2717 let pred_name = self.interner.resolve(predicate);
2718 let subj_name = self.interner.resolve(subject);
2719 format!("{} can {} the {}", subj_name, pred_name, obj_name)
2720 } else {
2721 let pred_name = self.interner.resolve(predicate);
2722 let subj_name = self.interner.resolve(subject);
2723 format!("{} is {}", subj_name, pred_name)
2724 };
2725
2726 Ok(Stmt::Check {
2727 subject,
2728 predicate,
2729 is_capability,
2730 object,
2731 source_text,
2732 span: start_span,
2733 })
2734 }
2735
2736 fn parse_listen_statement(&mut self) -> ParseResult<Stmt<'a>> {
2739 self.advance(); if !self.check_preposition_is("on") {
2743 return Err(ParseError {
2744 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2745 span: self.current_span(),
2746 });
2747 }
2748 self.advance(); let address = self.parse_imperative_expr()?;
2752
2753 Ok(Stmt::Listen { address })
2754 }
2755
2756 fn parse_connect_statement(&mut self) -> ParseResult<Stmt<'a>> {
2759 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2763 return Err(ParseError {
2764 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2765 span: self.current_span(),
2766 });
2767 }
2768 self.advance(); let address = self.parse_imperative_expr()?;
2772
2773 Ok(Stmt::ConnectTo { address })
2774 }
2775
2776 fn parse_sleep_statement(&mut self) -> ParseResult<Stmt<'a>> {
2779 self.advance(); let milliseconds = self.parse_imperative_expr()?;
2783
2784 Ok(Stmt::Sleep { milliseconds })
2785 }
2786
2787 fn parse_sync_statement(&mut self) -> ParseResult<Stmt<'a>> {
2790 self.advance(); let var = match &self.tokens[self.current].kind {
2795 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2796 let s = *sym;
2797 self.advance();
2798 s
2799 }
2800 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2801 let s = self.tokens[self.current].lexeme;
2802 self.advance();
2803 s
2804 }
2805 _ => {
2806 return Err(ParseError {
2807 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2808 span: self.current_span(),
2809 });
2810 }
2811 };
2812
2813 if !self.check_preposition_is("on") {
2815 return Err(ParseError {
2816 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2817 span: self.current_span(),
2818 });
2819 }
2820 self.advance(); let topic = self.parse_imperative_expr()?;
2824
2825 Ok(Stmt::Sync { var, topic })
2826 }
2827
2828 fn parse_mount_statement(&mut self) -> ParseResult<Stmt<'a>> {
2832 self.advance(); let var = match &self.tokens[self.current].kind {
2837 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2838 let s = *sym;
2839 self.advance();
2840 s
2841 }
2842 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2843 let s = self.tokens[self.current].lexeme;
2844 self.advance();
2845 s
2846 }
2847 _ => {
2848 return Err(ParseError {
2849 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2850 span: self.current_span(),
2851 });
2852 }
2853 };
2854
2855 if !self.check(&TokenType::At) {
2857 return Err(ParseError {
2858 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2859 span: self.current_span(),
2860 });
2861 }
2862 self.advance(); let path = self.parse_imperative_expr()?;
2866
2867 Ok(Stmt::Mount { var, path })
2868 }
2869
2870 fn lookahead_contains_into(&self) -> bool {
2876 for i in self.current..std::cmp::min(self.current + 5, self.tokens.len()) {
2877 if matches!(self.tokens[i].kind, TokenType::Into) {
2878 return true;
2879 }
2880 }
2881 false
2882 }
2883
2884 fn lookahead_is_first_of(&self) -> bool {
2886 self.current + 3 < self.tokens.len()
2888 && matches!(self.tokens.get(self.current + 1), Some(t) if matches!(t.kind, TokenType::Article(_)))
2889 && self.tokens.get(self.current + 2)
2890 .map(|t| self.interner.resolve(t.lexeme).to_lowercase() == "first")
2891 .unwrap_or(false)
2892 }
2893
2894 fn parse_launch_statement(&mut self) -> ParseResult<Stmt<'a>> {
2897 self.advance(); if !self.check_article() {
2901 return Err(ParseError {
2902 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2903 span: self.current_span(),
2904 });
2905 }
2906 self.advance();
2907
2908 if !self.check(&TokenType::Task) {
2910 return Err(ParseError {
2911 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2912 span: self.current_span(),
2913 });
2914 }
2915 self.advance();
2916
2917 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2919 return Err(ParseError {
2920 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2921 span: self.current_span(),
2922 });
2923 }
2924 self.advance();
2925
2926 let function = match &self.tokens[self.current].kind {
2929 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2930 let s = *sym;
2931 self.advance();
2932 s
2933 }
2934 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2935 let s = self.tokens[self.current].lexeme;
2936 self.advance();
2937 s
2938 }
2939 _ => {
2940 return Err(ParseError {
2941 kind: ParseErrorKind::ExpectedKeyword { keyword: "function name".to_string() },
2942 span: self.current_span(),
2943 });
2944 }
2945 };
2946
2947 let args = if self.check(&TokenType::LParen) {
2949 self.parse_call_arguments()?
2950 } else if self.check_word("with") {
2951 self.advance(); let mut args = Vec::new();
2953 let arg = self.parse_imperative_expr()?;
2954 args.push(arg);
2955 while self.check(&TokenType::And) {
2957 self.advance();
2958 let arg = self.parse_imperative_expr()?;
2959 args.push(arg);
2960 }
2961 args
2962 } else {
2963 Vec::new()
2964 };
2965
2966 Ok(Stmt::LaunchTask { function, args })
2967 }
2968
2969 fn parse_send_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2972 self.advance(); let value = self.parse_imperative_expr()?;
2976
2977 if !self.check(&TokenType::Into) {
2979 return Err(ParseError {
2980 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
2981 span: self.current_span(),
2982 });
2983 }
2984 self.advance();
2985
2986 let pipe = self.parse_imperative_expr()?;
2988
2989 Ok(Stmt::SendPipe { value, pipe })
2990 }
2991
2992 fn parse_receive_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2995 self.advance(); let var = self.expect_identifier()?;
2999
3000 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3002 return Err(ParseError {
3003 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3004 span: self.current_span(),
3005 });
3006 }
3007 self.advance();
3008
3009 let pipe = self.parse_imperative_expr()?;
3011
3012 Ok(Stmt::ReceivePipe { var, pipe })
3013 }
3014
3015 fn parse_try_statement(&mut self) -> ParseResult<Stmt<'a>> {
3018 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3022 return Err(ParseError {
3023 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3024 span: self.current_span(),
3025 });
3026 }
3027 self.advance();
3028
3029 if self.check(&TokenType::Send) {
3031 self.advance(); let value = self.parse_imperative_expr()?;
3033
3034 if !self.check(&TokenType::Into) {
3035 return Err(ParseError {
3036 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
3037 span: self.current_span(),
3038 });
3039 }
3040 self.advance();
3041
3042 let pipe = self.parse_imperative_expr()?;
3043 Ok(Stmt::TrySendPipe { value, pipe, result: None })
3044 } else if self.check(&TokenType::Receive) {
3045 self.advance(); let var = self.expect_identifier()?;
3048
3049 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3050 return Err(ParseError {
3051 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3052 span: self.current_span(),
3053 });
3054 }
3055 self.advance();
3056
3057 let pipe = self.parse_imperative_expr()?;
3058 Ok(Stmt::TryReceivePipe { var, pipe })
3059 } else {
3060 Err(ParseError {
3061 kind: ParseErrorKind::ExpectedKeyword { keyword: "send or receive".to_string() },
3062 span: self.current_span(),
3063 })
3064 }
3065 }
3066
3067 fn parse_escape_body(&mut self) -> ParseResult<(crate::intern::Symbol, crate::intern::Symbol, crate::token::Span)> {
3070 let start_span = self.current_span();
3071 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3075 return Err(ParseError {
3076 kind: ParseErrorKind::Custom(
3077 "Expected 'to' after 'Escape'. Syntax: Escape to Rust:".to_string()
3078 ),
3079 span: self.current_span(),
3080 });
3081 }
3082 self.advance(); let language = match &self.peek().kind {
3086 TokenType::ProperName(sym) => {
3087 let s = *sym;
3088 self.advance();
3089 s
3090 }
3091 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3092 let s = *sym;
3093 self.advance();
3094 s
3095 }
3096 _ => {
3097 return Err(ParseError {
3098 kind: ParseErrorKind::Custom(
3099 "Expected language name after 'Escape to'. Currently only 'Rust' is supported.".to_string()
3100 ),
3101 span: self.current_span(),
3102 });
3103 }
3104 };
3105
3106 if !language.is(self.interner, "Rust") {
3108 let lang_str = self.interner.resolve(language);
3109 return Err(ParseError {
3110 kind: ParseErrorKind::Custom(
3111 format!("Unsupported escape target '{}'. Only 'Rust' is supported.", lang_str)
3112 ),
3113 span: self.current_span(),
3114 });
3115 }
3116
3117 if !self.check(&TokenType::Colon) {
3119 return Err(ParseError {
3120 kind: ParseErrorKind::Custom(
3121 "Expected ':' after 'Escape to Rust'. Syntax: Escape to Rust:".to_string()
3122 ),
3123 span: self.current_span(),
3124 });
3125 }
3126 self.advance(); if !self.check(&TokenType::Indent) {
3130 return Err(ParseError {
3131 kind: ParseErrorKind::Custom(
3132 "Expected indented block after 'Escape to Rust:'.".to_string()
3133 ),
3134 span: self.current_span(),
3135 });
3136 }
3137 self.advance(); let code = match &self.peek().kind {
3141 TokenType::EscapeBlock(sym) => {
3142 let s = *sym;
3143 self.advance();
3144 s
3145 }
3146 _ => {
3147 return Err(ParseError {
3148 kind: ParseErrorKind::Custom(
3149 "Escape block body is empty or malformed.".to_string()
3150 ),
3151 span: self.current_span(),
3152 });
3153 }
3154 };
3155
3156 if self.check(&TokenType::Dedent) {
3158 self.advance();
3159 }
3160
3161 let end_span = self.previous().span;
3162 Ok((language, code, crate::token::Span::new(start_span.start, end_span.end)))
3163 }
3164
3165 fn parse_escape_statement(&mut self) -> ParseResult<Stmt<'a>> {
3167 let (language, code, span) = self.parse_escape_body()?;
3168 Ok(Stmt::Escape { language, code, span })
3169 }
3170
3171 fn parse_escape_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
3174 let (language, code, _span) = self.parse_escape_body()?;
3175 Ok(self.ctx.alloc_imperative_expr(Expr::Escape { language, code }))
3176 }
3177
3178 fn parse_requires_block(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
3181 let mut deps = Vec::new();
3182
3183 loop {
3184 if self.is_at_end() {
3186 break;
3187 }
3188 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
3189 break;
3190 }
3191
3192 if self.check(&TokenType::Indent)
3194 || self.check(&TokenType::Dedent)
3195 || self.check(&TokenType::Newline)
3196 {
3197 self.advance();
3198 continue;
3199 }
3200
3201 if matches!(self.peek().kind, TokenType::Article(_)) {
3203 let dep = self.parse_require_line()?;
3204 deps.push(dep);
3205 continue;
3206 }
3207
3208 self.advance();
3210 }
3211
3212 Ok(deps)
3213 }
3214
3215 fn parse_require_line(&mut self) -> ParseResult<Stmt<'a>> {
3218 let start_span = self.current_span();
3219
3220 if !matches!(self.peek().kind, TokenType::Article(_)) {
3222 return Err(crate::error::ParseError {
3223 kind: crate::error::ParseErrorKind::Custom(
3224 "Expected 'The' to begin a dependency declaration.".to_string(),
3225 ),
3226 span: self.current_span(),
3227 });
3228 }
3229 self.advance(); let crate_name = if let TokenType::StringLiteral(sym) = self.peek().kind {
3233 let s = sym;
3234 self.advance();
3235 s
3236 } else {
3237 return Err(crate::error::ParseError {
3238 kind: crate::error::ParseErrorKind::Custom(
3239 "Expected a string literal for the crate name, e.g. \"serde\".".to_string(),
3240 ),
3241 span: self.current_span(),
3242 });
3243 };
3244
3245 if !self.check_word("crate") {
3247 return Err(crate::error::ParseError {
3248 kind: crate::error::ParseErrorKind::Custom(
3249 "Expected the word 'crate' after the crate name.".to_string(),
3250 ),
3251 span: self.current_span(),
3252 });
3253 }
3254 self.advance(); if !self.check_word("version") {
3258 return Err(crate::error::ParseError {
3259 kind: crate::error::ParseErrorKind::Custom(
3260 "Expected 'version' after 'crate'.".to_string(),
3261 ),
3262 span: self.current_span(),
3263 });
3264 }
3265 self.advance(); let version = if let TokenType::StringLiteral(sym) = self.peek().kind {
3269 let s = sym;
3270 self.advance();
3271 s
3272 } else {
3273 return Err(crate::error::ParseError {
3274 kind: crate::error::ParseErrorKind::Custom(
3275 "Expected a string literal for the version, e.g. \"1.0\".".to_string(),
3276 ),
3277 span: self.current_span(),
3278 });
3279 };
3280
3281 let mut features = Vec::new();
3283 if self.check_preposition_is("with") {
3284 self.advance(); if !self.check_word("features") {
3288 return Err(crate::error::ParseError {
3289 kind: crate::error::ParseErrorKind::Custom(
3290 "Expected 'features' after 'with'.".to_string(),
3291 ),
3292 span: self.current_span(),
3293 });
3294 }
3295 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3299 features.push(sym);
3300 self.advance();
3301 } else {
3302 return Err(crate::error::ParseError {
3303 kind: crate::error::ParseErrorKind::Custom(
3304 "Expected a string literal for a feature name.".to_string(),
3305 ),
3306 span: self.current_span(),
3307 });
3308 }
3309
3310 while self.check(&TokenType::And) {
3312 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3314 features.push(sym);
3315 self.advance();
3316 } else {
3317 return Err(crate::error::ParseError {
3318 kind: crate::error::ParseErrorKind::Custom(
3319 "Expected a string literal for a feature name after 'and'.".to_string(),
3320 ),
3321 span: self.current_span(),
3322 });
3323 }
3324 }
3325 }
3326
3327 if self.check(&TokenType::For) {
3329 self.advance(); while !self.check(&TokenType::Period) && !self.check(&TokenType::EOF)
3331 && !self.check(&TokenType::Newline)
3332 && !matches!(self.peek().kind, TokenType::BlockHeader { .. })
3333 {
3334 self.advance();
3335 }
3336 }
3337
3338 if self.check(&TokenType::Period) {
3340 self.advance();
3341 }
3342
3343 let end_span = self.previous().span;
3344
3345 Ok(Stmt::Require {
3346 crate_name,
3347 version,
3348 features,
3349 span: crate::token::Span::new(start_span.start, end_span.end),
3350 })
3351 }
3352
3353 fn parse_stop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3356 self.advance(); let handle = self.parse_imperative_expr()?;
3359
3360 Ok(Stmt::StopTask { handle })
3361 }
3362
3363 fn parse_select_statement(&mut self) -> ParseResult<Stmt<'a>> {
3371 use crate::ast::stmt::SelectBranch;
3372
3373 self.advance(); if !self.check_article() {
3377 return Err(ParseError {
3378 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
3379 span: self.current_span(),
3380 });
3381 }
3382 self.advance();
3383
3384 if !self.check_word("first") {
3386 return Err(ParseError {
3387 kind: ParseErrorKind::ExpectedKeyword { keyword: "first".to_string() },
3388 span: self.current_span(),
3389 });
3390 }
3391 self.advance();
3392
3393 if !self.check_preposition_is("of") {
3395 return Err(ParseError {
3396 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3397 span: self.current_span(),
3398 });
3399 }
3400 self.advance();
3401
3402 if !self.check(&TokenType::Colon) {
3404 return Err(ParseError {
3405 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3406 span: self.current_span(),
3407 });
3408 }
3409 self.advance();
3410
3411 if !self.check(&TokenType::Indent) {
3413 return Err(ParseError {
3414 kind: ParseErrorKind::ExpectedStatement,
3415 span: self.current_span(),
3416 });
3417 }
3418 self.advance();
3419
3420 let mut branches = Vec::new();
3422 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3423 let branch = self.parse_select_branch()?;
3424 branches.push(branch);
3425 }
3426
3427 if self.check(&TokenType::Dedent) {
3429 self.advance();
3430 }
3431
3432 Ok(Stmt::Select { branches })
3433 }
3434
3435 fn parse_select_branch(&mut self) -> ParseResult<crate::ast::stmt::SelectBranch<'a>> {
3437 use crate::ast::stmt::SelectBranch;
3438
3439 if self.check(&TokenType::Receive) {
3440 self.advance(); let var = match &self.tokens[self.current].kind {
3443 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3444 let s = *sym;
3445 self.advance();
3446 s
3447 }
3448 _ => {
3449 return Err(ParseError {
3450 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
3451 span: self.current_span(),
3452 });
3453 }
3454 };
3455
3456 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3457 return Err(ParseError {
3458 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3459 span: self.current_span(),
3460 });
3461 }
3462 self.advance();
3463
3464 let pipe = self.parse_imperative_expr()?;
3465
3466 if !self.check(&TokenType::Colon) {
3468 return Err(ParseError {
3469 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3470 span: self.current_span(),
3471 });
3472 }
3473 self.advance();
3474
3475 let body = self.parse_indented_block()?;
3477
3478 Ok(SelectBranch::Receive { var, pipe, body })
3479 } else if self.check_word("after") {
3480 self.advance(); let milliseconds = self.parse_imperative_expr()?;
3483
3484 if self.check_word("seconds") || self.check_word("milliseconds") {
3486 self.advance();
3487 }
3488
3489 if !self.check(&TokenType::Colon) {
3491 return Err(ParseError {
3492 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3493 span: self.current_span(),
3494 });
3495 }
3496 self.advance();
3497
3498 let body = self.parse_indented_block()?;
3500
3501 Ok(SelectBranch::Timeout { milliseconds, body })
3502 } else {
3503 Err(ParseError {
3504 kind: ParseErrorKind::ExpectedKeyword { keyword: "Receive or After".to_string() },
3505 span: self.current_span(),
3506 })
3507 }
3508 }
3509
3510 fn parse_indented_block(&mut self) -> ParseResult<crate::ast::stmt::Block<'a>> {
3512 if !self.check(&TokenType::Indent) {
3514 return Err(ParseError {
3515 kind: ParseErrorKind::ExpectedStatement,
3516 span: self.current_span(),
3517 });
3518 }
3519 self.advance();
3520
3521 let mut stmts = Vec::new();
3522 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3523 let stmt = self.parse_statement()?;
3524 stmts.push(stmt);
3525 if self.check(&TokenType::Period) {
3526 self.advance();
3527 }
3528 }
3529
3530 if self.check(&TokenType::Dedent) {
3532 self.advance();
3533 }
3534
3535 let block = self.ctx.stmts.expect("imperative arenas not initialized")
3536 .alloc_slice(stmts.into_iter());
3537
3538 Ok(block)
3539 }
3540
3541 fn parse_give_statement(&mut self) -> ParseResult<Stmt<'a>> {
3542 self.advance(); let object = self.parse_imperative_expr()?;
3546
3547 if !self.check_to_preposition() {
3549 return Err(ParseError {
3550 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3551 span: self.current_span(),
3552 });
3553 }
3554 self.advance(); let recipient = self.parse_imperative_expr()?;
3558
3559 if let Expr::Identifier(sym) = object {
3561 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Moved);
3562 }
3563
3564 Ok(Stmt::Give { object, recipient })
3565 }
3566
3567 fn parse_show_statement(&mut self) -> ParseResult<Stmt<'a>> {
3568 self.advance(); let object = self.parse_condition()?;
3573
3574 let recipient = if self.check_to_preposition() {
3578 self.advance(); if self.check_article() {
3583 self.advance(); }
3585 if self.check(&TokenType::Console) {
3586 self.advance(); let show_sym = self.interner.intern("show");
3588 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3589 } else {
3590 self.parse_imperative_expr()?
3592 }
3593 } else {
3594 let show_sym = self.interner.intern("show");
3596 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3597 };
3598
3599 if let Expr::Identifier(sym) = object {
3601 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Borrowed);
3602 }
3603
3604 Ok(Stmt::Show { object, recipient })
3605 }
3606
3607 fn parse_push_statement(&mut self) -> ParseResult<Stmt<'a>> {
3610 self.advance(); let value = self.parse_imperative_expr()?;
3614
3615 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3617 return Err(ParseError {
3618 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3619 span: self.current_span(),
3620 });
3621 }
3622 self.advance(); let collection = self.parse_imperative_expr()?;
3626
3627 Ok(Stmt::Push { value, collection })
3628 }
3629
3630 fn parse_pop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3633 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3637 return Err(ParseError {
3638 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3639 span: self.current_span(),
3640 });
3641 }
3642 self.advance(); let collection = self.parse_imperative_expr()?;
3646
3647 let into = if self.check(&TokenType::Into) || self.check_preposition_is("into") {
3649 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = &self.peek().kind {
3653 let sym = *sym;
3654 self.advance();
3655 Some(sym)
3656 } else if let Some(token) = self.tokens.get(self.current) {
3657 let sym = token.lexeme;
3659 self.advance();
3660 Some(sym)
3661 } else {
3662 return Err(ParseError {
3663 kind: ParseErrorKind::ExpectedIdentifier,
3664 span: self.current_span(),
3665 });
3666 }
3667 } else {
3668 None
3669 };
3670
3671 Ok(Stmt::Pop { collection, into })
3672 }
3673
3674 fn parse_add_statement(&mut self) -> ParseResult<Stmt<'a>> {
3677 self.advance(); let value = self.parse_imperative_expr()?;
3681
3682 if !self.check_preposition_is("to") && !self.check(&TokenType::To) {
3684 return Err(ParseError {
3685 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3686 span: self.current_span(),
3687 });
3688 }
3689 self.advance(); let collection = self.parse_imperative_expr()?;
3693
3694 Ok(Stmt::Add { value, collection })
3695 }
3696
3697 fn parse_remove_statement(&mut self) -> ParseResult<Stmt<'a>> {
3700 self.advance(); let value = self.parse_imperative_expr()?;
3704
3705 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3707 return Err(ParseError {
3708 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3709 span: self.current_span(),
3710 });
3711 }
3712 self.advance(); let collection = self.parse_imperative_expr()?;
3716
3717 Ok(Stmt::Remove { value, collection })
3718 }
3719
3720 fn parse_read_statement(&mut self) -> ParseResult<Stmt<'a>> {
3724 self.advance(); let var = self.expect_identifier()?;
3728
3729 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3731 return Err(ParseError {
3732 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3733 span: self.current_span(),
3734 });
3735 }
3736 self.advance(); if self.check_article() {
3740 self.advance();
3741 }
3742
3743 let source = if self.check(&TokenType::Console) {
3745 self.advance(); ReadSource::Console
3747 } else if self.check(&TokenType::File) {
3748 self.advance(); let path = self.parse_imperative_expr()?;
3750 ReadSource::File(path)
3751 } else {
3752 return Err(ParseError {
3753 kind: ParseErrorKind::ExpectedKeyword { keyword: "console or file".to_string() },
3754 span: self.current_span(),
3755 });
3756 };
3757
3758 Ok(Stmt::ReadFrom { var, source })
3759 }
3760
3761 fn parse_write_statement(&mut self) -> ParseResult<Stmt<'a>> {
3764 self.advance(); let content = self.parse_imperative_expr()?;
3768
3769 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3771 return Err(ParseError {
3772 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3773 span: self.current_span(),
3774 });
3775 }
3776 self.advance(); if !self.check(&TokenType::File) {
3780 return Err(ParseError {
3781 kind: ParseErrorKind::ExpectedKeyword { keyword: "file".to_string() },
3782 span: self.current_span(),
3783 });
3784 }
3785 self.advance(); let path = self.parse_imperative_expr()?;
3789
3790 Ok(Stmt::WriteFile { content, path })
3791 }
3792
3793 fn parse_zone_statement(&mut self) -> ParseResult<Stmt<'a>> {
3799 self.advance(); if self.check_article() {
3803 self.advance();
3804 }
3805
3806 if self.check(&TokenType::New) {
3808 self.advance();
3809 }
3810
3811 if !self.check(&TokenType::Zone) {
3813 return Err(ParseError {
3814 kind: ParseErrorKind::ExpectedKeyword { keyword: "zone".to_string() },
3815 span: self.current_span(),
3816 });
3817 }
3818 self.advance(); if !self.check(&TokenType::Called) {
3822 return Err(ParseError {
3823 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
3824 span: self.current_span(),
3825 });
3826 }
3827 self.advance(); let name = match &self.peek().kind {
3831 TokenType::StringLiteral(sym) => {
3832 let s = *sym;
3833 self.advance();
3834 s
3835 }
3836 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3837 let s = *sym;
3838 self.advance();
3839 s
3840 }
3841 _ => {
3842 let token = self.peek().clone();
3844 self.advance();
3845 token.lexeme
3846 }
3847 };
3848
3849 let mut capacity = None;
3850 let mut source_file = None;
3851
3852 if self.check(&TokenType::Mapped) {
3854 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3858 return Err(ParseError {
3859 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3860 span: self.current_span(),
3861 });
3862 }
3863 self.advance(); if let TokenType::StringLiteral(path) = &self.peek().kind {
3867 source_file = Some(*path);
3868 self.advance();
3869 } else {
3870 return Err(ParseError {
3871 kind: ParseErrorKind::ExpectedKeyword { keyword: "file path string".to_string() },
3872 span: self.current_span(),
3873 });
3874 }
3875 }
3876 else if self.check_of_preposition() {
3878 self.advance(); if !self.check(&TokenType::Size) {
3882 return Err(ParseError {
3883 kind: ParseErrorKind::ExpectedKeyword { keyword: "size".to_string() },
3884 span: self.current_span(),
3885 });
3886 }
3887 self.advance(); let size_value = match &self.peek().kind {
3891 TokenType::Number(sym) => {
3892 let num_str = self.interner.resolve(*sym);
3893 let val = num_str.replace('_', "").parse::<usize>().unwrap_or(0);
3894 self.advance();
3895 val
3896 }
3897 TokenType::Cardinal(n) => {
3898 let val = *n as usize;
3899 self.advance();
3900 val
3901 }
3902 _ => {
3903 return Err(ParseError {
3904 kind: ParseErrorKind::ExpectedNumber,
3905 span: self.current_span(),
3906 });
3907 }
3908 };
3909
3910 let unit_multiplier = self.parse_size_unit()?;
3912 capacity = Some(size_value * unit_multiplier);
3913 }
3914
3915 if !self.check(&TokenType::Colon) {
3917 return Err(ParseError {
3918 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3919 span: self.current_span(),
3920 });
3921 }
3922 self.advance(); if !self.check(&TokenType::Indent) {
3926 return Err(ParseError {
3927 kind: ParseErrorKind::ExpectedStatement,
3928 span: self.current_span(),
3929 });
3930 }
3931 self.advance(); let mut body_stmts = Vec::new();
3935 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3936 let stmt = self.parse_statement()?;
3937 body_stmts.push(stmt);
3938 if self.check(&TokenType::Period) {
3939 self.advance();
3940 }
3941 }
3942
3943 if self.check(&TokenType::Dedent) {
3945 self.advance();
3946 }
3947
3948 let body = self.ctx.stmts.expect("imperative arenas not initialized")
3949 .alloc_slice(body_stmts.into_iter());
3950
3951 Ok(Stmt::Zone { name, capacity, source_file, body })
3952 }
3953
3954 fn parse_size_unit(&mut self) -> ParseResult<usize> {
3956 let token = self.peek().clone();
3957 let unit_str = self.interner.resolve(token.lexeme).to_uppercase();
3958 self.advance();
3959
3960 match unit_str.as_str() {
3961 "B" | "BYTES" | "BYTE" => Ok(1),
3962 "KB" | "KILOBYTE" | "KILOBYTES" => Ok(1024),
3963 "MB" | "MEGABYTE" | "MEGABYTES" => Ok(1024 * 1024),
3964 "GB" | "GIGABYTE" | "GIGABYTES" => Ok(1024 * 1024 * 1024),
3965 _ => Err(ParseError {
3966 kind: ParseErrorKind::ExpectedKeyword {
3967 keyword: "size unit (B, KB, MB, GB)".to_string(),
3968 },
3969 span: token.span,
3970 }),
3971 }
3972 }
3973
3974 fn parse_concurrent_block(&mut self) -> ParseResult<Stmt<'a>> {
3983 self.advance(); if !self.check(&TokenType::All) {
3987 return Err(ParseError {
3988 kind: ParseErrorKind::ExpectedKeyword { keyword: "all".to_string() },
3989 span: self.current_span(),
3990 });
3991 }
3992 self.advance(); if !self.check_of_preposition() {
3996 return Err(ParseError {
3997 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3998 span: self.current_span(),
3999 });
4000 }
4001 self.advance(); if !self.check_article() {
4005 return Err(ParseError {
4006 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
4007 span: self.current_span(),
4008 });
4009 }
4010 self.advance(); if !self.check(&TokenType::Following) {
4014 return Err(ParseError {
4015 kind: ParseErrorKind::ExpectedKeyword { keyword: "following".to_string() },
4016 span: self.current_span(),
4017 });
4018 }
4019 self.advance(); if !self.check(&TokenType::Colon) {
4023 return Err(ParseError {
4024 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4025 span: self.current_span(),
4026 });
4027 }
4028 self.advance(); if !self.check(&TokenType::Indent) {
4032 return Err(ParseError {
4033 kind: ParseErrorKind::ExpectedStatement,
4034 span: self.current_span(),
4035 });
4036 }
4037 self.advance(); let mut task_stmts = Vec::new();
4041 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4042 let stmt = self.parse_statement()?;
4043 task_stmts.push(stmt);
4044 if self.check(&TokenType::Period) {
4045 self.advance();
4046 }
4047 }
4048
4049 if self.check(&TokenType::Dedent) {
4051 self.advance();
4052 }
4053
4054 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
4055 .alloc_slice(task_stmts.into_iter());
4056
4057 Ok(Stmt::Concurrent { tasks })
4058 }
4059
4060 fn parse_parallel_block(&mut self) -> ParseResult<Stmt<'a>> {
4069 self.advance(); if !self.check(&TokenType::Colon) {
4073 return Err(ParseError {
4074 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4075 span: self.current_span(),
4076 });
4077 }
4078 self.advance(); if !self.check(&TokenType::Indent) {
4082 return Err(ParseError {
4083 kind: ParseErrorKind::ExpectedStatement,
4084 span: self.current_span(),
4085 });
4086 }
4087 self.advance(); let mut task_stmts = Vec::new();
4091 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4092 let stmt = self.parse_statement()?;
4093 task_stmts.push(stmt);
4094 if self.check(&TokenType::Period) {
4095 self.advance();
4096 }
4097 }
4098
4099 if self.check(&TokenType::Dedent) {
4101 self.advance();
4102 }
4103
4104 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
4105 .alloc_slice(task_stmts.into_iter());
4106
4107 Ok(Stmt::Parallel { tasks })
4108 }
4109
4110 fn parse_inspect_statement(&mut self) -> ParseResult<Stmt<'a>> {
4117 self.advance(); let target = self.parse_imperative_expr()?;
4121
4122 if !self.check(&TokenType::Colon) {
4124 return Err(ParseError {
4125 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4126 span: self.current_span(),
4127 });
4128 }
4129 self.advance(); if !self.check(&TokenType::Indent) {
4133 return Err(ParseError {
4134 kind: ParseErrorKind::ExpectedStatement,
4135 span: self.current_span(),
4136 });
4137 }
4138 self.advance(); let mut arms = Vec::new();
4141 let mut has_otherwise = false;
4142
4143 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4145 if self.check(&TokenType::Otherwise) {
4146 self.advance(); if !self.check(&TokenType::Colon) {
4150 return Err(ParseError {
4151 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4152 span: self.current_span(),
4153 });
4154 }
4155 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4159 self.advance(); let mut stmts = Vec::new();
4161 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4162 let stmt = self.parse_statement()?;
4163 stmts.push(stmt);
4164 if self.check(&TokenType::Period) {
4165 self.advance();
4166 }
4167 }
4168 if self.check(&TokenType::Dedent) {
4169 self.advance();
4170 }
4171 stmts
4172 } else {
4173 let stmt = self.parse_statement()?;
4175 if self.check(&TokenType::Period) {
4176 self.advance();
4177 }
4178 vec![stmt]
4179 };
4180
4181 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4182 .alloc_slice(body_stmts.into_iter());
4183
4184 arms.push(MatchArm { enum_name: None, variant: None, bindings: vec![], body });
4185 has_otherwise = true;
4186 break;
4187 }
4188
4189 if self.check(&TokenType::If) {
4190 let arm = self.parse_match_arm()?;
4192 arms.push(arm);
4193 } else if self.check(&TokenType::When) || self.check_word("When") {
4194 let arm = self.parse_when_arm()?;
4196 arms.push(arm);
4197 } else if self.check(&TokenType::Newline) {
4198 self.advance();
4200 } else {
4201 self.advance();
4203 }
4204 }
4205
4206 if self.check(&TokenType::Dedent) {
4208 self.advance();
4209 }
4210
4211 Ok(Stmt::Inspect { target, arms, has_otherwise })
4212 }
4213
4214 fn parse_match_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4216 self.advance(); if !self.check_word("it") {
4220 return Err(ParseError {
4221 kind: ParseErrorKind::ExpectedKeyword { keyword: "it".to_string() },
4222 span: self.current_span(),
4223 });
4224 }
4225 self.advance(); if !self.check(&TokenType::Is) {
4229 return Err(ParseError {
4230 kind: ParseErrorKind::ExpectedKeyword { keyword: "is".to_string() },
4231 span: self.current_span(),
4232 });
4233 }
4234 self.advance(); if self.check_article() {
4238 self.advance();
4239 }
4240
4241 let variant = self.expect_identifier()?;
4243
4244 let enum_name = self.find_variant(variant);
4246
4247 let bindings = if self.check(&TokenType::LParen) {
4249 self.parse_pattern_bindings()?
4250 } else {
4251 vec![]
4252 };
4253
4254 if !self.check(&TokenType::Colon) {
4256 return Err(ParseError {
4257 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4258 span: self.current_span(),
4259 });
4260 }
4261 self.advance(); if !self.check(&TokenType::Indent) {
4265 return Err(ParseError {
4266 kind: ParseErrorKind::ExpectedStatement,
4267 span: self.current_span(),
4268 });
4269 }
4270 self.advance(); let mut body_stmts = Vec::new();
4274 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4275 let stmt = self.parse_statement()?;
4276 body_stmts.push(stmt);
4277 if self.check(&TokenType::Period) {
4278 self.advance();
4279 }
4280 }
4281
4282 if self.check(&TokenType::Dedent) {
4284 self.advance();
4285 }
4286
4287 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4288 .alloc_slice(body_stmts.into_iter());
4289
4290 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4291 }
4292
4293 fn parse_when_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4295 self.advance(); let variant = self.expect_identifier()?;
4299
4300 let (enum_name, variant_fields) = self.type_registry
4302 .as_ref()
4303 .and_then(|r| r.find_variant(variant).map(|(enum_name, vdef)| {
4304 let fields: Vec<_> = vdef.fields.iter().map(|f| f.name).collect();
4305 (Some(enum_name), fields)
4306 }))
4307 .unwrap_or((None, vec![]));
4308
4309 let bindings = if self.check(&TokenType::LParen) {
4311 let raw_bindings = self.parse_when_bindings()?;
4312 raw_bindings.into_iter().enumerate().map(|(i, binding)| {
4314 let field = variant_fields.get(i).copied().unwrap_or(binding);
4315 (field, binding)
4316 }).collect()
4317 } else {
4318 vec![]
4319 };
4320
4321 if !self.check(&TokenType::Colon) {
4323 return Err(ParseError {
4324 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4325 span: self.current_span(),
4326 });
4327 }
4328 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4332 self.advance(); let mut stmts = Vec::new();
4334 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4335 let stmt = self.parse_statement()?;
4336 stmts.push(stmt);
4337 if self.check(&TokenType::Period) {
4338 self.advance();
4339 }
4340 }
4341 if self.check(&TokenType::Dedent) {
4342 self.advance();
4343 }
4344 stmts
4345 } else {
4346 let stmt = self.parse_statement()?;
4348 if self.check(&TokenType::Period) {
4349 self.advance();
4350 }
4351 vec![stmt]
4352 };
4353
4354 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4355 .alloc_slice(body_stmts.into_iter());
4356
4357 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4358 }
4359
4360 fn parse_when_bindings(&mut self) -> ParseResult<Vec<Symbol>> {
4362 self.advance(); let mut bindings = Vec::new();
4364
4365 loop {
4366 let binding = self.expect_identifier()?;
4367 bindings.push(binding);
4368
4369 if !self.check(&TokenType::Comma) {
4370 break;
4371 }
4372 self.advance(); }
4374
4375 if !self.check(&TokenType::RParen) {
4376 return Err(ParseError {
4377 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4378 span: self.current_span(),
4379 });
4380 }
4381 self.advance(); Ok(bindings)
4384 }
4385
4386 fn parse_pattern_bindings(&mut self) -> ParseResult<Vec<(Symbol, Symbol)>> {
4388 self.advance(); let mut bindings = Vec::new();
4390
4391 loop {
4392 let field = self.expect_identifier()?;
4393 let binding = if self.check(&TokenType::Colon) {
4394 self.advance(); self.expect_identifier()?
4396 } else {
4397 field };
4399 bindings.push((field, binding));
4400
4401 if !self.check(&TokenType::Comma) {
4402 break;
4403 }
4404 self.advance(); }
4406
4407 if !self.check(&TokenType::RParen) {
4408 return Err(ParseError {
4409 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4410 span: self.current_span(),
4411 });
4412 }
4413 self.advance(); Ok(bindings)
4416 }
4417
4418 fn parse_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4422 use crate::ast::Expr;
4423 let mut fields = Vec::new();
4424
4425 self.advance();
4427
4428 loop {
4429 let field_name = self.expect_identifier()?;
4431
4432 let value = self.parse_comparison()?;
4435
4436 fields.push((field_name, value));
4437
4438 if self.check(&TokenType::And) {
4440 self.advance(); continue;
4442 }
4443 break;
4444 }
4445
4446 Ok(fields)
4447 }
4448
4449 fn parse_variant_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4451 self.parse_constructor_fields()
4452 }
4453
4454 fn parse_struct_init_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4456 self.parse_constructor_fields()
4457 }
4458
4459 fn parse_generic_type_args(&mut self, type_name: Symbol) -> ParseResult<Vec<TypeExpr<'a>>> {
4463 if !self.is_generic_type(type_name) {
4465 return Ok(vec![]);
4466 }
4467
4468 if !self.check_preposition_is("of") {
4470 return Ok(vec![]); }
4472 self.advance(); let mut type_args = Vec::new();
4475 loop {
4476 let type_arg = self.parse_type_expression()?;
4478 type_args.push(type_arg);
4479
4480 if self.check(&TokenType::And) || self.check_to_preposition() {
4482 self.advance(); continue;
4484 }
4485 break;
4486 }
4487
4488 Ok(type_args)
4489 }
4490
4491 fn skip_type_def_content(&mut self) {
4495 while !self.is_at_end() {
4496 if matches!(
4498 self.tokens.get(self.current),
4499 Some(Token { kind: TokenType::BlockHeader { .. }, .. })
4500 ) {
4501 break;
4502 }
4503 self.advance();
4504 }
4505 }
4506
4507 fn parse_theorem_block(&mut self) -> ParseResult<Stmt<'a>> {
4515 use crate::ast::theorem::{TheoremBlock, ProofStrategy};
4516
4517 self.skip_whitespace_tokens();
4519
4520 if self.check(&TokenType::Colon) {
4525 self.advance();
4526 }
4527
4528 self.skip_whitespace_tokens();
4530
4531 let name = if let Some(token) = self.tokens.get(self.current) {
4533 match &token.kind {
4534 TokenType::Noun(_)
4535 | TokenType::ProperName(_)
4536 | TokenType::Verb { .. }
4537 | TokenType::Adjective(_) => {
4538 let name = self.interner.resolve(token.lexeme).to_string();
4539 self.advance();
4540 name
4541 }
4542 _ => {
4543 let lexeme = self.interner.resolve(token.lexeme);
4545 if !lexeme.is_empty() && lexeme.chars().next().map(|c| c.is_alphanumeric()).unwrap_or(false) {
4546 let name = lexeme.to_string();
4547 self.advance();
4548 name
4549 } else {
4550 "Anonymous".to_string()
4551 }
4552 }
4553 }
4554 } else {
4555 "Anonymous".to_string()
4556 };
4557
4558 self.skip_whitespace_tokens();
4559
4560 if self.check(&TokenType::Period) {
4562 self.advance();
4563 }
4564
4565 self.skip_whitespace_tokens();
4566
4567 let mut premises = Vec::new();
4570 while self.check(&TokenType::Given) {
4571 self.advance(); if self.check(&TokenType::Colon) {
4575 self.advance();
4576 }
4577
4578 self.skip_whitespace_tokens();
4579
4580 let premise_expr = self.parse_sentence()?;
4582 premises.push(premise_expr);
4583
4584 self.world_state.end_sentence();
4587
4588 if self.check(&TokenType::Period) {
4590 self.advance();
4591 }
4592
4593 self.skip_whitespace_tokens();
4594 }
4595
4596 let goal = if self.check(&TokenType::Prove) {
4598 self.advance(); if self.check(&TokenType::Colon) {
4601 self.advance();
4602 }
4603
4604 self.skip_whitespace_tokens();
4605
4606 let goal_expr = self.parse_sentence()?;
4607
4608 if self.check(&TokenType::Period) {
4609 self.advance();
4610 }
4611
4612 goal_expr
4613 } else {
4614 return Err(ParseError {
4615 kind: ParseErrorKind::ExpectedKeyword { keyword: "Prove".to_string() },
4616 span: self.current_span(),
4617 });
4618 };
4619
4620 self.skip_whitespace_tokens();
4621
4622 let strategy = if self.check(&TokenType::BlockHeader { block_type: crate::token::BlockType::Proof }) {
4624 self.advance();
4625 self.skip_whitespace_tokens();
4626
4627 if self.check(&TokenType::Colon) {
4628 self.advance();
4629 }
4630
4631 self.skip_whitespace_tokens();
4632
4633 if self.check(&TokenType::Auto) {
4634 self.advance();
4635 ProofStrategy::Auto
4636 } else {
4637 ProofStrategy::Auto
4639 }
4640 } else {
4641 ProofStrategy::Auto
4643 };
4644
4645 if self.check(&TokenType::Period) {
4647 self.advance();
4648 }
4649
4650 let theorem = TheoremBlock {
4651 name,
4652 premises,
4653 goal,
4654 strategy,
4655 };
4656
4657 Ok(Stmt::Theorem(theorem))
4658 }
4659
4660 fn skip_whitespace_tokens(&mut self) {
4662 while self.check(&TokenType::Newline) || self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) {
4663 self.advance();
4664 }
4665 }
4666
4667 fn parse_function_def(&mut self) -> ParseResult<Stmt<'a>> {
4672 self.parse_function_def_with_flags(HashSet::new())
4673 }
4674
4675 fn parse_function_def_with_flags(&mut self, opt_flags: HashSet<OptFlag>) -> ParseResult<Stmt<'a>> {
4677 if self.check(&TokenType::To) || self.check_preposition_is("to") {
4679 self.advance();
4680 }
4681
4682 let mut is_native = if self.check(&TokenType::Native) {
4684 self.advance(); true
4686 } else {
4687 false
4688 };
4689
4690 let name = self.expect_identifier()?;
4692
4693 let mut parsed_generics: Vec<Symbol> = Vec::new();
4695 if self.check_preposition_is("of") {
4696 self.advance(); loop {
4698 if !self.check(&TokenType::LBracket) {
4699 return Err(ParseError {
4700 kind: ParseErrorKind::Custom("Expected '[TypeParam]' after 'of' in generic function".to_string()),
4701 span: self.current_span(),
4702 });
4703 }
4704 self.advance(); let type_param = self.expect_identifier()?;
4706 parsed_generics.push(type_param);
4707 if !self.check(&TokenType::RBracket) {
4708 return Err(ParseError {
4709 kind: ParseErrorKind::Custom("Expected ']' after type parameter name".to_string()),
4710 span: self.current_span(),
4711 });
4712 }
4713 self.advance(); if self.check_word("and") {
4715 self.advance(); } else {
4717 break;
4718 }
4719 }
4720 }
4721
4722 let mut params = Vec::new();
4724 while self.check(&TokenType::LParen) {
4725 self.advance(); if self.check(&TokenType::RParen) {
4729 self.advance(); break;
4731 }
4732
4733 loop {
4735 let param_name = self.expect_identifier()?;
4736
4737 if !self.check(&TokenType::Colon) {
4739 return Err(ParseError {
4740 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4741 span: self.current_span(),
4742 });
4743 }
4744 self.advance(); let param_type_expr = self.parse_type_expression()?;
4748 let param_type = self.ctx.alloc_type_expr(param_type_expr);
4749
4750 params.push((param_name, param_type));
4751
4752 if self.check(&TokenType::Comma) {
4754 self.advance(); continue;
4756 }
4757 break;
4758 }
4759
4760 if !self.check(&TokenType::RParen) {
4762 return Err(ParseError {
4763 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4764 span: self.current_span(),
4765 });
4766 }
4767 self.advance(); if self.check_word("and") || self.check_preposition() || self.check(&TokenType::From) {
4772 self.advance();
4773 }
4774 }
4775
4776 let return_type = if self.check(&TokenType::Arrow) {
4778 self.advance(); let ret_type_expr = self.parse_type_expression()?;
4780 Some(self.ctx.alloc_type_expr(ret_type_expr))
4781 } else {
4782 None
4783 };
4784
4785 let mut native_path: Option<Symbol> = None;
4787 let mut is_exported = false;
4788 let mut export_target: Option<Symbol> = None;
4789
4790 if self.check_word("is") {
4791 self.advance(); if self.check(&TokenType::Native) {
4793 self.advance(); is_native = true;
4796 if let TokenType::StringLiteral(sym) = self.peek().kind {
4797 native_path = Some(sym);
4798 self.advance(); } else {
4800 return Err(ParseError {
4801 kind: ParseErrorKind::Custom(
4802 "Expected a string literal for native function path (e.g., is native \"reqwest::blocking::get\")".to_string()
4803 ),
4804 span: self.current_span(),
4805 });
4806 }
4807 } else if self.check_word("exported") {
4808 self.advance(); is_exported = true;
4811 if self.check_word("for") {
4812 self.advance(); let target_sym = self.expect_identifier()?;
4814 let target_str = self.interner.resolve(target_sym);
4815 if !target_str.eq_ignore_ascii_case("c") && !target_str.eq_ignore_ascii_case("wasm") {
4816 return Err(ParseError {
4817 kind: ParseErrorKind::Custom(
4818 format!("Unsupported export target \"{}\". Supported targets are \"c\" and \"wasm\".", target_str)
4819 ),
4820 span: self.current_span(),
4821 });
4822 }
4823 export_target = Some(target_sym);
4824 }
4825 }
4826 }
4827
4828 if is_native {
4830 if self.check(&TokenType::Period) {
4832 self.advance();
4833 }
4834 if self.check(&TokenType::Newline) {
4835 self.advance();
4836 }
4837
4838 let empty_body = self.ctx.stmts.expect("imperative arenas not initialized")
4840 .alloc_slice(std::iter::empty());
4841
4842 return Ok(Stmt::FunctionDef {
4843 name,
4844 generics: parsed_generics,
4845 params,
4846 body: empty_body,
4847 return_type,
4848 is_native: true,
4849 native_path,
4850 is_exported: false,
4851 export_target: None,
4852 opt_flags: opt_flags.clone(),
4853 });
4854 }
4855
4856 if !self.check(&TokenType::Colon) {
4858 return Err(ParseError {
4859 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4860 span: self.current_span(),
4861 });
4862 }
4863 self.advance(); if !self.check(&TokenType::Indent) {
4867 return Err(ParseError {
4868 kind: ParseErrorKind::ExpectedStatement,
4869 span: self.current_span(),
4870 });
4871 }
4872 self.advance(); let mut body_stmts = Vec::new();
4876 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4877 if self.check(&TokenType::Newline) {
4879 self.advance();
4880 continue;
4881 }
4882 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
4884 break;
4885 }
4886 let stmt = self.parse_statement()?;
4887 body_stmts.push(stmt);
4888 if self.check(&TokenType::Period) {
4889 self.advance();
4890 }
4891 }
4892
4893 if self.check(&TokenType::Dedent) {
4895 self.advance();
4896 }
4897
4898 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4900 .alloc_slice(body_stmts.into_iter());
4901
4902 Ok(Stmt::FunctionDef {
4903 name,
4904 generics: parsed_generics,
4905 params,
4906 body,
4907 return_type,
4908 is_native: false,
4909 native_path: None,
4910 is_exported,
4911 export_target,
4912 opt_flags,
4913 })
4914 }
4915
4916 fn parse_primary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
4918 use crate::ast::{Expr, Literal};
4919
4920 let token = self.peek().clone();
4921 match &token.kind {
4922 TokenType::New => {
4926 self.advance(); let base_type_name = self.expect_identifier()?;
4928
4929 let type_name = if self.check(&TokenType::From) {
4931 self.advance(); let module_name = self.expect_identifier()?;
4933 let module_str = self.interner.resolve(module_name);
4934 let base_str = self.interner.resolve(base_type_name);
4935 let qualified = format!("{}::{}", module_str, base_str);
4936 self.interner.intern(&qualified)
4937 } else {
4938 base_type_name
4939 };
4940
4941 if let Some(enum_name) = self.find_variant(type_name) {
4943 let fields = if self.check_word("with") {
4945 self.parse_variant_constructor_fields()?
4946 } else {
4947 vec![]
4948 };
4949 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
4950 enum_name,
4951 variant: type_name,
4952 fields,
4953 });
4954 return self.parse_field_access_chain(base);
4955 }
4956
4957 let type_args = self.parse_generic_type_args(type_name)?;
4959
4960 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
4963 self.parse_struct_init_fields()?
4964 } else {
4965 vec![]
4966 };
4967
4968 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
4969 return self.parse_field_access_chain(base);
4970 }
4971
4972 TokenType::Article(_) => {
4976 if let Some(next) = self.tokens.get(self.current + 1) {
4979 if matches!(next.kind, TokenType::Manifest) {
4980 self.advance(); return self.parse_primary_expr();
4983 }
4984 if matches!(next.kind, TokenType::Chunk) {
4985 self.advance(); return self.parse_primary_expr();
4988 }
4989 if matches!(next.kind, TokenType::Length) {
4990 self.advance(); return self.parse_primary_expr();
4992 }
4993 }
4994 if let Some(next) = self.tokens.get(self.current + 1) {
4996 if matches!(next.kind, TokenType::New) {
4997 self.advance(); self.advance(); let base_type_name = self.expect_identifier()?;
5000
5001 let type_name = if self.check(&TokenType::From) {
5003 self.advance(); let module_name = self.expect_identifier()?;
5005 let module_str = self.interner.resolve(module_name);
5006 let base_str = self.interner.resolve(base_type_name);
5007 let qualified = format!("{}::{}", module_str, base_str);
5008 self.interner.intern(&qualified)
5009 } else {
5010 base_type_name
5011 };
5012
5013 if let Some(enum_name) = self.find_variant(type_name) {
5015 let fields = if self.check_word("with") {
5017 self.parse_variant_constructor_fields()?
5018 } else {
5019 vec![]
5020 };
5021 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
5022 enum_name,
5023 variant: type_name,
5024 fields,
5025 });
5026 return self.parse_field_access_chain(base);
5027 }
5028
5029 let type_args = self.parse_generic_type_args(type_name)?;
5031
5032 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
5035 self.parse_struct_init_fields()?
5036 } else {
5037 vec![]
5038 };
5039
5040 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
5041 return self.parse_field_access_chain(base);
5042 }
5043 }
5044 let sym = token.lexeme;
5046 self.advance();
5047 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5048 return self.parse_field_access_chain(base);
5049 }
5050
5051 TokenType::Item => {
5053 self.advance(); let index = if let TokenType::Number(sym) = &self.peek().kind {
5057 let sym = *sym;
5059 self.advance();
5060 let num_str = self.interner.resolve(sym);
5061 let index_val = num_str.parse::<i64>().unwrap_or(0);
5062
5063 if index_val == 0 {
5065 return Err(ParseError {
5066 kind: ParseErrorKind::ZeroIndex,
5067 span: self.current_span(),
5068 });
5069 }
5070
5071 self.ctx.alloc_imperative_expr(
5072 Expr::Literal(crate::ast::Literal::Number(index_val))
5073 )
5074 } else if self.check(&TokenType::LParen) {
5075 self.advance(); let inner = self.parse_imperative_expr()?;
5078 if !self.check(&TokenType::RParen) {
5079 return Err(ParseError {
5080 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5081 span: self.current_span(),
5082 });
5083 }
5084 self.advance(); inner
5086 } else if let TokenType::StringLiteral(sym) = self.peek().kind {
5087 let sym = sym;
5089 self.advance();
5090 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Text(sym)))
5091 } else if !self.check_preposition_is("of") {
5092 let word = self.interner.resolve(self.peek().lexeme);
5094 if word == "true" {
5095 self.advance();
5096 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(true)))
5097 } else if word == "false" {
5098 self.advance();
5099 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(false)))
5100 } else {
5101 let sym = self.peek().lexeme;
5103 self.advance();
5104 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5105 }
5106 } else {
5107 return Err(ParseError {
5108 kind: ParseErrorKind::ExpectedExpression,
5109 span: self.current_span(),
5110 });
5111 };
5112
5113 if !self.check_preposition_is("of") {
5115 return Err(ParseError {
5116 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5117 span: self.current_span(),
5118 });
5119 }
5120 self.advance(); let collection = self.parse_primary_expr()?;
5125
5126 Ok(self.ctx.alloc_imperative_expr(Expr::Index {
5127 collection,
5128 index,
5129 }))
5130 }
5131
5132 TokenType::Items => {
5135 let is_slice_syntax = if let Some(next) = self.tokens.get(self.current + 1) {
5139 matches!(next.kind, TokenType::Number(_) | TokenType::LParen)
5140 } else {
5141 false
5142 };
5143
5144 if !is_slice_syntax {
5145 let sym = token.lexeme;
5147 self.advance();
5148 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5149 return self.parse_field_access_chain(base);
5150 }
5151
5152 self.advance(); let start = if let TokenType::Number(sym) = &self.peek().kind {
5156 let sym = *sym;
5158 self.advance();
5159 let num_str = self.interner.resolve(sym);
5160 let start_val = num_str.parse::<i64>().unwrap_or(0);
5161
5162 if start_val == 0 {
5164 return Err(ParseError {
5165 kind: ParseErrorKind::ZeroIndex,
5166 span: self.current_span(),
5167 });
5168 }
5169
5170 self.ctx.alloc_imperative_expr(
5171 Expr::Literal(crate::ast::Literal::Number(start_val))
5172 )
5173 } else if self.check(&TokenType::LParen) {
5174 self.advance(); let inner = self.parse_imperative_expr()?;
5177 if !self.check(&TokenType::RParen) {
5178 return Err(ParseError {
5179 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5180 span: self.current_span(),
5181 });
5182 }
5183 self.advance(); inner
5185 } else if self.check(&TokenType::Length) {
5186 self.advance(); if self.check_preposition_is("of") {
5189 self.advance(); let target = self.parse_primary_expr()?;
5191 self.ctx.alloc_imperative_expr(Expr::Length { collection: target })
5192 } else {
5193 let sym = self.tokens[self.current - 1].lexeme;
5195 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5196 }
5197 } else if !self.check_preposition_is("through") {
5198 let sym = self.peek().lexeme;
5200 self.advance();
5201 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5202 } else {
5203 return Err(ParseError {
5204 kind: ParseErrorKind::ExpectedExpression,
5205 span: self.current_span(),
5206 });
5207 };
5208
5209 if !self.check_preposition_is("through") {
5211 return Err(ParseError {
5212 kind: ParseErrorKind::ExpectedKeyword { keyword: "through".to_string() },
5213 span: self.current_span(),
5214 });
5215 }
5216 self.advance(); let end = if let TokenType::Number(sym) = &self.peek().kind {
5220 let sym = *sym;
5222 self.advance();
5223 let num_str = self.interner.resolve(sym);
5224 let end_val = num_str.parse::<i64>().unwrap_or(0);
5225
5226 if end_val == 0 {
5228 return Err(ParseError {
5229 kind: ParseErrorKind::ZeroIndex,
5230 span: self.current_span(),
5231 });
5232 }
5233
5234 self.ctx.alloc_imperative_expr(
5235 Expr::Literal(crate::ast::Literal::Number(end_val))
5236 )
5237 } else if self.check(&TokenType::LParen) {
5238 self.advance(); let inner = self.parse_imperative_expr()?;
5241 if !self.check(&TokenType::RParen) {
5242 return Err(ParseError {
5243 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5244 span: self.current_span(),
5245 });
5246 }
5247 self.advance(); inner
5249 } else if self.check(&TokenType::Length) {
5250 self.advance(); if self.check_preposition_is("of") {
5253 self.advance(); let target = self.parse_primary_expr()?;
5255 self.ctx.alloc_imperative_expr(Expr::Length { collection: target })
5256 } else {
5257 let sym = self.tokens[self.current - 1].lexeme;
5259 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5260 }
5261 } else if !self.check_preposition_is("of") {
5262 let sym = self.peek().lexeme;
5264 self.advance();
5265 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5266 } else {
5267 return Err(ParseError {
5268 kind: ParseErrorKind::ExpectedExpression,
5269 span: self.current_span(),
5270 });
5271 };
5272
5273 let collection = if self.check_preposition_is("of") {
5276 self.advance(); self.parse_imperative_expr()?
5278 } else {
5279 let items_sym = self.interner.intern("items");
5282 self.ctx.alloc_imperative_expr(Expr::Identifier(items_sym))
5283 };
5284
5285 Ok(self.ctx.alloc_imperative_expr(Expr::Slice {
5286 collection,
5287 start,
5288 end,
5289 }))
5290 }
5291
5292 TokenType::LBracket => {
5294 self.advance(); let mut items = Vec::new();
5297 if !self.check(&TokenType::RBracket) {
5298 loop {
5299 items.push(self.parse_imperative_expr()?);
5300 if !self.check(&TokenType::Comma) {
5301 break;
5302 }
5303 self.advance(); }
5305 }
5306
5307 if !self.check(&TokenType::RBracket) {
5308 return Err(ParseError {
5309 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
5310 span: self.current_span(),
5311 });
5312 }
5313 self.advance(); if items.is_empty() && self.check_word("of") {
5317 self.advance(); let type_name = self.expect_identifier()?;
5319 let seq_sym = self.interner.intern("Seq");
5321 return Ok(self.ctx.alloc_imperative_expr(Expr::New {
5322 type_name: seq_sym,
5323 type_args: vec![TypeExpr::Named(type_name)],
5324 init_fields: vec![],
5325 }));
5326 }
5327
5328 Ok(self.ctx.alloc_imperative_expr(Expr::List(items)))
5329 }
5330
5331 TokenType::Number(sym) => {
5332 let num_str = self.interner.resolve(*sym).to_string();
5333 self.advance();
5334
5335 if let TokenType::CalendarUnit(unit) = self.peek().kind {
5337 return self.parse_span_literal_from_num(&num_str);
5338 }
5339
5340 if num_str.contains('.') || num_str.contains('e') || num_str.contains('E') {
5342 let num = num_str.parse::<f64>().unwrap_or(0.0);
5343 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Float(num))))
5344 } else {
5345 let num = num_str.parse::<i64>().unwrap_or(0);
5346 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(num))))
5347 }
5348 }
5349
5350 TokenType::StringLiteral(sym) => {
5352 self.advance();
5353 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Text(*sym))))
5354 }
5355
5356 TokenType::InterpolatedString(sym) => {
5358 let raw = self.interner.resolve(*sym).to_string();
5359 self.advance();
5360 let parts = self.parse_interpolation_parts(&raw)?;
5361 Ok(self.ctx.alloc_imperative_expr(Expr::InterpolatedString(parts)))
5362 }
5363
5364 TokenType::CharLiteral(sym) => {
5366 let char_str = self.interner.resolve(*sym);
5367 let ch = char_str.chars().next().unwrap_or('\0');
5368 self.advance();
5369 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Char(ch))))
5370 }
5371
5372 TokenType::DurationLiteral { nanos, .. } => {
5374 let nanos = *nanos;
5375 self.advance();
5376 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Duration(nanos))))
5377 }
5378
5379 TokenType::DateLiteral { days } => {
5382 let days = *days;
5383 self.advance();
5384
5385 if self.check(&TokenType::At) {
5387 self.advance(); if let TokenType::TimeLiteral { nanos_from_midnight } = self.peek().kind {
5391 let time_nanos = nanos_from_midnight;
5392 self.advance(); let moment_nanos = (days as i64) * 86_400_000_000_000 + time_nanos;
5396 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Moment(moment_nanos))));
5397 } else {
5398 return Err(ParseError {
5399 kind: ParseErrorKind::ExpectedExpression,
5400 span: self.current_span(),
5401 });
5402 }
5403 }
5404
5405 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Date(days))))
5406 }
5407
5408 TokenType::TimeLiteral { nanos_from_midnight } => {
5410 let nanos = *nanos_from_midnight;
5411 self.advance();
5412 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Time(nanos))))
5413 }
5414
5415 TokenType::Nothing => {
5417 self.advance();
5418 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)))
5419 }
5420
5421 TokenType::Some => {
5423 self.advance(); let value = self.parse_imperative_expr()?;
5425 Ok(self.ctx.alloc_imperative_expr(Expr::OptionSome { value }))
5426 }
5427
5428 TokenType::Length => {
5430 let func_name = self.peek().lexeme;
5431
5432 if self.tokens.get(self.current + 1)
5434 .map(|t| matches!(t.kind, TokenType::LParen))
5435 .unwrap_or(false)
5436 {
5437 self.advance(); return self.parse_call_expr(func_name);
5439 }
5440
5441 self.advance(); if !self.check_preposition_is("of") {
5445 return Err(ParseError {
5446 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5447 span: self.current_span(),
5448 });
5449 }
5450 self.advance(); let collection = self.parse_primary_expr()?;
5455 Ok(self.ctx.alloc_imperative_expr(Expr::Length { collection }))
5456 }
5457
5458 TokenType::Copy => {
5460 let func_name = self.peek().lexeme;
5461
5462 if self.tokens.get(self.current + 1)
5464 .map(|t| matches!(t.kind, TokenType::LParen))
5465 .unwrap_or(false)
5466 {
5467 self.advance(); return self.parse_call_expr(func_name);
5469 }
5470
5471 self.advance(); if !self.check_preposition_is("of") {
5475 return Err(ParseError {
5476 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5477 span: self.current_span(),
5478 });
5479 }
5480 self.advance(); let expr = self.parse_imperative_expr()?;
5483 Ok(self.ctx.alloc_imperative_expr(Expr::Copy { expr }))
5484 }
5485
5486 TokenType::Manifest => {
5488 self.advance(); if !self.check_preposition_is("of") {
5492 return Err(ParseError {
5493 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5494 span: self.current_span(),
5495 });
5496 }
5497 self.advance(); let zone = self.parse_imperative_expr()?;
5500 Ok(self.ctx.alloc_imperative_expr(Expr::ManifestOf { zone }))
5501 }
5502
5503 TokenType::Chunk => {
5505 self.advance(); if !self.check(&TokenType::At) {
5509 return Err(ParseError {
5510 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
5511 span: self.current_span(),
5512 });
5513 }
5514 self.advance(); let index = self.parse_imperative_expr()?;
5517
5518 if !self.check_preposition_is("in") && !self.check(&TokenType::In) {
5520 return Err(ParseError {
5521 kind: ParseErrorKind::ExpectedKeyword { keyword: "in".to_string() },
5522 span: self.current_span(),
5523 });
5524 }
5525 self.advance(); let zone = self.parse_imperative_expr()?;
5528 Ok(self.ctx.alloc_imperative_expr(Expr::ChunkAt { index, zone }))
5529 }
5530
5531 TokenType::Verb { lemma, .. } => {
5535 let word = self.interner.resolve(*lemma).to_lowercase();
5536 if word == "empty" {
5537 self.advance();
5538 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5539 }
5540 let sym = token.lexeme;
5542 self.advance();
5543 if self.check(&TokenType::LParen) {
5544 return self.parse_call_expr(sym);
5545 }
5546 self.verify_identifier_access(sym)?;
5548 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5549 self.parse_field_access_chain(base)
5550 }
5551
5552 TokenType::TemporalAdverb(_) | TokenType::ScopalAdverb(_) | TokenType::Adverb(_) => {
5554 let sym = token.lexeme;
5555 self.advance();
5556 if self.check(&TokenType::LParen) {
5557 return self.parse_call_expr(sym);
5558 }
5559 self.verify_identifier_access(sym)?;
5561 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5562 self.parse_field_access_chain(base)
5563 }
5564
5565 TokenType::Read | TokenType::Write | TokenType::File | TokenType::Console |
5568 TokenType::Add | TokenType::Remove => {
5569 let sym = token.lexeme;
5570 self.advance();
5571 if self.check(&TokenType::LParen) {
5572 return self.parse_call_expr(sym);
5573 }
5574 self.verify_identifier_access(sym)?;
5576 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5577 self.parse_field_access_chain(base)
5578 }
5579
5580 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
5583 let sym = *sym;
5584 let word = self.interner.resolve(sym);
5585
5586 if word == "true" {
5588 self.advance();
5589 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(true))));
5590 }
5591 if word == "false" {
5592 self.advance();
5593 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(false))));
5594 }
5595
5596 if word == "empty" {
5598 self.advance();
5599 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5600 }
5601
5602 if word == "none" {
5604 self.advance();
5605 return Ok(self.ctx.alloc_imperative_expr(Expr::OptionNone));
5606 }
5607
5608 self.advance();
5610
5611 if self.check(&TokenType::LParen) {
5613 return self.parse_call_expr(sym);
5614 }
5615
5616 if let Some(enum_name) = self.find_variant(sym) {
5618 let fields = if self.check_word("with") {
5619 self.parse_variant_constructor_fields()?
5620 } else {
5621 vec![]
5622 };
5623 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
5624 enum_name,
5625 variant: sym,
5626 fields,
5627 });
5628 return self.parse_field_access_chain(base);
5629 }
5630
5631 self.verify_identifier_access(sym)?;
5633 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5634 self.parse_field_access_chain(base)
5636 }
5637
5638 TokenType::Pronoun { .. } => {
5640 let sym = token.lexeme;
5641 self.advance();
5642 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5643 self.parse_field_access_chain(base)
5645 }
5646
5647 TokenType::Merge | TokenType::Increase => {
5649 let sym = token.lexeme;
5650 self.advance();
5651
5652 if self.check(&TokenType::LParen) {
5654 return self.parse_call_expr(sym);
5655 }
5656
5657 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5658 self.parse_field_access_chain(base)
5659 }
5660
5661 TokenType::Escape => {
5665 if self.tokens.get(self.current + 1).map_or(false, |t|
5666 matches!(t.kind, TokenType::To) || {
5667 if let TokenType::Preposition(sym) = t.kind {
5668 sym.is(self.interner, "to")
5669 } else {
5670 false
5671 }
5672 }
5673 ) {
5674 return self.parse_escape_expr();
5675 }
5676 let sym = token.lexeme;
5678 self.advance();
5679 if self.check(&TokenType::LParen) {
5680 return self.parse_call_expr(sym);
5681 }
5682 self.verify_identifier_access(sym)?;
5683 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5684 self.parse_field_access_chain(base)
5685 }
5686
5687 TokenType::Values | TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared | TokenType::Particle(_) | TokenType::Preposition(_) | TokenType::All => { let sym = token.lexeme;
5699 self.advance();
5700
5701 if self.check(&TokenType::LParen) {
5703 return self.parse_call_expr(sym);
5704 }
5705
5706 self.verify_identifier_access(sym)?;
5707 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5708 self.parse_field_access_chain(base)
5709 }
5710
5711 TokenType::Ambiguous { primary, alternatives } => {
5713 let sym = token.lexeme;
5716
5717 let is_identifier_token = match &**primary {
5719 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5720 TokenType::Verb { .. } => true,
5721 _ => alternatives.iter().any(|t| matches!(t,
5722 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5723 TokenType::Verb { .. }
5724 ))
5725 };
5726
5727 if is_identifier_token {
5728 self.advance();
5729
5730 if self.check(&TokenType::LParen) {
5732 return self.parse_call_expr(sym);
5733 }
5734
5735 self.verify_identifier_access(sym)?;
5736 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5737 self.parse_field_access_chain(base)
5739 } else {
5740 Err(ParseError {
5741 kind: ParseErrorKind::ExpectedExpression,
5742 span: self.current_span(),
5743 })
5744 }
5745 }
5746
5747 TokenType::LParen => {
5749 if let Some(closure) = self.try_parse(|p| p.parse_closure_expr()) {
5752 return Ok(closure);
5753 }
5754
5755 self.advance(); let first = self.parse_imperative_expr()?;
5758
5759 if self.check(&TokenType::Comma) {
5761 let mut items = vec![first];
5763 while self.check(&TokenType::Comma) {
5764 self.advance(); items.push(self.parse_imperative_expr()?);
5766 }
5767
5768 if !self.check(&TokenType::RParen) {
5769 return Err(ParseError {
5770 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5771 span: self.current_span(),
5772 });
5773 }
5774 self.advance(); let base = self.ctx.alloc_imperative_expr(Expr::Tuple(items));
5777 self.parse_field_access_chain(base)
5778 } else {
5779 if !self.check(&TokenType::RParen) {
5781 return Err(ParseError {
5782 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5783 span: self.current_span(),
5784 });
5785 }
5786 self.advance(); Ok(first)
5788 }
5789 }
5790
5791 TokenType::Call => {
5793 self.advance(); let function = match &self.peek().kind {
5795 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
5796 let s = *sym;
5797 self.advance();
5798 s
5799 }
5800 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
5801 let s = self.peek().lexeme;
5802 self.advance();
5803 s
5804 }
5805 _ => {
5806 return Err(ParseError {
5807 kind: ParseErrorKind::ExpectedIdentifier,
5808 span: self.current_span(),
5809 });
5810 }
5811 };
5812 let args = if self.check_preposition_is("with") {
5813 self.advance(); self.parse_call_arguments()?
5815 } else {
5816 Vec::new()
5817 };
5818 Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
5819 }
5820
5821 _ => {
5822 Err(ParseError {
5823 kind: ParseErrorKind::ExpectedExpression,
5824 span: self.current_span(),
5825 })
5826 }
5827 }
5828 }
5829
5830 fn parse_closure_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5833 use crate::ast::stmt::ClosureBody;
5834
5835 if !self.check(&TokenType::LParen) {
5837 return Err(ParseError {
5838 kind: ParseErrorKind::ExpectedExpression,
5839 span: self.current_span(),
5840 });
5841 }
5842 self.advance(); let mut params = Vec::new();
5846 if !self.check(&TokenType::RParen) {
5847 let name = self.expect_identifier()?;
5849 if !self.check(&TokenType::Colon) {
5850 return Err(ParseError {
5851 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
5852 span: self.current_span(),
5853 });
5854 }
5855 self.advance(); let ty = self.parse_type_expression()?;
5857 let ty_ref = self.ctx.alloc_type_expr(ty);
5858 params.push((name, ty_ref));
5859
5860 while self.check(&TokenType::Comma) {
5862 self.advance(); let name = self.expect_identifier()?;
5864 if !self.check(&TokenType::Colon) {
5865 return Err(ParseError {
5866 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
5867 span: self.current_span(),
5868 });
5869 }
5870 self.advance(); let ty = self.parse_type_expression()?;
5872 let ty_ref = self.ctx.alloc_type_expr(ty);
5873 params.push((name, ty_ref));
5874 }
5875 }
5876
5877 if !self.check(&TokenType::RParen) {
5879 return Err(ParseError {
5880 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5881 span: self.current_span(),
5882 });
5883 }
5884 self.advance(); if !self.check(&TokenType::Arrow) {
5888 return Err(ParseError {
5889 kind: ParseErrorKind::ExpectedKeyword { keyword: "->".to_string() },
5890 span: self.current_span(),
5891 });
5892 }
5893 self.advance(); let body = if self.check(&TokenType::Colon) {
5897 self.advance(); if !self.check(&TokenType::Indent) {
5900 return Err(ParseError {
5901 kind: ParseErrorKind::ExpectedStatement,
5902 span: self.current_span(),
5903 });
5904 }
5905 self.advance(); let mut block_stmts = Vec::new();
5908 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
5909 let stmt = self.parse_statement()?;
5910 block_stmts.push(stmt);
5911 if self.check(&TokenType::Period) {
5912 self.advance();
5913 }
5914 }
5915 if self.check(&TokenType::Dedent) {
5916 self.advance(); }
5918
5919 let block = self.ctx.stmts.expect("imperative arenas not initialized")
5920 .alloc_slice(block_stmts.into_iter());
5921 ClosureBody::Block(block)
5922 } else {
5923 let expr = self.parse_condition()?;
5925 ClosureBody::Expression(expr)
5926 };
5927
5928 Ok(self.ctx.alloc_imperative_expr(Expr::Closure {
5929 params,
5930 body,
5931 return_type: None,
5932 }))
5933 }
5934
5935 fn parse_imperative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5939 self.parse_condition()
5940 }
5941
5942 fn parse_xor_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5945 let mut left = self.parse_additive_expr()?;
5946
5947 while self.check(&TokenType::Xor) {
5948 self.advance(); let right = self.parse_additive_expr()?;
5950 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5951 op: BinaryOpKind::BitXor,
5952 left,
5953 right,
5954 });
5955 }
5956
5957 Ok(left)
5958 }
5959
5960 fn parse_additive_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5962 let mut left = self.parse_shift_expr()?;
5963
5964 loop {
5965 match &self.peek().kind {
5966 TokenType::Plus => {
5967 self.advance();
5968 let right = self.parse_shift_expr()?;
5969 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5970 op: BinaryOpKind::Add,
5971 left,
5972 right,
5973 });
5974 }
5975 TokenType::Minus => {
5976 self.advance();
5977 let right = self.parse_shift_expr()?;
5978 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5979 op: BinaryOpKind::Subtract,
5980 left,
5981 right,
5982 });
5983 }
5984 TokenType::Combined => {
5986 self.advance(); if !self.check_preposition_is("with") {
5989 return Err(ParseError {
5990 kind: ParseErrorKind::ExpectedKeyword { keyword: "with".to_string() },
5991 span: self.current_span(),
5992 });
5993 }
5994 self.advance(); let right = self.parse_shift_expr()?;
5996 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5997 op: BinaryOpKind::Concat,
5998 left,
5999 right,
6000 });
6001 }
6002 TokenType::Union => {
6004 self.advance(); let right = self.parse_shift_expr()?;
6006 left = self.ctx.alloc_imperative_expr(Expr::Union {
6007 left,
6008 right,
6009 });
6010 }
6011 TokenType::Intersection => {
6012 self.advance(); let right = self.parse_shift_expr()?;
6014 left = self.ctx.alloc_imperative_expr(Expr::Intersection {
6015 left,
6016 right,
6017 });
6018 }
6019 TokenType::Contains => {
6021 self.advance(); let value = self.parse_shift_expr()?;
6023 left = self.ctx.alloc_imperative_expr(Expr::Contains {
6024 collection: left,
6025 value,
6026 });
6027 }
6028 _ => break,
6029 }
6030 }
6031
6032 Ok(left)
6033 }
6034
6035 fn parse_shift_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6038 let mut left = self.parse_multiplicative_expr()?;
6039
6040 loop {
6041 if !self.check(&TokenType::Shifted) {
6042 break;
6043 }
6044 self.advance(); let is_left = self.check_word("left");
6047 if is_left {
6048 self.advance(); } else if self.check_word("right") {
6050 self.advance(); } else {
6052 return Err(ParseError {
6053 kind: ParseErrorKind::ExpectedKeyword { keyword: "left or right".to_string() },
6054 span: self.current_span(),
6055 });
6056 }
6057
6058 if !self.check_preposition_is("by") && !self.check_word("by") {
6060 return Err(ParseError {
6061 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
6062 span: self.current_span(),
6063 });
6064 }
6065 self.advance(); let right = self.parse_multiplicative_expr()?;
6068 let op = if is_left { BinaryOpKind::Shl } else { BinaryOpKind::Shr };
6069 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp { op, left, right });
6070 }
6071
6072 Ok(left)
6073 }
6074
6075 fn parse_unary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6077 use crate::ast::{Expr, Literal};
6078
6079 if self.check(&TokenType::Minus) {
6080 self.advance(); let operand = self.parse_unary_expr()?; return Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp {
6084 op: BinaryOpKind::Subtract,
6085 left: self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(0))),
6086 right: operand,
6087 }));
6088 }
6089 self.parse_primary_expr()
6090 }
6091
6092 fn parse_multiplicative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6094 let mut left = self.parse_unary_expr()?;
6095
6096 loop {
6097 let op = match &self.peek().kind {
6098 TokenType::Star => {
6099 self.advance();
6100 BinaryOpKind::Multiply
6101 }
6102 TokenType::Slash => {
6103 self.advance();
6104 BinaryOpKind::Divide
6105 }
6106 TokenType::Percent => {
6107 self.advance();
6108 BinaryOpKind::Modulo
6109 }
6110 _ => break,
6111 };
6112 let right = self.parse_unary_expr()?;
6113 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
6114 op,
6115 left,
6116 right,
6117 });
6118 }
6119
6120 Ok(left)
6121 }
6122
6123 fn try_parse_binary_op(&mut self) -> Option<BinaryOpKind> {
6125 match &self.peek().kind {
6126 TokenType::Plus => {
6127 self.advance();
6128 Some(BinaryOpKind::Add)
6129 }
6130 TokenType::Minus => {
6131 self.advance();
6132 Some(BinaryOpKind::Subtract)
6133 }
6134 TokenType::Star => {
6135 self.advance();
6136 Some(BinaryOpKind::Multiply)
6137 }
6138 TokenType::Slash => {
6139 self.advance();
6140 Some(BinaryOpKind::Divide)
6141 }
6142 _ => None,
6143 }
6144 }
6145
6146 fn parse_interpolation_parts(&mut self, raw: &str) -> ParseResult<Vec<crate::ast::stmt::StringPart<'a>>> {
6153 use crate::ast::stmt::StringPart;
6154
6155 let mut parts = Vec::new();
6156 let chars: Vec<char> = raw.chars().collect();
6157 let mut i = 0;
6158 let mut literal_buf = String::new();
6159
6160 while i < chars.len() {
6161 match chars[i] {
6162 '{' if i + 1 < chars.len() && chars[i + 1] == '{' => {
6163 literal_buf.push('{');
6165 i += 2;
6166 }
6167 '{' => {
6168 if !literal_buf.is_empty() {
6170 let sym = self.interner.intern(&literal_buf);
6171 parts.push(StringPart::Literal(sym));
6172 literal_buf.clear();
6173 }
6174
6175 let start = i + 1;
6177 let mut depth = 1;
6178 let mut j = start;
6179 while j < chars.len() && depth > 0 {
6180 if chars[j] == '{' { depth += 1; }
6181 if chars[j] == '}' { depth -= 1; }
6182 if depth > 0 { j += 1; }
6183 }
6184 if depth != 0 {
6185 return Err(ParseError {
6186 kind: crate::error::ParseErrorKind::Custom(
6187 "Unclosed interpolation brace in string".to_string()
6188 ),
6189 span: self.current_span(),
6190 });
6191 }
6192
6193 let hole_content: String = chars[start..j].iter().collect();
6194
6195 let (hole_after_debug, is_debug) = {
6200 if let Some(eq_pos) = hole_content.rfind('=') {
6201 let before_eq = hole_content[..eq_pos].trim();
6202 let is_double_eq = eq_pos > 0 && hole_content.as_bytes().get(eq_pos - 1) == Some(&b'=');
6205 let is_preceded_by_comparison = eq_pos > 0 && matches!(hole_content.as_bytes().get(eq_pos - 1), Some(b'!' | b'<' | b'>'));
6206 if !is_double_eq && !is_preceded_by_comparison
6207 && !before_eq.is_empty()
6208 && before_eq.chars().all(|c| c.is_alphanumeric() || c == '_')
6209 {
6210 (hole_content[..eq_pos].to_string() + &hole_content[eq_pos + 1..], true)
6211 } else {
6212 (hole_content.clone(), false)
6213 }
6214 } else {
6215 (hole_content.clone(), false)
6216 }
6217 };
6218
6219 let (expr_str, format_spec) = if let Some(colon_pos) = hole_after_debug.rfind(':') {
6221 let before = &hole_after_debug[..colon_pos];
6222 let after = &hole_after_debug[colon_pos + 1..];
6223 if !after.is_empty() && (after.starts_with('.') || after.starts_with('<') || after.starts_with('>') || after.starts_with('^') || after == "$" || after.chars().next().map_or(false, |c| c.is_ascii_digit())) {
6226 let valid = if after == "$" {
6228 true
6229 } else if after.starts_with('.') {
6230 after[1..].parse::<usize>().is_ok()
6231 } else if after.starts_with('<') || after.starts_with('>') || after.starts_with('^') {
6232 after[1..].parse::<usize>().is_ok()
6233 } else {
6234 after.parse::<usize>().is_ok()
6235 };
6236 if !valid {
6237 return Err(ParseError {
6238 kind: crate::error::ParseErrorKind::Custom(
6239 format!("Invalid format specifier `{}` in interpolation hole", after)
6240 ),
6241 span: self.current_span(),
6242 });
6243 }
6244 (before.to_string(), Some(after.to_string()))
6245 } else {
6246 (hole_after_debug.clone(), None)
6247 }
6248 } else {
6249 (hole_after_debug.clone(), None)
6250 };
6251
6252 let expr_source = expr_str.trim().to_string();
6254 if expr_source.is_empty() {
6255 return Err(ParseError {
6256 kind: crate::error::ParseErrorKind::Custom(
6257 "Empty interpolation hole in string".to_string()
6258 ),
6259 span: self.current_span(),
6260 });
6261 }
6262
6263 let sub_expr = {
6266 let mut sub_lexer = crate::lexer::Lexer::new(&expr_source, self.interner);
6267 let sub_tokens = sub_lexer.tokenize();
6268
6269 let saved_tokens = std::mem::replace(&mut self.tokens, sub_tokens);
6271 let saved_current = self.current;
6272 self.current = 0;
6273
6274 let result = self.parse_primary_or_binary_expr();
6275
6276 self.tokens = saved_tokens;
6278 self.current = saved_current;
6279
6280 result?
6281 };
6282
6283 let format_sym = format_spec.map(|s| self.interner.intern(&s));
6284 parts.push(StringPart::Expr {
6285 value: sub_expr,
6286 format_spec: format_sym,
6287 debug: is_debug,
6288 });
6289
6290 i = j + 1; }
6292 '}' if i + 1 < chars.len() && chars[i + 1] == '}' => {
6293 literal_buf.push('}');
6295 i += 2;
6296 }
6297 _ => {
6298 literal_buf.push(chars[i]);
6299 i += 1;
6300 }
6301 }
6302 }
6303
6304 if !literal_buf.is_empty() {
6306 let sym = self.interner.intern(&literal_buf);
6307 parts.push(StringPart::Literal(sym));
6308 }
6309
6310 Ok(parts)
6311 }
6312
6313 fn parse_primary_or_binary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6315 self.parse_imperative_expr()
6316 }
6317
6318 fn parse_span_literal_from_num(&mut self, first_num_str: &str) -> ParseResult<&'a Expr<'a>> {
6319 use crate::ast::Literal;
6320 use crate::token::CalendarUnit;
6321
6322 let first_num = first_num_str.parse::<i32>().unwrap_or(0);
6323
6324 let unit = match self.peek().kind {
6326 TokenType::CalendarUnit(u) => u,
6327 _ => {
6328 return Err(ParseError {
6329 kind: ParseErrorKind::ExpectedKeyword { keyword: "calendar unit (day, week, month, year)".to_string() },
6330 span: self.current_span(),
6331 });
6332 }
6333 };
6334 self.advance(); let mut total_months: i32 = 0;
6338 let mut total_days: i32 = 0;
6339
6340 match unit {
6342 CalendarUnit::Day => total_days += first_num,
6343 CalendarUnit::Week => total_days += first_num * 7,
6344 CalendarUnit::Month => total_months += first_num,
6345 CalendarUnit::Year => total_months += first_num * 12,
6346 }
6347
6348 while self.check(&TokenType::And) {
6350 self.advance(); let next_num = match &self.peek().kind {
6354 TokenType::Number(sym) => {
6355 let num_str = self.interner.resolve(*sym).to_string();
6356 self.advance();
6357 num_str.parse::<i32>().unwrap_or(0)
6358 }
6359 _ => break, };
6361
6362 let next_unit = match self.peek().kind {
6364 TokenType::CalendarUnit(u) => {
6365 self.advance();
6366 u
6367 }
6368 _ => break, };
6370
6371 match next_unit {
6373 CalendarUnit::Day => total_days += next_num,
6374 CalendarUnit::Week => total_days += next_num * 7,
6375 CalendarUnit::Month => total_months += next_num,
6376 CalendarUnit::Year => total_months += next_num * 12,
6377 }
6378 }
6379
6380 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Span {
6381 months: total_months,
6382 days: total_days,
6383 })))
6384 }
6385
6386 fn parse_call_expr(&mut self, function: Symbol) -> ParseResult<&'a Expr<'a>> {
6388 use crate::ast::Expr;
6389
6390 self.advance(); let mut args = Vec::new();
6393 if !self.check(&TokenType::RParen) {
6394 loop {
6395 args.push(self.parse_imperative_expr()?);
6396 if !self.check(&TokenType::Comma) {
6397 break;
6398 }
6399 self.advance(); }
6401 }
6402
6403 if !self.check(&TokenType::RParen) {
6404 return Err(ParseError {
6405 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
6406 span: self.current_span(),
6407 });
6408 }
6409 self.advance(); Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
6412 }
6413
6414 fn parse_field_access_chain(&mut self, base: &'a Expr<'a>) -> ParseResult<&'a Expr<'a>> {
6417 use crate::ast::Expr;
6418
6419 let mut result = base;
6420
6421 loop {
6423 if self.check(&TokenType::Possessive) {
6424 self.advance(); let field = self.expect_identifier()?;
6427 result = self.ctx.alloc_imperative_expr(Expr::FieldAccess {
6428 object: result,
6429 field,
6430 });
6431 } else if self.check(&TokenType::LBracket) {
6432 self.advance(); let index = self.parse_imperative_expr()?;
6435
6436 if !self.check(&TokenType::RBracket) {
6437 return Err(ParseError {
6438 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
6439 span: self.current_span(),
6440 });
6441 }
6442 self.advance(); result = self.ctx.alloc_imperative_expr(Expr::Index {
6445 collection: result,
6446 index,
6447 });
6448 } else {
6449 break;
6450 }
6451 }
6452
6453 Ok(result)
6454 }
6455
6456 fn verify_identifier_access(&self, sym: Symbol) -> ParseResult<()> {
6459 if self.mode != ParserMode::Imperative {
6460 return Ok(());
6461 }
6462
6463 if let Some(crate::drs::OwnershipState::Moved) = self.world_state.get_ownership_by_var(sym) {
6465 return Err(ParseError {
6466 kind: ParseErrorKind::UseAfterMove {
6467 name: self.interner.resolve(sym).to_string()
6468 },
6469 span: self.current_span(),
6470 });
6471 }
6472
6473 Ok(())
6474 }
6475
6476 fn expect_identifier(&mut self) -> ParseResult<Symbol> {
6477 let token = self.peek().clone();
6478 match &token.kind {
6479 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
6481 self.advance();
6482 Ok(*sym)
6483 }
6484 TokenType::Verb { .. } => {
6487 let sym = token.lexeme;
6488 self.advance();
6489 Ok(sym)
6490 }
6491 TokenType::Article(_) => {
6493 let sym = token.lexeme;
6494 self.advance();
6495 Ok(sym)
6496 }
6497 TokenType::Pronoun { .. } | TokenType::Items | TokenType::Values | TokenType::Item | TokenType::Nothing | TokenType::TemporalAdverb(_) |
6505 TokenType::ScopalAdverb(_) |
6506 TokenType::Adverb(_) |
6507 TokenType::Read |
6509 TokenType::Write |
6510 TokenType::File |
6511 TokenType::Console |
6512 TokenType::Merge |
6514 TokenType::Increase |
6515 TokenType::Decrease |
6516 TokenType::Tally |
6518 TokenType::SharedSet |
6519 TokenType::SharedSequence |
6520 TokenType::CollaborativeSequence |
6521 TokenType::Add |
6524 TokenType::Remove |
6525 TokenType::First |
6526 TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared | TokenType::All | TokenType::CalendarUnit(_) |
6534 TokenType::Focus(_) |
6536 TokenType::Particle(_) |
6538 TokenType::Preposition(_) |
6540 TokenType::Escape => {
6542 let sym = token.lexeme;
6544 self.advance();
6545 Ok(sym)
6546 }
6547 TokenType::Ambiguous { .. } => {
6548 let sym = token.lexeme;
6551 self.advance();
6552 Ok(sym)
6553 }
6554 _ => Err(ParseError {
6555 kind: ParseErrorKind::ExpectedIdentifier,
6556 span: self.current_span(),
6557 }),
6558 }
6559 }
6560
6561 fn consume_content_word_for_relative(&mut self) -> ParseResult<Symbol> {
6562 let t = self.advance().clone();
6563 match t.kind {
6564 TokenType::Noun(s) | TokenType::Adjective(s) => Ok(s),
6565 TokenType::ProperName(s) => Ok(s),
6566 TokenType::Verb { lemma, .. } => Ok(lemma),
6567 other => Err(ParseError {
6568 kind: ParseErrorKind::ExpectedContentWord { found: other },
6569 span: self.current_span(),
6570 }),
6571 }
6572 }
6573
6574 fn check_modal(&self) -> bool {
6575 matches!(
6576 self.peek().kind,
6577 TokenType::Must
6578 | TokenType::Shall
6579 | TokenType::Should
6580 | TokenType::Can
6581 | TokenType::May
6582 | TokenType::Cannot
6583 | TokenType::Could
6584 | TokenType::Would
6585 | TokenType::Might
6586 )
6587 }
6588
6589 fn check_pronoun(&self) -> bool {
6590 match &self.peek().kind {
6591 TokenType::Pronoun { case, .. } => {
6592 if self.noun_priority_mode && matches!(case, Case::Possessive) {
6594 return false;
6595 }
6596 true
6597 }
6598 TokenType::Ambiguous { primary, alternatives } => {
6599 if self.noun_priority_mode {
6601 let has_possessive = matches!(**primary, TokenType::Pronoun { case: Case::Possessive, .. })
6602 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { case: Case::Possessive, .. }));
6603 if has_possessive {
6604 return false;
6605 }
6606 }
6607 matches!(**primary, TokenType::Pronoun { .. })
6608 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { .. }))
6609 }
6610 _ => false,
6611 }
6612 }
6613
6614 fn parse_atom(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
6615 if self.check_focus() {
6617 return self.parse_focus();
6618 }
6619
6620 if self.check_measure() {
6622 return self.parse_measure();
6623 }
6624
6625 if self.check_quantifier() {
6626 self.advance();
6627 return self.parse_quantified();
6628 }
6629
6630 if self.check_npi_quantifier() {
6631 return self.parse_npi_quantified();
6632 }
6633
6634 if self.check_temporal_npi() {
6635 return self.parse_temporal_npi();
6636 }
6637
6638 if self.match_token(&[TokenType::LParen]) {
6639 let expr = self.parse_sentence()?;
6640 self.consume(TokenType::RParen)?;
6641 return Ok(expr);
6642 }
6643
6644 if self.check_pronoun() {
6646 let token = self.advance().clone();
6647 let (gender, number) = match &token.kind {
6648 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
6649 TokenType::Ambiguous { primary, alternatives } => {
6650 if let TokenType::Pronoun { gender, number, .. } = **primary {
6651 (gender, number)
6652 } else {
6653 alternatives.iter().find_map(|t| {
6654 if let TokenType::Pronoun { gender, number, .. } = t {
6655 Some((*gender, *number))
6656 } else {
6657 None
6658 }
6659 }).unwrap_or((Gender::Unknown, Number::Singular))
6660 }
6661 }
6662 _ => (Gender::Unknown, Number::Singular),
6663 };
6664
6665 let token_text = self.interner.resolve(token.lexeme);
6666
6667 if token_text.eq_ignore_ascii_case("it") && self.check_verb() {
6670 if let TokenType::Verb { lemma, time, .. } = &self.peek().kind {
6671 let lemma_str = self.interner.resolve(*lemma);
6672 if Lexer::is_weather_verb(lemma_str) {
6673 let verb = *lemma;
6674 let verb_time = *time;
6675 self.advance(); let event_var = self.get_event_var();
6678 let suppress_existential = self.drs.in_conditional_antecedent();
6679 if suppress_existential {
6680 let event_class = self.interner.intern("Event");
6681 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
6682 }
6683 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6684 event_var,
6685 verb,
6686 roles: self.ctx.roles.alloc_slice(vec![]), modifiers: self.ctx.syms.alloc_slice(vec![]),
6688 suppress_existential,
6689 world: None,
6690 })));
6691
6692 return Ok(match verb_time {
6693 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
6694 operator: TemporalOperator::Past,
6695 body: neo_event,
6696 }),
6697 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
6698 operator: TemporalOperator::Future,
6699 body: neo_event,
6700 }),
6701 _ => neo_event,
6702 });
6703 }
6704 }
6705 }
6706
6707 let resolved = if token_text.eq_ignore_ascii_case("i") {
6709 ResolvedPronoun::Constant(self.interner.intern("Speaker"))
6710 } else if token_text.eq_ignore_ascii_case("you") {
6711 ResolvedPronoun::Constant(self.interner.intern("Addressee"))
6712 } else {
6713 self.resolve_pronoun(gender, number)?
6715 };
6716
6717 if self.check_performative() {
6719 if let TokenType::Performative(act) = self.advance().kind.clone() {
6720 let sym = match resolved {
6721 ResolvedPronoun::Variable(s) | ResolvedPronoun::Constant(s) => s,
6722 };
6723 if self.check(&TokenType::To) {
6725 self.advance(); if self.check_verb() {
6728 let infinitive_verb = self.consume_verb();
6729
6730 let content = self.ctx.exprs.alloc(LogicExpr::Predicate {
6731 name: infinitive_verb,
6732 args: self.ctx.terms.alloc_slice([Term::Constant(sym)]),
6733 world: None,
6734 });
6735
6736 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6737 performer: sym,
6738 act_type: act,
6739 content,
6740 }));
6741 }
6742 }
6743
6744 if self.check(&TokenType::That) {
6746 self.advance();
6747 }
6748 let content = self.parse_sentence()?;
6749 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6750 performer: sym,
6751 act_type: act,
6752 content,
6753 }));
6754 }
6755 }
6756
6757 return match resolved {
6760 ResolvedPronoun::Variable(sym) => self.parse_predicate_with_subject_as_var(sym),
6761 ResolvedPronoun::Constant(sym) => self.parse_predicate_with_subject(sym),
6762 };
6763 }
6764
6765 let _had_both = self.match_token(&[TokenType::Both]);
6768
6769 let subject = self.parse_noun_phrase(true)?;
6770
6771 if subject.definiteness == Some(Definiteness::Indefinite)
6777 || subject.definiteness == Some(Definiteness::Distal) {
6778 let gender = Self::infer_noun_gender(self.interner.resolve(subject.noun));
6779 let number = if Self::is_plural_noun(self.interner.resolve(subject.noun)) {
6780 Number::Plural
6781 } else {
6782 Number::Singular
6783 };
6784 self.drs.introduce_referent(subject.noun, subject.noun, gender, number);
6786 }
6787
6788 if self.check(&TokenType::And) {
6790 match self.try_parse_plural_subject(&subject) {
6791 Ok(Some(result)) => return Ok(result),
6792 Ok(None) => {} Err(e) => return Err(e), }
6795 }
6796
6797 if self.check_scopal_adverb() {
6799 return self.parse_scopal_adverb(&subject);
6800 }
6801
6802 if self.check(&TokenType::Comma) {
6804 let saved_pos = self.current;
6805 self.advance(); if self.check_pronoun() {
6809 let topic_attempt = self.try_parse(|p| {
6810 let token = p.peek().clone();
6811 let pronoun_features = match &token.kind {
6812 TokenType::Pronoun { gender, number, .. } => Some((*gender, *number)),
6813 TokenType::Ambiguous { primary, alternatives } => {
6814 if let TokenType::Pronoun { gender, number, .. } = **primary {
6815 Some((gender, number))
6816 } else {
6817 alternatives.iter().find_map(|t| {
6818 if let TokenType::Pronoun { gender, number, .. } = t {
6819 Some((*gender, *number))
6820 } else {
6821 None
6822 }
6823 })
6824 }
6825 }
6826 _ => None,
6827 };
6828
6829 if let Some((gender, number)) = pronoun_features {
6830 p.advance(); let resolved = p.resolve_pronoun(gender, number)?;
6832 let resolved_term = match resolved {
6833 ResolvedPronoun::Variable(s) => Term::Variable(s),
6834 ResolvedPronoun::Constant(s) => Term::Constant(s),
6835 };
6836
6837 if p.check_verb() {
6838 let verb = p.consume_verb();
6839 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6840 name: verb,
6841 args: p.ctx.terms.alloc_slice([
6842 resolved_term,
6843 Term::Constant(subject.noun),
6844 ]),
6845 world: None,
6846 });
6847 p.wrap_with_definiteness_full(&subject, predicate)
6848 } else {
6849 Err(ParseError {
6850 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6851 span: p.current_span(),
6852 })
6853 }
6854 } else {
6855 Err(ParseError {
6856 kind: ParseErrorKind::ExpectedContentWord { found: token.kind },
6857 span: p.current_span(),
6858 })
6859 }
6860 });
6861
6862 if let Some(result) = topic_attempt {
6863 return Ok(result);
6864 }
6865 }
6866
6867 if self.check_content_word() {
6869 let topic_attempt = self.try_parse(|p| {
6870 let real_subject = p.parse_noun_phrase(true)?;
6871 if p.check_verb() {
6872 let verb = p.consume_verb();
6873 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6874 name: verb,
6875 args: p.ctx.terms.alloc_slice([
6876 Term::Constant(real_subject.noun),
6877 Term::Constant(subject.noun),
6878 ]),
6879 world: None,
6880 });
6881 p.wrap_with_definiteness_full(&subject, predicate)
6882 } else {
6883 Err(ParseError {
6884 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6885 span: p.current_span(),
6886 })
6887 }
6888 });
6889
6890 if let Some(result) = topic_attempt {
6891 return Ok(result);
6892 }
6893 }
6894
6895 self.current = saved_pos;
6897 }
6898
6899 let mut relative_clause: Option<(Symbol, &'a LogicExpr<'a>)> = None;
6901 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
6902 self.advance();
6903 let var_name = self.next_var_name();
6904 let rel_pred = self.parse_relative_clause(var_name)?;
6905 relative_clause = Some((var_name, rel_pred));
6906 } else if matches!(self.peek().kind, TokenType::Article(_)) && self.is_contact_clause_pattern() {
6907 let var_name = self.next_var_name();
6910 let rel_pred = self.parse_relative_clause(var_name)?;
6911 relative_clause = Some((var_name, rel_pred));
6912 }
6913
6914 if let Some((var_name, rel_clause)) = relative_clause {
6916 if self.check_verb() {
6917 let (verb, verb_time, _, _) = self.consume_verb_with_metadata();
6918 let var_term = Term::Variable(var_name);
6919
6920 let event_var = self.get_event_var();
6921 let suppress_existential = self.drs.in_conditional_antecedent();
6922 let mut modifiers = vec![];
6923 if verb_time == Time::Past {
6924 modifiers.push(self.interner.intern("Past"));
6925 }
6926 let main_pred = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6927 event_var,
6928 verb,
6929 roles: self.ctx.roles.alloc_slice(vec![
6930 (ThematicRole::Agent, var_term),
6931 ]),
6932 modifiers: self.ctx.syms.alloc_slice(modifiers),
6933 suppress_existential,
6934 world: None,
6935 })));
6936
6937 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6938 name: subject.noun,
6939 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6940 world: None,
6941 });
6942
6943 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6944 left: type_pred,
6945 op: TokenType::And,
6946 right: rel_clause,
6947 });
6948
6949 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6950 left: inner,
6951 op: TokenType::And,
6952 right: main_pred,
6953 });
6954
6955 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6956 kind: QuantifierKind::Existential,
6957 variable: var_name,
6958 body,
6959 island_id: self.current_island,
6960 }));
6961 }
6962
6963 if self.is_at_end() || self.check(&TokenType::Period) || self.check(&TokenType::Comma) {
6966 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6967 name: subject.noun,
6968 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6969 world: None,
6970 });
6971
6972 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6973 left: type_pred,
6974 op: TokenType::And,
6975 right: rel_clause,
6976 });
6977
6978 let uniqueness_body = if subject.definiteness == Some(Definiteness::Definite) {
6980 let y_var = self.next_var_name();
6981 let type_pred_y = self.ctx.exprs.alloc(LogicExpr::Predicate {
6982 name: subject.noun,
6983 args: self.ctx.terms.alloc_slice([Term::Variable(y_var)]),
6984 world: None,
6985 });
6986 let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
6987 left: self.ctx.terms.alloc(Term::Variable(y_var)),
6988 right: self.ctx.terms.alloc(Term::Variable(var_name)),
6989 });
6990 let uniqueness_cond = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6991 left: type_pred_y,
6992 op: TokenType::If,
6993 right: identity,
6994 });
6995 let uniqueness = self.ctx.exprs.alloc(LogicExpr::Quantifier {
6996 kind: QuantifierKind::Universal,
6997 variable: y_var,
6998 body: uniqueness_cond,
6999 island_id: self.current_island,
7000 });
7001 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7002 left: body,
7003 op: TokenType::And,
7004 right: uniqueness,
7005 })
7006 } else {
7007 body
7008 };
7009
7010 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7011 kind: QuantifierKind::Existential,
7012 variable: var_name,
7013 body: uniqueness_body,
7014 island_id: self.current_island,
7015 }));
7016 }
7017
7018 relative_clause = Some((var_name, rel_clause));
7020 }
7021
7022 if self.check(&TokenType::Identity) {
7024 self.advance();
7025 let right = self.consume_content_word()?;
7026 return Ok(self.ctx.exprs.alloc(LogicExpr::Identity {
7027 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7028 right: self.ctx.terms.alloc(Term::Constant(right)),
7029 }));
7030 }
7031
7032 if self.check_modal() {
7033 if let Some((var_name, rel_clause)) = relative_clause {
7034 let modal_pred = self.parse_aspect_chain_with_term(Term::Variable(var_name))?;
7035
7036 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7037 name: subject.noun,
7038 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7039 world: None,
7040 });
7041
7042 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7043 left: type_pred,
7044 op: TokenType::And,
7045 right: rel_clause,
7046 });
7047
7048 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7049 left: inner,
7050 op: TokenType::And,
7051 right: modal_pred,
7052 });
7053
7054 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7055 kind: QuantifierKind::Existential,
7056 variable: var_name,
7057 body,
7058 island_id: self.current_island,
7059 }));
7060 }
7061
7062 let modal_pred = self.parse_aspect_chain(subject.noun)?;
7063 return self.wrap_with_definiteness_full(&subject, modal_pred);
7064 }
7065
7066 if self.check(&TokenType::Is) || self.check(&TokenType::Are)
7067 || self.check(&TokenType::Was) || self.check(&TokenType::Were)
7068 {
7069 let copula_time = if self.check(&TokenType::Was) || self.check(&TokenType::Were) {
7070 Time::Past
7071 } else {
7072 Time::Present
7073 };
7074 self.advance();
7075
7076 let is_negated = self.check(&TokenType::Not);
7078 if is_negated {
7079 self.advance(); }
7081
7082 if self.check_number() {
7085 let measure = self.parse_measure_phrase()?;
7086
7087 if self.check_comparative() {
7089 return self.parse_comparative(&subject, copula_time, Some(measure));
7090 }
7091
7092 if self.check_content_word() {
7094 let adj = self.consume_content_word()?;
7095 let result = self.ctx.exprs.alloc(LogicExpr::Predicate {
7096 name: adj,
7097 args: self.ctx.terms.alloc_slice([
7098 Term::Constant(subject.noun),
7099 *measure,
7100 ]),
7101 world: None,
7102 });
7103 return self.wrap_with_definiteness_full(&subject, result);
7104 }
7105
7106 if self.check(&TokenType::Period) || self.is_at_end() {
7109 if self.mode == ParserMode::Imperative {
7111 let variable = self.interner.resolve(subject.noun).to_string();
7112 let value = if let Term::Value { kind, .. } = measure {
7113 format!("{:?}", kind)
7114 } else {
7115 "value".to_string()
7116 };
7117 return Err(ParseError {
7118 kind: ParseErrorKind::IsValueEquality { variable, value },
7119 span: self.current_span(),
7120 });
7121 }
7122 let result = self.ctx.exprs.alloc(LogicExpr::Identity {
7123 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7124 right: measure,
7125 });
7126 return self.wrap_with_definiteness_full(&subject, result);
7127 }
7128 }
7129
7130 if self.check_comparative() {
7132 return self.parse_comparative(&subject, copula_time, None);
7133 }
7134
7135 if self.check(&TokenType::Period) || self.is_at_end() {
7137 let var = self.next_var_name();
7138 let body = self.ctx.exprs.alloc(LogicExpr::Identity {
7139 left: self.ctx.terms.alloc(Term::Variable(var)),
7140 right: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7141 });
7142 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7143 kind: QuantifierKind::Existential,
7144 variable: var,
7145 body,
7146 island_id: self.current_island,
7147 }));
7148 }
7149
7150 if self.check(&TokenType::Article(Definiteness::Definite)) {
7152 let saved_pos = self.current;
7153 self.advance();
7154 if self.check_superlative() {
7155 return self.parse_superlative(&subject);
7156 }
7157 self.current = saved_pos;
7158 }
7159
7160 if self.check_article() {
7162 let predicate_np = self.parse_noun_phrase(true)?;
7163 let predicate_noun = predicate_np.noun;
7164
7165 if self.event_reading_mode {
7168 let noun_str = self.interner.resolve(predicate_noun);
7169 if let Some(base_verb) = lexicon::lookup_agentive_noun(noun_str) {
7170 let event_adj = predicate_np.adjectives.iter().find(|adj| {
7172 lexicon::is_event_modifier_adjective(self.interner.resolve(**adj))
7173 });
7174
7175 if let Some(&adj_sym) = event_adj {
7176 let verb_sym = self.interner.intern(base_verb);
7178 let event_var = self.get_event_var();
7179
7180 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7181 name: verb_sym,
7182 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
7183 world: None,
7184 });
7185
7186 let agent_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7187 name: self.interner.intern("Agent"),
7188 args: self.ctx.terms.alloc_slice([
7189 Term::Variable(event_var),
7190 Term::Constant(subject.noun),
7191 ]),
7192 world: None,
7193 });
7194
7195 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7196 name: adj_sym,
7197 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
7198 world: None,
7199 });
7200
7201 let verb_agent = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7203 left: verb_pred,
7204 op: TokenType::And,
7205 right: agent_pred,
7206 });
7207
7208 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7210 left: verb_agent,
7211 op: TokenType::And,
7212 right: adj_pred,
7213 });
7214
7215 let event_reading = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7217 kind: QuantifierKind::Existential,
7218 variable: event_var,
7219 body,
7220 island_id: self.current_island,
7221 });
7222
7223 return self.wrap_with_definiteness(subject.definiteness, subject.noun, event_reading);
7224 }
7225 }
7226 }
7227
7228 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7229 let predicate_sort = lexicon::lookup_sort(self.interner.resolve(predicate_noun));
7230
7231 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
7232 if !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
7233 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7234 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7235 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_noun)),
7236 });
7237 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7238 }
7239 }
7240
7241 let mut predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
7244
7245 for &adj_sym in predicate_np.adjectives {
7247 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7248 name: adj_sym,
7249 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7250 world: None,
7251 });
7252 predicates.push(adj_pred);
7253 }
7254
7255 let noun_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7257 name: predicate_noun,
7258 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7259 world: None,
7260 });
7261 predicates.push(noun_pred);
7262
7263 let result = if predicates.len() == 1 {
7265 predicates[0]
7266 } else {
7267 let mut combined = predicates[0];
7268 for pred in &predicates[1..] {
7269 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7270 left: combined,
7271 op: TokenType::And,
7272 right: *pred,
7273 });
7274 }
7275 combined
7276 };
7277
7278 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7279 }
7280
7281 let prefer_adjective = if let TokenType::Ambiguous { primary, alternatives } = &self.peek().kind {
7284 let is_simple_verb = if let TokenType::Verb { aspect, .. } = **primary {
7285 aspect == Aspect::Simple
7286 } else {
7287 false
7288 };
7289 let has_adj_alt = alternatives.iter().any(|t| matches!(t, TokenType::Adjective(_)));
7290 is_simple_verb && has_adj_alt
7291 } else {
7292 false
7293 };
7294
7295 if !prefer_adjective && self.check_verb() {
7296 let (verb, _verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
7297
7298 if verb_class.is_stative() && verb_aspect == Aspect::Progressive {
7300 return Err(ParseError {
7301 kind: ParseErrorKind::StativeProgressiveConflict,
7302 span: self.current_span(),
7303 });
7304 }
7305
7306 let mut goal_args: Vec<Term<'a>> = Vec::new();
7309 while self.check_to_preposition() {
7310 self.advance(); let goal = self.parse_noun_phrase(true)?;
7312 goal_args.push(self.noun_phrase_to_term(&goal));
7313 }
7314
7315 if self.check_by_preposition() {
7317 self.advance(); let agent = self.parse_noun_phrase(true)?;
7319
7320 let mut args = vec![
7322 self.noun_phrase_to_term(&agent),
7323 self.noun_phrase_to_term(&subject),
7324 ];
7325 args.extend(goal_args);
7326
7327 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7328 name: verb,
7329 args: self.ctx.terms.alloc_slice(args),
7330 world: None,
7331 });
7332
7333 let with_time = if copula_time == Time::Past {
7334 self.ctx.exprs.alloc(LogicExpr::Temporal {
7335 operator: TemporalOperator::Past,
7336 body: predicate,
7337 })
7338 } else {
7339 predicate
7340 };
7341
7342 return self.wrap_with_definiteness(subject.definiteness, subject.noun, with_time);
7343 }
7344
7345 if copula_time == Time::Past && verb_aspect == Aspect::Simple
7350 && subject.definiteness != Some(Definiteness::Definite) {
7351 let var_name = self.next_var_name();
7353 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7354 name: verb,
7355 args: self.ctx.terms.alloc_slice([
7356 Term::Variable(var_name),
7357 Term::Constant(subject.noun),
7358 ]),
7359 world: None,
7360 });
7361
7362 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7363 name: subject.noun,
7364 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7365 world: None,
7366 });
7367
7368 let temporal = self.ctx.exprs.alloc(LogicExpr::Temporal {
7369 operator: TemporalOperator::Past,
7370 body: predicate,
7371 });
7372
7373 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7374 left: type_pred,
7375 op: TokenType::And,
7376 right: temporal,
7377 });
7378
7379 let result = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7380 kind: QuantifierKind::Existential,
7381 variable: var_name,
7382 body,
7383 island_id: self.current_island,
7384 });
7385
7386 if is_negated {
7388 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7389 op: TokenType::Not,
7390 operand: result,
7391 }));
7392 }
7393 return Ok(result);
7394 }
7395
7396 let verb_str = self.interner.resolve(verb).to_lowercase();
7399 let subject_term = if lexicon::is_intensional_predicate(&verb_str) {
7400 Term::Intension(subject.noun)
7401 } else {
7402 Term::Constant(subject.noun)
7403 };
7404
7405 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7406 name: verb,
7407 args: self.ctx.terms.alloc_slice([subject_term]),
7408 world: None,
7409 });
7410
7411 let with_aspect = if verb_aspect == Aspect::Progressive {
7412 let operator = if verb_class == VerbClass::Semelfactive {
7414 AspectOperator::Iterative
7415 } else {
7416 AspectOperator::Progressive
7417 };
7418 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7419 operator,
7420 body: predicate,
7421 })
7422 } else {
7423 predicate
7424 };
7425
7426 let with_time = if copula_time == Time::Past {
7427 self.ctx.exprs.alloc(LogicExpr::Temporal {
7428 operator: TemporalOperator::Past,
7429 body: with_aspect,
7430 })
7431 } else {
7432 with_aspect
7433 };
7434
7435 let final_expr = if is_negated {
7436 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7437 op: TokenType::Not,
7438 operand: with_time,
7439 })
7440 } else {
7441 with_time
7442 };
7443
7444 if subject.definiteness == Some(Definiteness::Definite) {
7448 return Ok(final_expr);
7449 }
7450
7451 return self.wrap_with_definiteness(subject.definiteness, subject.noun, final_expr);
7452 }
7453
7454 if let Some((var_name, rel_clause)) = relative_clause {
7456 let var_term = Term::Variable(var_name);
7457 let pred_word = self.consume_content_word()?;
7458
7459 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7460 name: pred_word,
7461 args: self.ctx.terms.alloc_slice([var_term]),
7462 world: None,
7463 });
7464
7465 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7466 name: subject.noun,
7467 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7468 world: None,
7469 });
7470
7471 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7472 left: type_pred,
7473 op: TokenType::And,
7474 right: rel_clause,
7475 });
7476
7477 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7478 left: inner,
7479 op: TokenType::And,
7480 right: main_pred,
7481 });
7482
7483 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7484 kind: QuantifierKind::Existential,
7485 variable: var_name,
7486 body,
7487 island_id: self.current_island,
7488 }));
7489 }
7490
7491 if let TokenType::ProperName(predicate_name) = self.peek().kind {
7496 self.advance(); let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
7498 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7499 right: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7500 });
7501 let result = if is_negated {
7502 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7503 op: TokenType::Not,
7504 operand: identity,
7505 })
7506 } else {
7507 identity
7508 };
7509 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7510 }
7511
7512 let predicate_name = self.consume_content_word()?;
7515
7516 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7518 let predicate_str = self.interner.resolve(predicate_name);
7519
7520 if let Some(s_sort) = subject_sort {
7522 if !crate::ontology::check_sort_compatibility(predicate_str, s_sort) {
7523 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7524 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7525 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7526 });
7527 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7528 }
7529 }
7530
7531 let predicate_sort = lexicon::lookup_sort(predicate_str);
7533 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
7534 if s_sort != p_sort && !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
7535 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7536 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7537 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7538 });
7539 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7540 }
7541 }
7542
7543 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7544 name: predicate_name,
7545 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7546 world: None,
7547 });
7548
7549 let result = if is_negated {
7551 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7552 op: TokenType::Not,
7553 operand: predicate,
7554 })
7555 } else {
7556 predicate
7557 };
7558 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7559 }
7560
7561 if self.check_auxiliary() && self.is_true_auxiliary_usage() {
7565 let aux_time = if let TokenType::Auxiliary(time) = self.advance().kind {
7566 time
7567 } else {
7568 Time::None
7569 };
7570 self.pending_time = Some(aux_time);
7571
7572 if self.match_token(&[TokenType::Not]) {
7574 self.negative_depth += 1;
7575
7576 if self.check(&TokenType::Ever) {
7578 self.advance();
7579 }
7580
7581 if self.check_verb() || self.check(&TokenType::Do) {
7583 let verb = if self.check(&TokenType::Do) {
7584 self.advance(); self.interner.intern("Do")
7586 } else {
7587 self.consume_verb()
7588 };
7589 let subject_term = self.noun_phrase_to_term(&subject);
7590
7591 if self.check_npi_object() {
7593 let npi_token = self.advance().kind.clone();
7594 let obj_var = self.next_var_name();
7595
7596 let restriction_name = match npi_token {
7597 TokenType::Anything => "Thing",
7598 TokenType::Anyone => "Person",
7599 _ => "Thing",
7600 };
7601
7602 let restriction_sym = self.interner.intern(restriction_name);
7603 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7604 name: restriction_sym,
7605 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7606 world: None,
7607 });
7608
7609 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7610 name: verb,
7611 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7612 world: None,
7613 });
7614
7615 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7616 left: obj_restriction,
7617 op: TokenType::And,
7618 right: verb_pred,
7619 });
7620
7621 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7622 kind: QuantifierKind::Existential,
7623 variable: obj_var,
7624 body,
7625 island_id: self.current_island,
7626 });
7627
7628 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7629 let with_time = match effective_time {
7630 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7631 operator: TemporalOperator::Past,
7632 body: quantified,
7633 }),
7634 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7635 operator: TemporalOperator::Future,
7636 body: quantified,
7637 }),
7638 _ => quantified,
7639 };
7640
7641 self.negative_depth -= 1;
7642 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7643 op: TokenType::Not,
7644 operand: with_time,
7645 }));
7646 }
7647
7648 if self.check_quantifier() {
7650 let quantifier_token = self.advance().kind.clone();
7651 let object_np = self.parse_noun_phrase(false)?;
7652 let obj_var = self.next_var_name();
7653
7654 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7655 name: object_np.noun,
7656 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7657 world: None,
7658 });
7659
7660 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7661 name: verb,
7662 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7663 world: None,
7664 });
7665
7666 let (kind, body) = match quantifier_token {
7667 TokenType::Any => {
7668 if self.is_negative_context() {
7669 (
7670 QuantifierKind::Existential,
7671 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7672 left: obj_restriction,
7673 op: TokenType::And,
7674 right: verb_pred,
7675 }),
7676 )
7677 } else {
7678 (
7679 QuantifierKind::Universal,
7680 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7681 left: obj_restriction,
7682 op: TokenType::If,
7683 right: verb_pred,
7684 }),
7685 )
7686 }
7687 }
7688 TokenType::Some => (
7689 QuantifierKind::Existential,
7690 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7691 left: obj_restriction,
7692 op: TokenType::And,
7693 right: verb_pred,
7694 }),
7695 ),
7696 TokenType::All => (
7697 QuantifierKind::Universal,
7698 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7699 left: obj_restriction,
7700 op: TokenType::If,
7701 right: verb_pred,
7702 }),
7703 ),
7704 _ => (
7705 QuantifierKind::Existential,
7706 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7707 left: obj_restriction,
7708 op: TokenType::And,
7709 right: verb_pred,
7710 }),
7711 ),
7712 };
7713
7714 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7715 kind,
7716 variable: obj_var,
7717 body,
7718 island_id: self.current_island,
7719 });
7720
7721 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7722 let with_time = match effective_time {
7723 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7724 operator: TemporalOperator::Past,
7725 body: quantified,
7726 }),
7727 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7728 operator: TemporalOperator::Future,
7729 body: quantified,
7730 }),
7731 _ => quantified,
7732 };
7733
7734 self.negative_depth -= 1;
7735 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7736 op: TokenType::Not,
7737 operand: with_time,
7738 }));
7739 }
7740
7741 let mut roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
7742
7743 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7745 let mut modifiers: Vec<Symbol> = vec![];
7746 match effective_time {
7747 Time::Past => modifiers.push(self.interner.intern("Past")),
7748 Time::Future => modifiers.push(self.interner.intern("Future")),
7749 _ => {}
7750 }
7751
7752 if self.check_content_word() || self.check_article() || self.check_pronoun() {
7754 if self.check_pronoun() {
7755 let pronoun_token = self.advance();
7757 let pronoun_sym = pronoun_token.lexeme;
7758 roles.push((ThematicRole::Theme, Term::Constant(pronoun_sym)));
7759 } else {
7760 let object = self.parse_noun_phrase(false)?;
7761 let object_term = self.noun_phrase_to_term(&object);
7762 roles.push((ThematicRole::Theme, object_term));
7763 }
7764 }
7765
7766 let event_var = self.get_event_var();
7767 let suppress_existential = self.drs.in_conditional_antecedent();
7768 if suppress_existential {
7769 let event_class = self.interner.intern("Event");
7770 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7771 }
7772 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7773 event_var,
7774 verb,
7775 roles: self.ctx.roles.alloc_slice(roles),
7776 modifiers: self.ctx.syms.alloc_slice(modifiers),
7777 suppress_existential,
7778 world: None,
7779 })));
7780
7781 self.negative_depth -= 1;
7782 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7783 op: TokenType::Not,
7784 operand: neo_event,
7785 }));
7786 }
7787
7788 self.negative_depth -= 1;
7789 }
7790 }
7792
7793 if self.check_presup_trigger() && !self.is_followed_by_np_object() && self.is_followed_by_gerund() {
7799 let presup_kind = match self.advance().kind {
7800 TokenType::PresupTrigger(kind) => kind,
7801 TokenType::Verb { lemma, .. } => {
7802 let s = self.interner.resolve(lemma).to_lowercase();
7803 crate::lexicon::lookup_presup_trigger(&s)
7804 .expect("Lexicon mismatch: Verb flagged as trigger but lookup failed")
7805 }
7806 _ => panic!("Expected presupposition trigger"),
7807 };
7808 return self.parse_presupposition(&subject, presup_kind);
7809 }
7810
7811 let noun_str = self.interner.resolve(subject.noun);
7813 let is_bare_plural = subject.definiteness.is_none()
7814 && subject.possessor.is_none()
7815 && Self::is_plural_noun(noun_str)
7816 && self.check_verb();
7817
7818 if is_bare_plural {
7819 let var_name = self.next_var_name();
7820 let (verb, verb_time, verb_aspect, _) = self.consume_verb_with_metadata();
7821
7822 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7823 name: subject.noun,
7824 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7825 world: None,
7826 });
7827
7828 let mut args = vec![Term::Variable(var_name)];
7829 if self.check_content_word() {
7830 let object = self.parse_noun_phrase(false)?;
7831 args.push(self.noun_phrase_to_term(&object));
7832 }
7833
7834 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7835 name: verb,
7836 args: self.ctx.terms.alloc_slice(args),
7837 world: None,
7838 });
7839
7840 let effective_time = self.pending_time.take().unwrap_or(verb_time);
7841 let with_time = match effective_time {
7842 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7843 operator: TemporalOperator::Past,
7844 body: verb_pred,
7845 }),
7846 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7847 operator: TemporalOperator::Future,
7848 body: verb_pred,
7849 }),
7850 _ => verb_pred,
7851 };
7852
7853 let with_aspect = if verb_aspect == Aspect::Progressive {
7854 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7855 operator: AspectOperator::Progressive,
7856 body: with_time,
7857 })
7858 } else {
7859 with_time
7860 };
7861
7862 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7863 left: type_pred,
7864 op: TokenType::If,
7865 right: with_aspect,
7866 });
7867
7868 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7869 kind: QuantifierKind::Generic,
7870 variable: var_name,
7871 body,
7872 island_id: self.current_island,
7873 }));
7874 }
7875
7876 if self.check(&TokenType::Does) || self.check(&TokenType::Do) {
7878 self.advance(); let is_negated = self.match_token(&[TokenType::Not]);
7880
7881 if self.check_verb() {
7882 let verb = self.consume_verb();
7883 let verb_lemma = self.interner.resolve(verb).to_lowercase();
7884
7885 if self.check_wh_word() {
7887 let wh_token = self.advance().kind.clone();
7888 let is_who = matches!(wh_token, TokenType::Who);
7889 let is_what = matches!(wh_token, TokenType::What);
7890
7891 let is_sluicing = self.is_at_end() ||
7892 self.check(&TokenType::Period) ||
7893 self.check(&TokenType::Comma);
7894
7895 if is_sluicing {
7896 if let Some(template) = self.last_event_template.clone() {
7897 let wh_var = self.next_var_name();
7898 let subject_term = self.noun_phrase_to_term(&subject);
7899
7900 let roles: Vec<_> = if is_who {
7901 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7902 .chain(template.non_agent_roles.iter().cloned())
7903 .collect()
7904 } else if is_what {
7905 vec![
7906 (ThematicRole::Agent, subject_term.clone()),
7907 (ThematicRole::Theme, Term::Variable(wh_var)),
7908 ]
7909 } else {
7910 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7911 .chain(template.non_agent_roles.iter().cloned())
7912 .collect()
7913 };
7914
7915 let event_var = self.get_event_var();
7916 let suppress_existential = self.drs.in_conditional_antecedent();
7917 if suppress_existential {
7918 let event_class = self.interner.intern("Event");
7919 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7920 }
7921 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7922 event_var,
7923 verb: template.verb,
7924 roles: self.ctx.roles.alloc_slice(roles),
7925 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
7926 suppress_existential,
7927 world: None,
7928 })));
7929
7930 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7931 wh_variable: wh_var,
7932 body: reconstructed,
7933 });
7934
7935 let know_event_var = self.get_event_var();
7936 let suppress_existential2 = self.drs.in_conditional_antecedent();
7937 if suppress_existential2 {
7938 let event_class = self.interner.intern("Event");
7939 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
7940 }
7941 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7942 event_var: know_event_var,
7943 verb,
7944 roles: self.ctx.roles.alloc_slice(vec![
7945 (ThematicRole::Agent, subject_term),
7946 (ThematicRole::Theme, Term::Proposition(question)),
7947 ]),
7948 modifiers: self.ctx.syms.alloc_slice(vec![]),
7949 suppress_existential: suppress_existential2,
7950 world: None,
7951 })));
7952
7953 let result = if is_negated {
7954 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7955 op: TokenType::Not,
7956 operand: know_event,
7957 })
7958 } else {
7959 know_event
7960 };
7961
7962 return self.wrap_with_definiteness_full(&subject, result);
7963 }
7964 }
7965 }
7966
7967 if verb_lemma == "exist" && is_negated {
7969 let var_name = self.next_var_name();
7971 let restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7972 name: subject.noun,
7973 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7974 world: None,
7975 });
7976 let exists = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7977 kind: QuantifierKind::Existential,
7978 variable: var_name,
7979 body: restriction,
7980 island_id: self.current_island,
7981 });
7982 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7983 op: TokenType::Not,
7984 operand: exists,
7985 }));
7986 }
7987
7988 let subject_term = self.noun_phrase_to_term(&subject);
7991 let modifiers: Vec<Symbol> = vec![];
7992
7993 if self.check(&TokenType::Reflexive) {
7995 self.advance();
7996 let roles = vec![
7997 (ThematicRole::Agent, subject_term.clone()),
7998 (ThematicRole::Theme, subject_term),
7999 ];
8000 let event_var = self.get_event_var();
8001 let suppress_existential = self.drs.in_conditional_antecedent();
8002 if suppress_existential {
8003 let event_class = self.interner.intern("Event");
8004 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8005 }
8006 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8007 event_var,
8008 verb,
8009 roles: self.ctx.roles.alloc_slice(roles),
8010 modifiers: self.ctx.syms.alloc_slice(modifiers),
8011 suppress_existential,
8012 world: None,
8013 })));
8014
8015 let result = if is_negated {
8016 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8017 op: TokenType::Not,
8018 operand: neo_event,
8019 })
8020 } else {
8021 neo_event
8022 };
8023 return self.wrap_with_definiteness_full(&subject, result);
8024 }
8025
8026 if self.check_npi_quantifier() || self.check_quantifier() || self.check_article() {
8028 let (obj_quantifier, was_definite_article) = if self.check_npi_quantifier() {
8029 let tok = self.advance().kind.clone();
8031 (Some(tok), false)
8032 } else if self.check_quantifier() {
8033 (Some(self.advance().kind.clone()), false)
8034 } else {
8035 let art = self.advance().kind.clone();
8036 if let TokenType::Article(def) = art {
8037 if def == Definiteness::Indefinite {
8038 (Some(TokenType::Some), false)
8039 } else {
8040 (None, true)
8041 }
8042 } else {
8043 (None, false)
8044 }
8045 };
8046
8047 let object_np = self.parse_noun_phrase(false)?;
8048 let obj_var = self.next_var_name();
8049
8050 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8051 name: object_np.noun,
8052 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8053 world: None,
8054 });
8055
8056 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8058 self.advance();
8059 let rel_clause = self.parse_relative_clause(obj_var)?;
8060 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8061 left: type_pred,
8062 op: TokenType::And,
8063 right: rel_clause,
8064 })
8065 } else {
8066 type_pred
8067 };
8068
8069 let event_var = self.get_event_var();
8070 let suppress_existential = self.drs.in_conditional_antecedent();
8071 if suppress_existential {
8072 let event_class = self.interner.intern("Event");
8073 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8074 }
8075
8076 let roles = vec![
8077 (ThematicRole::Agent, subject_term),
8078 (ThematicRole::Theme, Term::Variable(obj_var)),
8079 ];
8080
8081 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8082 event_var,
8083 verb,
8084 roles: self.ctx.roles.alloc_slice(roles),
8085 modifiers: self.ctx.syms.alloc_slice(modifiers),
8086 suppress_existential,
8087 world: None,
8088 })));
8089
8090 let quantifier_kind = match &obj_quantifier {
8094 Some(TokenType::Any) if is_negated => QuantifierKind::Existential,
8095 Some(TokenType::All) => QuantifierKind::Universal,
8096 Some(TokenType::No) => QuantifierKind::Universal,
8097 _ => QuantifierKind::Existential,
8098 };
8099
8100 let obj_body = match &obj_quantifier {
8101 Some(TokenType::All) => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8102 left: obj_restriction,
8103 op: TokenType::If,
8104 right: neo_event,
8105 }),
8106 Some(TokenType::No) => {
8107 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8108 op: TokenType::Not,
8109 operand: neo_event,
8110 });
8111 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8112 left: obj_restriction,
8113 op: TokenType::If,
8114 right: neg,
8115 })
8116 }
8117 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8118 left: obj_restriction,
8119 op: TokenType::And,
8120 right: neo_event,
8121 }),
8122 };
8123
8124 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8125 kind: quantifier_kind,
8126 variable: obj_var,
8127 body: obj_body,
8128 island_id: self.current_island,
8129 });
8130
8131 let result = if is_negated && matches!(obj_quantifier, Some(TokenType::Any)) {
8133 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8134 op: TokenType::Not,
8135 operand: obj_quantified,
8136 })
8137 } else if is_negated {
8138 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8140 op: TokenType::Not,
8141 operand: obj_quantified,
8142 })
8143 } else {
8144 obj_quantified
8145 };
8146
8147 return self.wrap_with_definiteness_full(&subject, result);
8148 }
8149
8150 let roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
8152 let event_var = self.get_event_var();
8153 let suppress_existential = self.drs.in_conditional_antecedent();
8154 if suppress_existential {
8155 let event_class = self.interner.intern("Event");
8156 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8157 }
8158
8159 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8160 event_var,
8161 verb,
8162 roles: self.ctx.roles.alloc_slice(roles),
8163 modifiers: self.ctx.syms.alloc_slice(modifiers),
8164 suppress_existential,
8165 world: None,
8166 })));
8167
8168 if is_negated {
8169 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8170 op: TokenType::Not,
8171 operand: neo_event,
8172 }));
8173 }
8174 return Ok(neo_event);
8175 }
8176 }
8177
8178 let is_perfect_aux = if self.check_verb() {
8184 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
8185 word == "has" || word == "have" || word == "had"
8186 } else {
8187 false
8188 };
8189 if subject.definiteness == Some(Definiteness::Definite) && self.check_verb() && self.pending_time.is_none() && !is_perfect_aux {
8190 let saved_pos = self.current;
8191
8192 if let Some(garden_path_result) = self.try_parse(|p| {
8194 let (modifier_verb, _modifier_time, _, _) = p.consume_verb_with_metadata();
8195
8196 let mut pp_mods: Vec<&'a LogicExpr<'a>> = Vec::new();
8198 while p.check_preposition() {
8199 let prep = if let TokenType::Preposition(prep) = p.advance().kind {
8200 prep
8201 } else {
8202 break;
8203 };
8204 if p.check_article() || p.check_content_word() {
8205 let pp_obj = p.parse_noun_phrase(false)?;
8206 let pp_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8207 name: prep,
8208 args: p.ctx.terms.alloc_slice([Term::Variable(p.interner.intern("x")), Term::Constant(pp_obj.noun)]),
8209 world: None,
8210 });
8211 pp_mods.push(pp_pred);
8212 }
8213 }
8214
8215 if !p.check_verb() {
8217 return Err(ParseError {
8218 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
8219 span: p.current_span(),
8220 });
8221 }
8222
8223 let (main_verb, main_time, _, _) = p.consume_verb_with_metadata();
8224
8225 let var = p.interner.intern("x");
8227
8228 let type_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8230 name: subject.noun,
8231 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
8232 world: None,
8233 });
8234
8235 let mod_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8237 name: modifier_verb,
8238 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
8239 world: None,
8240 });
8241
8242 let main_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8244 name: main_verb,
8245 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
8246 world: None,
8247 });
8248
8249 let mut body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
8251 left: type_pred,
8252 op: TokenType::And,
8253 right: mod_pred,
8254 });
8255
8256 for pp in pp_mods {
8258 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
8259 left: body,
8260 op: TokenType::And,
8261 right: pp,
8262 });
8263 }
8264
8265 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
8267 left: body,
8268 op: TokenType::And,
8269 right: main_pred,
8270 });
8271
8272 let with_time = match main_time {
8274 Time::Past => p.ctx.exprs.alloc(LogicExpr::Temporal {
8275 operator: TemporalOperator::Past,
8276 body,
8277 }),
8278 Time::Future => p.ctx.exprs.alloc(LogicExpr::Temporal {
8279 operator: TemporalOperator::Future,
8280 body,
8281 }),
8282 _ => body,
8283 };
8284
8285 Ok(p.ctx.exprs.alloc(LogicExpr::Quantifier {
8287 kind: QuantifierKind::Existential,
8288 variable: var,
8289 body: with_time,
8290 island_id: p.current_island,
8291 }))
8292 }) {
8293 return Ok(garden_path_result);
8294 }
8295
8296 self.current = saved_pos;
8298 }
8299
8300 if self.check_modal() {
8301 return self.parse_aspect_chain(subject.noun);
8302 }
8303
8304 if self.check_content_word() {
8306 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
8307 if word == "has" || word == "have" || word == "had" {
8308 let is_perfect_aspect = if self.current + 1 < self.tokens.len() {
8310 let next_token = &self.tokens[self.current + 1].kind;
8311 matches!(
8312 next_token,
8313 TokenType::Verb { .. } | TokenType::Not
8314 ) && !matches!(next_token, TokenType::Number(_))
8315 } else {
8316 false
8317 };
8318 if is_perfect_aspect {
8319 return self.parse_aspect_chain(subject.noun);
8320 }
8321 }
8323 }
8324
8325 if self.check(&TokenType::Had) {
8327 return self.parse_aspect_chain(subject.noun);
8328 }
8329
8330 if self.check(&TokenType::Never) {
8332 self.advance();
8333 let verb = self.consume_verb();
8334 let subject_term = self.noun_phrase_to_term(&subject);
8335 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8336 name: verb,
8337 args: self.ctx.terms.alloc_slice([subject_term]),
8338 world: None,
8339 });
8340 let result = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8341 op: TokenType::Not,
8342 operand: verb_pred,
8343 });
8344 return self.wrap_with_definiteness_full(&subject, result);
8345 }
8346
8347 if self.check_verb() {
8348 let (mut verb, verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
8349
8350 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
8352 let verb_str = self.interner.resolve(verb);
8353 if let Some(s_sort) = subject_sort {
8354 if !crate::ontology::check_sort_compatibility(verb_str, s_sort) {
8355 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
8356 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
8357 vehicle: self.ctx.terms.alloc(Term::Constant(verb)),
8358 });
8359 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
8360 }
8361 }
8362
8363 if self.is_control_verb(verb) {
8365 return self.parse_control_structure(&subject, verb, verb_time);
8366 }
8367
8368 if let Some((var_name, rel_clause)) = relative_clause {
8370 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8371 name: verb,
8372 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8373 world: None,
8374 });
8375
8376 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8377 let with_time = match effective_time {
8378 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
8379 operator: TemporalOperator::Past,
8380 body: main_pred,
8381 }),
8382 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
8383 operator: TemporalOperator::Future,
8384 body: main_pred,
8385 }),
8386 _ => main_pred,
8387 };
8388
8389 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8391 name: subject.noun,
8392 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8393 world: None,
8394 });
8395
8396 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8397 left: type_pred,
8398 op: TokenType::And,
8399 right: rel_clause,
8400 });
8401
8402 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8403 left: inner,
8404 op: TokenType::And,
8405 right: with_time,
8406 });
8407
8408 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
8409 kind: QuantifierKind::Existential,
8410 variable: var_name,
8411 body,
8412 island_id: self.current_island,
8413 }));
8414 }
8415
8416 let subject_term = self.noun_phrase_to_term(&subject);
8417 let mut args = vec![subject_term.clone()];
8418
8419 let unknown = self.interner.intern("?");
8420
8421 if self.check_wh_word() {
8423 let wh_token = self.advance().kind.clone();
8424
8425 let is_who = matches!(wh_token, TokenType::Who);
8427 let is_what = matches!(wh_token, TokenType::What);
8428
8429 let is_sluicing = self.is_at_end() ||
8431 self.check(&TokenType::Period) ||
8432 self.check(&TokenType::Comma);
8433
8434 if is_sluicing {
8435 if let Some(template) = self.last_event_template.clone() {
8437 let wh_var = self.next_var_name();
8438
8439 let roles: Vec<_> = if is_who {
8441 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
8443 .chain(template.non_agent_roles.iter().cloned())
8444 .collect()
8445 } else if is_what {
8446 vec![
8448 (ThematicRole::Agent, subject_term.clone()),
8449 (ThematicRole::Theme, Term::Variable(wh_var)),
8450 ]
8451 } else {
8452 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
8454 .chain(template.non_agent_roles.iter().cloned())
8455 .collect()
8456 };
8457
8458 let event_var = self.get_event_var();
8459 let suppress_existential = self.drs.in_conditional_antecedent();
8460 if suppress_existential {
8461 let event_class = self.interner.intern("Event");
8462 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8463 }
8464 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8465 event_var,
8466 verb: template.verb,
8467 roles: self.ctx.roles.alloc_slice(roles),
8468 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
8469 suppress_existential,
8470 world: None,
8471 })));
8472
8473 let question = self.ctx.exprs.alloc(LogicExpr::Question {
8474 wh_variable: wh_var,
8475 body: reconstructed,
8476 });
8477
8478 let know_event_var = self.get_event_var();
8480 let suppress_existential2 = self.drs.in_conditional_antecedent();
8481 if suppress_existential2 {
8482 let event_class = self.interner.intern("Event");
8483 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8484 }
8485 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8486 event_var: know_event_var,
8487 verb,
8488 roles: self.ctx.roles.alloc_slice(vec![
8489 (ThematicRole::Agent, subject_term),
8490 (ThematicRole::Theme, Term::Proposition(question)),
8491 ]),
8492 modifiers: self.ctx.syms.alloc_slice(vec![]),
8493 suppress_existential: suppress_existential2,
8494 world: None,
8495 })));
8496
8497 return self.wrap_with_definiteness_full(&subject, know_event);
8498 }
8499 }
8500
8501 let embedded = self.parse_embedded_wh_clause()?;
8503 let question = self.ctx.exprs.alloc(LogicExpr::Question {
8504 wh_variable: self.interner.intern("x"),
8505 body: embedded,
8506 });
8507
8508 let know_event_var = self.get_event_var();
8510 let suppress_existential = self.drs.in_conditional_antecedent();
8511 if suppress_existential {
8512 let event_class = self.interner.intern("Event");
8513 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8514 }
8515 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8516 event_var: know_event_var,
8517 verb,
8518 roles: self.ctx.roles.alloc_slice(vec![
8519 (ThematicRole::Agent, subject_term),
8520 (ThematicRole::Theme, Term::Proposition(question)),
8521 ]),
8522 modifiers: self.ctx.syms.alloc_slice(vec![]),
8523 suppress_existential,
8524 world: None,
8525 })));
8526
8527 return self.wrap_with_definiteness_full(&subject, know_event);
8528 }
8529
8530 let mut object_term: Option<Term<'a>> = None;
8531 let mut second_object_term: Option<Term<'a>> = None;
8532 let mut object_superlative: Option<(Symbol, Symbol)> = None; if self.check(&TokenType::Reflexive) {
8534 self.advance();
8535 let term = self.noun_phrase_to_term(&subject);
8536 object_term = Some(term.clone());
8537 args.push(term);
8538
8539 if let TokenType::Particle(particle_sym) = self.peek().kind {
8541 let verb_str = self.interner.resolve(verb).to_lowercase();
8542 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8543 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8544 self.advance();
8545 verb = self.interner.intern(phrasal_lemma);
8546 }
8547 }
8548 } else if self.check_pronoun() {
8549 let token = self.advance().clone();
8550 if let TokenType::Pronoun { gender, number, .. } = token.kind {
8551 let resolved = self.resolve_pronoun(gender, number)?;
8552 let term = match resolved {
8553 ResolvedPronoun::Variable(s) => Term::Variable(s),
8554 ResolvedPronoun::Constant(s) => Term::Constant(s),
8555 };
8556 object_term = Some(term.clone());
8557 args.push(term);
8558
8559 if let TokenType::Particle(particle_sym) = self.peek().kind {
8561 let verb_str = self.interner.resolve(verb).to_lowercase();
8562 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8563 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8564 self.advance();
8565 verb = self.interner.intern(phrasal_lemma);
8566 }
8567 }
8568 }
8569 } else if self.check_quantifier() || self.check_article() {
8570 let (obj_quantifier, was_definite_article) = if self.check_quantifier() {
8572 (Some(self.advance().kind.clone()), false)
8573 } else {
8574 let art = self.advance().kind.clone();
8575 if let TokenType::Article(def) = art {
8576 if def == Definiteness::Indefinite {
8577 (Some(TokenType::Some), false)
8578 } else {
8579 (None, true) }
8581 } else {
8582 (None, false)
8583 }
8584 };
8585
8586 let object_np = self.parse_noun_phrase(false)?;
8587
8588 if let Some(adj) = object_np.superlative {
8590 object_superlative = Some((adj, object_np.noun));
8591 }
8592
8593 if let TokenType::Particle(particle_sym) = self.peek().kind {
8595 let verb_str = self.interner.resolve(verb).to_lowercase();
8596 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8597 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8598 self.advance(); verb = self.interner.intern(phrasal_lemma);
8600 }
8601 }
8602
8603 if let Some(obj_q) = obj_quantifier {
8604 let verb_str = self.interner.resolve(verb).to_lowercase();
8608 let is_opaque = lexicon::lookup_verb_db(&verb_str)
8609 .map(|meta| meta.features.contains(&lexicon::Feature::Opaque))
8610 .unwrap_or(false);
8611
8612 if is_opaque && matches!(obj_q, TokenType::Some) {
8613 let intension_term = Term::Intension(object_np.noun);
8615
8616 let event_var = self.get_event_var();
8618 let mut modifiers = self.collect_adverbs();
8619 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8620 match effective_time {
8621 Time::Past => modifiers.push(self.interner.intern("Past")),
8622 Time::Future => modifiers.push(self.interner.intern("Future")),
8623 _ => {}
8624 }
8625
8626 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8627 let roles = vec![
8628 (ThematicRole::Agent, subject_term_for_event),
8629 (ThematicRole::Theme, intension_term),
8630 ];
8631
8632 let suppress_existential = self.drs.in_conditional_antecedent();
8633 if suppress_existential {
8634 let event_class = self.interner.intern("Event");
8635 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8636 }
8637 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8638 event_var,
8639 verb,
8640 roles: self.ctx.roles.alloc_slice(roles),
8641 modifiers: self.ctx.syms.alloc_slice(modifiers),
8642 suppress_existential,
8643 world: None,
8644 })));
8645
8646 return self.wrap_with_definiteness_full(&subject, neo_event);
8647 }
8648
8649 let obj_var = self.next_var_name();
8650
8651 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8653 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8654 Number::Plural
8655 } else {
8656 Number::Singular
8657 };
8658 if object_np.definiteness == Some(Definiteness::Definite) {
8660 self.drs.introduce_referent_with_source(obj_var, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8661 } else {
8662 self.drs.introduce_referent(obj_var, object_np.noun, obj_gender, obj_number);
8663 }
8664
8665 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8666 name: object_np.noun,
8667 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8668 world: None,
8669 });
8670
8671 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8672 self.advance();
8673 let rel_clause = self.parse_relative_clause(obj_var)?;
8674 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8675 left: type_pred,
8676 op: TokenType::And,
8677 right: rel_clause,
8678 })
8679 } else {
8680 type_pred
8681 };
8682
8683 let event_var = self.get_event_var();
8684 let mut modifiers = self.collect_adverbs();
8685 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8686 match effective_time {
8687 Time::Past => modifiers.push(self.interner.intern("Past")),
8688 Time::Future => modifiers.push(self.interner.intern("Future")),
8689 _ => {}
8690 }
8691
8692 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8693 let roles = vec![
8694 (ThematicRole::Agent, subject_term_for_event),
8695 (ThematicRole::Theme, Term::Variable(obj_var)),
8696 ];
8697
8698 let template_roles = vec![
8701 (ThematicRole::Agent, subject_term_for_event),
8702 (ThematicRole::Theme, Term::Constant(object_np.noun)),
8703 ];
8704 self.capture_event_template(verb, &template_roles, &modifiers);
8705
8706 let suppress_existential = self.drs.in_conditional_antecedent();
8707 if suppress_existential {
8708 let event_class = self.interner.intern("Event");
8709 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8710 }
8711 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8712 event_var,
8713 verb,
8714 roles: self.ctx.roles.alloc_slice(roles),
8715 modifiers: self.ctx.syms.alloc_slice(modifiers),
8716 suppress_existential,
8717 world: None,
8718 })));
8719
8720 let obj_kind = match obj_q {
8721 TokenType::All => QuantifierKind::Universal,
8722 TokenType::Some => QuantifierKind::Existential,
8723 TokenType::No => QuantifierKind::Universal,
8724 TokenType::Most => QuantifierKind::Most,
8725 TokenType::Few => QuantifierKind::Few,
8726 TokenType::Many => QuantifierKind::Many,
8727 TokenType::Cardinal(n) => QuantifierKind::Cardinal(n),
8728 TokenType::AtLeast(n) => QuantifierKind::AtLeast(n),
8729 TokenType::AtMost(n) => QuantifierKind::AtMost(n),
8730 _ => QuantifierKind::Existential,
8731 };
8732
8733 let obj_body = match obj_q {
8734 TokenType::All => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8735 left: obj_restriction,
8736 op: TokenType::If,
8737 right: neo_event,
8738 }),
8739 TokenType::No => {
8740 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8741 op: TokenType::Not,
8742 operand: neo_event,
8743 });
8744 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8745 left: obj_restriction,
8746 op: TokenType::If,
8747 right: neg,
8748 })
8749 }
8750 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8751 left: obj_restriction,
8752 op: TokenType::And,
8753 right: neo_event,
8754 }),
8755 };
8756
8757 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8759 kind: obj_kind,
8760 variable: obj_var,
8761 body: obj_body,
8762 island_id: self.current_island,
8763 });
8764
8765 return self.wrap_with_definiteness_full(&subject, obj_quantified);
8767 } else {
8768 if was_definite_article {
8773 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8774 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8775 Number::Plural
8776 } else {
8777 Number::Singular
8778 };
8779 self.drs.introduce_referent_with_source(object_np.noun, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8781 }
8782
8783 let term = self.noun_phrase_to_term(&object_np);
8784 object_term = Some(term.clone());
8785 args.push(term);
8786 }
8787 } else if self.check_focus() {
8788 let focus_kind = if let TokenType::Focus(k) = self.advance().kind {
8789 k
8790 } else {
8791 FocusKind::Only
8792 };
8793
8794 let event_var = self.get_event_var();
8795 let mut modifiers = self.collect_adverbs();
8796 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8797 match effective_time {
8798 Time::Past => modifiers.push(self.interner.intern("Past")),
8799 Time::Future => modifiers.push(self.interner.intern("Future")),
8800 _ => {}
8801 }
8802
8803 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8804
8805 if self.check_preposition() {
8806 let prep_token = self.advance().clone();
8807 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8808 sym
8809 } else {
8810 self.interner.intern("to")
8811 };
8812 let pp_obj = self.parse_noun_phrase(false)?;
8813 let pp_obj_term = Term::Constant(pp_obj.noun);
8814
8815 let roles = vec![(ThematicRole::Agent, subject_term_for_event)];
8816 let suppress_existential = self.drs.in_conditional_antecedent();
8817 if suppress_existential {
8818 let event_class = self.interner.intern("Event");
8819 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8820 }
8821 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8822 event_var,
8823 verb,
8824 roles: self.ctx.roles.alloc_slice(roles),
8825 modifiers: self.ctx.syms.alloc_slice(modifiers),
8826 suppress_existential,
8827 world: None,
8828 })));
8829
8830 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8831 name: prep_name,
8832 args: self.ctx.terms.alloc_slice([Term::Variable(event_var), pp_obj_term]),
8833 world: None,
8834 });
8835
8836 let with_pp = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8837 left: neo_event,
8838 op: TokenType::And,
8839 right: pp_pred,
8840 });
8841
8842 let focused_ref = self.ctx.terms.alloc(pp_obj_term);
8843 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8844 kind: focus_kind,
8845 focused: focused_ref,
8846 scope: with_pp,
8847 }));
8848 }
8849
8850 let focused_np = self.parse_noun_phrase(false)?;
8851 let focused_term = self.noun_phrase_to_term(&focused_np);
8852 args.push(focused_term.clone());
8853
8854 let roles = vec![
8855 (ThematicRole::Agent, subject_term_for_event),
8856 (ThematicRole::Theme, focused_term.clone()),
8857 ];
8858
8859 let suppress_existential = self.drs.in_conditional_antecedent();
8860 if suppress_existential {
8861 let event_class = self.interner.intern("Event");
8862 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8863 }
8864 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8865 event_var,
8866 verb,
8867 roles: self.ctx.roles.alloc_slice(roles),
8868 modifiers: self.ctx.syms.alloc_slice(modifiers),
8869 suppress_existential,
8870 world: None,
8871 })));
8872
8873 let focused_ref = self.ctx.terms.alloc(focused_term);
8874 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8875 kind: focus_kind,
8876 focused: focused_ref,
8877 scope: neo_event,
8878 }));
8879 } else if self.check_number() {
8880 let measure = self.parse_measure_phrase()?;
8882
8883 if self.check_content_word() {
8885 let noun_sym = self.consume_content_word()?;
8886 let count_term = *measure;
8888 object_term = Some(count_term.clone());
8889 args.push(count_term);
8890 second_object_term = Some(Term::Constant(noun_sym));
8891 args.push(Term::Constant(noun_sym));
8892 } else {
8893 object_term = Some(*measure);
8895 args.push(*measure);
8896 }
8897 } else if self.check_content_word() || self.check_article() {
8898 let object = self.parse_noun_phrase(false)?;
8899 if let Some(adj) = object.superlative {
8900 object_superlative = Some((adj, object.noun));
8901 }
8902
8903 let mut all_objects: Vec<Symbol> = vec![object.noun];
8905
8906 while self.check(&TokenType::And) {
8908 let saved = self.current;
8909 self.advance(); if self.check_content_word() || self.check_article() {
8911 let next_obj = match self.parse_noun_phrase(false) {
8912 Ok(np) => np,
8913 Err(_) => {
8914 self.current = saved;
8915 break;
8916 }
8917 };
8918 all_objects.push(next_obj.noun);
8919 } else {
8920 self.current = saved;
8921 break;
8922 }
8923 }
8924
8925 if self.check(&TokenType::Respectively) {
8927 let respectively_span = self.peek().span;
8928 if all_objects.len() > 1 {
8930 return Err(ParseError {
8931 kind: ParseErrorKind::RespectivelyLengthMismatch {
8932 subject_count: 1,
8933 object_count: all_objects.len(),
8934 },
8935 span: respectively_span,
8936 });
8937 }
8938 self.advance(); }
8941
8942 let term = self.noun_phrase_to_term(&object);
8944 object_term = Some(term.clone());
8945 args.push(term.clone());
8946
8947 if all_objects.len() > 1 {
8949 let obj_members: Vec<Term<'a>> = all_objects.iter()
8950 .map(|o| Term::Constant(*o))
8951 .collect();
8952 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
8953 args.pop();
8955 args.push(obj_group);
8956 }
8957
8958 if let TokenType::Particle(particle_sym) = self.peek().kind {
8960 let verb_str = self.interner.resolve(verb).to_lowercase();
8961 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8962 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8963 self.advance(); verb = self.interner.intern(phrasal_lemma);
8965 }
8966 }
8967
8968 if self.check_number() {
8970 let measure = self.parse_measure_phrase()?;
8971 second_object_term = Some(*measure);
8972 args.push(*measure);
8973 }
8974 else {
8976 let verb_str = self.interner.resolve(verb);
8977 if Lexer::is_ditransitive_verb(verb_str) && (self.check_content_word() || self.check_article()) {
8978 let second_np = self.parse_noun_phrase(false)?;
8979 let second_term = self.noun_phrase_to_term(&second_np);
8980 second_object_term = Some(second_term.clone());
8981 args.push(second_term);
8982 }
8983 }
8984 }
8985
8986 let mut pp_predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
8987 while self.check_preposition() || self.check_to() {
8988 let prep_token = self.advance().clone();
8989 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8990 sym
8991 } else if matches!(prep_token.kind, TokenType::To) {
8992 self.interner.intern("To")
8993 } else {
8994 continue;
8995 };
8996
8997 let pp_obj_term = if self.check(&TokenType::Reflexive) {
8998 self.advance();
8999 self.noun_phrase_to_term(&subject)
9000 } else if self.check_pronoun() {
9001 let token = self.advance().clone();
9002 if let TokenType::Pronoun { gender, number, .. } = token.kind {
9003 let resolved = self.resolve_pronoun(gender, number)?;
9004 match resolved {
9005 ResolvedPronoun::Variable(s) => Term::Variable(s),
9006 ResolvedPronoun::Constant(s) => Term::Constant(s),
9007 }
9008 } else {
9009 continue;
9010 }
9011 } else if self.check_content_word() || self.check_article() {
9012 let prep_obj = self.parse_noun_phrase(false)?;
9013 self.noun_phrase_to_term(&prep_obj)
9014 } else {
9015 continue;
9016 };
9017
9018 if self.pp_attach_to_noun {
9019 if let Some(ref obj) = object_term {
9020 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9022 name: prep_name,
9023 args: self.ctx.terms.alloc_slice([obj.clone(), pp_obj_term]),
9024 world: None,
9025 });
9026 pp_predicates.push(pp_pred);
9027 } else {
9028 args.push(pp_obj_term);
9029 }
9030 } else {
9031 let event_sym = self.get_event_var();
9033 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9034 name: prep_name,
9035 args: self.ctx.terms.alloc_slice([Term::Variable(event_sym), pp_obj_term]),
9036 world: None,
9037 });
9038 pp_predicates.push(pp_pred);
9039 }
9040 }
9041
9042 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
9044 self.advance();
9045 let rel_var = self.next_var_name();
9046 let rel_pred = self.parse_relative_clause(rel_var)?;
9047 pp_predicates.push(rel_pred);
9048 }
9049
9050 let mut modifiers = self.collect_adverbs();
9052
9053 let effective_time = self.pending_time.take().unwrap_or(verb_time);
9055 match effective_time {
9056 Time::Past => modifiers.push(self.interner.intern("Past")),
9057 Time::Future => modifiers.push(self.interner.intern("Future")),
9058 _ => {}
9059 }
9060
9061 if verb_aspect == Aspect::Progressive {
9063 modifiers.push(self.interner.intern("Progressive"));
9064 } else if verb_aspect == Aspect::Perfect {
9065 modifiers.push(self.interner.intern("Perfect"));
9066 }
9067
9068 let mut roles: Vec<(ThematicRole, Term<'a>)> = Vec::new();
9070
9071 let verb_str_for_check = self.interner.resolve(verb).to_lowercase();
9073 let is_unaccusative = crate::lexicon::lookup_verb_db(&verb_str_for_check)
9074 .map(|meta| meta.features.contains(&crate::lexicon::Feature::Unaccusative))
9075 .unwrap_or(false);
9076
9077 let has_object = object_term.is_some() || second_object_term.is_some();
9079 let subject_role = if is_unaccusative && !has_object {
9080 ThematicRole::Theme
9081 } else {
9082 ThematicRole::Agent
9083 };
9084
9085 roles.push((subject_role, subject_term));
9086 if let Some(second_obj) = second_object_term {
9087 if let Some(first_obj) = object_term {
9089 roles.push((ThematicRole::Recipient, first_obj));
9090 }
9091 roles.push((ThematicRole::Theme, second_obj));
9092 } else if let Some(obj) = object_term {
9093 roles.push((ThematicRole::Theme, obj));
9095 }
9096
9097 let event_var = self.get_event_var();
9099
9100 self.capture_event_template(verb, &roles, &modifiers);
9102
9103 let suppress_existential = self.drs.in_conditional_antecedent();
9105 if suppress_existential {
9106 let event_class = self.interner.intern("Event");
9107 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
9108 }
9109 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
9110 event_var,
9111 verb,
9112 roles: self.ctx.roles.alloc_slice(roles),
9113 modifiers: self.ctx.syms.alloc_slice(modifiers),
9114 suppress_existential,
9115 world: None,
9116 })));
9117
9118 let with_pps = if pp_predicates.is_empty() {
9120 neo_event
9121 } else {
9122 let mut combined = neo_event;
9123 for pp in pp_predicates {
9124 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9125 left: combined,
9126 op: TokenType::And,
9127 right: pp,
9128 });
9129 }
9130 combined
9131 };
9132
9133 let with_aspect = if verb_aspect == Aspect::Progressive {
9135 if verb_class == crate::lexicon::VerbClass::Semelfactive {
9137 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9138 operator: AspectOperator::Iterative,
9139 body: with_pps,
9140 })
9141 } else {
9142 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9144 operator: AspectOperator::Progressive,
9145 body: with_pps,
9146 })
9147 }
9148 } else if verb_aspect == Aspect::Perfect {
9149 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9150 operator: AspectOperator::Perfect,
9151 body: with_pps,
9152 })
9153 } else if effective_time == Time::Present && verb_aspect == Aspect::Simple {
9154 if !verb_class.is_stative() {
9156 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9157 operator: AspectOperator::Habitual,
9158 body: with_pps,
9159 })
9160 } else {
9161 with_pps
9163 }
9164 } else {
9165 with_pps
9166 };
9167
9168 let with_adverbs = with_aspect;
9169
9170 let with_temporal = if self.check_temporal_adverb() {
9172 let anchor = if let TokenType::TemporalAdverb(adv) = self.advance().kind.clone() {
9173 adv
9174 } else {
9175 panic!("Expected temporal adverb");
9176 };
9177 self.ctx.exprs.alloc(LogicExpr::TemporalAnchor {
9178 anchor,
9179 body: with_adverbs,
9180 })
9181 } else {
9182 with_adverbs
9183 };
9184
9185 let wrapped = self.wrap_with_definiteness_full(&subject, with_temporal)?;
9186
9187 if let Some((adj, noun)) = object_superlative {
9189 let superlative_expr = self.ctx.exprs.alloc(LogicExpr::Superlative {
9190 adjective: adj,
9191 subject: self.ctx.terms.alloc(Term::Constant(noun)),
9192 domain: noun,
9193 });
9194 return Ok(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9195 left: wrapped,
9196 op: TokenType::And,
9197 right: superlative_expr,
9198 }));
9199 }
9200
9201 return Ok(wrapped);
9202 }
9203
9204 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(subject.noun)))
9205 }
9206
9207 fn check_preposition(&self) -> bool {
9208 matches!(self.peek().kind, TokenType::Preposition(_))
9209 }
9210
9211 fn check_by_preposition(&self) -> bool {
9212 if let TokenType::Preposition(p) = self.peek().kind {
9213 p.is(self.interner, "by")
9214 } else {
9215 false
9216 }
9217 }
9218
9219 fn check_preposition_is(&self, word: &str) -> bool {
9220 if let TokenType::Preposition(p) = self.peek().kind {
9221 p.is(self.interner, word)
9222 } else {
9223 false
9224 }
9225 }
9226
9227 fn check_word(&self, word: &str) -> bool {
9229 let token = self.peek();
9230 let lexeme = self.interner.resolve(token.lexeme);
9231 lexeme.eq_ignore_ascii_case(word)
9232 }
9233
9234 fn peek_word_at(&self, offset: usize, word: &str) -> bool {
9235 if self.current + offset >= self.tokens.len() {
9236 return false;
9237 }
9238 let token = &self.tokens[self.current + offset];
9239 let lexeme = self.interner.resolve(token.lexeme);
9240 lexeme.eq_ignore_ascii_case(word)
9241 }
9242
9243 fn check_to_preposition(&self) -> bool {
9244 match self.peek().kind {
9245 TokenType::To => true,
9246 TokenType::Preposition(p) => p.is(self.interner, "to"),
9247 _ => false,
9248 }
9249 }
9250
9251 fn check_content_word(&self) -> bool {
9252 match &self.peek().kind {
9253 TokenType::Noun(_)
9254 | TokenType::Adjective(_)
9255 | TokenType::NonIntersectiveAdjective(_)
9256 | TokenType::Verb { .. }
9257 | TokenType::ProperName(_)
9258 | TokenType::Article(_) => true,
9259 TokenType::Ambiguous { primary, alternatives } => {
9260 Self::is_content_word_type(primary)
9261 || alternatives.iter().any(Self::is_content_word_type)
9262 }
9263 _ => false,
9264 }
9265 }
9266
9267 fn is_content_word_type(t: &TokenType) -> bool {
9268 matches!(
9269 t,
9270 TokenType::Noun(_)
9271 | TokenType::Adjective(_)
9272 | TokenType::NonIntersectiveAdjective(_)
9273 | TokenType::Verb { .. }
9274 | TokenType::ProperName(_)
9275 | TokenType::Article(_)
9276 )
9277 }
9278
9279 fn check_verb(&self) -> bool {
9280 match &self.peek().kind {
9281 TokenType::Verb { .. } => true,
9282 TokenType::Ambiguous { primary, alternatives } => {
9283 if self.noun_priority_mode {
9284 return false;
9285 }
9286 matches!(**primary, TokenType::Verb { .. })
9287 || alternatives.iter().any(|t| matches!(t, TokenType::Verb { .. }))
9288 }
9289 _ => false,
9290 }
9291 }
9292
9293 fn check_adverb(&self) -> bool {
9294 matches!(self.peek().kind, TokenType::Adverb(_))
9295 }
9296
9297 fn check_performative(&self) -> bool {
9298 matches!(self.peek().kind, TokenType::Performative(_))
9299 }
9300
9301 fn collect_adverbs(&mut self) -> Vec<Symbol> {
9302 let mut adverbs = Vec::new();
9303 while self.check_adverb() {
9304 if let TokenType::Adverb(adv) = self.advance().kind.clone() {
9305 adverbs.push(adv);
9306 }
9307 if self.check(&TokenType::And) {
9309 self.advance();
9310 }
9311 }
9312 adverbs
9313 }
9314
9315 fn check_auxiliary(&self) -> bool {
9316 matches!(self.peek().kind, TokenType::Auxiliary(_))
9317 }
9318
9319 fn is_true_auxiliary_usage(&self) -> bool {
9326 if self.current + 1 >= self.tokens.len() {
9327 return false;
9328 }
9329
9330 let next_token = &self.tokens[self.current + 1].kind;
9331
9332 if matches!(next_token, TokenType::Not) {
9334 return true;
9335 }
9336
9337 if matches!(next_token, TokenType::Verb { .. }) {
9339 return true;
9340 }
9341
9342 if matches!(
9344 next_token,
9345 TokenType::Pronoun { .. }
9346 | TokenType::Article(_)
9347 | TokenType::Noun(_)
9348 | TokenType::ProperName(_)
9349 ) {
9350 return false;
9351 }
9352
9353 true
9355 }
9356
9357 fn check_auxiliary_as_main_verb(&self) -> bool {
9360 if let TokenType::Auxiliary(Time::Past) = self.peek().kind {
9361 if self.current + 1 < self.tokens.len() {
9363 let next = &self.tokens[self.current + 1].kind;
9364 matches!(
9365 next,
9366 TokenType::Pronoun { .. }
9367 | TokenType::Article(_)
9368 | TokenType::Noun(_)
9369 | TokenType::ProperName(_)
9370 )
9371 } else {
9372 false
9373 }
9374 } else {
9375 false
9376 }
9377 }
9378
9379 fn parse_do_as_main_verb(&mut self, subject_term: Term<'a>) -> ParseResult<&'a LogicExpr<'a>> {
9382 let aux_token = self.advance();
9384 let verb_time = if let TokenType::Auxiliary(time) = aux_token.kind {
9385 time
9386 } else {
9387 Time::Past
9388 };
9389
9390 let verb = self.interner.intern("Do");
9392
9393 let object_term = if let TokenType::Pronoun { .. } = self.peek().kind {
9395 self.advance();
9397 let it_sym = self.interner.intern("it");
9400 Term::Constant(it_sym)
9401 } else {
9402 let object = self.parse_noun_phrase(false)?;
9403 self.noun_phrase_to_term(&object)
9404 };
9405
9406 let event_var = self.get_event_var();
9408 let suppress_existential = self.drs.in_conditional_antecedent();
9409
9410 let mut modifiers = Vec::new();
9411 if verb_time == Time::Past {
9412 modifiers.push(self.interner.intern("Past"));
9413 } else if verb_time == Time::Future {
9414 modifiers.push(self.interner.intern("Future"));
9415 }
9416
9417 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
9418 event_var,
9419 verb,
9420 roles: self.ctx.roles.alloc_slice(vec![
9421 (ThematicRole::Agent, subject_term),
9422 (ThematicRole::Theme, object_term),
9423 ]),
9424 modifiers: self.ctx.syms.alloc_slice(modifiers),
9425 suppress_existential,
9426 world: None,
9427 })));
9428
9429 Ok(neo_event)
9430 }
9431
9432 fn check_to(&self) -> bool {
9433 matches!(self.peek().kind, TokenType::To)
9434 }
9435
9436 fn has_modal_subordination_ahead(&self) -> bool {
9440 for i in self.current..self.tokens.len() {
9443 match &self.tokens[i].kind {
9444 TokenType::Would | TokenType::Could | TokenType::Should | TokenType::Might => {
9445 return true;
9446 }
9447 TokenType::Period | TokenType::EOF => break,
9449 _ => {}
9450 }
9451 }
9452 false
9453 }
9454
9455 fn consume_verb(&mut self) -> Symbol {
9456 let t = self.advance().clone();
9457 match t.kind {
9458 TokenType::Verb { lemma, .. } => lemma,
9459 TokenType::Ambiguous { primary, .. } => match *primary {
9460 TokenType::Verb { lemma, .. } => lemma,
9461 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
9462 },
9463 _ => panic!("Expected verb, got {:?}", t.kind),
9464 }
9465 }
9466
9467 fn consume_verb_with_metadata(&mut self) -> (Symbol, Time, Aspect, VerbClass) {
9468 let t = self.advance().clone();
9469 match t.kind {
9470 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
9471 TokenType::Ambiguous { primary, .. } => match *primary {
9472 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
9473 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
9474 },
9475 _ => panic!("Expected verb, got {:?}", t.kind),
9476 }
9477 }
9478
9479 fn match_token(&mut self, types: &[TokenType]) -> bool {
9480 for t in types {
9481 if self.check(t) {
9482 self.advance();
9483 return true;
9484 }
9485 }
9486 false
9487 }
9488
9489 fn check_quantifier(&self) -> bool {
9490 matches!(
9491 self.peek().kind,
9492 TokenType::All
9493 | TokenType::No
9494 | TokenType::Some
9495 | TokenType::Any
9496 | TokenType::Most
9497 | TokenType::Few
9498 | TokenType::Many
9499 | TokenType::Cardinal(_)
9500 | TokenType::AtLeast(_)
9501 | TokenType::AtMost(_)
9502 )
9503 }
9504
9505 fn check_npi_quantifier(&self) -> bool {
9506 matches!(
9507 self.peek().kind,
9508 TokenType::Nobody | TokenType::Nothing | TokenType::NoOne
9509 )
9510 }
9511
9512 fn check_npi_object(&self) -> bool {
9513 matches!(
9514 self.peek().kind,
9515 TokenType::Anything | TokenType::Anyone
9516 )
9517 }
9518
9519 fn check_temporal_npi(&self) -> bool {
9520 matches!(
9521 self.peek().kind,
9522 TokenType::Ever | TokenType::Never
9523 )
9524 }
9525
9526 fn parse_npi_quantified(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9527 let npi_token = self.advance().kind.clone();
9528 let var_name = self.next_var_name();
9529
9530 let (restriction_name, is_person) = match npi_token {
9531 TokenType::Nobody | TokenType::NoOne => ("Person", true),
9532 TokenType::Nothing => ("Thing", false),
9533 _ => ("Thing", false),
9534 };
9535
9536 let restriction_sym = self.interner.intern(restriction_name);
9537 let subject_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9538 name: restriction_sym,
9539 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9540 world: None,
9541 });
9542
9543 self.negative_depth += 1;
9544
9545 let verb = self.consume_verb();
9546
9547 if self.check_npi_object() {
9548 let obj_npi_token = self.advance().kind.clone();
9549 let obj_var = self.next_var_name();
9550
9551 let obj_restriction_name = match obj_npi_token {
9552 TokenType::Anything => "Thing",
9553 TokenType::Anyone => "Person",
9554 _ => "Thing",
9555 };
9556
9557 let obj_restriction_sym = self.interner.intern(obj_restriction_name);
9558 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
9559 name: obj_restriction_sym,
9560 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
9561 world: None,
9562 });
9563
9564 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9565 name: verb,
9566 args: self.ctx.terms.alloc_slice([Term::Variable(var_name), Term::Variable(obj_var)]),
9567 world: None,
9568 });
9569
9570 let verb_and_obj = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9571 left: obj_restriction,
9572 op: TokenType::And,
9573 right: verb_pred,
9574 });
9575
9576 let inner_existential = self.ctx.exprs.alloc(LogicExpr::Quantifier {
9577 kind: crate::ast::QuantifierKind::Existential,
9578 variable: obj_var,
9579 body: verb_and_obj,
9580 island_id: self.current_island,
9581 });
9582
9583 self.negative_depth -= 1;
9584
9585 let negated = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9586 op: TokenType::Not,
9587 operand: inner_existential,
9588 });
9589
9590 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9591 left: subject_pred,
9592 op: TokenType::If,
9593 right: negated,
9594 });
9595
9596 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9597 kind: crate::ast::QuantifierKind::Universal,
9598 variable: var_name,
9599 body,
9600 island_id: self.current_island,
9601 }));
9602 }
9603
9604 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9605 name: verb,
9606 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9607 world: None,
9608 });
9609
9610 self.negative_depth -= 1;
9611
9612 let negated_verb = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9613 op: TokenType::Not,
9614 operand: verb_pred,
9615 });
9616
9617 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9618 left: subject_pred,
9619 op: TokenType::If,
9620 right: negated_verb,
9621 });
9622
9623 Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9624 kind: crate::ast::QuantifierKind::Universal,
9625 variable: var_name,
9626 body,
9627 island_id: self.current_island,
9628 }))
9629 }
9630
9631 fn parse_temporal_npi(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9632 let npi_token = self.advance().kind.clone();
9633 let is_never = matches!(npi_token, TokenType::Never);
9634
9635 let subject = self.parse_noun_phrase(true)?;
9636
9637 if is_never {
9638 self.negative_depth += 1;
9639 }
9640
9641 let verb = self.consume_verb();
9642 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9643 name: verb,
9644 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
9645 world: None,
9646 });
9647
9648 if is_never {
9649 self.negative_depth -= 1;
9650 Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9651 op: TokenType::Not,
9652 operand: verb_pred,
9653 }))
9654 } else {
9655 Ok(verb_pred)
9656 }
9657 }
9658
9659 fn check(&self, kind: &TokenType) -> bool {
9660 if self.is_at_end() {
9661 return false;
9662 }
9663 std::mem::discriminant(&self.peek().kind) == std::mem::discriminant(kind)
9664 }
9665
9666 fn check_any(&self, kinds: &[TokenType]) -> bool {
9667 if self.is_at_end() {
9668 return false;
9669 }
9670 let current = std::mem::discriminant(&self.peek().kind);
9671 kinds.iter().any(|k| std::mem::discriminant(k) == current)
9672 }
9673
9674 fn check_article(&self) -> bool {
9675 matches!(self.peek().kind, TokenType::Article(_))
9676 }
9677
9678 fn advance(&mut self) -> &Token {
9679 if !self.is_at_end() {
9680 self.current += 1;
9681 }
9682 self.previous()
9683 }
9684
9685 fn is_at_end(&self) -> bool {
9686 self.peek().kind == TokenType::EOF
9687 }
9688
9689 fn peek(&self) -> &Token {
9690 &self.tokens[self.current]
9691 }
9692
9693 fn peek_next_is_string_literal(&self) -> bool {
9696 self.tokens.get(self.current + 1)
9697 .map(|t| matches!(t.kind, TokenType::StringLiteral(_)))
9698 .unwrap_or(false)
9699 }
9700
9701 fn previous(&self) -> &Token {
9702 &self.tokens[self.current - 1]
9703 }
9704
9705 fn current_span(&self) -> crate::token::Span {
9706 self.peek().span
9707 }
9708
9709 fn consume(&mut self, kind: TokenType) -> ParseResult<&Token> {
9710 if self.check(&kind) {
9711 Ok(self.advance())
9712 } else {
9713 Err(ParseError {
9714 kind: ParseErrorKind::UnexpectedToken {
9715 expected: kind,
9716 found: self.peek().kind.clone(),
9717 },
9718 span: self.current_span(),
9719 })
9720 }
9721 }
9722
9723 fn consume_content_word(&mut self) -> ParseResult<Symbol> {
9724 let t = self.advance().clone();
9725 match t.kind {
9726 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9727 TokenType::Article(_) => Ok(t.lexeme),
9729 TokenType::Number(s) => Ok(s),
9731 TokenType::ProperName(s) => {
9732 if self.mode == ParserMode::Imperative {
9734 if !self.drs.has_referent_by_variable(s) {
9735 return Err(ParseError {
9736 kind: ParseErrorKind::UndefinedVariable {
9737 name: self.interner.resolve(s).to_string()
9738 },
9739 span: t.span,
9740 });
9741 }
9742 return Ok(s);
9743 }
9744
9745 let s_str = self.interner.resolve(s);
9747 let gender = Self::infer_gender(s_str);
9748
9749 self.drs.introduce_proper_name(s, s, gender);
9751
9752 Ok(s)
9753 }
9754 TokenType::Verb { lemma, .. } => Ok(lemma),
9755 TokenType::Ambiguous { primary, .. } => {
9756 match *primary {
9757 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9758 TokenType::Verb { lemma, .. } => Ok(lemma),
9759 TokenType::ProperName(s) => {
9760 if self.mode == ParserMode::Imperative {
9762 if !self.drs.has_referent_by_variable(s) {
9763 return Err(ParseError {
9764 kind: ParseErrorKind::UndefinedVariable {
9765 name: self.interner.resolve(s).to_string()
9766 },
9767 span: t.span,
9768 });
9769 }
9770 return Ok(s);
9771 }
9772 let s_str = self.interner.resolve(s);
9774 let gender = Self::infer_gender(s_str);
9775 self.drs.introduce_proper_name(s, s, gender);
9776 Ok(s)
9777 }
9778 _ => Err(ParseError {
9779 kind: ParseErrorKind::ExpectedContentWord { found: *primary },
9780 span: self.current_span(),
9781 }),
9782 }
9783 }
9784 other => Err(ParseError {
9785 kind: ParseErrorKind::ExpectedContentWord { found: other },
9786 span: self.current_span(),
9787 }),
9788 }
9789 }
9790
9791 fn consume_copula(&mut self) -> ParseResult<()> {
9792 if self.match_token(&[TokenType::Is, TokenType::Are, TokenType::Was, TokenType::Were]) {
9793 Ok(())
9794 } else {
9795 Err(ParseError {
9796 kind: ParseErrorKind::ExpectedCopula,
9797 span: self.current_span(),
9798 })
9799 }
9800 }
9801
9802 fn check_comparative(&self) -> bool {
9803 matches!(self.peek().kind, TokenType::Comparative(_))
9804 }
9805
9806 fn is_contact_clause_pattern(&self) -> bool {
9807 let mut pos = self.current;
9810
9811 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Article(_)) {
9813 pos += 1;
9814 } else {
9815 return false;
9816 }
9817
9818 while pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Adjective(_)) {
9820 pos += 1;
9821 }
9822
9823 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Adjective(_)) {
9825 pos += 1;
9826 } else {
9827 return false;
9828 }
9829
9830 pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Verb { .. } | TokenType::Article(_))
9832 }
9833
9834 fn check_superlative(&self) -> bool {
9835 matches!(self.peek().kind, TokenType::Superlative(_))
9836 }
9837
9838 fn check_scopal_adverb(&self) -> bool {
9839 matches!(self.peek().kind, TokenType::ScopalAdverb(_))
9840 }
9841
9842 fn check_temporal_adverb(&self) -> bool {
9843 matches!(self.peek().kind, TokenType::TemporalAdverb(_))
9844 }
9845
9846 fn check_non_intersective_adjective(&self) -> bool {
9847 matches!(self.peek().kind, TokenType::NonIntersectiveAdjective(_))
9848 }
9849
9850 fn check_focus(&self) -> bool {
9851 matches!(self.peek().kind, TokenType::Focus(_))
9852 }
9853
9854 fn check_measure(&self) -> bool {
9855 matches!(self.peek().kind, TokenType::Measure(_))
9856 }
9857
9858 fn check_presup_trigger(&self) -> bool {
9859 match &self.peek().kind {
9860 TokenType::PresupTrigger(_) => true,
9861 TokenType::Verb { lemma, .. } => {
9862 let s = self.interner.resolve(*lemma).to_lowercase();
9863 crate::lexicon::lookup_presup_trigger(&s).is_some()
9864 }
9865 _ => false,
9866 }
9867 }
9868
9869 fn is_followed_by_np_object(&self) -> bool {
9870 if self.current + 1 >= self.tokens.len() {
9871 return false;
9872 }
9873 let next = &self.tokens[self.current + 1].kind;
9874 matches!(next,
9875 TokenType::ProperName(_) |
9876 TokenType::Article(_) |
9877 TokenType::Noun(_) |
9878 TokenType::Pronoun { .. } |
9879 TokenType::Reflexive |
9880 TokenType::Who |
9881 TokenType::What |
9882 TokenType::Where |
9883 TokenType::When |
9884 TokenType::Why
9885 )
9886 }
9887
9888 fn is_followed_by_gerund(&self) -> bool {
9889 if self.current + 1 >= self.tokens.len() {
9890 return false;
9891 }
9892 matches!(self.tokens[self.current + 1].kind, TokenType::Verb { .. })
9893 }
9894
9895 fn parse_spawn_statement(&mut self) -> ParseResult<Stmt<'a>> {
9901 self.advance(); if !self.check_article() {
9905 return Err(ParseError {
9906 kind: ParseErrorKind::ExpectedKeyword { keyword: "a/an".to_string() },
9907 span: self.current_span(),
9908 });
9909 }
9910 self.advance(); let agent_type = match &self.tokens[self.current].kind {
9914 TokenType::Noun(sym) | TokenType::ProperName(sym) => {
9915 let s = *sym;
9916 self.advance();
9917 s
9918 }
9919 _ => {
9920 return Err(ParseError {
9921 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent type".to_string() },
9922 span: self.current_span(),
9923 });
9924 }
9925 };
9926
9927 if !self.check(&TokenType::Called) {
9929 return Err(ParseError {
9930 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
9931 span: self.current_span(),
9932 });
9933 }
9934 self.advance(); let name = if let TokenType::StringLiteral(sym) = &self.tokens[self.current].kind {
9938 let s = *sym;
9939 self.advance();
9940 s
9941 } else {
9942 return Err(ParseError {
9943 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent name".to_string() },
9944 span: self.current_span(),
9945 });
9946 };
9947
9948 Ok(Stmt::Spawn { agent_type, name })
9949 }
9950
9951 fn parse_send_statement(&mut self) -> ParseResult<Stmt<'a>> {
9953 self.advance(); let message = self.parse_imperative_expr()?;
9957
9958 if !self.check_preposition_is("to") {
9960 return Err(ParseError {
9961 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9962 span: self.current_span(),
9963 });
9964 }
9965 self.advance(); let destination = self.parse_imperative_expr()?;
9969
9970 Ok(Stmt::SendMessage { message, destination })
9971 }
9972
9973 fn parse_await_statement(&mut self) -> ParseResult<Stmt<'a>> {
9975 self.advance(); if self.check_word("response") {
9979 self.advance();
9980 }
9981
9982 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
9984 return Err(ParseError {
9985 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
9986 span: self.current_span(),
9987 });
9988 }
9989 self.advance(); let source = self.parse_imperative_expr()?;
9993
9994 if !self.check_word("into") {
9996 return Err(ParseError {
9997 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
9998 span: self.current_span(),
9999 });
10000 }
10001 self.advance(); let into = match &self.tokens[self.current].kind {
10005 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
10006 let s = *sym;
10007 self.advance();
10008 s
10009 }
10010 _ if self.check_content_word() => {
10012 let sym = self.tokens[self.current].lexeme;
10013 self.advance();
10014 sym
10015 }
10016 _ => {
10017 return Err(ParseError {
10018 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
10019 span: self.current_span(),
10020 });
10021 }
10022 };
10023
10024 Ok(Stmt::AwaitMessage { source, into })
10025 }
10026
10027 fn parse_merge_statement(&mut self) -> ParseResult<Stmt<'a>> {
10033 self.advance(); let source = self.parse_imperative_expr()?;
10037
10038 if !self.check_word("into") {
10040 return Err(ParseError {
10041 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
10042 span: self.current_span(),
10043 });
10044 }
10045 self.advance(); let target = self.parse_imperative_expr()?;
10049
10050 Ok(Stmt::MergeCrdt { source, target })
10051 }
10052
10053 fn parse_increase_statement(&mut self) -> ParseResult<Stmt<'a>> {
10055 self.advance(); let expr = self.parse_imperative_expr()?;
10059
10060 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
10062 (object, field)
10063 } else {
10064 return Err(ParseError {
10065 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
10066 span: self.current_span(),
10067 });
10068 };
10069
10070 if !self.check_preposition_is("by") {
10072 return Err(ParseError {
10073 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
10074 span: self.current_span(),
10075 });
10076 }
10077 self.advance(); let amount = self.parse_imperative_expr()?;
10081
10082 Ok(Stmt::IncreaseCrdt { object, field: *field, amount })
10083 }
10084
10085 fn parse_decrease_statement(&mut self) -> ParseResult<Stmt<'a>> {
10087 self.advance(); let expr = self.parse_imperative_expr()?;
10091
10092 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
10094 (object, field)
10095 } else {
10096 return Err(ParseError {
10097 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
10098 span: self.current_span(),
10099 });
10100 };
10101
10102 if !self.check_preposition_is("by") {
10104 return Err(ParseError {
10105 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
10106 span: self.current_span(),
10107 });
10108 }
10109 self.advance(); let amount = self.parse_imperative_expr()?;
10113
10114 Ok(Stmt::DecreaseCrdt { object, field: *field, amount })
10115 }
10116
10117 fn parse_append_statement(&mut self) -> ParseResult<Stmt<'a>> {
10119 self.advance(); let value = self.parse_imperative_expr()?;
10123
10124 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
10126 return Err(ParseError {
10127 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
10128 span: self.current_span(),
10129 });
10130 }
10131 self.advance(); let sequence = self.parse_imperative_expr()?;
10135
10136 Ok(Stmt::AppendToSequence { sequence, value })
10137 }
10138
10139 fn parse_resolve_statement(&mut self) -> ParseResult<Stmt<'a>> {
10141 self.advance(); let expr = self.parse_imperative_expr()?;
10145
10146 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
10148 (object, field)
10149 } else {
10150 return Err(ParseError {
10151 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's title')".to_string() },
10152 span: self.current_span(),
10153 });
10154 };
10155
10156 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
10158 return Err(ParseError {
10159 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
10160 span: self.current_span(),
10161 });
10162 }
10163 self.advance(); let value = self.parse_imperative_expr()?;
10167
10168 Ok(Stmt::ResolveConflict { object, field: *field, value })
10169 }
10170
10171}
10172