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 |
743 BlockType::Hardware | BlockType::Property => ParserMode::Declarative,
744 BlockType::No => self.mode, };
746 self.current += 1;
747 } else {
748 break;
749 }
750 }
751 }
752
753 pub fn get_event_var(&mut self) -> Symbol {
754 self.discourse_event_var.unwrap_or_else(|| self.interner.intern("e"))
755 }
756
757 pub fn capture_event_template(&mut self, verb: Symbol, roles: &[(ThematicRole, Term<'a>)], modifiers: &[Symbol]) {
758 let non_agent_roles: Vec<_> = roles.iter()
759 .filter(|(role, _)| *role != ThematicRole::Agent)
760 .cloned()
761 .collect();
762 self.last_event_template = Some(EventTemplate {
763 verb,
764 non_agent_roles,
765 modifiers: modifiers.to_vec(),
766 });
767 }
768
769 fn parse_embedded_wh_clause(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
770 let var_name = self.interner.intern("x");
772 let var_term = Term::Variable(var_name);
773
774 if self.check_verb() {
775 let verb = self.consume_verb();
777 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
778 name: verb,
779 args: self.ctx.terms.alloc_slice([var_term]),
780 world: None,
781 });
782 return Ok(body);
783 }
784
785 if self.check_content_word() || self.check_article() {
786 let subject = self.parse_noun_phrase(true)?;
788 if self.check_verb() {
789 let verb = self.consume_verb();
790 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
791 name: verb,
792 args: self.ctx.terms.alloc_slice([
793 Term::Constant(subject.noun),
794 var_term,
795 ]),
796 world: None,
797 });
798 return Ok(body);
799 }
800 }
801
802 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(var_name)))
804 }
805
806 pub fn set_pp_attachment_mode(&mut self, attach_to_noun: bool) {
807 self.pp_attach_to_noun = attach_to_noun;
808 }
809
810 pub fn set_noun_priority_mode(&mut self, mode: bool) {
811 self.noun_priority_mode = mode;
812 }
813
814 pub fn set_collective_mode(&mut self, mode: bool) {
815 self.collective_mode = mode;
816 }
817
818 pub fn set_event_reading_mode(&mut self, mode: bool) {
819 self.event_reading_mode = mode;
820 }
821
822 pub fn set_negative_scope_mode(&mut self, mode: NegativeScopeMode) {
823 self.negative_scope_mode = mode;
824 }
825
826 pub fn set_modal_preference(&mut self, pref: ModalPreference) {
827 self.modal_preference = pref;
828 }
829
830 fn checkpoint(&self) -> ParserCheckpoint {
831 ParserCheckpoint {
832 pos: self.current,
833 var_counter: self.var_counter,
834 bindings_len: self.donkey_bindings.len(),
835 island: self.current_island,
836 time: self.pending_time,
837 negative_depth: self.negative_depth,
838 }
839 }
840
841 fn restore(&mut self, cp: ParserCheckpoint) {
842 self.current = cp.pos;
843 self.var_counter = cp.var_counter;
844 self.donkey_bindings.truncate(cp.bindings_len);
845 self.current_island = cp.island;
846 self.pending_time = cp.time;
847 self.negative_depth = cp.negative_depth;
848 }
849
850 fn is_negative_context(&self) -> bool {
851 self.negative_depth % 2 == 1
852 }
853
854 pub fn guard(&mut self) -> ParserGuard<'_, 'a, 'ctx, 'int> {
855 ParserGuard {
856 checkpoint: self.checkpoint(),
857 parser: self,
858 committed: false,
859 }
860 }
861
862 pub(super) fn try_parse<F, T>(&mut self, op: F) -> Option<T>
863 where
864 F: FnOnce(&mut Self) -> ParseResult<T>,
865 {
866 let cp = self.checkpoint();
867 match op(self) {
868 Ok(res) => Some(res),
869 Err(_) => {
870 self.restore(cp);
871 None
872 }
873 }
874 }
875
876 fn resolve_pronoun(&mut self, gender: Gender, number: Number) -> ParseResult<ResolvedPronoun> {
877 if self.world_state.in_discourse_mode() && self.world_state.has_prior_modal_context() {
882 if let Some(candidate) = self.world_state.resolve_via_telescope(gender) {
885 return Ok(ResolvedPronoun::Variable(candidate.variable));
886 }
887 let blocked_candidates: Vec<_> = self.world_state.telescope_candidates()
891 .iter()
892 .filter(|c| c.in_modal_scope)
893 .collect();
894 if !blocked_candidates.is_empty() {
895 let has_upcoming_modal = self.has_modal_subordination_ahead();
898 if has_upcoming_modal {
899 if let Some(candidate) = blocked_candidates.into_iter().find(|c| {
901 c.gender == gender || gender == Gender::Unknown || c.gender == Gender::Unknown
902 }) {
903 return Ok(ResolvedPronoun::Variable(candidate.variable));
904 }
905 }
906 return Err(ParseError {
908 kind: ParseErrorKind::ScopeViolation(
909 "Cannot access hypothetical entity from reality. Use modal subordination (e.g., 'would') to continue a hypothetical context.".to_string()
910 ),
911 span: self.current_span(),
912 });
913 }
914 }
916
917 let current_box = self.drs.current_box_index();
919 match self.drs.resolve_pronoun(current_box, gender, number) {
920 Ok(sym) => return Ok(ResolvedPronoun::Variable(sym)),
921 Err(crate::drs::ScopeError::InaccessibleReferent { gender: g, reason, .. }) => {
922 if self.world_state.in_discourse_mode() {
926 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
927 return Ok(ResolvedPronoun::Variable(candidate.variable));
928 }
929 }
930 return Err(ParseError {
932 kind: ParseErrorKind::ScopeViolation(reason),
933 span: self.current_span(),
934 });
935 }
936 Err(crate::drs::ScopeError::NoMatchingReferent { gender: g, number: n }) => {
937 if !self.world_state.has_prior_modal_context() {
939 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
940 return Ok(ResolvedPronoun::Variable(candidate.variable));
941 }
942 }
943
944 if self.world_state.in_discourse_mode() {
946 return Err(ParseError {
947 kind: ParseErrorKind::UnresolvedPronoun {
948 gender: g,
949 number: n,
950 },
951 span: self.current_span(),
952 });
953 }
954
955 let deictic_name = match (g, n) {
958 (Gender::Male, Number::Singular) => "Him",
959 (Gender::Female, Number::Singular) => "Her",
960 (Gender::Neuter, Number::Singular) => "It",
961 (Gender::Male, Number::Plural) | (Gender::Female, Number::Plural) => "Them",
962 (Gender::Neuter, Number::Plural) => "Them",
963 (Gender::Unknown, _) => "Someone",
964 };
965 let sym = self.interner.intern(deictic_name);
966 self.drs.introduce_referent(sym, sym, g, n);
968 return Ok(ResolvedPronoun::Constant(sym));
969 }
970 }
971 }
972
973 fn resolve_donkey_pronoun(&mut self, gender: Gender) -> Option<Symbol> {
974 for (noun_class, var_name, used, _wide_neg) in self.donkey_bindings.iter_mut().rev() {
975 let noun_str = self.interner.resolve(*noun_class);
976 let noun_gender = Self::infer_noun_gender(noun_str);
977 if noun_gender == gender || gender == Gender::Neuter || noun_gender == Gender::Unknown {
978 *used = true; return Some(*var_name);
980 }
981 }
982 None
983 }
984
985 fn infer_noun_gender(noun: &str) -> Gender {
986 let lower = noun.to_lowercase();
987 if lexicon::is_female_noun(&lower) {
988 Gender::Female
989 } else if lexicon::is_male_noun(&lower) {
990 Gender::Male
991 } else if lexicon::is_neuter_noun(&lower) {
992 Gender::Neuter
993 } else {
994 Gender::Unknown
995 }
996 }
997
998 fn is_plural_noun(noun: &str) -> bool {
999 let lower = noun.to_lowercase();
1000 if lexicon::is_proper_name(&lower) {
1002 return false;
1003 }
1004 if lexicon::is_irregular_plural(&lower) {
1005 return true;
1006 }
1007 lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2
1008 }
1009
1010 fn singularize_noun(noun: &str) -> String {
1011 let lower = noun.to_lowercase();
1012 if let Some(singular) = lexicon::singularize(&lower) {
1013 return singular.to_string();
1014 }
1015 if lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2 {
1016 let base = &lower[..lower.len() - 1];
1017 let mut chars: Vec<char> = base.chars().collect();
1018 if !chars.is_empty() {
1019 chars[0] = chars[0].to_uppercase().next().unwrap();
1020 }
1021 return chars.into_iter().collect();
1022 }
1023 let mut chars: Vec<char> = lower.chars().collect();
1024 if !chars.is_empty() {
1025 chars[0] = chars[0].to_uppercase().next().unwrap();
1026 }
1027 chars.into_iter().collect()
1028 }
1029
1030 fn infer_gender(name: &str) -> Gender {
1031 let lower = name.to_lowercase();
1032 if lexicon::is_male_name(&lower) {
1033 Gender::Male
1034 } else if lexicon::is_female_name(&lower) {
1035 Gender::Female
1036 } else {
1037 Gender::Unknown
1038 }
1039 }
1040
1041
1042 fn next_var_name(&mut self) -> Symbol {
1043 const VARS: &[&str] = &["x", "y", "z", "w", "v", "u"];
1044 let idx = self.var_counter;
1045 self.var_counter += 1;
1046 if idx < VARS.len() {
1047 self.interner.intern(VARS[idx])
1048 } else {
1049 let name = format!("x{}", idx - VARS.len() + 1);
1050 self.interner.intern(&name)
1051 }
1052 }
1053
1054 pub fn parse(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
1071 let mut result = self.parse_sentence()?;
1072
1073 while self.check(&TokenType::Period) || self.check(&TokenType::Exclamation) {
1076 self.advance(); if !self.is_at_end() {
1078 let next = self.parse_sentence()?;
1079 result = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1080 left: result,
1081 op: TokenType::And,
1082 right: next,
1083 });
1084 }
1085 }
1086
1087 Ok(result)
1088 }
1089
1090 pub fn parse_program(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
1108 let mut statements = Vec::new();
1109 let mut in_definition_block = false;
1110 let mut pending_opt_flags: HashSet<OptFlag> = HashSet::new();
1111
1112 if self.mode == ParserMode::Declarative {
1114 }
1118
1119 while !self.is_at_end() {
1120 if let Some(Token { kind: TokenType::BlockHeader { block_type }, .. }) = self.tokens.get(self.current) {
1122 match block_type {
1123 BlockType::Definition => {
1124 in_definition_block = true;
1125 self.mode = ParserMode::Declarative;
1126 self.advance();
1127 continue;
1128 }
1129 BlockType::Main => {
1130 in_definition_block = false;
1131 self.mode = ParserMode::Imperative;
1132 self.advance();
1133 continue;
1134 }
1135 BlockType::No => {
1136 self.advance(); if let Some(token) = self.tokens.get(self.current) {
1141 let word = self.interner.resolve(token.lexeme).to_lowercase();
1142 match word.as_str() {
1143 "memo" => { pending_opt_flags.insert(OptFlag::NoMemo); }
1144 "tco" => { pending_opt_flags.insert(OptFlag::NoTCO); }
1145 "peephole" => { pending_opt_flags.insert(OptFlag::NoPeephole); }
1146 "borrow" => { pending_opt_flags.insert(OptFlag::NoBorrow); }
1147 "optimize" => {
1148 pending_opt_flags.insert(OptFlag::NoOptimize);
1149 pending_opt_flags.insert(OptFlag::NoMemo);
1150 pending_opt_flags.insert(OptFlag::NoTCO);
1151 pending_opt_flags.insert(OptFlag::NoPeephole);
1152 pending_opt_flags.insert(OptFlag::NoBorrow);
1153 }
1154 _ => {} }
1156 self.advance(); }
1158 while self.check(&TokenType::Newline) {
1160 self.advance();
1161 }
1162 continue;
1163 }
1164 BlockType::Function => {
1165 in_definition_block = false;
1166 self.mode = ParserMode::Imperative;
1167 self.advance();
1168 let flags = std::mem::take(&mut pending_opt_flags);
1170 let func_def = self.parse_function_def_with_flags(flags)?;
1171 statements.push(func_def);
1172 continue;
1173 }
1174 BlockType::TypeDef => {
1175 self.advance();
1178 self.skip_type_def_content();
1179 continue;
1180 }
1181 BlockType::Policy => {
1182 in_definition_block = true; self.mode = ParserMode::Declarative;
1186 self.advance();
1187 continue;
1188 }
1189 BlockType::Hardware | BlockType::Property => {
1190 in_definition_block = true;
1193 self.mode = ParserMode::Declarative;
1194 self.advance();
1195 continue;
1196 }
1197 BlockType::Theorem => {
1198 in_definition_block = false;
1200 self.mode = ParserMode::Declarative;
1201 self.advance();
1202 let theorem = self.parse_theorem_block()?;
1203 statements.push(theorem);
1204 continue;
1205 }
1206 BlockType::Requires => {
1207 in_definition_block = false;
1208 self.mode = ParserMode::Declarative;
1209 self.advance();
1210 let deps = self.parse_requires_block()?;
1211 statements.extend(deps);
1212 continue;
1213 }
1214 _ => {
1215 in_definition_block = false;
1217 self.mode = ParserMode::Declarative;
1218 self.advance();
1219 continue;
1220 }
1221 }
1222 }
1223
1224 if in_definition_block {
1226 self.advance();
1227 continue;
1228 }
1229
1230 if self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) || self.check(&TokenType::Newline) {
1232 self.advance();
1233 continue;
1234 }
1235
1236 if self.mode == ParserMode::Imperative {
1238 let stmt = self.parse_statement()?;
1239 statements.push(stmt);
1240
1241 if self.check(&TokenType::Period) {
1242 self.advance();
1243 }
1244 } else {
1245 self.advance();
1247 }
1248 }
1249
1250 Ok(statements)
1251 }
1252
1253 fn parse_statement(&mut self) -> ParseResult<Stmt<'a>> {
1254 if self.check(&TokenType::To) || self.check_preposition_is("to") {
1257 return self.parse_function_def();
1258 }
1259 if self.check(&TokenType::Let) {
1260 return self.parse_let_statement();
1261 }
1262 if self.check(&TokenType::Mut) {
1265 return self.parse_equals_assignment(true);
1266 }
1267 if self.peek_equals_assignment() {
1270 return self.parse_equals_assignment(false);
1271 }
1272 if self.check(&TokenType::Set) {
1273 return self.parse_set_statement();
1274 }
1275 if self.check(&TokenType::Return) {
1276 return self.parse_return_statement();
1277 }
1278 if self.check(&TokenType::Break) {
1279 return self.parse_break_statement();
1280 }
1281 if self.check(&TokenType::If) {
1282 return self.parse_if_statement();
1283 }
1284 if self.check(&TokenType::Assert) {
1285 return self.parse_assert_statement();
1286 }
1287 if self.check(&TokenType::Trust) {
1289 return self.parse_trust_statement();
1290 }
1291 if self.check(&TokenType::Check) {
1293 return self.parse_check_statement();
1294 }
1295 if self.check(&TokenType::Listen) {
1297 return self.parse_listen_statement();
1298 }
1299 if self.check(&TokenType::NetConnect) {
1300 return self.parse_connect_statement();
1301 }
1302 if self.check(&TokenType::Sleep) {
1303 return self.parse_sleep_statement();
1304 }
1305 if self.check(&TokenType::Sync) {
1307 return self.parse_sync_statement();
1308 }
1309 if self.check(&TokenType::Mount) {
1311 return self.parse_mount_statement();
1312 }
1313 if self.check(&TokenType::While) {
1314 return self.parse_while_statement();
1315 }
1316 if self.check(&TokenType::Repeat) {
1317 return self.parse_repeat_statement();
1318 }
1319 if self.check(&TokenType::For) {
1321 return self.parse_for_statement();
1322 }
1323 if self.check(&TokenType::Call) {
1324 return self.parse_call_statement();
1325 }
1326 if self.check(&TokenType::Give) {
1327 return self.parse_give_statement();
1328 }
1329 if self.check(&TokenType::Show) {
1330 return self.parse_show_statement();
1331 }
1332 if self.check(&TokenType::Inspect) {
1334 return self.parse_inspect_statement();
1335 }
1336
1337 if self.check(&TokenType::Push) {
1339 return self.parse_push_statement();
1340 }
1341 if self.check(&TokenType::Pop) {
1342 return self.parse_pop_statement();
1343 }
1344 if self.check(&TokenType::Add) {
1346 return self.parse_add_statement();
1347 }
1348 if self.check(&TokenType::Remove) {
1349 return self.parse_remove_statement();
1350 }
1351
1352 if self.check(&TokenType::Inside) {
1354 return self.parse_zone_statement();
1355 }
1356
1357 if self.check(&TokenType::Attempt) {
1359 return self.parse_concurrent_block();
1360 }
1361 if self.check(&TokenType::Simultaneously) {
1362 return self.parse_parallel_block();
1363 }
1364
1365 if self.check(&TokenType::Read) {
1367 return self.parse_read_statement();
1368 }
1369 if self.check(&TokenType::Write) {
1370 return self.parse_write_statement();
1371 }
1372
1373 if self.check(&TokenType::Spawn) {
1375 return self.parse_spawn_statement();
1376 }
1377 if self.check(&TokenType::Send) {
1378 if self.lookahead_contains_into() {
1380 return self.parse_send_pipe_statement();
1381 }
1382 return self.parse_send_statement();
1383 }
1384 if self.check(&TokenType::Await) {
1385 if self.lookahead_is_first_of() {
1387 return self.parse_select_statement();
1388 }
1389 return self.parse_await_statement();
1390 }
1391
1392 if self.check(&TokenType::Merge) {
1394 return self.parse_merge_statement();
1395 }
1396 if self.check(&TokenType::Increase) {
1397 return self.parse_increase_statement();
1398 }
1399 if self.check(&TokenType::Decrease) {
1401 return self.parse_decrease_statement();
1402 }
1403 if self.check(&TokenType::Append) {
1404 return self.parse_append_statement();
1405 }
1406 if self.check(&TokenType::Resolve) {
1407 return self.parse_resolve_statement();
1408 }
1409
1410 if self.check(&TokenType::Launch) {
1412 return self.parse_launch_statement();
1413 }
1414 if self.check(&TokenType::Stop) {
1415 return self.parse_stop_statement();
1416 }
1417 if self.check(&TokenType::Try) {
1418 return self.parse_try_statement();
1419 }
1420 if self.check(&TokenType::Receive) {
1421 return self.parse_receive_pipe_statement();
1422 }
1423
1424 if self.check(&TokenType::Escape) {
1426 return self.parse_escape_statement();
1427 }
1428
1429 if self.tokens.get(self.current + 1)
1433 .map(|t| matches!(t.kind, TokenType::LParen))
1434 .unwrap_or(false)
1435 {
1436 let function = self.peek().lexeme;
1438 self.advance(); let expr = self.parse_call_expr(function)?;
1442 if let Expr::Call { function, args } = expr {
1443 return Ok(Stmt::Call { function: *function, args: args.clone() });
1444 }
1445 }
1446
1447 Err(ParseError {
1448 kind: ParseErrorKind::ExpectedStatement,
1449 span: self.current_span(),
1450 })
1451 }
1452
1453 fn parse_if_statement(&mut self) -> ParseResult<Stmt<'a>> {
1454 self.advance(); let cond = self.parse_condition()?;
1458
1459 if self.check(&TokenType::Then) {
1461 self.advance();
1462 }
1463
1464 if !self.check(&TokenType::Colon) {
1466 return Err(ParseError {
1467 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1468 span: self.current_span(),
1469 });
1470 }
1471 self.advance(); if !self.check(&TokenType::Indent) {
1475 return Err(ParseError {
1476 kind: ParseErrorKind::ExpectedStatement,
1477 span: self.current_span(),
1478 });
1479 }
1480 self.advance(); let mut then_stmts = Vec::new();
1484 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1485 let stmt = self.parse_statement()?;
1486 then_stmts.push(stmt);
1487 if self.check(&TokenType::Period) {
1488 self.advance();
1489 }
1490 }
1491
1492 if self.check(&TokenType::Dedent) {
1494 self.advance();
1495 }
1496
1497 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1499 .alloc_slice(then_stmts.into_iter());
1500
1501 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1503 self.advance(); if self.check(&TokenType::If) {
1507 let nested_if = self.parse_if_statement()?;
1509 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1510 .alloc_slice(std::iter::once(nested_if));
1511 Some(nested_slice)
1512 } else {
1513 if !self.check(&TokenType::Colon) {
1515 return Err(ParseError {
1516 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1517 span: self.current_span(),
1518 });
1519 }
1520 self.advance(); if !self.check(&TokenType::Indent) {
1523 return Err(ParseError {
1524 kind: ParseErrorKind::ExpectedStatement,
1525 span: self.current_span(),
1526 });
1527 }
1528 self.advance(); let mut else_stmts = Vec::new();
1531 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1532 let stmt = self.parse_statement()?;
1533 else_stmts.push(stmt);
1534 if self.check(&TokenType::Period) {
1535 self.advance();
1536 }
1537 }
1538
1539 if self.check(&TokenType::Dedent) {
1540 self.advance();
1541 }
1542
1543 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1544 .alloc_slice(else_stmts.into_iter()))
1545 }
1546 } else if self.check(&TokenType::Elif) {
1547 self.advance(); let nested_if = self.parse_elif_as_if()?;
1551 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1552 .alloc_slice(std::iter::once(nested_if));
1553 Some(nested_slice)
1554 } else {
1555 None
1556 };
1557
1558 Ok(Stmt::If {
1559 cond,
1560 then_block,
1561 else_block,
1562 })
1563 }
1564
1565 fn parse_elif_as_if(&mut self) -> ParseResult<Stmt<'a>> {
1568 let cond = self.parse_condition()?;
1570
1571 if !self.check(&TokenType::Colon) {
1573 return Err(ParseError {
1574 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1575 span: self.current_span(),
1576 });
1577 }
1578 self.advance(); if !self.check(&TokenType::Indent) {
1582 return Err(ParseError {
1583 kind: ParseErrorKind::ExpectedStatement,
1584 span: self.current_span(),
1585 });
1586 }
1587 self.advance(); let mut then_stmts = Vec::new();
1591 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1592 let stmt = self.parse_statement()?;
1593 then_stmts.push(stmt);
1594 if self.check(&TokenType::Period) {
1595 self.advance();
1596 }
1597 }
1598
1599 if self.check(&TokenType::Dedent) {
1601 self.advance();
1602 }
1603
1604 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1606 .alloc_slice(then_stmts.into_iter());
1607
1608 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1610 self.advance(); if self.check(&TokenType::If) {
1614 let nested_if = self.parse_if_statement()?;
1615 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1616 .alloc_slice(std::iter::once(nested_if));
1617 Some(nested_slice)
1618 } else {
1619 if !self.check(&TokenType::Colon) {
1621 return Err(ParseError {
1622 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1623 span: self.current_span(),
1624 });
1625 }
1626 self.advance(); if !self.check(&TokenType::Indent) {
1629 return Err(ParseError {
1630 kind: ParseErrorKind::ExpectedStatement,
1631 span: self.current_span(),
1632 });
1633 }
1634 self.advance(); let mut else_stmts = Vec::new();
1637 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1638 let stmt = self.parse_statement()?;
1639 else_stmts.push(stmt);
1640 if self.check(&TokenType::Period) {
1641 self.advance();
1642 }
1643 }
1644
1645 if self.check(&TokenType::Dedent) {
1646 self.advance();
1647 }
1648
1649 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1650 .alloc_slice(else_stmts.into_iter()))
1651 }
1652 } else if self.check(&TokenType::Elif) {
1653 self.advance(); let nested_if = self.parse_elif_as_if()?;
1655 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1656 .alloc_slice(std::iter::once(nested_if));
1657 Some(nested_slice)
1658 } else {
1659 None
1660 };
1661
1662 Ok(Stmt::If {
1663 cond,
1664 then_block,
1665 else_block,
1666 })
1667 }
1668
1669 fn parse_while_statement(&mut self) -> ParseResult<Stmt<'a>> {
1670 self.advance(); let cond = self.parse_condition()?;
1673
1674 let decreasing = if self.check(&TokenType::LParen) {
1676 self.advance(); if !self.check_word("decreasing") {
1680 return Err(ParseError {
1681 kind: ParseErrorKind::ExpectedKeyword { keyword: "decreasing".to_string() },
1682 span: self.current_span(),
1683 });
1684 }
1685 self.advance(); let variant = self.parse_imperative_expr()?;
1688
1689 if !self.check(&TokenType::RParen) {
1690 return Err(ParseError {
1691 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1692 span: self.current_span(),
1693 });
1694 }
1695 self.advance(); Some(variant)
1698 } else {
1699 None
1700 };
1701
1702 if !self.check(&TokenType::Colon) {
1703 return Err(ParseError {
1704 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1705 span: self.current_span(),
1706 });
1707 }
1708 self.advance(); if !self.check(&TokenType::Indent) {
1711 return Err(ParseError {
1712 kind: ParseErrorKind::ExpectedStatement,
1713 span: self.current_span(),
1714 });
1715 }
1716 self.advance(); let mut body_stmts = Vec::new();
1719 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1720 let stmt = self.parse_statement()?;
1721 body_stmts.push(stmt);
1722 if self.check(&TokenType::Period) {
1723 self.advance();
1724 }
1725 }
1726
1727 if self.check(&TokenType::Dedent) {
1728 self.advance();
1729 }
1730
1731 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1732 .alloc_slice(body_stmts.into_iter());
1733
1734 Ok(Stmt::While { cond, body, decreasing })
1735 }
1736
1737 fn parse_loop_pattern(&mut self) -> ParseResult<Pattern> {
1740 use crate::ast::stmt::Pattern;
1741
1742 if self.check(&TokenType::LParen) {
1744 self.advance(); let mut identifiers = Vec::new();
1747 loop {
1748 let id = self.expect_identifier()?;
1749 identifiers.push(id);
1750
1751 if self.check(&TokenType::Comma) {
1753 self.advance(); continue;
1755 }
1756 break;
1757 }
1758
1759 if !self.check(&TokenType::RParen) {
1761 return Err(ParseError {
1762 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1763 span: self.current_span(),
1764 });
1765 }
1766 self.advance(); Ok(Pattern::Tuple(identifiers))
1769 } else {
1770 let id = self.expect_identifier()?;
1772 Ok(Pattern::Identifier(id))
1773 }
1774 }
1775
1776 fn parse_repeat_statement(&mut self) -> ParseResult<Stmt<'a>> {
1777 self.advance(); if self.check(&TokenType::For) {
1781 self.advance();
1782 }
1783
1784 let pattern = self.parse_loop_pattern()?;
1786
1787 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1789 self.advance(); let start = self.parse_imperative_expr()?;
1791
1792 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1794 return Err(ParseError {
1795 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1796 span: self.current_span(),
1797 });
1798 }
1799 self.advance();
1800
1801 let end = self.parse_imperative_expr()?;
1802 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1803 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1804 self.advance(); self.parse_imperative_expr()?
1806 } else {
1807 return Err(ParseError {
1808 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1809 span: self.current_span(),
1810 });
1811 };
1812
1813 if !self.check(&TokenType::Colon) {
1815 return Err(ParseError {
1816 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1817 span: self.current_span(),
1818 });
1819 }
1820 self.advance();
1821
1822 if !self.check(&TokenType::Indent) {
1824 return Err(ParseError {
1825 kind: ParseErrorKind::ExpectedStatement,
1826 span: self.current_span(),
1827 });
1828 }
1829 self.advance();
1830
1831 let mut body_stmts = Vec::new();
1833 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1834 let stmt = self.parse_statement()?;
1835 body_stmts.push(stmt);
1836 if self.check(&TokenType::Period) {
1837 self.advance();
1838 }
1839 }
1840
1841 if self.check(&TokenType::Dedent) {
1842 self.advance();
1843 }
1844
1845 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1846 .alloc_slice(body_stmts.into_iter());
1847
1848 Ok(Stmt::Repeat { pattern, iterable, body })
1849 }
1850
1851 fn parse_for_statement(&mut self) -> ParseResult<Stmt<'a>> {
1854 self.advance(); let pattern = self.parse_loop_pattern()?;
1858
1859 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1861 self.advance(); let start = self.parse_imperative_expr()?;
1863
1864 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1866 return Err(ParseError {
1867 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1868 span: self.current_span(),
1869 });
1870 }
1871 self.advance();
1872
1873 let end = self.parse_imperative_expr()?;
1874 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1875 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1876 self.advance(); self.parse_imperative_expr()?
1878 } else {
1879 return Err(ParseError {
1880 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1881 span: self.current_span(),
1882 });
1883 };
1884
1885 if !self.check(&TokenType::Colon) {
1887 return Err(ParseError {
1888 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1889 span: self.current_span(),
1890 });
1891 }
1892 self.advance();
1893
1894 if !self.check(&TokenType::Indent) {
1896 return Err(ParseError {
1897 kind: ParseErrorKind::ExpectedStatement,
1898 span: self.current_span(),
1899 });
1900 }
1901 self.advance();
1902
1903 let mut body_stmts = Vec::new();
1905 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1906 let stmt = self.parse_statement()?;
1907 body_stmts.push(stmt);
1908 if self.check(&TokenType::Period) {
1909 self.advance();
1910 }
1911 }
1912
1913 if self.check(&TokenType::Dedent) {
1914 self.advance();
1915 }
1916
1917 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1918 .alloc_slice(body_stmts.into_iter());
1919
1920 Ok(Stmt::Repeat { pattern, iterable, body })
1921 }
1922
1923 fn parse_call_statement(&mut self) -> ParseResult<Stmt<'a>> {
1924 self.advance(); let function = match &self.peek().kind {
1930 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
1931 let s = *sym;
1932 self.advance();
1933 s
1934 }
1935 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
1936 let s = self.peek().lexeme;
1938 self.advance();
1939 s
1940 }
1941 _ => {
1942 return Err(ParseError {
1943 kind: ParseErrorKind::ExpectedIdentifier,
1944 span: self.current_span(),
1945 });
1946 }
1947 };
1948
1949 let args = if self.check_preposition_is("with") {
1951 self.advance(); self.parse_call_arguments()?
1953 } else {
1954 Vec::new()
1955 };
1956
1957 Ok(Stmt::Call { function, args })
1958 }
1959
1960 fn parse_call_arguments(&mut self) -> ParseResult<Vec<&'a Expr<'a>>> {
1961 let mut args = Vec::new();
1962
1963 let arg = self.parse_call_arg()?;
1965 args.push(arg);
1966
1967 while self.check(&TokenType::And) || self.check(&TokenType::Comma) {
1969 self.advance(); let arg = self.parse_call_arg()?;
1971 args.push(arg);
1972 }
1973
1974 Ok(args)
1975 }
1976
1977 fn parse_call_arg(&mut self) -> ParseResult<&'a Expr<'a>> {
1978 if self.check(&TokenType::Give) {
1980 self.advance(); let value = self.parse_comparison()?;
1982 return Ok(self.ctx.alloc_imperative_expr(Expr::Give { value }));
1983 }
1984
1985 self.parse_comparison()
1988 }
1989
1990 fn parse_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1991 self.parse_or_condition()
1994 }
1995
1996 fn parse_or_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1998 let mut left = self.parse_and_condition()?;
1999
2000 while self.check(&TokenType::Or) || self.check_word("or") {
2001 self.advance();
2002 let right = self.parse_and_condition()?;
2003 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
2004 op: BinaryOpKind::Or,
2005 left,
2006 right,
2007 });
2008 }
2009
2010 Ok(left)
2011 }
2012
2013 fn parse_and_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
2015 let mut left = self.parse_comparison()?;
2016
2017 while self.check(&TokenType::And) || self.check_word("and") {
2018 self.advance();
2019 let right = self.parse_comparison()?;
2020 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
2021 op: BinaryOpKind::And,
2022 left,
2023 right,
2024 });
2025 }
2026
2027 Ok(left)
2028 }
2029
2030 fn parse_comparison(&mut self) -> ParseResult<&'a Expr<'a>> {
2032 if self.check(&TokenType::Not) || self.check_word("not") {
2034 self.advance(); let operand = self.parse_comparison()?; return Ok(self.ctx.alloc_imperative_expr(Expr::Not { operand }));
2037 }
2038
2039 let left = self.parse_xor_expr()?;
2040
2041 let op = if self.check(&TokenType::Equals) {
2043 self.advance();
2044 Some(BinaryOpKind::Eq)
2045 } else if self.check(&TokenType::Identity) {
2046 self.advance();
2048 Some(BinaryOpKind::Eq)
2049 } else if self.check_word("is") {
2050 let saved_pos = self.current;
2052 self.advance(); if self.check_word("greater") {
2055 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
2057 self.advance(); Some(BinaryOpKind::Gt)
2059 } else {
2060 self.current = saved_pos;
2061 None
2062 }
2063 } else if self.check_word("less") {
2064 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
2066 self.advance(); Some(BinaryOpKind::Lt)
2068 } else {
2069 self.current = saved_pos;
2070 None
2071 }
2072 } else if self.check_word("at") {
2073 self.advance(); if self.check_word("least") {
2075 self.advance(); Some(BinaryOpKind::GtEq)
2077 } else if self.check_word("most") {
2078 self.advance(); Some(BinaryOpKind::LtEq)
2080 } else {
2081 self.current = saved_pos;
2082 None
2083 }
2084 } else if self.check_word("not") || self.check(&TokenType::Not) {
2085 self.advance(); Some(BinaryOpKind::NotEq)
2088 } else if self.check_word("equal") {
2089 self.advance(); if self.check_preposition_is("to") {
2092 self.advance(); Some(BinaryOpKind::Eq)
2094 } else {
2095 self.current = saved_pos;
2096 None
2097 }
2098 } else {
2099 self.current = saved_pos;
2100 None
2101 }
2102 } else if self.check(&TokenType::Lt) {
2103 self.advance();
2104 Some(BinaryOpKind::Lt)
2105 } else if self.check(&TokenType::Gt) {
2106 self.advance();
2107 Some(BinaryOpKind::Gt)
2108 } else if self.check(&TokenType::LtEq) {
2109 self.advance();
2110 Some(BinaryOpKind::LtEq)
2111 } else if self.check(&TokenType::GtEq) {
2112 self.advance();
2113 Some(BinaryOpKind::GtEq)
2114 } else if self.check(&TokenType::EqEq) || self.check(&TokenType::Assign) {
2115 self.advance();
2116 Some(BinaryOpKind::Eq)
2117 } else if self.check(&TokenType::NotEq) {
2118 self.advance();
2119 Some(BinaryOpKind::NotEq)
2120 } else {
2121 None
2122 };
2123
2124 if let Some(op) = op {
2125 let right = self.parse_xor_expr()?;
2126 Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp { op, left, right }))
2127 } else {
2128 Ok(left)
2129 }
2130 }
2131
2132 fn parse_let_statement(&mut self) -> ParseResult<Stmt<'a>> {
2133 self.advance(); let mutable = if self.check_mutable_keyword() {
2137 self.advance();
2138 true
2139 } else {
2140 false
2141 };
2142
2143 let var = self.expect_identifier()?;
2145
2146 let ty = if self.check(&TokenType::Colon) {
2148 self.advance(); let type_expr = self.parse_type_expression()?;
2150 Some(self.ctx.alloc_type_expr(type_expr))
2151 } else {
2152 None
2153 };
2154
2155 if !self.check(&TokenType::Be) && !self.check(&TokenType::Assign) {
2157 return Err(ParseError {
2158 kind: ParseErrorKind::ExpectedKeyword { keyword: "be or =".to_string() },
2159 span: self.current_span(),
2160 });
2161 }
2162 self.advance(); if self.check_word("mounted") {
2166 self.advance(); if !self.check(&TokenType::At) && !self.check_preposition_is("at") {
2168 return Err(ParseError {
2169 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2170 span: self.current_span(),
2171 });
2172 }
2173 self.advance(); let path = self.parse_imperative_expr()?;
2175 return Ok(Stmt::Mount { var, path });
2176 }
2177
2178 if self.check_article() {
2180 let saved_pos = self.current;
2181 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = self.peek().kind {
2185 let word = self.interner.resolve(sym).to_lowercase();
2186 if word == "peeragent" {
2187 self.advance(); if self.check(&TokenType::At) || self.check_preposition_is("at") {
2191 self.advance(); let address = self.parse_imperative_expr()?;
2195
2196 return Ok(Stmt::LetPeerAgent { var, address });
2197 }
2198 }
2199 }
2200 self.current = saved_pos;
2202 }
2203
2204 if self.check_article() {
2206 let saved_pos = self.current;
2207 self.advance(); if self.check(&TokenType::Pipe) {
2210 self.advance(); if !self.check_word("of") {
2214 return Err(ParseError {
2215 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
2216 span: self.current_span(),
2217 });
2218 }
2219 self.advance(); let element_type = self.expect_identifier()?;
2223
2224 return Ok(Stmt::CreatePipe { var, element_type, capacity: None });
2227 }
2228 self.current = saved_pos;
2230 }
2231
2232 if self.check(&TokenType::Launch) {
2234 self.advance(); if !self.check_article() {
2238 return Err(ParseError {
2239 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2240 span: self.current_span(),
2241 });
2242 }
2243 self.advance();
2244
2245 if !self.check(&TokenType::Task) {
2247 return Err(ParseError {
2248 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2249 span: self.current_span(),
2250 });
2251 }
2252 self.advance();
2253
2254 if !self.check(&TokenType::To) && !self.check_word("to") {
2256 return Err(ParseError {
2257 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2258 span: self.current_span(),
2259 });
2260 }
2261 self.advance();
2262
2263 let function = self.expect_identifier()?;
2265
2266 let args = if self.check_word("with") {
2268 self.advance();
2269 self.parse_call_arguments()?
2270 } else {
2271 vec![]
2272 };
2273
2274 return Ok(Stmt::LaunchTaskWithHandle { handle: var, function, args });
2275 }
2276
2277 let value = self.parse_imperative_expr()?;
2279
2280 if let Some(declared_ty) = &ty {
2282 if let Some(inferred) = self.infer_literal_type(value) {
2283 if !self.check_type_compatibility(declared_ty, inferred) {
2284 let expected = match declared_ty {
2285 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2286 self.interner.resolve(*sym).to_string()
2287 }
2288 _ => "unknown".to_string(),
2289 };
2290 return Err(ParseError {
2291 kind: ParseErrorKind::TypeMismatch {
2292 expected,
2293 found: inferred.to_string(),
2294 },
2295 span: self.current_span(),
2296 });
2297 }
2298 }
2299 }
2300
2301 let value = if self.check_word("with") {
2303 let saved = self.current;
2304 self.advance(); if self.check_word("capacity") {
2306 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2308 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2309 } else {
2310 self.current = saved; value
2312 }
2313 } else {
2314 value
2315 };
2316
2317 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2319
2320 Ok(Stmt::Let { var, ty, value, mutable })
2321 }
2322
2323 fn check_mutable_keyword(&self) -> bool {
2324 if matches!(self.peek().kind, TokenType::Mut) {
2326 return true;
2327 }
2328 if let TokenType::Noun(sym) | TokenType::Adjective(sym) = self.peek().kind {
2330 let word = self.interner.resolve(sym).to_lowercase();
2331 word == "mutable" || word == "mut"
2332 } else {
2333 false
2334 }
2335 }
2336
2337 fn infer_literal_type(&self, expr: &Expr<'_>) -> Option<&'static str> {
2339 match expr {
2340 Expr::Literal(lit) => match lit {
2341 crate::ast::Literal::Number(_) => Some("Int"),
2342 crate::ast::Literal::Float(_) => Some("Real"),
2343 crate::ast::Literal::Text(_) => Some("Text"),
2344 crate::ast::Literal::Boolean(_) => Some("Bool"),
2345 crate::ast::Literal::Nothing => Some("Unit"),
2346 crate::ast::Literal::Char(_) => Some("Char"),
2347 crate::ast::Literal::Duration(_) => Some("Duration"),
2348 crate::ast::Literal::Date(_) => Some("Date"),
2349 crate::ast::Literal::Moment(_) => Some("Moment"),
2350 crate::ast::Literal::Span { .. } => Some("Span"),
2351 crate::ast::Literal::Time(_) => Some("Time"),
2352 },
2353 _ => None, }
2355 }
2356
2357 fn check_type_compatibility(&self, declared: &TypeExpr<'_>, inferred: &str) -> bool {
2359 match declared {
2360 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2361 let declared_name = self.interner.resolve(*sym);
2362 declared_name.eq_ignore_ascii_case(inferred)
2364 || (declared_name.eq_ignore_ascii_case("Nat") && inferred == "Int")
2365 || (declared_name.eq_ignore_ascii_case("Byte") && inferred == "Int")
2366 }
2367 _ => true, }
2369 }
2370
2371 fn peek_equals_assignment(&self) -> bool {
2378 let is_identifier = matches!(
2382 self.peek().kind,
2383 TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Identifier
2384 | TokenType::Adjective(_) | TokenType::Verb { .. }
2385 | TokenType::Particle(_) | TokenType::Ambiguous { .. }
2386 | TokenType::Pronoun { .. }
2387 );
2388 if !is_identifier {
2389 return false;
2390 }
2391
2392 if self.current + 1 >= self.tokens.len() {
2394 return false;
2395 }
2396
2397 let next = &self.tokens[self.current + 1].kind;
2398
2399 if matches!(next, TokenType::Assign) {
2401 return true;
2402 }
2403
2404 if matches!(next, TokenType::Colon) {
2407 let mut offset = 2;
2408 while self.current + offset < self.tokens.len() {
2409 let tok = &self.tokens[self.current + offset].kind;
2410 if matches!(tok, TokenType::Assign) {
2411 return true;
2412 }
2413 if matches!(tok, TokenType::Period | TokenType::Newline | TokenType::EOF) {
2414 return false;
2415 }
2416 offset += 1;
2417 }
2418 }
2419
2420 false
2421 }
2422
2423 fn parse_equals_assignment(&mut self, explicit_mutable: bool) -> ParseResult<Stmt<'a>> {
2425 if explicit_mutable {
2427 self.advance(); }
2429
2430 let var = self.expect_identifier()?;
2432
2433 let ty = if self.check(&TokenType::Colon) {
2435 self.advance(); let type_expr = self.parse_type_expression()?;
2437 Some(self.ctx.alloc_type_expr(type_expr))
2438 } else {
2439 None
2440 };
2441
2442 if !self.check(&TokenType::Assign) {
2444 return Err(ParseError {
2445 kind: ParseErrorKind::ExpectedKeyword { keyword: "=".to_string() },
2446 span: self.current_span(),
2447 });
2448 }
2449 self.advance(); let value = self.parse_imperative_expr()?;
2453
2454 let value = if self.check_word("with") {
2456 let saved = self.current;
2457 self.advance(); if self.check_word("capacity") {
2459 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2461 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2462 } else {
2463 self.current = saved; value
2465 }
2466 } else {
2467 value
2468 };
2469
2470 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2472
2473 Ok(Stmt::Let { var, ty, value, mutable: explicit_mutable })
2474 }
2475
2476 fn parse_set_statement(&mut self) -> ParseResult<Stmt<'a>> {
2477 use crate::ast::Expr;
2478 self.advance(); let target_expr = self.parse_imperative_expr()?;
2482
2483 let target_expr = if self.check(&TokenType::At) {
2485 self.advance(); let key = self.parse_imperative_expr()?;
2487 self.ctx.alloc_imperative_expr(Expr::Index { collection: target_expr, index: key })
2488 } else {
2489 target_expr
2490 };
2491
2492 let is_to = self.check(&TokenType::To) || matches!(
2494 &self.peek().kind,
2495 TokenType::Preposition(sym) if self.interner.resolve(*sym) == "to"
2496 );
2497 if !is_to {
2498 return Err(ParseError {
2499 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2500 span: self.current_span(),
2501 });
2502 }
2503 self.advance(); let value = self.parse_imperative_expr()?;
2507
2508 match target_expr {
2511 Expr::FieldAccess { object, field } => {
2512 Ok(Stmt::SetField { object: *object, field: *field, value })
2513 }
2514 Expr::Identifier(target) => {
2515 Ok(Stmt::Set { target: *target, value })
2516 }
2517 Expr::Index { collection, index } => {
2518 Ok(Stmt::SetIndex { collection: *collection, index: *index, value })
2519 }
2520 _ => Err(ParseError {
2521 kind: ParseErrorKind::ExpectedIdentifier,
2522 span: self.current_span(),
2523 })
2524 }
2525 }
2526
2527 fn parse_return_statement(&mut self) -> ParseResult<Stmt<'a>> {
2528 self.advance(); if self.check(&TokenType::Period) || self.is_at_end() {
2532 return Ok(Stmt::Return { value: None });
2533 }
2534
2535 let value = self.parse_comparison()?;
2537 Ok(Stmt::Return { value: Some(value) })
2538 }
2539
2540 fn parse_break_statement(&mut self) -> ParseResult<Stmt<'a>> {
2541 self.advance(); Ok(Stmt::Break)
2543 }
2544
2545 fn parse_assert_statement(&mut self) -> ParseResult<Stmt<'a>> {
2546 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2550 self.advance();
2551 }
2552
2553 let condition = self.parse_condition()?;
2556
2557 Ok(Stmt::RuntimeAssert { condition })
2558 }
2559
2560 fn parse_trust_statement(&mut self) -> ParseResult<Stmt<'a>> {
2563 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2567 self.advance();
2568 }
2569
2570 let saved_mode = self.mode;
2572 self.mode = ParserMode::Declarative;
2573
2574 let proposition = self.parse()?;
2576
2577 self.mode = saved_mode;
2579
2580 if !self.check(&TokenType::Because) {
2582 return Err(ParseError {
2583 kind: ParseErrorKind::UnexpectedToken {
2584 expected: TokenType::Because,
2585 found: self.peek().kind.clone(),
2586 },
2587 span: self.current_span(),
2588 });
2589 }
2590 self.advance(); let justification = match &self.peek().kind {
2594 TokenType::StringLiteral(sym) => {
2595 let s = *sym;
2596 self.advance();
2597 s
2598 }
2599 _ => {
2600 return Err(ParseError {
2601 kind: ParseErrorKind::UnexpectedToken {
2602 expected: TokenType::StringLiteral(self.interner.intern("")),
2603 found: self.peek().kind.clone(),
2604 },
2605 span: self.current_span(),
2606 });
2607 }
2608 };
2609
2610 Ok(Stmt::Trust { proposition, justification })
2611 }
2612
2613 fn parse_check_statement(&mut self) -> ParseResult<Stmt<'a>> {
2617 let start_span = self.current_span();
2618 self.advance(); if self.check(&TokenType::That) {
2622 self.advance();
2623 }
2624
2625 if matches!(self.peek().kind, TokenType::Article(_)) {
2627 self.advance();
2628 }
2629
2630 let subject = match &self.peek().kind {
2632 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2633 let s = *sym;
2634 self.advance();
2635 s
2636 }
2637 _ => {
2638 let tok = self.peek();
2640 let s = tok.lexeme;
2641 self.advance();
2642 s
2643 }
2644 };
2645
2646 let is_capability;
2648 let predicate;
2649 let object;
2650
2651 if self.check(&TokenType::Is) || self.check(&TokenType::Are) {
2652 is_capability = false;
2654 self.advance(); predicate = match &self.peek().kind {
2658 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2659 let s = *sym;
2660 self.advance();
2661 s
2662 }
2663 _ => {
2664 let tok = self.peek();
2665 let s = tok.lexeme;
2666 self.advance();
2667 s
2668 }
2669 };
2670 object = None;
2671 } else if self.check(&TokenType::Can) {
2672 is_capability = true;
2674 self.advance(); predicate = match &self.peek().kind {
2678 TokenType::Verb { lemma, .. } => {
2679 let s = *lemma;
2680 self.advance();
2681 s
2682 }
2683 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2684 let s = *sym;
2685 self.advance();
2686 s
2687 }
2688 _ => {
2689 let tok = self.peek();
2690 let s = tok.lexeme;
2691 self.advance();
2692 s
2693 }
2694 };
2695
2696 if matches!(self.peek().kind, TokenType::Article(_)) {
2698 self.advance();
2699 }
2700
2701 let obj = match &self.peek().kind {
2703 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2704 let s = *sym;
2705 self.advance();
2706 s
2707 }
2708 _ => {
2709 let tok = self.peek();
2710 let s = tok.lexeme;
2711 self.advance();
2712 s
2713 }
2714 };
2715 object = Some(obj);
2716 } else {
2717 return Err(ParseError {
2718 kind: ParseErrorKind::ExpectedKeyword { keyword: "is/can".to_string() },
2719 span: self.current_span(),
2720 });
2721 }
2722
2723 let source_text = if is_capability {
2725 let obj_name = self.interner.resolve(object.unwrap());
2726 let pred_name = self.interner.resolve(predicate);
2727 let subj_name = self.interner.resolve(subject);
2728 format!("{} can {} the {}", subj_name, pred_name, obj_name)
2729 } else {
2730 let pred_name = self.interner.resolve(predicate);
2731 let subj_name = self.interner.resolve(subject);
2732 format!("{} is {}", subj_name, pred_name)
2733 };
2734
2735 Ok(Stmt::Check {
2736 subject,
2737 predicate,
2738 is_capability,
2739 object,
2740 source_text,
2741 span: start_span,
2742 })
2743 }
2744
2745 fn parse_listen_statement(&mut self) -> ParseResult<Stmt<'a>> {
2748 self.advance(); if !self.check_preposition_is("on") {
2752 return Err(ParseError {
2753 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2754 span: self.current_span(),
2755 });
2756 }
2757 self.advance(); let address = self.parse_imperative_expr()?;
2761
2762 Ok(Stmt::Listen { address })
2763 }
2764
2765 fn parse_connect_statement(&mut self) -> ParseResult<Stmt<'a>> {
2768 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2772 return Err(ParseError {
2773 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2774 span: self.current_span(),
2775 });
2776 }
2777 self.advance(); let address = self.parse_imperative_expr()?;
2781
2782 Ok(Stmt::ConnectTo { address })
2783 }
2784
2785 fn parse_sleep_statement(&mut self) -> ParseResult<Stmt<'a>> {
2788 self.advance(); let milliseconds = self.parse_imperative_expr()?;
2792
2793 Ok(Stmt::Sleep { milliseconds })
2794 }
2795
2796 fn parse_sync_statement(&mut self) -> ParseResult<Stmt<'a>> {
2799 self.advance(); let var = match &self.tokens[self.current].kind {
2804 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2805 let s = *sym;
2806 self.advance();
2807 s
2808 }
2809 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2810 let s = self.tokens[self.current].lexeme;
2811 self.advance();
2812 s
2813 }
2814 _ => {
2815 return Err(ParseError {
2816 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2817 span: self.current_span(),
2818 });
2819 }
2820 };
2821
2822 if !self.check_preposition_is("on") {
2824 return Err(ParseError {
2825 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2826 span: self.current_span(),
2827 });
2828 }
2829 self.advance(); let topic = self.parse_imperative_expr()?;
2833
2834 Ok(Stmt::Sync { var, topic })
2835 }
2836
2837 fn parse_mount_statement(&mut self) -> ParseResult<Stmt<'a>> {
2841 self.advance(); let var = match &self.tokens[self.current].kind {
2846 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2847 let s = *sym;
2848 self.advance();
2849 s
2850 }
2851 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2852 let s = self.tokens[self.current].lexeme;
2853 self.advance();
2854 s
2855 }
2856 _ => {
2857 return Err(ParseError {
2858 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2859 span: self.current_span(),
2860 });
2861 }
2862 };
2863
2864 if !self.check(&TokenType::At) {
2866 return Err(ParseError {
2867 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2868 span: self.current_span(),
2869 });
2870 }
2871 self.advance(); let path = self.parse_imperative_expr()?;
2875
2876 Ok(Stmt::Mount { var, path })
2877 }
2878
2879 fn lookahead_contains_into(&self) -> bool {
2885 for i in self.current..std::cmp::min(self.current + 5, self.tokens.len()) {
2886 if matches!(self.tokens[i].kind, TokenType::Into) {
2887 return true;
2888 }
2889 }
2890 false
2891 }
2892
2893 fn lookahead_is_first_of(&self) -> bool {
2895 self.current + 3 < self.tokens.len()
2897 && matches!(self.tokens.get(self.current + 1), Some(t) if matches!(t.kind, TokenType::Article(_)))
2898 && self.tokens.get(self.current + 2)
2899 .map(|t| self.interner.resolve(t.lexeme).to_lowercase() == "first")
2900 .unwrap_or(false)
2901 }
2902
2903 fn parse_launch_statement(&mut self) -> ParseResult<Stmt<'a>> {
2906 self.advance(); if !self.check_article() {
2910 return Err(ParseError {
2911 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2912 span: self.current_span(),
2913 });
2914 }
2915 self.advance();
2916
2917 if !self.check(&TokenType::Task) {
2919 return Err(ParseError {
2920 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2921 span: self.current_span(),
2922 });
2923 }
2924 self.advance();
2925
2926 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2928 return Err(ParseError {
2929 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2930 span: self.current_span(),
2931 });
2932 }
2933 self.advance();
2934
2935 let function = match &self.tokens[self.current].kind {
2938 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2939 let s = *sym;
2940 self.advance();
2941 s
2942 }
2943 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2944 let s = self.tokens[self.current].lexeme;
2945 self.advance();
2946 s
2947 }
2948 _ => {
2949 return Err(ParseError {
2950 kind: ParseErrorKind::ExpectedKeyword { keyword: "function name".to_string() },
2951 span: self.current_span(),
2952 });
2953 }
2954 };
2955
2956 let args = if self.check(&TokenType::LParen) {
2958 self.parse_call_arguments()?
2959 } else if self.check_word("with") {
2960 self.advance(); let mut args = Vec::new();
2962 let arg = self.parse_imperative_expr()?;
2963 args.push(arg);
2964 while self.check(&TokenType::And) {
2966 self.advance();
2967 let arg = self.parse_imperative_expr()?;
2968 args.push(arg);
2969 }
2970 args
2971 } else {
2972 Vec::new()
2973 };
2974
2975 Ok(Stmt::LaunchTask { function, args })
2976 }
2977
2978 fn parse_send_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2981 self.advance(); let value = self.parse_imperative_expr()?;
2985
2986 if !self.check(&TokenType::Into) {
2988 return Err(ParseError {
2989 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
2990 span: self.current_span(),
2991 });
2992 }
2993 self.advance();
2994
2995 let pipe = self.parse_imperative_expr()?;
2997
2998 Ok(Stmt::SendPipe { value, pipe })
2999 }
3000
3001 fn parse_receive_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
3004 self.advance(); let var = self.expect_identifier()?;
3008
3009 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3011 return Err(ParseError {
3012 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3013 span: self.current_span(),
3014 });
3015 }
3016 self.advance();
3017
3018 let pipe = self.parse_imperative_expr()?;
3020
3021 Ok(Stmt::ReceivePipe { var, pipe })
3022 }
3023
3024 fn parse_try_statement(&mut self) -> ParseResult<Stmt<'a>> {
3027 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3031 return Err(ParseError {
3032 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3033 span: self.current_span(),
3034 });
3035 }
3036 self.advance();
3037
3038 if self.check(&TokenType::Send) {
3040 self.advance(); let value = self.parse_imperative_expr()?;
3042
3043 if !self.check(&TokenType::Into) {
3044 return Err(ParseError {
3045 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
3046 span: self.current_span(),
3047 });
3048 }
3049 self.advance();
3050
3051 let pipe = self.parse_imperative_expr()?;
3052 Ok(Stmt::TrySendPipe { value, pipe, result: None })
3053 } else if self.check(&TokenType::Receive) {
3054 self.advance(); let var = self.expect_identifier()?;
3057
3058 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3059 return Err(ParseError {
3060 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3061 span: self.current_span(),
3062 });
3063 }
3064 self.advance();
3065
3066 let pipe = self.parse_imperative_expr()?;
3067 Ok(Stmt::TryReceivePipe { var, pipe })
3068 } else {
3069 Err(ParseError {
3070 kind: ParseErrorKind::ExpectedKeyword { keyword: "send or receive".to_string() },
3071 span: self.current_span(),
3072 })
3073 }
3074 }
3075
3076 fn parse_escape_body(&mut self) -> ParseResult<(crate::intern::Symbol, crate::intern::Symbol, crate::token::Span)> {
3079 let start_span = self.current_span();
3080 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3084 return Err(ParseError {
3085 kind: ParseErrorKind::Custom(
3086 "Expected 'to' after 'Escape'. Syntax: Escape to Rust:".to_string()
3087 ),
3088 span: self.current_span(),
3089 });
3090 }
3091 self.advance(); let language = match &self.peek().kind {
3095 TokenType::ProperName(sym) => {
3096 let s = *sym;
3097 self.advance();
3098 s
3099 }
3100 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3101 let s = *sym;
3102 self.advance();
3103 s
3104 }
3105 _ => {
3106 return Err(ParseError {
3107 kind: ParseErrorKind::Custom(
3108 "Expected language name after 'Escape to'. Currently only 'Rust' is supported.".to_string()
3109 ),
3110 span: self.current_span(),
3111 });
3112 }
3113 };
3114
3115 if !language.is(self.interner, "Rust") {
3117 let lang_str = self.interner.resolve(language);
3118 return Err(ParseError {
3119 kind: ParseErrorKind::Custom(
3120 format!("Unsupported escape target '{}'. Only 'Rust' is supported.", lang_str)
3121 ),
3122 span: self.current_span(),
3123 });
3124 }
3125
3126 if !self.check(&TokenType::Colon) {
3128 return Err(ParseError {
3129 kind: ParseErrorKind::Custom(
3130 "Expected ':' after 'Escape to Rust'. Syntax: Escape to Rust:".to_string()
3131 ),
3132 span: self.current_span(),
3133 });
3134 }
3135 self.advance(); if !self.check(&TokenType::Indent) {
3139 return Err(ParseError {
3140 kind: ParseErrorKind::Custom(
3141 "Expected indented block after 'Escape to Rust:'.".to_string()
3142 ),
3143 span: self.current_span(),
3144 });
3145 }
3146 self.advance(); let code = match &self.peek().kind {
3150 TokenType::EscapeBlock(sym) => {
3151 let s = *sym;
3152 self.advance();
3153 s
3154 }
3155 _ => {
3156 return Err(ParseError {
3157 kind: ParseErrorKind::Custom(
3158 "Escape block body is empty or malformed.".to_string()
3159 ),
3160 span: self.current_span(),
3161 });
3162 }
3163 };
3164
3165 if self.check(&TokenType::Dedent) {
3167 self.advance();
3168 }
3169
3170 let end_span = self.previous().span;
3171 Ok((language, code, crate::token::Span::new(start_span.start, end_span.end)))
3172 }
3173
3174 fn parse_escape_statement(&mut self) -> ParseResult<Stmt<'a>> {
3176 let (language, code, span) = self.parse_escape_body()?;
3177 Ok(Stmt::Escape { language, code, span })
3178 }
3179
3180 fn parse_escape_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
3183 let (language, code, _span) = self.parse_escape_body()?;
3184 Ok(self.ctx.alloc_imperative_expr(Expr::Escape { language, code }))
3185 }
3186
3187 fn parse_requires_block(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
3190 let mut deps = Vec::new();
3191
3192 loop {
3193 if self.is_at_end() {
3195 break;
3196 }
3197 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
3198 break;
3199 }
3200
3201 if self.check(&TokenType::Indent)
3203 || self.check(&TokenType::Dedent)
3204 || self.check(&TokenType::Newline)
3205 {
3206 self.advance();
3207 continue;
3208 }
3209
3210 if matches!(self.peek().kind, TokenType::Article(_)) {
3212 let dep = self.parse_require_line()?;
3213 deps.push(dep);
3214 continue;
3215 }
3216
3217 self.advance();
3219 }
3220
3221 Ok(deps)
3222 }
3223
3224 fn parse_require_line(&mut self) -> ParseResult<Stmt<'a>> {
3227 let start_span = self.current_span();
3228
3229 if !matches!(self.peek().kind, TokenType::Article(_)) {
3231 return Err(crate::error::ParseError {
3232 kind: crate::error::ParseErrorKind::Custom(
3233 "Expected 'The' to begin a dependency declaration.".to_string(),
3234 ),
3235 span: self.current_span(),
3236 });
3237 }
3238 self.advance(); let crate_name = if let TokenType::StringLiteral(sym) = self.peek().kind {
3242 let s = sym;
3243 self.advance();
3244 s
3245 } else {
3246 return Err(crate::error::ParseError {
3247 kind: crate::error::ParseErrorKind::Custom(
3248 "Expected a string literal for the crate name, e.g. \"serde\".".to_string(),
3249 ),
3250 span: self.current_span(),
3251 });
3252 };
3253
3254 if !self.check_word("crate") {
3256 return Err(crate::error::ParseError {
3257 kind: crate::error::ParseErrorKind::Custom(
3258 "Expected the word 'crate' after the crate name.".to_string(),
3259 ),
3260 span: self.current_span(),
3261 });
3262 }
3263 self.advance(); if !self.check_word("version") {
3267 return Err(crate::error::ParseError {
3268 kind: crate::error::ParseErrorKind::Custom(
3269 "Expected 'version' after 'crate'.".to_string(),
3270 ),
3271 span: self.current_span(),
3272 });
3273 }
3274 self.advance(); let version = if let TokenType::StringLiteral(sym) = self.peek().kind {
3278 let s = sym;
3279 self.advance();
3280 s
3281 } else {
3282 return Err(crate::error::ParseError {
3283 kind: crate::error::ParseErrorKind::Custom(
3284 "Expected a string literal for the version, e.g. \"1.0\".".to_string(),
3285 ),
3286 span: self.current_span(),
3287 });
3288 };
3289
3290 let mut features = Vec::new();
3292 if self.check_preposition_is("with") {
3293 self.advance(); if !self.check_word("features") {
3297 return Err(crate::error::ParseError {
3298 kind: crate::error::ParseErrorKind::Custom(
3299 "Expected 'features' after 'with'.".to_string(),
3300 ),
3301 span: self.current_span(),
3302 });
3303 }
3304 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3308 features.push(sym);
3309 self.advance();
3310 } else {
3311 return Err(crate::error::ParseError {
3312 kind: crate::error::ParseErrorKind::Custom(
3313 "Expected a string literal for a feature name.".to_string(),
3314 ),
3315 span: self.current_span(),
3316 });
3317 }
3318
3319 while self.check(&TokenType::And) {
3321 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3323 features.push(sym);
3324 self.advance();
3325 } else {
3326 return Err(crate::error::ParseError {
3327 kind: crate::error::ParseErrorKind::Custom(
3328 "Expected a string literal for a feature name after 'and'.".to_string(),
3329 ),
3330 span: self.current_span(),
3331 });
3332 }
3333 }
3334 }
3335
3336 if self.check(&TokenType::For) {
3338 self.advance(); while !self.check(&TokenType::Period) && !self.check(&TokenType::EOF)
3340 && !self.check(&TokenType::Newline)
3341 && !matches!(self.peek().kind, TokenType::BlockHeader { .. })
3342 {
3343 self.advance();
3344 }
3345 }
3346
3347 if self.check(&TokenType::Period) {
3349 self.advance();
3350 }
3351
3352 let end_span = self.previous().span;
3353
3354 Ok(Stmt::Require {
3355 crate_name,
3356 version,
3357 features,
3358 span: crate::token::Span::new(start_span.start, end_span.end),
3359 })
3360 }
3361
3362 fn parse_stop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3365 self.advance(); let handle = self.parse_imperative_expr()?;
3368
3369 Ok(Stmt::StopTask { handle })
3370 }
3371
3372 fn parse_select_statement(&mut self) -> ParseResult<Stmt<'a>> {
3380 use crate::ast::stmt::SelectBranch;
3381
3382 self.advance(); if !self.check_article() {
3386 return Err(ParseError {
3387 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
3388 span: self.current_span(),
3389 });
3390 }
3391 self.advance();
3392
3393 if !self.check_word("first") {
3395 return Err(ParseError {
3396 kind: ParseErrorKind::ExpectedKeyword { keyword: "first".to_string() },
3397 span: self.current_span(),
3398 });
3399 }
3400 self.advance();
3401
3402 if !self.check_preposition_is("of") {
3404 return Err(ParseError {
3405 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3406 span: self.current_span(),
3407 });
3408 }
3409 self.advance();
3410
3411 if !self.check(&TokenType::Colon) {
3413 return Err(ParseError {
3414 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3415 span: self.current_span(),
3416 });
3417 }
3418 self.advance();
3419
3420 if !self.check(&TokenType::Indent) {
3422 return Err(ParseError {
3423 kind: ParseErrorKind::ExpectedStatement,
3424 span: self.current_span(),
3425 });
3426 }
3427 self.advance();
3428
3429 let mut branches = Vec::new();
3431 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3432 let branch = self.parse_select_branch()?;
3433 branches.push(branch);
3434 }
3435
3436 if self.check(&TokenType::Dedent) {
3438 self.advance();
3439 }
3440
3441 Ok(Stmt::Select { branches })
3442 }
3443
3444 fn parse_select_branch(&mut self) -> ParseResult<crate::ast::stmt::SelectBranch<'a>> {
3446 use crate::ast::stmt::SelectBranch;
3447
3448 if self.check(&TokenType::Receive) {
3449 self.advance(); let var = match &self.tokens[self.current].kind {
3452 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3453 let s = *sym;
3454 self.advance();
3455 s
3456 }
3457 _ => {
3458 return Err(ParseError {
3459 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
3460 span: self.current_span(),
3461 });
3462 }
3463 };
3464
3465 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3466 return Err(ParseError {
3467 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3468 span: self.current_span(),
3469 });
3470 }
3471 self.advance();
3472
3473 let pipe = self.parse_imperative_expr()?;
3474
3475 if !self.check(&TokenType::Colon) {
3477 return Err(ParseError {
3478 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3479 span: self.current_span(),
3480 });
3481 }
3482 self.advance();
3483
3484 let body = self.parse_indented_block()?;
3486
3487 Ok(SelectBranch::Receive { var, pipe, body })
3488 } else if self.check_word("after") {
3489 self.advance(); let milliseconds = self.parse_imperative_expr()?;
3492
3493 if self.check_word("seconds") || self.check_word("milliseconds") {
3495 self.advance();
3496 }
3497
3498 if !self.check(&TokenType::Colon) {
3500 return Err(ParseError {
3501 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3502 span: self.current_span(),
3503 });
3504 }
3505 self.advance();
3506
3507 let body = self.parse_indented_block()?;
3509
3510 Ok(SelectBranch::Timeout { milliseconds, body })
3511 } else {
3512 Err(ParseError {
3513 kind: ParseErrorKind::ExpectedKeyword { keyword: "Receive or After".to_string() },
3514 span: self.current_span(),
3515 })
3516 }
3517 }
3518
3519 fn parse_indented_block(&mut self) -> ParseResult<crate::ast::stmt::Block<'a>> {
3521 if !self.check(&TokenType::Indent) {
3523 return Err(ParseError {
3524 kind: ParseErrorKind::ExpectedStatement,
3525 span: self.current_span(),
3526 });
3527 }
3528 self.advance();
3529
3530 let mut stmts = Vec::new();
3531 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3532 let stmt = self.parse_statement()?;
3533 stmts.push(stmt);
3534 if self.check(&TokenType::Period) {
3535 self.advance();
3536 }
3537 }
3538
3539 if self.check(&TokenType::Dedent) {
3541 self.advance();
3542 }
3543
3544 let block = self.ctx.stmts.expect("imperative arenas not initialized")
3545 .alloc_slice(stmts.into_iter());
3546
3547 Ok(block)
3548 }
3549
3550 fn parse_give_statement(&mut self) -> ParseResult<Stmt<'a>> {
3551 self.advance(); let object = self.parse_imperative_expr()?;
3555
3556 if !self.check_to_preposition() {
3558 return Err(ParseError {
3559 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3560 span: self.current_span(),
3561 });
3562 }
3563 self.advance(); let recipient = self.parse_imperative_expr()?;
3567
3568 if let Expr::Identifier(sym) = object {
3570 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Moved);
3571 }
3572
3573 Ok(Stmt::Give { object, recipient })
3574 }
3575
3576 fn parse_show_statement(&mut self) -> ParseResult<Stmt<'a>> {
3577 self.advance(); let object = self.parse_condition()?;
3582
3583 let recipient = if self.check_to_preposition() {
3587 self.advance(); if self.check_article() {
3592 self.advance(); }
3594 if self.check(&TokenType::Console) {
3595 self.advance(); let show_sym = self.interner.intern("show");
3597 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3598 } else {
3599 self.parse_imperative_expr()?
3601 }
3602 } else {
3603 let show_sym = self.interner.intern("show");
3605 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3606 };
3607
3608 if let Expr::Identifier(sym) = object {
3610 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Borrowed);
3611 }
3612
3613 Ok(Stmt::Show { object, recipient })
3614 }
3615
3616 fn parse_push_statement(&mut self) -> ParseResult<Stmt<'a>> {
3619 self.advance(); let value = self.parse_imperative_expr()?;
3623
3624 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3626 return Err(ParseError {
3627 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3628 span: self.current_span(),
3629 });
3630 }
3631 self.advance(); let collection = self.parse_imperative_expr()?;
3635
3636 Ok(Stmt::Push { value, collection })
3637 }
3638
3639 fn parse_pop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3642 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3646 return Err(ParseError {
3647 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3648 span: self.current_span(),
3649 });
3650 }
3651 self.advance(); let collection = self.parse_imperative_expr()?;
3655
3656 let into = if self.check(&TokenType::Into) || self.check_preposition_is("into") {
3658 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = &self.peek().kind {
3662 let sym = *sym;
3663 self.advance();
3664 Some(sym)
3665 } else if let Some(token) = self.tokens.get(self.current) {
3666 let sym = token.lexeme;
3668 self.advance();
3669 Some(sym)
3670 } else {
3671 return Err(ParseError {
3672 kind: ParseErrorKind::ExpectedIdentifier,
3673 span: self.current_span(),
3674 });
3675 }
3676 } else {
3677 None
3678 };
3679
3680 Ok(Stmt::Pop { collection, into })
3681 }
3682
3683 fn parse_add_statement(&mut self) -> ParseResult<Stmt<'a>> {
3686 self.advance(); let value = self.parse_imperative_expr()?;
3690
3691 if !self.check_preposition_is("to") && !self.check(&TokenType::To) {
3693 return Err(ParseError {
3694 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3695 span: self.current_span(),
3696 });
3697 }
3698 self.advance(); let collection = self.parse_imperative_expr()?;
3702
3703 Ok(Stmt::Add { value, collection })
3704 }
3705
3706 fn parse_remove_statement(&mut self) -> ParseResult<Stmt<'a>> {
3709 self.advance(); let value = self.parse_imperative_expr()?;
3713
3714 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3716 return Err(ParseError {
3717 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3718 span: self.current_span(),
3719 });
3720 }
3721 self.advance(); let collection = self.parse_imperative_expr()?;
3725
3726 Ok(Stmt::Remove { value, collection })
3727 }
3728
3729 fn parse_read_statement(&mut self) -> ParseResult<Stmt<'a>> {
3733 self.advance(); let var = self.expect_identifier()?;
3737
3738 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3740 return Err(ParseError {
3741 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3742 span: self.current_span(),
3743 });
3744 }
3745 self.advance(); if self.check_article() {
3749 self.advance();
3750 }
3751
3752 let source = if self.check(&TokenType::Console) {
3754 self.advance(); ReadSource::Console
3756 } else if self.check(&TokenType::File) {
3757 self.advance(); let path = self.parse_imperative_expr()?;
3759 ReadSource::File(path)
3760 } else {
3761 return Err(ParseError {
3762 kind: ParseErrorKind::ExpectedKeyword { keyword: "console or file".to_string() },
3763 span: self.current_span(),
3764 });
3765 };
3766
3767 Ok(Stmt::ReadFrom { var, source })
3768 }
3769
3770 fn parse_write_statement(&mut self) -> ParseResult<Stmt<'a>> {
3773 self.advance(); let content = self.parse_imperative_expr()?;
3777
3778 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3780 return Err(ParseError {
3781 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3782 span: self.current_span(),
3783 });
3784 }
3785 self.advance(); if !self.check(&TokenType::File) {
3789 return Err(ParseError {
3790 kind: ParseErrorKind::ExpectedKeyword { keyword: "file".to_string() },
3791 span: self.current_span(),
3792 });
3793 }
3794 self.advance(); let path = self.parse_imperative_expr()?;
3798
3799 Ok(Stmt::WriteFile { content, path })
3800 }
3801
3802 fn parse_zone_statement(&mut self) -> ParseResult<Stmt<'a>> {
3808 self.advance(); if self.check_article() {
3812 self.advance();
3813 }
3814
3815 if self.check(&TokenType::New) {
3817 self.advance();
3818 }
3819
3820 if !self.check(&TokenType::Zone) {
3822 return Err(ParseError {
3823 kind: ParseErrorKind::ExpectedKeyword { keyword: "zone".to_string() },
3824 span: self.current_span(),
3825 });
3826 }
3827 self.advance(); if !self.check(&TokenType::Called) {
3831 return Err(ParseError {
3832 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
3833 span: self.current_span(),
3834 });
3835 }
3836 self.advance(); let name = match &self.peek().kind {
3840 TokenType::StringLiteral(sym) => {
3841 let s = *sym;
3842 self.advance();
3843 s
3844 }
3845 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3846 let s = *sym;
3847 self.advance();
3848 s
3849 }
3850 _ => {
3851 let token = self.peek().clone();
3853 self.advance();
3854 token.lexeme
3855 }
3856 };
3857
3858 let mut capacity = None;
3859 let mut source_file = None;
3860
3861 if self.check(&TokenType::Mapped) {
3863 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3867 return Err(ParseError {
3868 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3869 span: self.current_span(),
3870 });
3871 }
3872 self.advance(); if let TokenType::StringLiteral(path) = &self.peek().kind {
3876 source_file = Some(*path);
3877 self.advance();
3878 } else {
3879 return Err(ParseError {
3880 kind: ParseErrorKind::ExpectedKeyword { keyword: "file path string".to_string() },
3881 span: self.current_span(),
3882 });
3883 }
3884 }
3885 else if self.check_of_preposition() {
3887 self.advance(); if !self.check(&TokenType::Size) {
3891 return Err(ParseError {
3892 kind: ParseErrorKind::ExpectedKeyword { keyword: "size".to_string() },
3893 span: self.current_span(),
3894 });
3895 }
3896 self.advance(); let size_value = match &self.peek().kind {
3900 TokenType::Number(sym) => {
3901 let num_str = self.interner.resolve(*sym);
3902 let val = num_str.replace('_', "").parse::<usize>().unwrap_or(0);
3903 self.advance();
3904 val
3905 }
3906 TokenType::Cardinal(n) => {
3907 let val = *n as usize;
3908 self.advance();
3909 val
3910 }
3911 _ => {
3912 return Err(ParseError {
3913 kind: ParseErrorKind::ExpectedNumber,
3914 span: self.current_span(),
3915 });
3916 }
3917 };
3918
3919 let unit_multiplier = self.parse_size_unit()?;
3921 capacity = Some(size_value * unit_multiplier);
3922 }
3923
3924 if !self.check(&TokenType::Colon) {
3926 return Err(ParseError {
3927 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3928 span: self.current_span(),
3929 });
3930 }
3931 self.advance(); if !self.check(&TokenType::Indent) {
3935 return Err(ParseError {
3936 kind: ParseErrorKind::ExpectedStatement,
3937 span: self.current_span(),
3938 });
3939 }
3940 self.advance(); let mut body_stmts = Vec::new();
3944 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3945 let stmt = self.parse_statement()?;
3946 body_stmts.push(stmt);
3947 if self.check(&TokenType::Period) {
3948 self.advance();
3949 }
3950 }
3951
3952 if self.check(&TokenType::Dedent) {
3954 self.advance();
3955 }
3956
3957 let body = self.ctx.stmts.expect("imperative arenas not initialized")
3958 .alloc_slice(body_stmts.into_iter());
3959
3960 Ok(Stmt::Zone { name, capacity, source_file, body })
3961 }
3962
3963 fn parse_size_unit(&mut self) -> ParseResult<usize> {
3965 let token = self.peek().clone();
3966 let unit_str = self.interner.resolve(token.lexeme).to_uppercase();
3967 self.advance();
3968
3969 match unit_str.as_str() {
3970 "B" | "BYTES" | "BYTE" => Ok(1),
3971 "KB" | "KILOBYTE" | "KILOBYTES" => Ok(1024),
3972 "MB" | "MEGABYTE" | "MEGABYTES" => Ok(1024 * 1024),
3973 "GB" | "GIGABYTE" | "GIGABYTES" => Ok(1024 * 1024 * 1024),
3974 _ => Err(ParseError {
3975 kind: ParseErrorKind::ExpectedKeyword {
3976 keyword: "size unit (B, KB, MB, GB)".to_string(),
3977 },
3978 span: token.span,
3979 }),
3980 }
3981 }
3982
3983 fn parse_concurrent_block(&mut self) -> ParseResult<Stmt<'a>> {
3992 self.advance(); if !self.check(&TokenType::All) {
3996 return Err(ParseError {
3997 kind: ParseErrorKind::ExpectedKeyword { keyword: "all".to_string() },
3998 span: self.current_span(),
3999 });
4000 }
4001 self.advance(); if !self.check_of_preposition() {
4005 return Err(ParseError {
4006 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
4007 span: self.current_span(),
4008 });
4009 }
4010 self.advance(); if !self.check_article() {
4014 return Err(ParseError {
4015 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
4016 span: self.current_span(),
4017 });
4018 }
4019 self.advance(); if !self.check(&TokenType::Following) {
4023 return Err(ParseError {
4024 kind: ParseErrorKind::ExpectedKeyword { keyword: "following".to_string() },
4025 span: self.current_span(),
4026 });
4027 }
4028 self.advance(); if !self.check(&TokenType::Colon) {
4032 return Err(ParseError {
4033 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4034 span: self.current_span(),
4035 });
4036 }
4037 self.advance(); if !self.check(&TokenType::Indent) {
4041 return Err(ParseError {
4042 kind: ParseErrorKind::ExpectedStatement,
4043 span: self.current_span(),
4044 });
4045 }
4046 self.advance(); let mut task_stmts = Vec::new();
4050 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4051 let stmt = self.parse_statement()?;
4052 task_stmts.push(stmt);
4053 if self.check(&TokenType::Period) {
4054 self.advance();
4055 }
4056 }
4057
4058 if self.check(&TokenType::Dedent) {
4060 self.advance();
4061 }
4062
4063 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
4064 .alloc_slice(task_stmts.into_iter());
4065
4066 Ok(Stmt::Concurrent { tasks })
4067 }
4068
4069 fn parse_parallel_block(&mut self) -> ParseResult<Stmt<'a>> {
4078 self.advance(); if !self.check(&TokenType::Colon) {
4082 return Err(ParseError {
4083 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4084 span: self.current_span(),
4085 });
4086 }
4087 self.advance(); if !self.check(&TokenType::Indent) {
4091 return Err(ParseError {
4092 kind: ParseErrorKind::ExpectedStatement,
4093 span: self.current_span(),
4094 });
4095 }
4096 self.advance(); let mut task_stmts = Vec::new();
4100 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4101 let stmt = self.parse_statement()?;
4102 task_stmts.push(stmt);
4103 if self.check(&TokenType::Period) {
4104 self.advance();
4105 }
4106 }
4107
4108 if self.check(&TokenType::Dedent) {
4110 self.advance();
4111 }
4112
4113 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
4114 .alloc_slice(task_stmts.into_iter());
4115
4116 Ok(Stmt::Parallel { tasks })
4117 }
4118
4119 fn parse_inspect_statement(&mut self) -> ParseResult<Stmt<'a>> {
4126 self.advance(); let target = self.parse_imperative_expr()?;
4130
4131 if !self.check(&TokenType::Colon) {
4133 return Err(ParseError {
4134 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4135 span: self.current_span(),
4136 });
4137 }
4138 self.advance(); if !self.check(&TokenType::Indent) {
4142 return Err(ParseError {
4143 kind: ParseErrorKind::ExpectedStatement,
4144 span: self.current_span(),
4145 });
4146 }
4147 self.advance(); let mut arms = Vec::new();
4150 let mut has_otherwise = false;
4151
4152 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4154 if self.check(&TokenType::Otherwise) {
4155 self.advance(); if !self.check(&TokenType::Colon) {
4159 return Err(ParseError {
4160 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4161 span: self.current_span(),
4162 });
4163 }
4164 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4168 self.advance(); let mut stmts = Vec::new();
4170 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4171 let stmt = self.parse_statement()?;
4172 stmts.push(stmt);
4173 if self.check(&TokenType::Period) {
4174 self.advance();
4175 }
4176 }
4177 if self.check(&TokenType::Dedent) {
4178 self.advance();
4179 }
4180 stmts
4181 } else {
4182 let stmt = self.parse_statement()?;
4184 if self.check(&TokenType::Period) {
4185 self.advance();
4186 }
4187 vec![stmt]
4188 };
4189
4190 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4191 .alloc_slice(body_stmts.into_iter());
4192
4193 arms.push(MatchArm { enum_name: None, variant: None, bindings: vec![], body });
4194 has_otherwise = true;
4195 break;
4196 }
4197
4198 if self.check(&TokenType::If) {
4199 let arm = self.parse_match_arm()?;
4201 arms.push(arm);
4202 } else if self.check(&TokenType::When) || self.check_word("When") {
4203 let arm = self.parse_when_arm()?;
4205 arms.push(arm);
4206 } else if self.check(&TokenType::Newline) {
4207 self.advance();
4209 } else {
4210 self.advance();
4212 }
4213 }
4214
4215 if self.check(&TokenType::Dedent) {
4217 self.advance();
4218 }
4219
4220 Ok(Stmt::Inspect { target, arms, has_otherwise })
4221 }
4222
4223 fn parse_match_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4225 self.advance(); if !self.check_word("it") {
4229 return Err(ParseError {
4230 kind: ParseErrorKind::ExpectedKeyword { keyword: "it".to_string() },
4231 span: self.current_span(),
4232 });
4233 }
4234 self.advance(); if !self.check(&TokenType::Is) {
4238 return Err(ParseError {
4239 kind: ParseErrorKind::ExpectedKeyword { keyword: "is".to_string() },
4240 span: self.current_span(),
4241 });
4242 }
4243 self.advance(); if self.check_article() {
4247 self.advance();
4248 }
4249
4250 let variant = self.expect_identifier()?;
4252
4253 let enum_name = self.find_variant(variant);
4255
4256 let bindings = if self.check(&TokenType::LParen) {
4258 self.parse_pattern_bindings()?
4259 } else {
4260 vec![]
4261 };
4262
4263 if !self.check(&TokenType::Colon) {
4265 return Err(ParseError {
4266 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4267 span: self.current_span(),
4268 });
4269 }
4270 self.advance(); if !self.check(&TokenType::Indent) {
4274 return Err(ParseError {
4275 kind: ParseErrorKind::ExpectedStatement,
4276 span: self.current_span(),
4277 });
4278 }
4279 self.advance(); let mut body_stmts = Vec::new();
4283 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4284 let stmt = self.parse_statement()?;
4285 body_stmts.push(stmt);
4286 if self.check(&TokenType::Period) {
4287 self.advance();
4288 }
4289 }
4290
4291 if self.check(&TokenType::Dedent) {
4293 self.advance();
4294 }
4295
4296 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4297 .alloc_slice(body_stmts.into_iter());
4298
4299 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4300 }
4301
4302 fn parse_when_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4304 self.advance(); let variant = self.expect_identifier()?;
4308
4309 let (enum_name, variant_fields) = self.type_registry
4311 .as_ref()
4312 .and_then(|r| r.find_variant(variant).map(|(enum_name, vdef)| {
4313 let fields: Vec<_> = vdef.fields.iter().map(|f| f.name).collect();
4314 (Some(enum_name), fields)
4315 }))
4316 .unwrap_or((None, vec![]));
4317
4318 let bindings = if self.check(&TokenType::LParen) {
4320 let raw_bindings = self.parse_when_bindings()?;
4321 raw_bindings.into_iter().enumerate().map(|(i, binding)| {
4323 let field = variant_fields.get(i).copied().unwrap_or(binding);
4324 (field, binding)
4325 }).collect()
4326 } else {
4327 vec![]
4328 };
4329
4330 if !self.check(&TokenType::Colon) {
4332 return Err(ParseError {
4333 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4334 span: self.current_span(),
4335 });
4336 }
4337 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4341 self.advance(); let mut stmts = Vec::new();
4343 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4344 let stmt = self.parse_statement()?;
4345 stmts.push(stmt);
4346 if self.check(&TokenType::Period) {
4347 self.advance();
4348 }
4349 }
4350 if self.check(&TokenType::Dedent) {
4351 self.advance();
4352 }
4353 stmts
4354 } else {
4355 let stmt = self.parse_statement()?;
4357 if self.check(&TokenType::Period) {
4358 self.advance();
4359 }
4360 vec![stmt]
4361 };
4362
4363 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4364 .alloc_slice(body_stmts.into_iter());
4365
4366 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4367 }
4368
4369 fn parse_when_bindings(&mut self) -> ParseResult<Vec<Symbol>> {
4371 self.advance(); let mut bindings = Vec::new();
4373
4374 loop {
4375 let binding = self.expect_identifier()?;
4376 bindings.push(binding);
4377
4378 if !self.check(&TokenType::Comma) {
4379 break;
4380 }
4381 self.advance(); }
4383
4384 if !self.check(&TokenType::RParen) {
4385 return Err(ParseError {
4386 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4387 span: self.current_span(),
4388 });
4389 }
4390 self.advance(); Ok(bindings)
4393 }
4394
4395 fn parse_pattern_bindings(&mut self) -> ParseResult<Vec<(Symbol, Symbol)>> {
4397 self.advance(); let mut bindings = Vec::new();
4399
4400 loop {
4401 let field = self.expect_identifier()?;
4402 let binding = if self.check(&TokenType::Colon) {
4403 self.advance(); self.expect_identifier()?
4405 } else {
4406 field };
4408 bindings.push((field, binding));
4409
4410 if !self.check(&TokenType::Comma) {
4411 break;
4412 }
4413 self.advance(); }
4415
4416 if !self.check(&TokenType::RParen) {
4417 return Err(ParseError {
4418 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4419 span: self.current_span(),
4420 });
4421 }
4422 self.advance(); Ok(bindings)
4425 }
4426
4427 fn parse_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4431 use crate::ast::Expr;
4432 let mut fields = Vec::new();
4433
4434 self.advance();
4436
4437 loop {
4438 let field_name = self.expect_identifier()?;
4440
4441 let value = self.parse_comparison()?;
4444
4445 fields.push((field_name, value));
4446
4447 if self.check(&TokenType::And) {
4449 self.advance(); continue;
4451 }
4452 break;
4453 }
4454
4455 Ok(fields)
4456 }
4457
4458 fn parse_variant_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4460 self.parse_constructor_fields()
4461 }
4462
4463 fn parse_struct_init_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4465 self.parse_constructor_fields()
4466 }
4467
4468 fn parse_generic_type_args(&mut self, type_name: Symbol) -> ParseResult<Vec<TypeExpr<'a>>> {
4472 if !self.is_generic_type(type_name) {
4474 return Ok(vec![]);
4475 }
4476
4477 if !self.check_preposition_is("of") {
4479 return Ok(vec![]); }
4481 self.advance(); let mut type_args = Vec::new();
4484 loop {
4485 let type_arg = self.parse_type_expression()?;
4487 type_args.push(type_arg);
4488
4489 if self.check(&TokenType::And) || self.check_to_preposition() {
4491 self.advance(); continue;
4493 }
4494 break;
4495 }
4496
4497 Ok(type_args)
4498 }
4499
4500 fn skip_type_def_content(&mut self) {
4504 while !self.is_at_end() {
4505 if matches!(
4507 self.tokens.get(self.current),
4508 Some(Token { kind: TokenType::BlockHeader { .. }, .. })
4509 ) {
4510 break;
4511 }
4512 self.advance();
4513 }
4514 }
4515
4516 fn parse_theorem_block(&mut self) -> ParseResult<Stmt<'a>> {
4524 use crate::ast::theorem::{TheoremBlock, ProofStrategy};
4525
4526 self.skip_whitespace_tokens();
4528
4529 if self.check(&TokenType::Colon) {
4534 self.advance();
4535 }
4536
4537 self.skip_whitespace_tokens();
4539
4540 let name = if let Some(token) = self.tokens.get(self.current) {
4542 match &token.kind {
4543 TokenType::Noun(_)
4544 | TokenType::ProperName(_)
4545 | TokenType::Verb { .. }
4546 | TokenType::Adjective(_) => {
4547 let name = self.interner.resolve(token.lexeme).to_string();
4548 self.advance();
4549 name
4550 }
4551 _ => {
4552 let lexeme = self.interner.resolve(token.lexeme);
4554 if !lexeme.is_empty() && lexeme.chars().next().map(|c| c.is_alphanumeric()).unwrap_or(false) {
4555 let name = lexeme.to_string();
4556 self.advance();
4557 name
4558 } else {
4559 "Anonymous".to_string()
4560 }
4561 }
4562 }
4563 } else {
4564 "Anonymous".to_string()
4565 };
4566
4567 self.skip_whitespace_tokens();
4568
4569 if self.check(&TokenType::Period) {
4571 self.advance();
4572 }
4573
4574 self.skip_whitespace_tokens();
4575
4576 let mut premises = Vec::new();
4579 while self.check(&TokenType::Given) {
4580 self.advance(); if self.check(&TokenType::Colon) {
4584 self.advance();
4585 }
4586
4587 self.skip_whitespace_tokens();
4588
4589 let premise_expr = self.parse_sentence()?;
4591 premises.push(premise_expr);
4592
4593 self.world_state.end_sentence();
4596
4597 if self.check(&TokenType::Period) {
4599 self.advance();
4600 }
4601
4602 self.skip_whitespace_tokens();
4603 }
4604
4605 let goal = if self.check(&TokenType::Prove) {
4607 self.advance(); if self.check(&TokenType::Colon) {
4610 self.advance();
4611 }
4612
4613 self.skip_whitespace_tokens();
4614
4615 let goal_expr = self.parse_sentence()?;
4616
4617 if self.check(&TokenType::Period) {
4618 self.advance();
4619 }
4620
4621 goal_expr
4622 } else {
4623 return Err(ParseError {
4624 kind: ParseErrorKind::ExpectedKeyword { keyword: "Prove".to_string() },
4625 span: self.current_span(),
4626 });
4627 };
4628
4629 self.skip_whitespace_tokens();
4630
4631 let strategy = if self.check(&TokenType::BlockHeader { block_type: crate::token::BlockType::Proof }) {
4633 self.advance();
4634 self.skip_whitespace_tokens();
4635
4636 if self.check(&TokenType::Colon) {
4637 self.advance();
4638 }
4639
4640 self.skip_whitespace_tokens();
4641
4642 if self.check(&TokenType::Auto) {
4643 self.advance();
4644 ProofStrategy::Auto
4645 } else {
4646 ProofStrategy::Auto
4648 }
4649 } else {
4650 ProofStrategy::Auto
4652 };
4653
4654 if self.check(&TokenType::Period) {
4656 self.advance();
4657 }
4658
4659 let theorem = TheoremBlock {
4660 name,
4661 premises,
4662 goal,
4663 strategy,
4664 };
4665
4666 Ok(Stmt::Theorem(theorem))
4667 }
4668
4669 fn skip_whitespace_tokens(&mut self) {
4671 while self.check(&TokenType::Newline) || self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) {
4672 self.advance();
4673 }
4674 }
4675
4676 fn parse_function_def(&mut self) -> ParseResult<Stmt<'a>> {
4681 self.parse_function_def_with_flags(HashSet::new())
4682 }
4683
4684 fn parse_function_def_with_flags(&mut self, opt_flags: HashSet<OptFlag>) -> ParseResult<Stmt<'a>> {
4686 if self.check(&TokenType::To) || self.check_preposition_is("to") {
4688 self.advance();
4689 }
4690
4691 let mut is_native = if self.check(&TokenType::Native) {
4693 self.advance(); true
4695 } else {
4696 false
4697 };
4698
4699 let name = self.expect_identifier()?;
4701
4702 let mut parsed_generics: Vec<Symbol> = Vec::new();
4704 if self.check_preposition_is("of") {
4705 self.advance(); loop {
4707 if !self.check(&TokenType::LBracket) {
4708 return Err(ParseError {
4709 kind: ParseErrorKind::Custom("Expected '[TypeParam]' after 'of' in generic function".to_string()),
4710 span: self.current_span(),
4711 });
4712 }
4713 self.advance(); let type_param = self.expect_identifier()?;
4715 parsed_generics.push(type_param);
4716 if !self.check(&TokenType::RBracket) {
4717 return Err(ParseError {
4718 kind: ParseErrorKind::Custom("Expected ']' after type parameter name".to_string()),
4719 span: self.current_span(),
4720 });
4721 }
4722 self.advance(); if self.check_word("and") {
4724 self.advance(); } else {
4726 break;
4727 }
4728 }
4729 }
4730
4731 let mut params = Vec::new();
4733 while self.check(&TokenType::LParen) {
4734 self.advance(); if self.check(&TokenType::RParen) {
4738 self.advance(); break;
4740 }
4741
4742 loop {
4744 let param_name = self.expect_identifier()?;
4745
4746 if !self.check(&TokenType::Colon) {
4748 return Err(ParseError {
4749 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4750 span: self.current_span(),
4751 });
4752 }
4753 self.advance(); let param_type_expr = self.parse_type_expression()?;
4757 let param_type = self.ctx.alloc_type_expr(param_type_expr);
4758
4759 params.push((param_name, param_type));
4760
4761 if self.check(&TokenType::Comma) {
4763 self.advance(); continue;
4765 }
4766 break;
4767 }
4768
4769 if !self.check(&TokenType::RParen) {
4771 return Err(ParseError {
4772 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4773 span: self.current_span(),
4774 });
4775 }
4776 self.advance(); if self.check_word("and") || self.check_preposition() || self.check(&TokenType::From) {
4781 self.advance();
4782 }
4783 }
4784
4785 let return_type = if self.check(&TokenType::Arrow) {
4787 self.advance(); let ret_type_expr = self.parse_type_expression()?;
4789 Some(self.ctx.alloc_type_expr(ret_type_expr))
4790 } else {
4791 None
4792 };
4793
4794 let mut native_path: Option<Symbol> = None;
4796 let mut is_exported = false;
4797 let mut export_target: Option<Symbol> = None;
4798
4799 if self.check_word("is") {
4800 self.advance(); if self.check(&TokenType::Native) {
4802 self.advance(); is_native = true;
4805 if let TokenType::StringLiteral(sym) = self.peek().kind {
4806 native_path = Some(sym);
4807 self.advance(); } else {
4809 return Err(ParseError {
4810 kind: ParseErrorKind::Custom(
4811 "Expected a string literal for native function path (e.g., is native \"reqwest::blocking::get\")".to_string()
4812 ),
4813 span: self.current_span(),
4814 });
4815 }
4816 } else if self.check_word("exported") {
4817 self.advance(); is_exported = true;
4820 if self.check_word("for") {
4821 self.advance(); let target_sym = self.expect_identifier()?;
4823 let target_str = self.interner.resolve(target_sym);
4824 if !target_str.eq_ignore_ascii_case("c") && !target_str.eq_ignore_ascii_case("wasm") {
4825 return Err(ParseError {
4826 kind: ParseErrorKind::Custom(
4827 format!("Unsupported export target \"{}\". Supported targets are \"c\" and \"wasm\".", target_str)
4828 ),
4829 span: self.current_span(),
4830 });
4831 }
4832 export_target = Some(target_sym);
4833 }
4834 }
4835 }
4836
4837 if is_native {
4839 if self.check(&TokenType::Period) {
4841 self.advance();
4842 }
4843 if self.check(&TokenType::Newline) {
4844 self.advance();
4845 }
4846
4847 let empty_body = self.ctx.stmts.expect("imperative arenas not initialized")
4849 .alloc_slice(std::iter::empty());
4850
4851 return Ok(Stmt::FunctionDef {
4852 name,
4853 generics: parsed_generics,
4854 params,
4855 body: empty_body,
4856 return_type,
4857 is_native: true,
4858 native_path,
4859 is_exported: false,
4860 export_target: None,
4861 opt_flags: opt_flags.clone(),
4862 });
4863 }
4864
4865 if !self.check(&TokenType::Colon) {
4867 return Err(ParseError {
4868 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4869 span: self.current_span(),
4870 });
4871 }
4872 self.advance(); if !self.check(&TokenType::Indent) {
4876 return Err(ParseError {
4877 kind: ParseErrorKind::ExpectedStatement,
4878 span: self.current_span(),
4879 });
4880 }
4881 self.advance(); let mut body_stmts = Vec::new();
4885 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4886 if self.check(&TokenType::Newline) {
4888 self.advance();
4889 continue;
4890 }
4891 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
4893 break;
4894 }
4895 let stmt = self.parse_statement()?;
4896 body_stmts.push(stmt);
4897 if self.check(&TokenType::Period) {
4898 self.advance();
4899 }
4900 }
4901
4902 if self.check(&TokenType::Dedent) {
4904 self.advance();
4905 }
4906
4907 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4909 .alloc_slice(body_stmts.into_iter());
4910
4911 Ok(Stmt::FunctionDef {
4912 name,
4913 generics: parsed_generics,
4914 params,
4915 body,
4916 return_type,
4917 is_native: false,
4918 native_path: None,
4919 is_exported,
4920 export_target,
4921 opt_flags,
4922 })
4923 }
4924
4925 fn parse_primary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
4927 use crate::ast::{Expr, Literal};
4928
4929 let token = self.peek().clone();
4930 match &token.kind {
4931 TokenType::New => {
4935 self.advance(); let base_type_name = self.expect_identifier()?;
4937
4938 let type_name = if self.check(&TokenType::From) {
4940 self.advance(); let module_name = self.expect_identifier()?;
4942 let module_str = self.interner.resolve(module_name);
4943 let base_str = self.interner.resolve(base_type_name);
4944 let qualified = format!("{}::{}", module_str, base_str);
4945 self.interner.intern(&qualified)
4946 } else {
4947 base_type_name
4948 };
4949
4950 if let Some(enum_name) = self.find_variant(type_name) {
4952 let fields = if self.check_word("with") {
4954 self.parse_variant_constructor_fields()?
4955 } else {
4956 vec![]
4957 };
4958 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
4959 enum_name,
4960 variant: type_name,
4961 fields,
4962 });
4963 return self.parse_field_access_chain(base);
4964 }
4965
4966 let type_args = self.parse_generic_type_args(type_name)?;
4968
4969 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
4972 self.parse_struct_init_fields()?
4973 } else {
4974 vec![]
4975 };
4976
4977 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
4978 return self.parse_field_access_chain(base);
4979 }
4980
4981 TokenType::Article(_) => {
4985 if let Some(next) = self.tokens.get(self.current + 1) {
4988 if matches!(next.kind, TokenType::Manifest) {
4989 self.advance(); return self.parse_primary_expr();
4992 }
4993 if matches!(next.kind, TokenType::Chunk) {
4994 self.advance(); return self.parse_primary_expr();
4997 }
4998 if matches!(next.kind, TokenType::Length) {
4999 self.advance(); return self.parse_primary_expr();
5001 }
5002 }
5003 if let Some(next) = self.tokens.get(self.current + 1) {
5005 if matches!(next.kind, TokenType::New) {
5006 self.advance(); self.advance(); let base_type_name = self.expect_identifier()?;
5009
5010 let type_name = if self.check(&TokenType::From) {
5012 self.advance(); let module_name = self.expect_identifier()?;
5014 let module_str = self.interner.resolve(module_name);
5015 let base_str = self.interner.resolve(base_type_name);
5016 let qualified = format!("{}::{}", module_str, base_str);
5017 self.interner.intern(&qualified)
5018 } else {
5019 base_type_name
5020 };
5021
5022 if let Some(enum_name) = self.find_variant(type_name) {
5024 let fields = if self.check_word("with") {
5026 self.parse_variant_constructor_fields()?
5027 } else {
5028 vec![]
5029 };
5030 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
5031 enum_name,
5032 variant: type_name,
5033 fields,
5034 });
5035 return self.parse_field_access_chain(base);
5036 }
5037
5038 let type_args = self.parse_generic_type_args(type_name)?;
5040
5041 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
5044 self.parse_struct_init_fields()?
5045 } else {
5046 vec![]
5047 };
5048
5049 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
5050 return self.parse_field_access_chain(base);
5051 }
5052 }
5053 let sym = token.lexeme;
5055 self.advance();
5056 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5057 return self.parse_field_access_chain(base);
5058 }
5059
5060 TokenType::Item => {
5062 self.advance(); let index = if let TokenType::Number(sym) = &self.peek().kind {
5066 let sym = *sym;
5068 self.advance();
5069 let num_str = self.interner.resolve(sym);
5070 let index_val = num_str.parse::<i64>().unwrap_or(0);
5071
5072 if index_val == 0 {
5074 return Err(ParseError {
5075 kind: ParseErrorKind::ZeroIndex,
5076 span: self.current_span(),
5077 });
5078 }
5079
5080 self.ctx.alloc_imperative_expr(
5081 Expr::Literal(crate::ast::Literal::Number(index_val))
5082 )
5083 } else if self.check(&TokenType::LParen) {
5084 self.advance(); let inner = self.parse_imperative_expr()?;
5087 if !self.check(&TokenType::RParen) {
5088 return Err(ParseError {
5089 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5090 span: self.current_span(),
5091 });
5092 }
5093 self.advance(); inner
5095 } else if let TokenType::StringLiteral(sym) = self.peek().kind {
5096 let sym = sym;
5098 self.advance();
5099 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Text(sym)))
5100 } else if !self.check_preposition_is("of") {
5101 let word = self.interner.resolve(self.peek().lexeme);
5103 if word == "true" {
5104 self.advance();
5105 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(true)))
5106 } else if word == "false" {
5107 self.advance();
5108 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(false)))
5109 } else {
5110 let sym = self.peek().lexeme;
5112 self.advance();
5113 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5114 }
5115 } else {
5116 return Err(ParseError {
5117 kind: ParseErrorKind::ExpectedExpression,
5118 span: self.current_span(),
5119 });
5120 };
5121
5122 if !self.check_preposition_is("of") {
5124 return Err(ParseError {
5125 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5126 span: self.current_span(),
5127 });
5128 }
5129 self.advance(); let collection = self.parse_primary_expr()?;
5134
5135 Ok(self.ctx.alloc_imperative_expr(Expr::Index {
5136 collection,
5137 index,
5138 }))
5139 }
5140
5141 TokenType::Items => {
5144 let is_slice_syntax = if let Some(next) = self.tokens.get(self.current + 1) {
5148 matches!(next.kind, TokenType::Number(_) | TokenType::LParen)
5149 } else {
5150 false
5151 };
5152
5153 if !is_slice_syntax {
5154 let sym = token.lexeme;
5156 self.advance();
5157 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5158 return self.parse_field_access_chain(base);
5159 }
5160
5161 self.advance(); let start = if let TokenType::Number(sym) = &self.peek().kind {
5165 let sym = *sym;
5167 self.advance();
5168 let num_str = self.interner.resolve(sym);
5169 let start_val = num_str.parse::<i64>().unwrap_or(0);
5170
5171 if start_val == 0 {
5173 return Err(ParseError {
5174 kind: ParseErrorKind::ZeroIndex,
5175 span: self.current_span(),
5176 });
5177 }
5178
5179 self.ctx.alloc_imperative_expr(
5180 Expr::Literal(crate::ast::Literal::Number(start_val))
5181 )
5182 } else if self.check(&TokenType::LParen) {
5183 self.advance(); let inner = self.parse_imperative_expr()?;
5186 if !self.check(&TokenType::RParen) {
5187 return Err(ParseError {
5188 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5189 span: self.current_span(),
5190 });
5191 }
5192 self.advance(); inner
5194 } else if self.check(&TokenType::Length) {
5195 self.advance(); if self.check_preposition_is("of") {
5198 self.advance(); let target = self.parse_primary_expr()?;
5200 self.ctx.alloc_imperative_expr(Expr::Length { collection: target })
5201 } else {
5202 let sym = self.tokens[self.current - 1].lexeme;
5204 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5205 }
5206 } else if !self.check_preposition_is("through") {
5207 let sym = self.peek().lexeme;
5209 self.advance();
5210 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5211 } else {
5212 return Err(ParseError {
5213 kind: ParseErrorKind::ExpectedExpression,
5214 span: self.current_span(),
5215 });
5216 };
5217
5218 if !self.check_preposition_is("through") {
5220 return Err(ParseError {
5221 kind: ParseErrorKind::ExpectedKeyword { keyword: "through".to_string() },
5222 span: self.current_span(),
5223 });
5224 }
5225 self.advance(); let end = if let TokenType::Number(sym) = &self.peek().kind {
5229 let sym = *sym;
5231 self.advance();
5232 let num_str = self.interner.resolve(sym);
5233 let end_val = num_str.parse::<i64>().unwrap_or(0);
5234
5235 if end_val == 0 {
5237 return Err(ParseError {
5238 kind: ParseErrorKind::ZeroIndex,
5239 span: self.current_span(),
5240 });
5241 }
5242
5243 self.ctx.alloc_imperative_expr(
5244 Expr::Literal(crate::ast::Literal::Number(end_val))
5245 )
5246 } else if self.check(&TokenType::LParen) {
5247 self.advance(); let inner = self.parse_imperative_expr()?;
5250 if !self.check(&TokenType::RParen) {
5251 return Err(ParseError {
5252 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5253 span: self.current_span(),
5254 });
5255 }
5256 self.advance(); inner
5258 } else if self.check(&TokenType::Length) {
5259 self.advance(); if self.check_preposition_is("of") {
5262 self.advance(); let target = self.parse_primary_expr()?;
5264 self.ctx.alloc_imperative_expr(Expr::Length { collection: target })
5265 } else {
5266 let sym = self.tokens[self.current - 1].lexeme;
5268 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5269 }
5270 } else if !self.check_preposition_is("of") {
5271 let sym = self.peek().lexeme;
5273 self.advance();
5274 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5275 } else {
5276 return Err(ParseError {
5277 kind: ParseErrorKind::ExpectedExpression,
5278 span: self.current_span(),
5279 });
5280 };
5281
5282 let collection = if self.check_preposition_is("of") {
5285 self.advance(); self.parse_imperative_expr()?
5287 } else {
5288 let items_sym = self.interner.intern("items");
5291 self.ctx.alloc_imperative_expr(Expr::Identifier(items_sym))
5292 };
5293
5294 Ok(self.ctx.alloc_imperative_expr(Expr::Slice {
5295 collection,
5296 start,
5297 end,
5298 }))
5299 }
5300
5301 TokenType::LBracket => {
5303 self.advance(); let mut items = Vec::new();
5306 if !self.check(&TokenType::RBracket) {
5307 loop {
5308 items.push(self.parse_imperative_expr()?);
5309 if !self.check(&TokenType::Comma) {
5310 break;
5311 }
5312 self.advance(); }
5314 }
5315
5316 if !self.check(&TokenType::RBracket) {
5317 return Err(ParseError {
5318 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
5319 span: self.current_span(),
5320 });
5321 }
5322 self.advance(); if items.is_empty() && self.check_word("of") {
5326 self.advance(); let type_name = self.expect_identifier()?;
5328 let seq_sym = self.interner.intern("Seq");
5330 return Ok(self.ctx.alloc_imperative_expr(Expr::New {
5331 type_name: seq_sym,
5332 type_args: vec![TypeExpr::Named(type_name)],
5333 init_fields: vec![],
5334 }));
5335 }
5336
5337 Ok(self.ctx.alloc_imperative_expr(Expr::List(items)))
5338 }
5339
5340 TokenType::Number(sym) => {
5341 let num_str = self.interner.resolve(*sym).to_string();
5342 self.advance();
5343
5344 if let TokenType::CalendarUnit(unit) = self.peek().kind {
5346 return self.parse_span_literal_from_num(&num_str);
5347 }
5348
5349 if num_str.contains('.') || num_str.contains('e') || num_str.contains('E') {
5351 let num = num_str.parse::<f64>().unwrap_or(0.0);
5352 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Float(num))))
5353 } else {
5354 let num = num_str.parse::<i64>().unwrap_or(0);
5355 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(num))))
5356 }
5357 }
5358
5359 TokenType::StringLiteral(sym) => {
5361 self.advance();
5362 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Text(*sym))))
5363 }
5364
5365 TokenType::InterpolatedString(sym) => {
5367 let raw = self.interner.resolve(*sym).to_string();
5368 self.advance();
5369 let parts = self.parse_interpolation_parts(&raw)?;
5370 Ok(self.ctx.alloc_imperative_expr(Expr::InterpolatedString(parts)))
5371 }
5372
5373 TokenType::CharLiteral(sym) => {
5375 let char_str = self.interner.resolve(*sym);
5376 let ch = char_str.chars().next().unwrap_or('\0');
5377 self.advance();
5378 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Char(ch))))
5379 }
5380
5381 TokenType::DurationLiteral { nanos, .. } => {
5383 let nanos = *nanos;
5384 self.advance();
5385 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Duration(nanos))))
5386 }
5387
5388 TokenType::DateLiteral { days } => {
5391 let days = *days;
5392 self.advance();
5393
5394 if self.check(&TokenType::At) {
5396 self.advance(); if let TokenType::TimeLiteral { nanos_from_midnight } = self.peek().kind {
5400 let time_nanos = nanos_from_midnight;
5401 self.advance(); let moment_nanos = (days as i64) * 86_400_000_000_000 + time_nanos;
5405 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Moment(moment_nanos))));
5406 } else {
5407 return Err(ParseError {
5408 kind: ParseErrorKind::ExpectedExpression,
5409 span: self.current_span(),
5410 });
5411 }
5412 }
5413
5414 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Date(days))))
5415 }
5416
5417 TokenType::TimeLiteral { nanos_from_midnight } => {
5419 let nanos = *nanos_from_midnight;
5420 self.advance();
5421 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Time(nanos))))
5422 }
5423
5424 TokenType::Nothing => {
5426 self.advance();
5427 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)))
5428 }
5429
5430 TokenType::Some => {
5432 self.advance(); let value = self.parse_imperative_expr()?;
5434 Ok(self.ctx.alloc_imperative_expr(Expr::OptionSome { value }))
5435 }
5436
5437 TokenType::Length => {
5439 let func_name = self.peek().lexeme;
5440
5441 if self.tokens.get(self.current + 1)
5443 .map(|t| matches!(t.kind, TokenType::LParen))
5444 .unwrap_or(false)
5445 {
5446 self.advance(); return self.parse_call_expr(func_name);
5448 }
5449
5450 self.advance(); if !self.check_preposition_is("of") {
5454 return Err(ParseError {
5455 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5456 span: self.current_span(),
5457 });
5458 }
5459 self.advance(); let collection = self.parse_primary_expr()?;
5464 Ok(self.ctx.alloc_imperative_expr(Expr::Length { collection }))
5465 }
5466
5467 TokenType::Copy => {
5469 let func_name = self.peek().lexeme;
5470
5471 if self.tokens.get(self.current + 1)
5473 .map(|t| matches!(t.kind, TokenType::LParen))
5474 .unwrap_or(false)
5475 {
5476 self.advance(); return self.parse_call_expr(func_name);
5478 }
5479
5480 self.advance(); if !self.check_preposition_is("of") {
5484 return Err(ParseError {
5485 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5486 span: self.current_span(),
5487 });
5488 }
5489 self.advance(); let expr = self.parse_imperative_expr()?;
5492 Ok(self.ctx.alloc_imperative_expr(Expr::Copy { expr }))
5493 }
5494
5495 TokenType::Manifest => {
5497 self.advance(); if !self.check_preposition_is("of") {
5501 return Err(ParseError {
5502 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5503 span: self.current_span(),
5504 });
5505 }
5506 self.advance(); let zone = self.parse_imperative_expr()?;
5509 Ok(self.ctx.alloc_imperative_expr(Expr::ManifestOf { zone }))
5510 }
5511
5512 TokenType::Chunk => {
5514 self.advance(); if !self.check(&TokenType::At) {
5518 return Err(ParseError {
5519 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
5520 span: self.current_span(),
5521 });
5522 }
5523 self.advance(); let index = self.parse_imperative_expr()?;
5526
5527 if !self.check_preposition_is("in") && !self.check(&TokenType::In) {
5529 return Err(ParseError {
5530 kind: ParseErrorKind::ExpectedKeyword { keyword: "in".to_string() },
5531 span: self.current_span(),
5532 });
5533 }
5534 self.advance(); let zone = self.parse_imperative_expr()?;
5537 Ok(self.ctx.alloc_imperative_expr(Expr::ChunkAt { index, zone }))
5538 }
5539
5540 TokenType::Verb { lemma, .. } => {
5544 let word = self.interner.resolve(*lemma).to_lowercase();
5545 if word == "empty" {
5546 self.advance();
5547 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5548 }
5549 let sym = token.lexeme;
5551 self.advance();
5552 if self.check(&TokenType::LParen) {
5553 return self.parse_call_expr(sym);
5554 }
5555 self.verify_identifier_access(sym)?;
5557 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5558 self.parse_field_access_chain(base)
5559 }
5560
5561 TokenType::TemporalAdverb(_) | TokenType::ScopalAdverb(_) | TokenType::Adverb(_) => {
5563 let sym = token.lexeme;
5564 self.advance();
5565 if self.check(&TokenType::LParen) {
5566 return self.parse_call_expr(sym);
5567 }
5568 self.verify_identifier_access(sym)?;
5570 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5571 self.parse_field_access_chain(base)
5572 }
5573
5574 TokenType::Read | TokenType::Write | TokenType::File | TokenType::Console |
5577 TokenType::Add | TokenType::Remove => {
5578 let sym = token.lexeme;
5579 self.advance();
5580 if self.check(&TokenType::LParen) {
5581 return self.parse_call_expr(sym);
5582 }
5583 self.verify_identifier_access(sym)?;
5585 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5586 self.parse_field_access_chain(base)
5587 }
5588
5589 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
5592 let sym = *sym;
5593 let word = self.interner.resolve(sym);
5594
5595 if word == "true" {
5597 self.advance();
5598 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(true))));
5599 }
5600 if word == "false" {
5601 self.advance();
5602 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(false))));
5603 }
5604
5605 if word == "empty" {
5607 self.advance();
5608 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5609 }
5610
5611 if word == "none" {
5613 self.advance();
5614 return Ok(self.ctx.alloc_imperative_expr(Expr::OptionNone));
5615 }
5616
5617 self.advance();
5619
5620 if self.check(&TokenType::LParen) {
5622 return self.parse_call_expr(sym);
5623 }
5624
5625 if let Some(enum_name) = self.find_variant(sym) {
5627 let fields = if self.check_word("with") {
5628 self.parse_variant_constructor_fields()?
5629 } else {
5630 vec![]
5631 };
5632 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
5633 enum_name,
5634 variant: sym,
5635 fields,
5636 });
5637 return self.parse_field_access_chain(base);
5638 }
5639
5640 self.verify_identifier_access(sym)?;
5642 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5643 self.parse_field_access_chain(base)
5645 }
5646
5647 TokenType::Pronoun { .. } => {
5649 let sym = token.lexeme;
5650 self.advance();
5651 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5652 self.parse_field_access_chain(base)
5654 }
5655
5656 TokenType::Merge | TokenType::Increase => {
5658 let sym = token.lexeme;
5659 self.advance();
5660
5661 if self.check(&TokenType::LParen) {
5663 return self.parse_call_expr(sym);
5664 }
5665
5666 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5667 self.parse_field_access_chain(base)
5668 }
5669
5670 TokenType::Escape => {
5674 if self.tokens.get(self.current + 1).map_or(false, |t|
5675 matches!(t.kind, TokenType::To) || {
5676 if let TokenType::Preposition(sym) = t.kind {
5677 sym.is(self.interner, "to")
5678 } else {
5679 false
5680 }
5681 }
5682 ) {
5683 return self.parse_escape_expr();
5684 }
5685 let sym = token.lexeme;
5687 self.advance();
5688 if self.check(&TokenType::LParen) {
5689 return self.parse_call_expr(sym);
5690 }
5691 self.verify_identifier_access(sym)?;
5692 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5693 self.parse_field_access_chain(base)
5694 }
5695
5696 TokenType::Values | TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared | TokenType::Particle(_) | TokenType::Preposition(_) | TokenType::All => { let sym = token.lexeme;
5708 self.advance();
5709
5710 if self.check(&TokenType::LParen) {
5712 return self.parse_call_expr(sym);
5713 }
5714
5715 self.verify_identifier_access(sym)?;
5716 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5717 self.parse_field_access_chain(base)
5718 }
5719
5720 TokenType::Ambiguous { primary, alternatives } => {
5722 let sym = token.lexeme;
5725
5726 let is_identifier_token = match &**primary {
5728 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5729 TokenType::Verb { .. } => true,
5730 _ => alternatives.iter().any(|t| matches!(t,
5731 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5732 TokenType::Verb { .. }
5733 ))
5734 };
5735
5736 if is_identifier_token {
5737 self.advance();
5738
5739 if self.check(&TokenType::LParen) {
5741 return self.parse_call_expr(sym);
5742 }
5743
5744 self.verify_identifier_access(sym)?;
5745 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5746 self.parse_field_access_chain(base)
5748 } else {
5749 Err(ParseError {
5750 kind: ParseErrorKind::ExpectedExpression,
5751 span: self.current_span(),
5752 })
5753 }
5754 }
5755
5756 TokenType::LParen => {
5758 if let Some(closure) = self.try_parse(|p| p.parse_closure_expr()) {
5761 return Ok(closure);
5762 }
5763
5764 self.advance(); let first = self.parse_imperative_expr()?;
5767
5768 if self.check(&TokenType::Comma) {
5770 let mut items = vec![first];
5772 while self.check(&TokenType::Comma) {
5773 self.advance(); items.push(self.parse_imperative_expr()?);
5775 }
5776
5777 if !self.check(&TokenType::RParen) {
5778 return Err(ParseError {
5779 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5780 span: self.current_span(),
5781 });
5782 }
5783 self.advance(); let base = self.ctx.alloc_imperative_expr(Expr::Tuple(items));
5786 self.parse_field_access_chain(base)
5787 } else {
5788 if !self.check(&TokenType::RParen) {
5790 return Err(ParseError {
5791 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5792 span: self.current_span(),
5793 });
5794 }
5795 self.advance(); Ok(first)
5797 }
5798 }
5799
5800 TokenType::Call => {
5802 self.advance(); let function = match &self.peek().kind {
5804 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
5805 let s = *sym;
5806 self.advance();
5807 s
5808 }
5809 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
5810 let s = self.peek().lexeme;
5811 self.advance();
5812 s
5813 }
5814 _ => {
5815 return Err(ParseError {
5816 kind: ParseErrorKind::ExpectedIdentifier,
5817 span: self.current_span(),
5818 });
5819 }
5820 };
5821 let args = if self.check_preposition_is("with") {
5822 self.advance(); self.parse_call_arguments()?
5824 } else {
5825 Vec::new()
5826 };
5827 Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
5828 }
5829
5830 _ => {
5831 Err(ParseError {
5832 kind: ParseErrorKind::ExpectedExpression,
5833 span: self.current_span(),
5834 })
5835 }
5836 }
5837 }
5838
5839 fn parse_closure_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5842 use crate::ast::stmt::ClosureBody;
5843
5844 if !self.check(&TokenType::LParen) {
5846 return Err(ParseError {
5847 kind: ParseErrorKind::ExpectedExpression,
5848 span: self.current_span(),
5849 });
5850 }
5851 self.advance(); let mut params = Vec::new();
5855 if !self.check(&TokenType::RParen) {
5856 let name = self.expect_identifier()?;
5858 if !self.check(&TokenType::Colon) {
5859 return Err(ParseError {
5860 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
5861 span: self.current_span(),
5862 });
5863 }
5864 self.advance(); let ty = self.parse_type_expression()?;
5866 let ty_ref = self.ctx.alloc_type_expr(ty);
5867 params.push((name, ty_ref));
5868
5869 while self.check(&TokenType::Comma) {
5871 self.advance(); let name = self.expect_identifier()?;
5873 if !self.check(&TokenType::Colon) {
5874 return Err(ParseError {
5875 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
5876 span: self.current_span(),
5877 });
5878 }
5879 self.advance(); let ty = self.parse_type_expression()?;
5881 let ty_ref = self.ctx.alloc_type_expr(ty);
5882 params.push((name, ty_ref));
5883 }
5884 }
5885
5886 if !self.check(&TokenType::RParen) {
5888 return Err(ParseError {
5889 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5890 span: self.current_span(),
5891 });
5892 }
5893 self.advance(); if !self.check(&TokenType::Arrow) {
5897 return Err(ParseError {
5898 kind: ParseErrorKind::ExpectedKeyword { keyword: "->".to_string() },
5899 span: self.current_span(),
5900 });
5901 }
5902 self.advance(); let body = if self.check(&TokenType::Colon) {
5906 self.advance(); if !self.check(&TokenType::Indent) {
5909 return Err(ParseError {
5910 kind: ParseErrorKind::ExpectedStatement,
5911 span: self.current_span(),
5912 });
5913 }
5914 self.advance(); let mut block_stmts = Vec::new();
5917 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
5918 let stmt = self.parse_statement()?;
5919 block_stmts.push(stmt);
5920 if self.check(&TokenType::Period) {
5921 self.advance();
5922 }
5923 }
5924 if self.check(&TokenType::Dedent) {
5925 self.advance(); }
5927
5928 let block = self.ctx.stmts.expect("imperative arenas not initialized")
5929 .alloc_slice(block_stmts.into_iter());
5930 ClosureBody::Block(block)
5931 } else {
5932 let expr = self.parse_condition()?;
5934 ClosureBody::Expression(expr)
5935 };
5936
5937 Ok(self.ctx.alloc_imperative_expr(Expr::Closure {
5938 params,
5939 body,
5940 return_type: None,
5941 }))
5942 }
5943
5944 fn parse_imperative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5948 self.parse_condition()
5949 }
5950
5951 fn parse_xor_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5954 let mut left = self.parse_additive_expr()?;
5955
5956 while self.check(&TokenType::Xor) {
5957 self.advance(); let right = self.parse_additive_expr()?;
5959 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5960 op: BinaryOpKind::BitXor,
5961 left,
5962 right,
5963 });
5964 }
5965
5966 Ok(left)
5967 }
5968
5969 fn parse_additive_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5971 let mut left = self.parse_shift_expr()?;
5972
5973 loop {
5974 match &self.peek().kind {
5975 TokenType::Plus => {
5976 self.advance();
5977 let right = self.parse_shift_expr()?;
5978 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5979 op: BinaryOpKind::Add,
5980 left,
5981 right,
5982 });
5983 }
5984 TokenType::Minus => {
5985 self.advance();
5986 let right = self.parse_shift_expr()?;
5987 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5988 op: BinaryOpKind::Subtract,
5989 left,
5990 right,
5991 });
5992 }
5993 TokenType::Combined => {
5995 self.advance(); if !self.check_preposition_is("with") {
5998 return Err(ParseError {
5999 kind: ParseErrorKind::ExpectedKeyword { keyword: "with".to_string() },
6000 span: self.current_span(),
6001 });
6002 }
6003 self.advance(); let right = self.parse_shift_expr()?;
6005 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
6006 op: BinaryOpKind::Concat,
6007 left,
6008 right,
6009 });
6010 }
6011 TokenType::Union => {
6013 self.advance(); let right = self.parse_shift_expr()?;
6015 left = self.ctx.alloc_imperative_expr(Expr::Union {
6016 left,
6017 right,
6018 });
6019 }
6020 TokenType::Intersection => {
6021 self.advance(); let right = self.parse_shift_expr()?;
6023 left = self.ctx.alloc_imperative_expr(Expr::Intersection {
6024 left,
6025 right,
6026 });
6027 }
6028 TokenType::Contains => {
6030 self.advance(); let value = self.parse_shift_expr()?;
6032 left = self.ctx.alloc_imperative_expr(Expr::Contains {
6033 collection: left,
6034 value,
6035 });
6036 }
6037 _ => break,
6038 }
6039 }
6040
6041 Ok(left)
6042 }
6043
6044 fn parse_shift_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6047 let mut left = self.parse_multiplicative_expr()?;
6048
6049 loop {
6050 if !self.check(&TokenType::Shifted) {
6051 break;
6052 }
6053 self.advance(); let is_left = self.check_word("left");
6056 if is_left {
6057 self.advance(); } else if self.check_word("right") {
6059 self.advance(); } else {
6061 return Err(ParseError {
6062 kind: ParseErrorKind::ExpectedKeyword { keyword: "left or right".to_string() },
6063 span: self.current_span(),
6064 });
6065 }
6066
6067 if !self.check_preposition_is("by") && !self.check_word("by") {
6069 return Err(ParseError {
6070 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
6071 span: self.current_span(),
6072 });
6073 }
6074 self.advance(); let right = self.parse_multiplicative_expr()?;
6077 let op = if is_left { BinaryOpKind::Shl } else { BinaryOpKind::Shr };
6078 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp { op, left, right });
6079 }
6080
6081 Ok(left)
6082 }
6083
6084 fn parse_unary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6086 use crate::ast::{Expr, Literal};
6087
6088 if self.check(&TokenType::Minus) {
6089 self.advance(); let operand = self.parse_unary_expr()?; return Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp {
6093 op: BinaryOpKind::Subtract,
6094 left: self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(0))),
6095 right: operand,
6096 }));
6097 }
6098 self.parse_primary_expr()
6099 }
6100
6101 fn parse_multiplicative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6103 let mut left = self.parse_unary_expr()?;
6104
6105 loop {
6106 let op = match &self.peek().kind {
6107 TokenType::Star => {
6108 self.advance();
6109 BinaryOpKind::Multiply
6110 }
6111 TokenType::Slash => {
6112 self.advance();
6113 BinaryOpKind::Divide
6114 }
6115 TokenType::Percent => {
6116 self.advance();
6117 BinaryOpKind::Modulo
6118 }
6119 _ => break,
6120 };
6121 let right = self.parse_unary_expr()?;
6122 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
6123 op,
6124 left,
6125 right,
6126 });
6127 }
6128
6129 Ok(left)
6130 }
6131
6132 fn try_parse_binary_op(&mut self) -> Option<BinaryOpKind> {
6134 match &self.peek().kind {
6135 TokenType::Plus => {
6136 self.advance();
6137 Some(BinaryOpKind::Add)
6138 }
6139 TokenType::Minus => {
6140 self.advance();
6141 Some(BinaryOpKind::Subtract)
6142 }
6143 TokenType::Star => {
6144 self.advance();
6145 Some(BinaryOpKind::Multiply)
6146 }
6147 TokenType::Slash => {
6148 self.advance();
6149 Some(BinaryOpKind::Divide)
6150 }
6151 _ => None,
6152 }
6153 }
6154
6155 fn parse_interpolation_parts(&mut self, raw: &str) -> ParseResult<Vec<crate::ast::stmt::StringPart<'a>>> {
6162 use crate::ast::stmt::StringPart;
6163
6164 let mut parts = Vec::new();
6165 let chars: Vec<char> = raw.chars().collect();
6166 let mut i = 0;
6167 let mut literal_buf = String::new();
6168
6169 while i < chars.len() {
6170 match chars[i] {
6171 '{' if i + 1 < chars.len() && chars[i + 1] == '{' => {
6172 literal_buf.push('{');
6174 i += 2;
6175 }
6176 '{' => {
6177 if !literal_buf.is_empty() {
6179 let sym = self.interner.intern(&literal_buf);
6180 parts.push(StringPart::Literal(sym));
6181 literal_buf.clear();
6182 }
6183
6184 let start = i + 1;
6186 let mut depth = 1;
6187 let mut j = start;
6188 while j < chars.len() && depth > 0 {
6189 if chars[j] == '{' { depth += 1; }
6190 if chars[j] == '}' { depth -= 1; }
6191 if depth > 0 { j += 1; }
6192 }
6193 if depth != 0 {
6194 return Err(ParseError {
6195 kind: crate::error::ParseErrorKind::Custom(
6196 "Unclosed interpolation brace in string".to_string()
6197 ),
6198 span: self.current_span(),
6199 });
6200 }
6201
6202 let hole_content: String = chars[start..j].iter().collect();
6203
6204 let (hole_after_debug, is_debug) = {
6209 if let Some(eq_pos) = hole_content.rfind('=') {
6210 let before_eq = hole_content[..eq_pos].trim();
6211 let is_double_eq = eq_pos > 0 && hole_content.as_bytes().get(eq_pos - 1) == Some(&b'=');
6214 let is_preceded_by_comparison = eq_pos > 0 && matches!(hole_content.as_bytes().get(eq_pos - 1), Some(b'!' | b'<' | b'>'));
6215 if !is_double_eq && !is_preceded_by_comparison
6216 && !before_eq.is_empty()
6217 && before_eq.chars().all(|c| c.is_alphanumeric() || c == '_')
6218 {
6219 (hole_content[..eq_pos].to_string() + &hole_content[eq_pos + 1..], true)
6220 } else {
6221 (hole_content.clone(), false)
6222 }
6223 } else {
6224 (hole_content.clone(), false)
6225 }
6226 };
6227
6228 let (expr_str, format_spec) = if let Some(colon_pos) = hole_after_debug.rfind(':') {
6230 let before = &hole_after_debug[..colon_pos];
6231 let after = &hole_after_debug[colon_pos + 1..];
6232 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())) {
6235 let valid = if after == "$" {
6237 true
6238 } else if after.starts_with('.') {
6239 after[1..].parse::<usize>().is_ok()
6240 } else if after.starts_with('<') || after.starts_with('>') || after.starts_with('^') {
6241 after[1..].parse::<usize>().is_ok()
6242 } else {
6243 after.parse::<usize>().is_ok()
6244 };
6245 if !valid {
6246 return Err(ParseError {
6247 kind: crate::error::ParseErrorKind::Custom(
6248 format!("Invalid format specifier `{}` in interpolation hole", after)
6249 ),
6250 span: self.current_span(),
6251 });
6252 }
6253 (before.to_string(), Some(after.to_string()))
6254 } else {
6255 (hole_after_debug.clone(), None)
6256 }
6257 } else {
6258 (hole_after_debug.clone(), None)
6259 };
6260
6261 let expr_source = expr_str.trim().to_string();
6263 if expr_source.is_empty() {
6264 return Err(ParseError {
6265 kind: crate::error::ParseErrorKind::Custom(
6266 "Empty interpolation hole in string".to_string()
6267 ),
6268 span: self.current_span(),
6269 });
6270 }
6271
6272 let sub_expr = {
6275 let mut sub_lexer = crate::lexer::Lexer::new(&expr_source, self.interner);
6276 let sub_tokens = sub_lexer.tokenize();
6277
6278 let saved_tokens = std::mem::replace(&mut self.tokens, sub_tokens);
6280 let saved_current = self.current;
6281 self.current = 0;
6282
6283 let result = self.parse_primary_or_binary_expr();
6284
6285 self.tokens = saved_tokens;
6287 self.current = saved_current;
6288
6289 result?
6290 };
6291
6292 let format_sym = format_spec.map(|s| self.interner.intern(&s));
6293 parts.push(StringPart::Expr {
6294 value: sub_expr,
6295 format_spec: format_sym,
6296 debug: is_debug,
6297 });
6298
6299 i = j + 1; }
6301 '}' if i + 1 < chars.len() && chars[i + 1] == '}' => {
6302 literal_buf.push('}');
6304 i += 2;
6305 }
6306 _ => {
6307 literal_buf.push(chars[i]);
6308 i += 1;
6309 }
6310 }
6311 }
6312
6313 if !literal_buf.is_empty() {
6315 let sym = self.interner.intern(&literal_buf);
6316 parts.push(StringPart::Literal(sym));
6317 }
6318
6319 Ok(parts)
6320 }
6321
6322 fn parse_primary_or_binary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6324 self.parse_imperative_expr()
6325 }
6326
6327 fn parse_span_literal_from_num(&mut self, first_num_str: &str) -> ParseResult<&'a Expr<'a>> {
6328 use crate::ast::Literal;
6329 use crate::token::CalendarUnit;
6330
6331 let first_num = first_num_str.parse::<i32>().unwrap_or(0);
6332
6333 let unit = match self.peek().kind {
6335 TokenType::CalendarUnit(u) => u,
6336 _ => {
6337 return Err(ParseError {
6338 kind: ParseErrorKind::ExpectedKeyword { keyword: "calendar unit (day, week, month, year)".to_string() },
6339 span: self.current_span(),
6340 });
6341 }
6342 };
6343 self.advance(); let mut total_months: i32 = 0;
6347 let mut total_days: i32 = 0;
6348
6349 match unit {
6351 CalendarUnit::Day => total_days += first_num,
6352 CalendarUnit::Week => total_days += first_num * 7,
6353 CalendarUnit::Month => total_months += first_num,
6354 CalendarUnit::Year => total_months += first_num * 12,
6355 }
6356
6357 while self.check(&TokenType::And) {
6359 self.advance(); let next_num = match &self.peek().kind {
6363 TokenType::Number(sym) => {
6364 let num_str = self.interner.resolve(*sym).to_string();
6365 self.advance();
6366 num_str.parse::<i32>().unwrap_or(0)
6367 }
6368 _ => break, };
6370
6371 let next_unit = match self.peek().kind {
6373 TokenType::CalendarUnit(u) => {
6374 self.advance();
6375 u
6376 }
6377 _ => break, };
6379
6380 match next_unit {
6382 CalendarUnit::Day => total_days += next_num,
6383 CalendarUnit::Week => total_days += next_num * 7,
6384 CalendarUnit::Month => total_months += next_num,
6385 CalendarUnit::Year => total_months += next_num * 12,
6386 }
6387 }
6388
6389 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Span {
6390 months: total_months,
6391 days: total_days,
6392 })))
6393 }
6394
6395 fn parse_call_expr(&mut self, function: Symbol) -> ParseResult<&'a Expr<'a>> {
6397 use crate::ast::Expr;
6398
6399 self.advance(); let mut args = Vec::new();
6402 if !self.check(&TokenType::RParen) {
6403 loop {
6404 args.push(self.parse_imperative_expr()?);
6405 if !self.check(&TokenType::Comma) {
6406 break;
6407 }
6408 self.advance(); }
6410 }
6411
6412 if !self.check(&TokenType::RParen) {
6413 return Err(ParseError {
6414 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
6415 span: self.current_span(),
6416 });
6417 }
6418 self.advance(); Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
6421 }
6422
6423 fn parse_field_access_chain(&mut self, base: &'a Expr<'a>) -> ParseResult<&'a Expr<'a>> {
6426 use crate::ast::Expr;
6427
6428 let mut result = base;
6429
6430 loop {
6432 if self.check(&TokenType::Possessive) {
6433 self.advance(); let field = self.expect_identifier()?;
6436 result = self.ctx.alloc_imperative_expr(Expr::FieldAccess {
6437 object: result,
6438 field,
6439 });
6440 } else if self.check(&TokenType::LBracket) {
6441 self.advance(); let index = self.parse_imperative_expr()?;
6444
6445 if !self.check(&TokenType::RBracket) {
6446 return Err(ParseError {
6447 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
6448 span: self.current_span(),
6449 });
6450 }
6451 self.advance(); result = self.ctx.alloc_imperative_expr(Expr::Index {
6454 collection: result,
6455 index,
6456 });
6457 } else {
6458 break;
6459 }
6460 }
6461
6462 Ok(result)
6463 }
6464
6465 fn verify_identifier_access(&self, sym: Symbol) -> ParseResult<()> {
6468 if self.mode != ParserMode::Imperative {
6469 return Ok(());
6470 }
6471
6472 if let Some(crate::drs::OwnershipState::Moved) = self.world_state.get_ownership_by_var(sym) {
6474 return Err(ParseError {
6475 kind: ParseErrorKind::UseAfterMove {
6476 name: self.interner.resolve(sym).to_string()
6477 },
6478 span: self.current_span(),
6479 });
6480 }
6481
6482 Ok(())
6483 }
6484
6485 fn expect_identifier(&mut self) -> ParseResult<Symbol> {
6486 let token = self.peek().clone();
6487 match &token.kind {
6488 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
6490 self.advance();
6491 Ok(*sym)
6492 }
6493 TokenType::Verb { .. } => {
6496 let sym = token.lexeme;
6497 self.advance();
6498 Ok(sym)
6499 }
6500 TokenType::Article(_) => {
6502 let sym = token.lexeme;
6503 self.advance();
6504 Ok(sym)
6505 }
6506 TokenType::Pronoun { .. } | TokenType::Items | TokenType::Values | TokenType::Item | TokenType::Nothing | TokenType::TemporalAdverb(_) |
6514 TokenType::ScopalAdverb(_) |
6515 TokenType::Adverb(_) |
6516 TokenType::Read |
6518 TokenType::Write |
6519 TokenType::File |
6520 TokenType::Console |
6521 TokenType::Merge |
6523 TokenType::Increase |
6524 TokenType::Decrease |
6525 TokenType::Tally |
6527 TokenType::SharedSet |
6528 TokenType::SharedSequence |
6529 TokenType::CollaborativeSequence |
6530 TokenType::Add |
6533 TokenType::Remove |
6534 TokenType::First |
6535 TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared | TokenType::All | TokenType::CalendarUnit(_) |
6543 TokenType::Focus(_) |
6545 TokenType::Particle(_) |
6547 TokenType::Preposition(_) |
6549 TokenType::Escape => {
6551 let sym = token.lexeme;
6553 self.advance();
6554 Ok(sym)
6555 }
6556 TokenType::Ambiguous { .. } => {
6557 let sym = token.lexeme;
6560 self.advance();
6561 Ok(sym)
6562 }
6563 _ => Err(ParseError {
6564 kind: ParseErrorKind::ExpectedIdentifier,
6565 span: self.current_span(),
6566 }),
6567 }
6568 }
6569
6570 fn consume_content_word_for_relative(&mut self) -> ParseResult<Symbol> {
6571 let t = self.advance().clone();
6572 match t.kind {
6573 TokenType::Noun(s) | TokenType::Adjective(s) => Ok(s),
6574 TokenType::ProperName(s) => Ok(s),
6575 TokenType::Verb { lemma, .. } => Ok(lemma),
6576 other => Err(ParseError {
6577 kind: ParseErrorKind::ExpectedContentWord { found: other },
6578 span: self.current_span(),
6579 }),
6580 }
6581 }
6582
6583 fn check_modal(&self) -> bool {
6584 matches!(
6585 self.peek().kind,
6586 TokenType::Must
6587 | TokenType::Shall
6588 | TokenType::Should
6589 | TokenType::Can
6590 | TokenType::May
6591 | TokenType::Cannot
6592 | TokenType::Could
6593 | TokenType::Would
6594 | TokenType::Might
6595 )
6596 }
6597
6598 fn check_pronoun(&self) -> bool {
6599 match &self.peek().kind {
6600 TokenType::Pronoun { case, .. } => {
6601 if self.noun_priority_mode && matches!(case, Case::Possessive) {
6603 return false;
6604 }
6605 true
6606 }
6607 TokenType::Ambiguous { primary, alternatives } => {
6608 if self.noun_priority_mode {
6610 let has_possessive = matches!(**primary, TokenType::Pronoun { case: Case::Possessive, .. })
6611 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { case: Case::Possessive, .. }));
6612 if has_possessive {
6613 return false;
6614 }
6615 }
6616 matches!(**primary, TokenType::Pronoun { .. })
6617 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { .. }))
6618 }
6619 _ => false,
6620 }
6621 }
6622
6623 fn parse_atom(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
6624 if self.check_focus() {
6626 return self.parse_focus();
6627 }
6628
6629 if self.check_measure() {
6631 return self.parse_measure();
6632 }
6633
6634 if self.check_quantifier() {
6635 self.advance();
6636 return self.parse_quantified();
6637 }
6638
6639 if self.check_npi_quantifier() {
6640 return self.parse_npi_quantified();
6641 }
6642
6643 if self.check_temporal_npi() {
6644 return self.parse_temporal_npi();
6645 }
6646
6647 if self.match_token(&[TokenType::LParen]) {
6648 let expr = self.parse_sentence()?;
6649 self.consume(TokenType::RParen)?;
6650 return Ok(expr);
6651 }
6652
6653 if self.check_pronoun() {
6655 let token = self.advance().clone();
6656 let (gender, number) = match &token.kind {
6657 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
6658 TokenType::Ambiguous { primary, alternatives } => {
6659 if let TokenType::Pronoun { gender, number, .. } = **primary {
6660 (gender, number)
6661 } else {
6662 alternatives.iter().find_map(|t| {
6663 if let TokenType::Pronoun { gender, number, .. } = t {
6664 Some((*gender, *number))
6665 } else {
6666 None
6667 }
6668 }).unwrap_or((Gender::Unknown, Number::Singular))
6669 }
6670 }
6671 _ => (Gender::Unknown, Number::Singular),
6672 };
6673
6674 let token_text = self.interner.resolve(token.lexeme);
6675
6676 if token_text.eq_ignore_ascii_case("it") && self.check_verb() {
6679 if let TokenType::Verb { lemma, time, .. } = &self.peek().kind {
6680 let lemma_str = self.interner.resolve(*lemma);
6681 if Lexer::is_weather_verb(lemma_str) {
6682 let verb = *lemma;
6683 let verb_time = *time;
6684 self.advance(); let event_var = self.get_event_var();
6687 let suppress_existential = self.drs.in_conditional_antecedent();
6688 if suppress_existential {
6689 let event_class = self.interner.intern("Event");
6690 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
6691 }
6692 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6693 event_var,
6694 verb,
6695 roles: self.ctx.roles.alloc_slice(vec![]), modifiers: self.ctx.syms.alloc_slice(vec![]),
6697 suppress_existential,
6698 world: None,
6699 })));
6700
6701 return Ok(match verb_time {
6702 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
6703 operator: TemporalOperator::Past,
6704 body: neo_event,
6705 }),
6706 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
6707 operator: TemporalOperator::Future,
6708 body: neo_event,
6709 }),
6710 _ => neo_event,
6711 });
6712 }
6713 }
6714 }
6715
6716 let resolved = if token_text.eq_ignore_ascii_case("i") {
6718 ResolvedPronoun::Constant(self.interner.intern("Speaker"))
6719 } else if token_text.eq_ignore_ascii_case("you") {
6720 ResolvedPronoun::Constant(self.interner.intern("Addressee"))
6721 } else {
6722 self.resolve_pronoun(gender, number)?
6724 };
6725
6726 if self.check_performative() {
6728 if let TokenType::Performative(act) = self.advance().kind.clone() {
6729 let sym = match resolved {
6730 ResolvedPronoun::Variable(s) | ResolvedPronoun::Constant(s) => s,
6731 };
6732 if self.check(&TokenType::To) {
6734 self.advance(); if self.check_verb() {
6737 let infinitive_verb = self.consume_verb();
6738
6739 let content = self.ctx.exprs.alloc(LogicExpr::Predicate {
6740 name: infinitive_verb,
6741 args: self.ctx.terms.alloc_slice([Term::Constant(sym)]),
6742 world: None,
6743 });
6744
6745 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6746 performer: sym,
6747 act_type: act,
6748 content,
6749 }));
6750 }
6751 }
6752
6753 if self.check(&TokenType::That) {
6755 self.advance();
6756 }
6757 let content = self.parse_sentence()?;
6758 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6759 performer: sym,
6760 act_type: act,
6761 content,
6762 }));
6763 }
6764 }
6765
6766 return match resolved {
6769 ResolvedPronoun::Variable(sym) => self.parse_predicate_with_subject_as_var(sym),
6770 ResolvedPronoun::Constant(sym) => self.parse_predicate_with_subject(sym),
6771 };
6772 }
6773
6774 let _had_both = self.match_token(&[TokenType::Both]);
6777
6778 let subject = self.parse_noun_phrase(true)?;
6779
6780 if subject.definiteness == Some(Definiteness::Indefinite)
6786 || subject.definiteness == Some(Definiteness::Distal) {
6787 let gender = Self::infer_noun_gender(self.interner.resolve(subject.noun));
6788 let number = if Self::is_plural_noun(self.interner.resolve(subject.noun)) {
6789 Number::Plural
6790 } else {
6791 Number::Singular
6792 };
6793 self.drs.introduce_referent(subject.noun, subject.noun, gender, number);
6795 }
6796
6797 if self.check(&TokenType::And) {
6799 match self.try_parse_plural_subject(&subject) {
6800 Ok(Some(result)) => return Ok(result),
6801 Ok(None) => {} Err(e) => return Err(e), }
6804 }
6805
6806 if self.check_scopal_adverb() {
6808 return self.parse_scopal_adverb(&subject);
6809 }
6810
6811 if self.check(&TokenType::Comma) {
6813 let saved_pos = self.current;
6814 self.advance(); if self.check_pronoun() {
6818 let topic_attempt = self.try_parse(|p| {
6819 let token = p.peek().clone();
6820 let pronoun_features = match &token.kind {
6821 TokenType::Pronoun { gender, number, .. } => Some((*gender, *number)),
6822 TokenType::Ambiguous { primary, alternatives } => {
6823 if let TokenType::Pronoun { gender, number, .. } = **primary {
6824 Some((gender, number))
6825 } else {
6826 alternatives.iter().find_map(|t| {
6827 if let TokenType::Pronoun { gender, number, .. } = t {
6828 Some((*gender, *number))
6829 } else {
6830 None
6831 }
6832 })
6833 }
6834 }
6835 _ => None,
6836 };
6837
6838 if let Some((gender, number)) = pronoun_features {
6839 p.advance(); let resolved = p.resolve_pronoun(gender, number)?;
6841 let resolved_term = match resolved {
6842 ResolvedPronoun::Variable(s) => Term::Variable(s),
6843 ResolvedPronoun::Constant(s) => Term::Constant(s),
6844 };
6845
6846 if p.check_verb() {
6847 let verb = p.consume_verb();
6848 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6849 name: verb,
6850 args: p.ctx.terms.alloc_slice([
6851 resolved_term,
6852 Term::Constant(subject.noun),
6853 ]),
6854 world: None,
6855 });
6856 p.wrap_with_definiteness_full(&subject, predicate)
6857 } else {
6858 Err(ParseError {
6859 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6860 span: p.current_span(),
6861 })
6862 }
6863 } else {
6864 Err(ParseError {
6865 kind: ParseErrorKind::ExpectedContentWord { found: token.kind },
6866 span: p.current_span(),
6867 })
6868 }
6869 });
6870
6871 if let Some(result) = topic_attempt {
6872 return Ok(result);
6873 }
6874 }
6875
6876 if self.check_content_word() {
6878 let topic_attempt = self.try_parse(|p| {
6879 let real_subject = p.parse_noun_phrase(true)?;
6880 if p.check_verb() {
6881 let verb = p.consume_verb();
6882 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6883 name: verb,
6884 args: p.ctx.terms.alloc_slice([
6885 Term::Constant(real_subject.noun),
6886 Term::Constant(subject.noun),
6887 ]),
6888 world: None,
6889 });
6890 p.wrap_with_definiteness_full(&subject, predicate)
6891 } else {
6892 Err(ParseError {
6893 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6894 span: p.current_span(),
6895 })
6896 }
6897 });
6898
6899 if let Some(result) = topic_attempt {
6900 return Ok(result);
6901 }
6902 }
6903
6904 self.current = saved_pos;
6906 }
6907
6908 let mut relative_clause: Option<(Symbol, &'a LogicExpr<'a>)> = None;
6910 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
6911 self.advance();
6912 let var_name = self.next_var_name();
6913 let rel_pred = self.parse_relative_clause(var_name)?;
6914 relative_clause = Some((var_name, rel_pred));
6915 } else if matches!(self.peek().kind, TokenType::Article(_)) && self.is_contact_clause_pattern() {
6916 let var_name = self.next_var_name();
6919 let rel_pred = self.parse_relative_clause(var_name)?;
6920 relative_clause = Some((var_name, rel_pred));
6921 }
6922
6923 if let Some((var_name, rel_clause)) = relative_clause {
6925 if self.check_verb() {
6926 let (verb, verb_time, _, _) = self.consume_verb_with_metadata();
6927 let var_term = Term::Variable(var_name);
6928
6929 let event_var = self.get_event_var();
6930 let suppress_existential = self.drs.in_conditional_antecedent();
6931 let mut modifiers = vec![];
6932 if verb_time == Time::Past {
6933 modifiers.push(self.interner.intern("Past"));
6934 }
6935 let main_pred = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6936 event_var,
6937 verb,
6938 roles: self.ctx.roles.alloc_slice(vec![
6939 (ThematicRole::Agent, var_term),
6940 ]),
6941 modifiers: self.ctx.syms.alloc_slice(modifiers),
6942 suppress_existential,
6943 world: None,
6944 })));
6945
6946 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6947 name: subject.noun,
6948 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6949 world: None,
6950 });
6951
6952 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6953 left: type_pred,
6954 op: TokenType::And,
6955 right: rel_clause,
6956 });
6957
6958 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6959 left: inner,
6960 op: TokenType::And,
6961 right: main_pred,
6962 });
6963
6964 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6965 kind: QuantifierKind::Existential,
6966 variable: var_name,
6967 body,
6968 island_id: self.current_island,
6969 }));
6970 }
6971
6972 if self.is_at_end() || self.check(&TokenType::Period) || self.check(&TokenType::Comma) {
6975 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6976 name: subject.noun,
6977 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6978 world: None,
6979 });
6980
6981 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6982 left: type_pred,
6983 op: TokenType::And,
6984 right: rel_clause,
6985 });
6986
6987 let uniqueness_body = if subject.definiteness == Some(Definiteness::Definite) {
6989 let y_var = self.next_var_name();
6990 let type_pred_y = self.ctx.exprs.alloc(LogicExpr::Predicate {
6991 name: subject.noun,
6992 args: self.ctx.terms.alloc_slice([Term::Variable(y_var)]),
6993 world: None,
6994 });
6995 let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
6996 left: self.ctx.terms.alloc(Term::Variable(y_var)),
6997 right: self.ctx.terms.alloc(Term::Variable(var_name)),
6998 });
6999 let uniqueness_cond = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7000 left: type_pred_y,
7001 op: TokenType::Implies,
7002 right: identity,
7003 });
7004 let uniqueness = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7005 kind: QuantifierKind::Universal,
7006 variable: y_var,
7007 body: uniqueness_cond,
7008 island_id: self.current_island,
7009 });
7010 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7011 left: body,
7012 op: TokenType::And,
7013 right: uniqueness,
7014 })
7015 } else {
7016 body
7017 };
7018
7019 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7020 kind: QuantifierKind::Existential,
7021 variable: var_name,
7022 body: uniqueness_body,
7023 island_id: self.current_island,
7024 }));
7025 }
7026
7027 relative_clause = Some((var_name, rel_clause));
7029 }
7030
7031 if self.check(&TokenType::Identity) {
7033 self.advance();
7034 let right = self.consume_content_word()?;
7035 return Ok(self.ctx.exprs.alloc(LogicExpr::Identity {
7036 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7037 right: self.ctx.terms.alloc(Term::Constant(right)),
7038 }));
7039 }
7040
7041 if self.check_modal() {
7042 if let Some((var_name, rel_clause)) = relative_clause {
7043 let modal_pred = self.parse_aspect_chain_with_term(Term::Variable(var_name))?;
7044
7045 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7046 name: subject.noun,
7047 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7048 world: None,
7049 });
7050
7051 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7052 left: type_pred,
7053 op: TokenType::And,
7054 right: rel_clause,
7055 });
7056
7057 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7058 left: inner,
7059 op: TokenType::And,
7060 right: modal_pred,
7061 });
7062
7063 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7064 kind: QuantifierKind::Existential,
7065 variable: var_name,
7066 body,
7067 island_id: self.current_island,
7068 }));
7069 }
7070
7071 let modal_pred = self.parse_aspect_chain(subject.noun)?;
7072 return self.wrap_with_definiteness_full(&subject, modal_pred);
7073 }
7074
7075 if self.check(&TokenType::Is) || self.check(&TokenType::Are)
7076 || self.check(&TokenType::Was) || self.check(&TokenType::Were)
7077 {
7078 let copula_time = if self.check(&TokenType::Was) || self.check(&TokenType::Were) {
7079 Time::Past
7080 } else {
7081 Time::Present
7082 };
7083 self.advance();
7084
7085 let is_negated = self.check(&TokenType::Not);
7087 if is_negated {
7088 self.advance(); }
7090
7091 if self.check_number() {
7094 let measure = self.parse_measure_phrase()?;
7095
7096 if self.check_comparative() {
7098 return self.parse_comparative(&subject, copula_time, Some(measure));
7099 }
7100
7101 if self.check_content_word() {
7103 let adj = self.consume_content_word()?;
7104 let result = self.ctx.exprs.alloc(LogicExpr::Predicate {
7105 name: adj,
7106 args: self.ctx.terms.alloc_slice([
7107 Term::Constant(subject.noun),
7108 *measure,
7109 ]),
7110 world: None,
7111 });
7112 return self.wrap_with_definiteness_full(&subject, result);
7113 }
7114
7115 if self.check(&TokenType::Period) || self.is_at_end() {
7118 if self.mode == ParserMode::Imperative {
7120 let variable = self.interner.resolve(subject.noun).to_string();
7121 let value = if let Term::Value { kind, .. } = measure {
7122 format!("{:?}", kind)
7123 } else {
7124 "value".to_string()
7125 };
7126 return Err(ParseError {
7127 kind: ParseErrorKind::IsValueEquality { variable, value },
7128 span: self.current_span(),
7129 });
7130 }
7131 let result = self.ctx.exprs.alloc(LogicExpr::Identity {
7132 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7133 right: measure,
7134 });
7135 return self.wrap_with_definiteness_full(&subject, result);
7136 }
7137 }
7138
7139 if self.check_comparative() {
7141 return self.parse_comparative(&subject, copula_time, None);
7142 }
7143
7144 if self.check(&TokenType::Period) || self.is_at_end() {
7146 let var = self.next_var_name();
7147 let body = self.ctx.exprs.alloc(LogicExpr::Identity {
7148 left: self.ctx.terms.alloc(Term::Variable(var)),
7149 right: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7150 });
7151 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7152 kind: QuantifierKind::Existential,
7153 variable: var,
7154 body,
7155 island_id: self.current_island,
7156 }));
7157 }
7158
7159 if self.check(&TokenType::Article(Definiteness::Definite)) {
7161 let saved_pos = self.current;
7162 self.advance();
7163 if self.check_superlative() {
7164 return self.parse_superlative(&subject);
7165 }
7166 self.current = saved_pos;
7167 }
7168
7169 if self.check_article() {
7171 let predicate_np = self.parse_noun_phrase(true)?;
7172 let predicate_noun = predicate_np.noun;
7173
7174 if self.event_reading_mode {
7177 let noun_str = self.interner.resolve(predicate_noun);
7178 if let Some(base_verb) = lexicon::lookup_agentive_noun(noun_str) {
7179 let event_adj = predicate_np.adjectives.iter().find(|adj| {
7181 lexicon::is_event_modifier_adjective(self.interner.resolve(**adj))
7182 });
7183
7184 if let Some(&adj_sym) = event_adj {
7185 let verb_sym = self.interner.intern(base_verb);
7187 let event_var = self.get_event_var();
7188
7189 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7190 name: verb_sym,
7191 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
7192 world: None,
7193 });
7194
7195 let agent_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7196 name: self.interner.intern("Agent"),
7197 args: self.ctx.terms.alloc_slice([
7198 Term::Variable(event_var),
7199 Term::Constant(subject.noun),
7200 ]),
7201 world: None,
7202 });
7203
7204 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7205 name: adj_sym,
7206 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
7207 world: None,
7208 });
7209
7210 let verb_agent = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7212 left: verb_pred,
7213 op: TokenType::And,
7214 right: agent_pred,
7215 });
7216
7217 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7219 left: verb_agent,
7220 op: TokenType::And,
7221 right: adj_pred,
7222 });
7223
7224 let event_reading = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7226 kind: QuantifierKind::Existential,
7227 variable: event_var,
7228 body,
7229 island_id: self.current_island,
7230 });
7231
7232 return self.wrap_with_definiteness(subject.definiteness, subject.noun, event_reading);
7233 }
7234 }
7235 }
7236
7237 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7238 let predicate_sort = lexicon::lookup_sort(self.interner.resolve(predicate_noun));
7239
7240 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
7241 if !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
7242 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7243 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7244 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_noun)),
7245 });
7246 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7247 }
7248 }
7249
7250 let mut predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
7253
7254 for &adj_sym in predicate_np.adjectives {
7256 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7257 name: adj_sym,
7258 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7259 world: None,
7260 });
7261 predicates.push(adj_pred);
7262 }
7263
7264 let noun_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7266 name: predicate_noun,
7267 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7268 world: None,
7269 });
7270 predicates.push(noun_pred);
7271
7272 let result = if predicates.len() == 1 {
7274 predicates[0]
7275 } else {
7276 let mut combined = predicates[0];
7277 for pred in &predicates[1..] {
7278 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7279 left: combined,
7280 op: TokenType::And,
7281 right: *pred,
7282 });
7283 }
7284 combined
7285 };
7286
7287 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7288 }
7289
7290 let prefer_adjective = if let TokenType::Ambiguous { primary, alternatives } = &self.peek().kind {
7293 let is_simple_verb = if let TokenType::Verb { aspect, .. } = **primary {
7294 aspect == Aspect::Simple
7295 } else {
7296 false
7297 };
7298 let has_adj_alt = alternatives.iter().any(|t| matches!(t, TokenType::Adjective(_)));
7299 is_simple_verb && has_adj_alt
7300 } else {
7301 false
7302 };
7303
7304 if !prefer_adjective && self.check_verb() {
7305 let (verb, _verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
7306
7307 if verb_class.is_stative() && verb_aspect == Aspect::Progressive {
7309 return Err(ParseError {
7310 kind: ParseErrorKind::StativeProgressiveConflict,
7311 span: self.current_span(),
7312 });
7313 }
7314
7315 let mut goal_args: Vec<Term<'a>> = Vec::new();
7318 while self.check_to_preposition() {
7319 self.advance(); let goal = self.parse_noun_phrase(true)?;
7321 goal_args.push(self.noun_phrase_to_term(&goal));
7322 }
7323
7324 if self.check_by_preposition() {
7326 self.advance(); let agent = self.parse_noun_phrase(true)?;
7328
7329 let mut args = vec![
7331 self.noun_phrase_to_term(&agent),
7332 self.noun_phrase_to_term(&subject),
7333 ];
7334 args.extend(goal_args);
7335
7336 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7337 name: verb,
7338 args: self.ctx.terms.alloc_slice(args),
7339 world: None,
7340 });
7341
7342 let with_time = if copula_time == Time::Past {
7343 self.ctx.exprs.alloc(LogicExpr::Temporal {
7344 operator: TemporalOperator::Past,
7345 body: predicate,
7346 })
7347 } else {
7348 predicate
7349 };
7350
7351 return self.wrap_with_definiteness(subject.definiteness, subject.noun, with_time);
7352 }
7353
7354 if copula_time == Time::Past && verb_aspect == Aspect::Simple
7359 && subject.definiteness != Some(Definiteness::Definite) {
7360 let var_name = self.next_var_name();
7362 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7363 name: verb,
7364 args: self.ctx.terms.alloc_slice([
7365 Term::Variable(var_name),
7366 Term::Constant(subject.noun),
7367 ]),
7368 world: None,
7369 });
7370
7371 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7372 name: subject.noun,
7373 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7374 world: None,
7375 });
7376
7377 let temporal = self.ctx.exprs.alloc(LogicExpr::Temporal {
7378 operator: TemporalOperator::Past,
7379 body: predicate,
7380 });
7381
7382 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7383 left: type_pred,
7384 op: TokenType::And,
7385 right: temporal,
7386 });
7387
7388 let result = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7389 kind: QuantifierKind::Existential,
7390 variable: var_name,
7391 body,
7392 island_id: self.current_island,
7393 });
7394
7395 if is_negated {
7397 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7398 op: TokenType::Not,
7399 operand: result,
7400 }));
7401 }
7402 return Ok(result);
7403 }
7404
7405 let verb_str = self.interner.resolve(verb).to_lowercase();
7408 let subject_term = if lexicon::is_intensional_predicate(&verb_str) {
7409 Term::Intension(subject.noun)
7410 } else {
7411 Term::Constant(subject.noun)
7412 };
7413
7414 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7415 name: verb,
7416 args: self.ctx.terms.alloc_slice([subject_term]),
7417 world: None,
7418 });
7419
7420 let with_aspect = if verb_aspect == Aspect::Progressive {
7421 let operator = if verb_class == VerbClass::Semelfactive {
7423 AspectOperator::Iterative
7424 } else {
7425 AspectOperator::Progressive
7426 };
7427 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7428 operator,
7429 body: predicate,
7430 })
7431 } else {
7432 predicate
7433 };
7434
7435 let with_time = if copula_time == Time::Past {
7436 self.ctx.exprs.alloc(LogicExpr::Temporal {
7437 operator: TemporalOperator::Past,
7438 body: with_aspect,
7439 })
7440 } else {
7441 with_aspect
7442 };
7443
7444 let final_expr = if is_negated {
7445 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7446 op: TokenType::Not,
7447 operand: with_time,
7448 })
7449 } else {
7450 with_time
7451 };
7452
7453 if subject.definiteness == Some(Definiteness::Definite) {
7457 return Ok(final_expr);
7458 }
7459
7460 return self.wrap_with_definiteness(subject.definiteness, subject.noun, final_expr);
7461 }
7462
7463 if let Some((var_name, rel_clause)) = relative_clause {
7465 let var_term = Term::Variable(var_name);
7466 let pred_word = self.consume_content_word()?;
7467
7468 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7469 name: pred_word,
7470 args: self.ctx.terms.alloc_slice([var_term]),
7471 world: None,
7472 });
7473
7474 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7475 name: subject.noun,
7476 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7477 world: None,
7478 });
7479
7480 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7481 left: type_pred,
7482 op: TokenType::And,
7483 right: rel_clause,
7484 });
7485
7486 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7487 left: inner,
7488 op: TokenType::And,
7489 right: main_pred,
7490 });
7491
7492 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7493 kind: QuantifierKind::Existential,
7494 variable: var_name,
7495 body,
7496 island_id: self.current_island,
7497 }));
7498 }
7499
7500 if let TokenType::ProperName(predicate_name) = self.peek().kind {
7505 self.advance(); let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
7507 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7508 right: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7509 });
7510 let result = if is_negated {
7511 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7512 op: TokenType::Not,
7513 operand: identity,
7514 })
7515 } else {
7516 identity
7517 };
7518 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7519 }
7520
7521 let predicate_name = self.consume_content_word()?;
7524
7525 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7527 let predicate_str = self.interner.resolve(predicate_name);
7528
7529 if let Some(s_sort) = subject_sort {
7531 if !crate::ontology::check_sort_compatibility(predicate_str, s_sort) {
7532 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7533 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7534 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7535 });
7536 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7537 }
7538 }
7539
7540 let predicate_sort = lexicon::lookup_sort(predicate_str);
7542 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
7543 if s_sort != p_sort && !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
7544 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7545 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7546 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7547 });
7548 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7549 }
7550 }
7551
7552 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7553 name: predicate_name,
7554 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7555 world: None,
7556 });
7557
7558 let result = if is_negated {
7560 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7561 op: TokenType::Not,
7562 operand: predicate,
7563 })
7564 } else {
7565 predicate
7566 };
7567 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7568 }
7569
7570 if self.check_auxiliary() && self.is_true_auxiliary_usage() {
7574 let aux_time = if let TokenType::Auxiliary(time) = self.advance().kind {
7575 time
7576 } else {
7577 Time::None
7578 };
7579 self.pending_time = Some(aux_time);
7580
7581 if self.match_token(&[TokenType::Not]) {
7583 self.negative_depth += 1;
7584
7585 if self.check(&TokenType::Ever) {
7587 self.advance();
7588 }
7589
7590 if self.check_verb() || self.check(&TokenType::Do) {
7592 let verb = if self.check(&TokenType::Do) {
7593 self.advance(); self.interner.intern("Do")
7595 } else {
7596 self.consume_verb()
7597 };
7598 let subject_term = self.noun_phrase_to_term(&subject);
7599
7600 if self.check_npi_object() {
7602 let npi_token = self.advance().kind.clone();
7603 let obj_var = self.next_var_name();
7604
7605 let restriction_name = match npi_token {
7606 TokenType::Anything => "Thing",
7607 TokenType::Anyone => "Person",
7608 _ => "Thing",
7609 };
7610
7611 let restriction_sym = self.interner.intern(restriction_name);
7612 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7613 name: restriction_sym,
7614 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7615 world: None,
7616 });
7617
7618 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7619 name: verb,
7620 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7621 world: None,
7622 });
7623
7624 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7625 left: obj_restriction,
7626 op: TokenType::And,
7627 right: verb_pred,
7628 });
7629
7630 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7631 kind: QuantifierKind::Existential,
7632 variable: obj_var,
7633 body,
7634 island_id: self.current_island,
7635 });
7636
7637 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7638 let with_time = match effective_time {
7639 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7640 operator: TemporalOperator::Past,
7641 body: quantified,
7642 }),
7643 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7644 operator: TemporalOperator::Future,
7645 body: quantified,
7646 }),
7647 _ => quantified,
7648 };
7649
7650 self.negative_depth -= 1;
7651 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7652 op: TokenType::Not,
7653 operand: with_time,
7654 }));
7655 }
7656
7657 if self.check_quantifier() {
7659 let quantifier_token = self.advance().kind.clone();
7660 let object_np = self.parse_noun_phrase(false)?;
7661 let obj_var = self.next_var_name();
7662
7663 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7664 name: object_np.noun,
7665 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7666 world: None,
7667 });
7668
7669 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7670 name: verb,
7671 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7672 world: None,
7673 });
7674
7675 let (kind, body) = match quantifier_token {
7676 TokenType::Any => {
7677 if self.is_negative_context() {
7678 (
7679 QuantifierKind::Existential,
7680 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7681 left: obj_restriction,
7682 op: TokenType::And,
7683 right: verb_pred,
7684 }),
7685 )
7686 } else {
7687 (
7688 QuantifierKind::Universal,
7689 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7690 left: obj_restriction,
7691 op: TokenType::Implies,
7692 right: verb_pred,
7693 }),
7694 )
7695 }
7696 }
7697 TokenType::Some => (
7698 QuantifierKind::Existential,
7699 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7700 left: obj_restriction,
7701 op: TokenType::And,
7702 right: verb_pred,
7703 }),
7704 ),
7705 TokenType::All => (
7706 QuantifierKind::Universal,
7707 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7708 left: obj_restriction,
7709 op: TokenType::Implies,
7710 right: verb_pred,
7711 }),
7712 ),
7713 _ => (
7714 QuantifierKind::Existential,
7715 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7716 left: obj_restriction,
7717 op: TokenType::And,
7718 right: verb_pred,
7719 }),
7720 ),
7721 };
7722
7723 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7724 kind,
7725 variable: obj_var,
7726 body,
7727 island_id: self.current_island,
7728 });
7729
7730 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7731 let with_time = match effective_time {
7732 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7733 operator: TemporalOperator::Past,
7734 body: quantified,
7735 }),
7736 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7737 operator: TemporalOperator::Future,
7738 body: quantified,
7739 }),
7740 _ => quantified,
7741 };
7742
7743 self.negative_depth -= 1;
7744 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7745 op: TokenType::Not,
7746 operand: with_time,
7747 }));
7748 }
7749
7750 let mut roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
7751
7752 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7754 let mut modifiers: Vec<Symbol> = vec![];
7755 match effective_time {
7756 Time::Past => modifiers.push(self.interner.intern("Past")),
7757 Time::Future => modifiers.push(self.interner.intern("Future")),
7758 _ => {}
7759 }
7760
7761 if self.check_content_word() || self.check_article() || self.check_pronoun() {
7763 if self.check_pronoun() {
7764 let pronoun_token = self.advance();
7766 let pronoun_sym = pronoun_token.lexeme;
7767 roles.push((ThematicRole::Theme, Term::Constant(pronoun_sym)));
7768 } else {
7769 let object = self.parse_noun_phrase(false)?;
7770 let object_term = self.noun_phrase_to_term(&object);
7771 roles.push((ThematicRole::Theme, object_term));
7772 }
7773 }
7774
7775 let event_var = self.get_event_var();
7776 let suppress_existential = self.drs.in_conditional_antecedent();
7777 if suppress_existential {
7778 let event_class = self.interner.intern("Event");
7779 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7780 }
7781 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7782 event_var,
7783 verb,
7784 roles: self.ctx.roles.alloc_slice(roles),
7785 modifiers: self.ctx.syms.alloc_slice(modifiers),
7786 suppress_existential,
7787 world: None,
7788 })));
7789
7790 self.negative_depth -= 1;
7791 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7792 op: TokenType::Not,
7793 operand: neo_event,
7794 }));
7795 }
7796
7797 self.negative_depth -= 1;
7798 }
7799 }
7801
7802 if self.check_presup_trigger() && !self.is_followed_by_np_object() && self.is_followed_by_gerund() {
7808 let presup_kind = match self.advance().kind {
7809 TokenType::PresupTrigger(kind) => kind,
7810 TokenType::Verb { lemma, .. } => {
7811 let s = self.interner.resolve(lemma).to_lowercase();
7812 crate::lexicon::lookup_presup_trigger(&s)
7813 .expect("Lexicon mismatch: Verb flagged as trigger but lookup failed")
7814 }
7815 _ => panic!("Expected presupposition trigger"),
7816 };
7817 return self.parse_presupposition(&subject, presup_kind);
7818 }
7819
7820 let noun_str = self.interner.resolve(subject.noun);
7822 let is_bare_plural = subject.definiteness.is_none()
7823 && subject.possessor.is_none()
7824 && Self::is_plural_noun(noun_str)
7825 && self.check_verb();
7826
7827 if is_bare_plural {
7828 let var_name = self.next_var_name();
7829 let (verb, verb_time, verb_aspect, _) = self.consume_verb_with_metadata();
7830
7831 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7832 name: subject.noun,
7833 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7834 world: None,
7835 });
7836
7837 let mut args = vec![Term::Variable(var_name)];
7838 if self.check_content_word() {
7839 let object = self.parse_noun_phrase(false)?;
7840 args.push(self.noun_phrase_to_term(&object));
7841 }
7842
7843 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7844 name: verb,
7845 args: self.ctx.terms.alloc_slice(args),
7846 world: None,
7847 });
7848
7849 let effective_time = self.pending_time.take().unwrap_or(verb_time);
7850 let with_time = match effective_time {
7851 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7852 operator: TemporalOperator::Past,
7853 body: verb_pred,
7854 }),
7855 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7856 operator: TemporalOperator::Future,
7857 body: verb_pred,
7858 }),
7859 _ => verb_pred,
7860 };
7861
7862 let with_aspect = if verb_aspect == Aspect::Progressive {
7863 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7864 operator: AspectOperator::Progressive,
7865 body: with_time,
7866 })
7867 } else {
7868 with_time
7869 };
7870
7871 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7872 left: type_pred,
7873 op: TokenType::Implies,
7874 right: with_aspect,
7875 });
7876
7877 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7878 kind: QuantifierKind::Generic,
7879 variable: var_name,
7880 body,
7881 island_id: self.current_island,
7882 }));
7883 }
7884
7885 if self.check(&TokenType::Does) || self.check(&TokenType::Do) {
7887 self.advance(); let is_negated = self.match_token(&[TokenType::Not]);
7889
7890 if self.check_verb() {
7891 let verb = self.consume_verb();
7892 let verb_lemma = self.interner.resolve(verb).to_lowercase();
7893
7894 if self.check_wh_word() {
7896 let wh_token = self.advance().kind.clone();
7897 let is_who = matches!(wh_token, TokenType::Who);
7898 let is_what = matches!(wh_token, TokenType::What);
7899
7900 let is_sluicing = self.is_at_end() ||
7901 self.check(&TokenType::Period) ||
7902 self.check(&TokenType::Comma);
7903
7904 if is_sluicing {
7905 if let Some(template) = self.last_event_template.clone() {
7906 let wh_var = self.next_var_name();
7907 let subject_term = self.noun_phrase_to_term(&subject);
7908
7909 let roles: Vec<_> = if is_who {
7910 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7911 .chain(template.non_agent_roles.iter().cloned())
7912 .collect()
7913 } else if is_what {
7914 vec![
7915 (ThematicRole::Agent, subject_term.clone()),
7916 (ThematicRole::Theme, Term::Variable(wh_var)),
7917 ]
7918 } else {
7919 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7920 .chain(template.non_agent_roles.iter().cloned())
7921 .collect()
7922 };
7923
7924 let event_var = self.get_event_var();
7925 let suppress_existential = self.drs.in_conditional_antecedent();
7926 if suppress_existential {
7927 let event_class = self.interner.intern("Event");
7928 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7929 }
7930 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7931 event_var,
7932 verb: template.verb,
7933 roles: self.ctx.roles.alloc_slice(roles),
7934 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
7935 suppress_existential,
7936 world: None,
7937 })));
7938
7939 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7940 wh_variable: wh_var,
7941 body: reconstructed,
7942 });
7943
7944 let know_event_var = self.get_event_var();
7945 let suppress_existential2 = self.drs.in_conditional_antecedent();
7946 if suppress_existential2 {
7947 let event_class = self.interner.intern("Event");
7948 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
7949 }
7950 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7951 event_var: know_event_var,
7952 verb,
7953 roles: self.ctx.roles.alloc_slice(vec![
7954 (ThematicRole::Agent, subject_term),
7955 (ThematicRole::Theme, Term::Proposition(question)),
7956 ]),
7957 modifiers: self.ctx.syms.alloc_slice(vec![]),
7958 suppress_existential: suppress_existential2,
7959 world: None,
7960 })));
7961
7962 let result = if is_negated {
7963 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7964 op: TokenType::Not,
7965 operand: know_event,
7966 })
7967 } else {
7968 know_event
7969 };
7970
7971 return self.wrap_with_definiteness_full(&subject, result);
7972 }
7973 }
7974 }
7975
7976 if verb_lemma == "exist" && is_negated {
7978 let var_name = self.next_var_name();
7980 let restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7981 name: subject.noun,
7982 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7983 world: None,
7984 });
7985 let exists = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7986 kind: QuantifierKind::Existential,
7987 variable: var_name,
7988 body: restriction,
7989 island_id: self.current_island,
7990 });
7991 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7992 op: TokenType::Not,
7993 operand: exists,
7994 }));
7995 }
7996
7997 let subject_term = self.noun_phrase_to_term(&subject);
8000 let modifiers: Vec<Symbol> = vec![];
8001
8002 if self.check(&TokenType::Reflexive) {
8004 self.advance();
8005 let roles = vec![
8006 (ThematicRole::Agent, subject_term.clone()),
8007 (ThematicRole::Theme, subject_term),
8008 ];
8009 let event_var = self.get_event_var();
8010 let suppress_existential = self.drs.in_conditional_antecedent();
8011 if suppress_existential {
8012 let event_class = self.interner.intern("Event");
8013 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8014 }
8015 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8016 event_var,
8017 verb,
8018 roles: self.ctx.roles.alloc_slice(roles),
8019 modifiers: self.ctx.syms.alloc_slice(modifiers),
8020 suppress_existential,
8021 world: None,
8022 })));
8023
8024 let result = if is_negated {
8025 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8026 op: TokenType::Not,
8027 operand: neo_event,
8028 })
8029 } else {
8030 neo_event
8031 };
8032 return self.wrap_with_definiteness_full(&subject, result);
8033 }
8034
8035 if self.check_npi_quantifier() || self.check_quantifier() || self.check_article() {
8037 let (obj_quantifier, was_definite_article) = if self.check_npi_quantifier() {
8038 let tok = self.advance().kind.clone();
8040 (Some(tok), false)
8041 } else if self.check_quantifier() {
8042 (Some(self.advance().kind.clone()), false)
8043 } else {
8044 let art = self.advance().kind.clone();
8045 if let TokenType::Article(def) = art {
8046 if def == Definiteness::Indefinite {
8047 (Some(TokenType::Some), false)
8048 } else {
8049 (None, true)
8050 }
8051 } else {
8052 (None, false)
8053 }
8054 };
8055
8056 let object_np = self.parse_noun_phrase(false)?;
8057 let obj_var = self.next_var_name();
8058
8059 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8060 name: object_np.noun,
8061 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8062 world: None,
8063 });
8064
8065 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8067 self.advance();
8068 let rel_clause = self.parse_relative_clause(obj_var)?;
8069 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8070 left: type_pred,
8071 op: TokenType::And,
8072 right: rel_clause,
8073 })
8074 } else {
8075 type_pred
8076 };
8077
8078 let event_var = self.get_event_var();
8079 let suppress_existential = self.drs.in_conditional_antecedent();
8080 if suppress_existential {
8081 let event_class = self.interner.intern("Event");
8082 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8083 }
8084
8085 let roles = vec![
8086 (ThematicRole::Agent, subject_term),
8087 (ThematicRole::Theme, Term::Variable(obj_var)),
8088 ];
8089
8090 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8091 event_var,
8092 verb,
8093 roles: self.ctx.roles.alloc_slice(roles),
8094 modifiers: self.ctx.syms.alloc_slice(modifiers),
8095 suppress_existential,
8096 world: None,
8097 })));
8098
8099 let quantifier_kind = match &obj_quantifier {
8103 Some(TokenType::Any) if is_negated => QuantifierKind::Existential,
8104 Some(TokenType::All) => QuantifierKind::Universal,
8105 Some(TokenType::No) => QuantifierKind::Universal,
8106 _ => QuantifierKind::Existential,
8107 };
8108
8109 let obj_body = match &obj_quantifier {
8110 Some(TokenType::All) => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8111 left: obj_restriction,
8112 op: TokenType::Implies,
8113 right: neo_event,
8114 }),
8115 Some(TokenType::No) => {
8116 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8117 op: TokenType::Not,
8118 operand: neo_event,
8119 });
8120 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8121 left: obj_restriction,
8122 op: TokenType::Implies,
8123 right: neg,
8124 })
8125 }
8126 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8127 left: obj_restriction,
8128 op: TokenType::And,
8129 right: neo_event,
8130 }),
8131 };
8132
8133 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8134 kind: quantifier_kind,
8135 variable: obj_var,
8136 body: obj_body,
8137 island_id: self.current_island,
8138 });
8139
8140 let result = if is_negated && matches!(obj_quantifier, Some(TokenType::Any)) {
8142 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8143 op: TokenType::Not,
8144 operand: obj_quantified,
8145 })
8146 } else if is_negated {
8147 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8149 op: TokenType::Not,
8150 operand: obj_quantified,
8151 })
8152 } else {
8153 obj_quantified
8154 };
8155
8156 return self.wrap_with_definiteness_full(&subject, result);
8157 }
8158
8159 let roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
8161 let event_var = self.get_event_var();
8162 let suppress_existential = self.drs.in_conditional_antecedent();
8163 if suppress_existential {
8164 let event_class = self.interner.intern("Event");
8165 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8166 }
8167
8168 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8169 event_var,
8170 verb,
8171 roles: self.ctx.roles.alloc_slice(roles),
8172 modifiers: self.ctx.syms.alloc_slice(modifiers),
8173 suppress_existential,
8174 world: None,
8175 })));
8176
8177 if is_negated {
8178 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8179 op: TokenType::Not,
8180 operand: neo_event,
8181 }));
8182 }
8183 return Ok(neo_event);
8184 }
8185 }
8186
8187 let is_perfect_aux = if self.check_verb() {
8193 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
8194 word == "has" || word == "have" || word == "had"
8195 } else {
8196 false
8197 };
8198 if subject.definiteness == Some(Definiteness::Definite) && self.check_verb() && self.pending_time.is_none() && !is_perfect_aux {
8199 let saved_pos = self.current;
8200
8201 if let Some(garden_path_result) = self.try_parse(|p| {
8203 let (modifier_verb, _modifier_time, _, _) = p.consume_verb_with_metadata();
8204
8205 let mut pp_mods: Vec<&'a LogicExpr<'a>> = Vec::new();
8207 while p.check_preposition() {
8208 let prep = if let TokenType::Preposition(prep) = p.advance().kind {
8209 prep
8210 } else {
8211 break;
8212 };
8213 if p.check_article() || p.check_content_word() {
8214 let pp_obj = p.parse_noun_phrase(false)?;
8215 let pp_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8216 name: prep,
8217 args: p.ctx.terms.alloc_slice([Term::Variable(p.interner.intern("x")), Term::Constant(pp_obj.noun)]),
8218 world: None,
8219 });
8220 pp_mods.push(pp_pred);
8221 }
8222 }
8223
8224 if !p.check_verb() {
8226 return Err(ParseError {
8227 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
8228 span: p.current_span(),
8229 });
8230 }
8231
8232 let (main_verb, main_time, _, _) = p.consume_verb_with_metadata();
8233
8234 let var = p.interner.intern("x");
8236
8237 let type_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8239 name: subject.noun,
8240 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
8241 world: None,
8242 });
8243
8244 let mod_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8246 name: modifier_verb,
8247 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
8248 world: None,
8249 });
8250
8251 let main_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8253 name: main_verb,
8254 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
8255 world: None,
8256 });
8257
8258 let mut body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
8260 left: type_pred,
8261 op: TokenType::And,
8262 right: mod_pred,
8263 });
8264
8265 for pp in pp_mods {
8267 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
8268 left: body,
8269 op: TokenType::And,
8270 right: pp,
8271 });
8272 }
8273
8274 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
8276 left: body,
8277 op: TokenType::And,
8278 right: main_pred,
8279 });
8280
8281 let with_time = match main_time {
8283 Time::Past => p.ctx.exprs.alloc(LogicExpr::Temporal {
8284 operator: TemporalOperator::Past,
8285 body,
8286 }),
8287 Time::Future => p.ctx.exprs.alloc(LogicExpr::Temporal {
8288 operator: TemporalOperator::Future,
8289 body,
8290 }),
8291 _ => body,
8292 };
8293
8294 Ok(p.ctx.exprs.alloc(LogicExpr::Quantifier {
8296 kind: QuantifierKind::Existential,
8297 variable: var,
8298 body: with_time,
8299 island_id: p.current_island,
8300 }))
8301 }) {
8302 return Ok(garden_path_result);
8303 }
8304
8305 self.current = saved_pos;
8307 }
8308
8309 if self.check_modal() {
8310 return self.parse_aspect_chain(subject.noun);
8311 }
8312
8313 if self.check_content_word() {
8315 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
8316 if word == "has" || word == "have" || word == "had" {
8317 let is_perfect_aspect = if self.current + 1 < self.tokens.len() {
8319 let next_token = &self.tokens[self.current + 1].kind;
8320 matches!(
8321 next_token,
8322 TokenType::Verb { .. } | TokenType::Not
8323 ) && !matches!(next_token, TokenType::Number(_))
8324 } else {
8325 false
8326 };
8327 if is_perfect_aspect {
8328 return self.parse_aspect_chain(subject.noun);
8329 }
8330 }
8332 }
8333
8334 if self.check(&TokenType::Had) {
8336 return self.parse_aspect_chain(subject.noun);
8337 }
8338
8339 if self.check(&TokenType::Never) {
8341 self.advance();
8342 let verb = self.consume_verb();
8343 let subject_term = self.noun_phrase_to_term(&subject);
8344 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8345 name: verb,
8346 args: self.ctx.terms.alloc_slice([subject_term]),
8347 world: None,
8348 });
8349 let result = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8350 op: TokenType::Not,
8351 operand: verb_pred,
8352 });
8353 return self.wrap_with_definiteness_full(&subject, result);
8354 }
8355
8356 if self.check_verb() {
8357 let (mut verb, verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
8358
8359 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
8361 let verb_str = self.interner.resolve(verb);
8362 if let Some(s_sort) = subject_sort {
8363 if !crate::ontology::check_sort_compatibility(verb_str, s_sort) {
8364 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
8365 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
8366 vehicle: self.ctx.terms.alloc(Term::Constant(verb)),
8367 });
8368 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
8369 }
8370 }
8371
8372 if self.is_control_verb(verb) {
8374 return self.parse_control_structure(&subject, verb, verb_time);
8375 }
8376
8377 if let Some((var_name, rel_clause)) = relative_clause {
8379 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8380 name: verb,
8381 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8382 world: None,
8383 });
8384
8385 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8386 let with_time = match effective_time {
8387 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
8388 operator: TemporalOperator::Past,
8389 body: main_pred,
8390 }),
8391 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
8392 operator: TemporalOperator::Future,
8393 body: main_pred,
8394 }),
8395 _ => main_pred,
8396 };
8397
8398 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8400 name: subject.noun,
8401 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8402 world: None,
8403 });
8404
8405 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8406 left: type_pred,
8407 op: TokenType::And,
8408 right: rel_clause,
8409 });
8410
8411 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8412 left: inner,
8413 op: TokenType::And,
8414 right: with_time,
8415 });
8416
8417 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
8418 kind: QuantifierKind::Existential,
8419 variable: var_name,
8420 body,
8421 island_id: self.current_island,
8422 }));
8423 }
8424
8425 let subject_term = self.noun_phrase_to_term(&subject);
8426 let mut args = vec![subject_term.clone()];
8427
8428 let unknown = self.interner.intern("?");
8429
8430 if self.check_wh_word() {
8432 let wh_token = self.advance().kind.clone();
8433
8434 let is_who = matches!(wh_token, TokenType::Who);
8436 let is_what = matches!(wh_token, TokenType::What);
8437
8438 let is_sluicing = self.is_at_end() ||
8440 self.check(&TokenType::Period) ||
8441 self.check(&TokenType::Comma);
8442
8443 if is_sluicing {
8444 if let Some(template) = self.last_event_template.clone() {
8446 let wh_var = self.next_var_name();
8447
8448 let roles: Vec<_> = if is_who {
8450 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
8452 .chain(template.non_agent_roles.iter().cloned())
8453 .collect()
8454 } else if is_what {
8455 vec![
8457 (ThematicRole::Agent, subject_term.clone()),
8458 (ThematicRole::Theme, Term::Variable(wh_var)),
8459 ]
8460 } else {
8461 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
8463 .chain(template.non_agent_roles.iter().cloned())
8464 .collect()
8465 };
8466
8467 let event_var = self.get_event_var();
8468 let suppress_existential = self.drs.in_conditional_antecedent();
8469 if suppress_existential {
8470 let event_class = self.interner.intern("Event");
8471 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8472 }
8473 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8474 event_var,
8475 verb: template.verb,
8476 roles: self.ctx.roles.alloc_slice(roles),
8477 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
8478 suppress_existential,
8479 world: None,
8480 })));
8481
8482 let question = self.ctx.exprs.alloc(LogicExpr::Question {
8483 wh_variable: wh_var,
8484 body: reconstructed,
8485 });
8486
8487 let know_event_var = self.get_event_var();
8489 let suppress_existential2 = self.drs.in_conditional_antecedent();
8490 if suppress_existential2 {
8491 let event_class = self.interner.intern("Event");
8492 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8493 }
8494 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8495 event_var: know_event_var,
8496 verb,
8497 roles: self.ctx.roles.alloc_slice(vec![
8498 (ThematicRole::Agent, subject_term),
8499 (ThematicRole::Theme, Term::Proposition(question)),
8500 ]),
8501 modifiers: self.ctx.syms.alloc_slice(vec![]),
8502 suppress_existential: suppress_existential2,
8503 world: None,
8504 })));
8505
8506 return self.wrap_with_definiteness_full(&subject, know_event);
8507 }
8508 }
8509
8510 let embedded = self.parse_embedded_wh_clause()?;
8512 let question = self.ctx.exprs.alloc(LogicExpr::Question {
8513 wh_variable: self.interner.intern("x"),
8514 body: embedded,
8515 });
8516
8517 let know_event_var = self.get_event_var();
8519 let suppress_existential = self.drs.in_conditional_antecedent();
8520 if suppress_existential {
8521 let event_class = self.interner.intern("Event");
8522 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8523 }
8524 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8525 event_var: know_event_var,
8526 verb,
8527 roles: self.ctx.roles.alloc_slice(vec![
8528 (ThematicRole::Agent, subject_term),
8529 (ThematicRole::Theme, Term::Proposition(question)),
8530 ]),
8531 modifiers: self.ctx.syms.alloc_slice(vec![]),
8532 suppress_existential,
8533 world: None,
8534 })));
8535
8536 return self.wrap_with_definiteness_full(&subject, know_event);
8537 }
8538
8539 let mut object_term: Option<Term<'a>> = None;
8540 let mut second_object_term: Option<Term<'a>> = None;
8541 let mut object_superlative: Option<(Symbol, Symbol)> = None; if self.check(&TokenType::Reflexive) {
8543 self.advance();
8544 let term = self.noun_phrase_to_term(&subject);
8545 object_term = Some(term.clone());
8546 args.push(term);
8547
8548 if let TokenType::Particle(particle_sym) = self.peek().kind {
8550 let verb_str = self.interner.resolve(verb).to_lowercase();
8551 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8552 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8553 self.advance();
8554 verb = self.interner.intern(phrasal_lemma);
8555 }
8556 }
8557 } else if self.check_pronoun() {
8558 let token = self.advance().clone();
8559 if let TokenType::Pronoun { gender, number, .. } = token.kind {
8560 let resolved = self.resolve_pronoun(gender, number)?;
8561 let term = match resolved {
8562 ResolvedPronoun::Variable(s) => Term::Variable(s),
8563 ResolvedPronoun::Constant(s) => Term::Constant(s),
8564 };
8565 object_term = Some(term.clone());
8566 args.push(term);
8567
8568 if let TokenType::Particle(particle_sym) = self.peek().kind {
8570 let verb_str = self.interner.resolve(verb).to_lowercase();
8571 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8572 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8573 self.advance();
8574 verb = self.interner.intern(phrasal_lemma);
8575 }
8576 }
8577 }
8578 } else if self.check_quantifier() || self.check_article() {
8579 let (obj_quantifier, was_definite_article) = if self.check_quantifier() {
8581 (Some(self.advance().kind.clone()), false)
8582 } else {
8583 let art = self.advance().kind.clone();
8584 if let TokenType::Article(def) = art {
8585 if def == Definiteness::Indefinite {
8586 (Some(TokenType::Some), false)
8587 } else {
8588 (None, true) }
8590 } else {
8591 (None, false)
8592 }
8593 };
8594
8595 let object_np = self.parse_noun_phrase(false)?;
8596
8597 if let Some(adj) = object_np.superlative {
8599 object_superlative = Some((adj, object_np.noun));
8600 }
8601
8602 if let TokenType::Particle(particle_sym) = self.peek().kind {
8604 let verb_str = self.interner.resolve(verb).to_lowercase();
8605 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8606 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8607 self.advance(); verb = self.interner.intern(phrasal_lemma);
8609 }
8610 }
8611
8612 if let Some(obj_q) = obj_quantifier {
8613 let verb_str = self.interner.resolve(verb).to_lowercase();
8617 let is_opaque = lexicon::lookup_verb_db(&verb_str)
8618 .map(|meta| meta.features.contains(&lexicon::Feature::Opaque))
8619 .unwrap_or(false);
8620
8621 if is_opaque && matches!(obj_q, TokenType::Some) {
8622 let intension_term = Term::Intension(object_np.noun);
8624
8625 let event_var = self.get_event_var();
8627 let mut modifiers = self.collect_adverbs();
8628 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8629 match effective_time {
8630 Time::Past => modifiers.push(self.interner.intern("Past")),
8631 Time::Future => modifiers.push(self.interner.intern("Future")),
8632 _ => {}
8633 }
8634
8635 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8636 let roles = vec![
8637 (ThematicRole::Agent, subject_term_for_event),
8638 (ThematicRole::Theme, intension_term),
8639 ];
8640
8641 let suppress_existential = self.drs.in_conditional_antecedent();
8642 if suppress_existential {
8643 let event_class = self.interner.intern("Event");
8644 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8645 }
8646 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8647 event_var,
8648 verb,
8649 roles: self.ctx.roles.alloc_slice(roles),
8650 modifiers: self.ctx.syms.alloc_slice(modifiers),
8651 suppress_existential,
8652 world: None,
8653 })));
8654
8655 return self.wrap_with_definiteness_full(&subject, neo_event);
8656 }
8657
8658 let obj_var = self.next_var_name();
8659
8660 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8662 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8663 Number::Plural
8664 } else {
8665 Number::Singular
8666 };
8667 if object_np.definiteness == Some(Definiteness::Definite) {
8669 self.drs.introduce_referent_with_source(obj_var, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8670 } else {
8671 self.drs.introduce_referent(obj_var, object_np.noun, obj_gender, obj_number);
8672 }
8673
8674 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8675 name: object_np.noun,
8676 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8677 world: None,
8678 });
8679
8680 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8681 self.advance();
8682 let rel_clause = self.parse_relative_clause(obj_var)?;
8683 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8684 left: type_pred,
8685 op: TokenType::And,
8686 right: rel_clause,
8687 })
8688 } else {
8689 type_pred
8690 };
8691
8692 let event_var = self.get_event_var();
8693 let mut modifiers = self.collect_adverbs();
8694 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8695 match effective_time {
8696 Time::Past => modifiers.push(self.interner.intern("Past")),
8697 Time::Future => modifiers.push(self.interner.intern("Future")),
8698 _ => {}
8699 }
8700
8701 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8702 let roles = vec![
8703 (ThematicRole::Agent, subject_term_for_event),
8704 (ThematicRole::Theme, Term::Variable(obj_var)),
8705 ];
8706
8707 let template_roles = vec![
8710 (ThematicRole::Agent, subject_term_for_event),
8711 (ThematicRole::Theme, Term::Constant(object_np.noun)),
8712 ];
8713 self.capture_event_template(verb, &template_roles, &modifiers);
8714
8715 let suppress_existential = self.drs.in_conditional_antecedent();
8716 if suppress_existential {
8717 let event_class = self.interner.intern("Event");
8718 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8719 }
8720 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8721 event_var,
8722 verb,
8723 roles: self.ctx.roles.alloc_slice(roles),
8724 modifiers: self.ctx.syms.alloc_slice(modifiers),
8725 suppress_existential,
8726 world: None,
8727 })));
8728
8729 let obj_kind = match obj_q {
8730 TokenType::All => QuantifierKind::Universal,
8731 TokenType::Some => QuantifierKind::Existential,
8732 TokenType::No => QuantifierKind::Universal,
8733 TokenType::Most => QuantifierKind::Most,
8734 TokenType::Few => QuantifierKind::Few,
8735 TokenType::Many => QuantifierKind::Many,
8736 TokenType::Cardinal(n) => QuantifierKind::Cardinal(n),
8737 TokenType::AtLeast(n) => QuantifierKind::AtLeast(n),
8738 TokenType::AtMost(n) => QuantifierKind::AtMost(n),
8739 _ => QuantifierKind::Existential,
8740 };
8741
8742 let obj_body = match obj_q {
8743 TokenType::All => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8744 left: obj_restriction,
8745 op: TokenType::Implies,
8746 right: neo_event,
8747 }),
8748 TokenType::No => {
8749 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8750 op: TokenType::Not,
8751 operand: neo_event,
8752 });
8753 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8754 left: obj_restriction,
8755 op: TokenType::Implies,
8756 right: neg,
8757 })
8758 }
8759 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8760 left: obj_restriction,
8761 op: TokenType::And,
8762 right: neo_event,
8763 }),
8764 };
8765
8766 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8768 kind: obj_kind,
8769 variable: obj_var,
8770 body: obj_body,
8771 island_id: self.current_island,
8772 });
8773
8774 return self.wrap_with_definiteness_full(&subject, obj_quantified);
8776 } else {
8777 if was_definite_article {
8782 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8783 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8784 Number::Plural
8785 } else {
8786 Number::Singular
8787 };
8788 self.drs.introduce_referent_with_source(object_np.noun, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8790 }
8791
8792 let term = self.noun_phrase_to_term(&object_np);
8793 object_term = Some(term.clone());
8794 args.push(term);
8795 }
8796 } else if self.check_focus() {
8797 let focus_kind = if let TokenType::Focus(k) = self.advance().kind {
8798 k
8799 } else {
8800 FocusKind::Only
8801 };
8802
8803 let event_var = self.get_event_var();
8804 let mut modifiers = self.collect_adverbs();
8805 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8806 match effective_time {
8807 Time::Past => modifiers.push(self.interner.intern("Past")),
8808 Time::Future => modifiers.push(self.interner.intern("Future")),
8809 _ => {}
8810 }
8811
8812 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8813
8814 if self.check_preposition() {
8815 let prep_token = self.advance().clone();
8816 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8817 sym
8818 } else {
8819 self.interner.intern("to")
8820 };
8821 let pp_obj = self.parse_noun_phrase(false)?;
8822 let pp_obj_term = Term::Constant(pp_obj.noun);
8823
8824 let roles = vec![(ThematicRole::Agent, subject_term_for_event)];
8825 let suppress_existential = self.drs.in_conditional_antecedent();
8826 if suppress_existential {
8827 let event_class = self.interner.intern("Event");
8828 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8829 }
8830 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8831 event_var,
8832 verb,
8833 roles: self.ctx.roles.alloc_slice(roles),
8834 modifiers: self.ctx.syms.alloc_slice(modifiers),
8835 suppress_existential,
8836 world: None,
8837 })));
8838
8839 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8840 name: prep_name,
8841 args: self.ctx.terms.alloc_slice([Term::Variable(event_var), pp_obj_term]),
8842 world: None,
8843 });
8844
8845 let with_pp = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8846 left: neo_event,
8847 op: TokenType::And,
8848 right: pp_pred,
8849 });
8850
8851 let focused_ref = self.ctx.terms.alloc(pp_obj_term);
8852 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8853 kind: focus_kind,
8854 focused: focused_ref,
8855 scope: with_pp,
8856 }));
8857 }
8858
8859 let focused_np = self.parse_noun_phrase(false)?;
8860 let focused_term = self.noun_phrase_to_term(&focused_np);
8861 args.push(focused_term.clone());
8862
8863 let roles = vec![
8864 (ThematicRole::Agent, subject_term_for_event),
8865 (ThematicRole::Theme, focused_term.clone()),
8866 ];
8867
8868 let suppress_existential = self.drs.in_conditional_antecedent();
8869 if suppress_existential {
8870 let event_class = self.interner.intern("Event");
8871 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8872 }
8873 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8874 event_var,
8875 verb,
8876 roles: self.ctx.roles.alloc_slice(roles),
8877 modifiers: self.ctx.syms.alloc_slice(modifiers),
8878 suppress_existential,
8879 world: None,
8880 })));
8881
8882 let focused_ref = self.ctx.terms.alloc(focused_term);
8883 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8884 kind: focus_kind,
8885 focused: focused_ref,
8886 scope: neo_event,
8887 }));
8888 } else if self.check_number() {
8889 let measure = self.parse_measure_phrase()?;
8891
8892 if self.check_content_word() {
8894 let noun_sym = self.consume_content_word()?;
8895 let count_term = *measure;
8897 object_term = Some(count_term.clone());
8898 args.push(count_term);
8899 second_object_term = Some(Term::Constant(noun_sym));
8900 args.push(Term::Constant(noun_sym));
8901 } else {
8902 object_term = Some(*measure);
8904 args.push(*measure);
8905 }
8906 } else if self.check_content_word() || self.check_article() {
8907 let object = self.parse_noun_phrase(false)?;
8908 if let Some(adj) = object.superlative {
8909 object_superlative = Some((adj, object.noun));
8910 }
8911
8912 let mut all_objects: Vec<Symbol> = vec![object.noun];
8914
8915 while self.check(&TokenType::And) {
8917 let saved = self.current;
8918 self.advance(); if self.check_content_word() || self.check_article() {
8920 let next_obj = match self.parse_noun_phrase(false) {
8921 Ok(np) => np,
8922 Err(_) => {
8923 self.current = saved;
8924 break;
8925 }
8926 };
8927 all_objects.push(next_obj.noun);
8928 } else {
8929 self.current = saved;
8930 break;
8931 }
8932 }
8933
8934 if self.check(&TokenType::Respectively) {
8936 let respectively_span = self.peek().span;
8937 if all_objects.len() > 1 {
8939 return Err(ParseError {
8940 kind: ParseErrorKind::RespectivelyLengthMismatch {
8941 subject_count: 1,
8942 object_count: all_objects.len(),
8943 },
8944 span: respectively_span,
8945 });
8946 }
8947 self.advance(); }
8950
8951 let term = self.noun_phrase_to_term(&object);
8953 object_term = Some(term.clone());
8954 args.push(term.clone());
8955
8956 if all_objects.len() > 1 {
8958 let obj_members: Vec<Term<'a>> = all_objects.iter()
8959 .map(|o| Term::Constant(*o))
8960 .collect();
8961 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
8962 args.pop();
8964 args.push(obj_group);
8965 }
8966
8967 if let TokenType::Particle(particle_sym) = self.peek().kind {
8969 let verb_str = self.interner.resolve(verb).to_lowercase();
8970 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8971 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8972 self.advance(); verb = self.interner.intern(phrasal_lemma);
8974 }
8975 }
8976
8977 if self.check_number() {
8979 let measure = self.parse_measure_phrase()?;
8980 second_object_term = Some(*measure);
8981 args.push(*measure);
8982 }
8983 else {
8985 let verb_str = self.interner.resolve(verb);
8986 if Lexer::is_ditransitive_verb(verb_str) && (self.check_content_word() || self.check_article()) {
8987 let second_np = self.parse_noun_phrase(false)?;
8988 let second_term = self.noun_phrase_to_term(&second_np);
8989 second_object_term = Some(second_term.clone());
8990 args.push(second_term);
8991 }
8992 }
8993 }
8994
8995 let mut pp_predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
8996 while self.check_preposition() || self.check_to() {
8997 let prep_token = self.advance().clone();
8998 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8999 sym
9000 } else if matches!(prep_token.kind, TokenType::To) {
9001 self.interner.intern("To")
9002 } else {
9003 continue;
9004 };
9005
9006 let pp_obj_term = if self.check(&TokenType::Reflexive) {
9007 self.advance();
9008 self.noun_phrase_to_term(&subject)
9009 } else if self.check_pronoun() {
9010 let token = self.advance().clone();
9011 if let TokenType::Pronoun { gender, number, .. } = token.kind {
9012 let resolved = self.resolve_pronoun(gender, number)?;
9013 match resolved {
9014 ResolvedPronoun::Variable(s) => Term::Variable(s),
9015 ResolvedPronoun::Constant(s) => Term::Constant(s),
9016 }
9017 } else {
9018 continue;
9019 }
9020 } else if self.check_content_word() || self.check_article() {
9021 let prep_obj = self.parse_noun_phrase(false)?;
9022 self.noun_phrase_to_term(&prep_obj)
9023 } else {
9024 continue;
9025 };
9026
9027 if self.pp_attach_to_noun {
9028 if let Some(ref obj) = object_term {
9029 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9031 name: prep_name,
9032 args: self.ctx.terms.alloc_slice([obj.clone(), pp_obj_term]),
9033 world: None,
9034 });
9035 pp_predicates.push(pp_pred);
9036 } else {
9037 args.push(pp_obj_term);
9038 }
9039 } else {
9040 let event_sym = self.get_event_var();
9042 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9043 name: prep_name,
9044 args: self.ctx.terms.alloc_slice([Term::Variable(event_sym), pp_obj_term]),
9045 world: None,
9046 });
9047 pp_predicates.push(pp_pred);
9048 }
9049 }
9050
9051 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
9053 self.advance();
9054 let rel_var = self.next_var_name();
9055 let rel_pred = self.parse_relative_clause(rel_var)?;
9056 pp_predicates.push(rel_pred);
9057 }
9058
9059 let mut modifiers = self.collect_adverbs();
9061
9062 let effective_time = self.pending_time.take().unwrap_or(verb_time);
9064 match effective_time {
9065 Time::Past => modifiers.push(self.interner.intern("Past")),
9066 Time::Future => modifiers.push(self.interner.intern("Future")),
9067 _ => {}
9068 }
9069
9070 if verb_aspect == Aspect::Progressive {
9072 modifiers.push(self.interner.intern("Progressive"));
9073 } else if verb_aspect == Aspect::Perfect {
9074 modifiers.push(self.interner.intern("Perfect"));
9075 }
9076
9077 let mut roles: Vec<(ThematicRole, Term<'a>)> = Vec::new();
9079
9080 let verb_str_for_check = self.interner.resolve(verb).to_lowercase();
9082 let is_unaccusative = crate::lexicon::lookup_verb_db(&verb_str_for_check)
9083 .map(|meta| meta.features.contains(&crate::lexicon::Feature::Unaccusative))
9084 .unwrap_or(false);
9085
9086 let has_object = object_term.is_some() || second_object_term.is_some();
9088 let subject_role = if is_unaccusative && !has_object {
9089 ThematicRole::Theme
9090 } else {
9091 ThematicRole::Agent
9092 };
9093
9094 roles.push((subject_role, subject_term));
9095 if let Some(second_obj) = second_object_term {
9096 if let Some(first_obj) = object_term {
9098 roles.push((ThematicRole::Recipient, first_obj));
9099 }
9100 roles.push((ThematicRole::Theme, second_obj));
9101 } else if let Some(obj) = object_term {
9102 roles.push((ThematicRole::Theme, obj));
9104 }
9105
9106 let event_var = self.get_event_var();
9108
9109 self.capture_event_template(verb, &roles, &modifiers);
9111
9112 let suppress_existential = self.drs.in_conditional_antecedent();
9114 if suppress_existential {
9115 let event_class = self.interner.intern("Event");
9116 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
9117 }
9118 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
9119 event_var,
9120 verb,
9121 roles: self.ctx.roles.alloc_slice(roles),
9122 modifiers: self.ctx.syms.alloc_slice(modifiers),
9123 suppress_existential,
9124 world: None,
9125 })));
9126
9127 let with_pps = if pp_predicates.is_empty() {
9129 neo_event
9130 } else {
9131 let mut combined = neo_event;
9132 for pp in pp_predicates {
9133 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9134 left: combined,
9135 op: TokenType::And,
9136 right: pp,
9137 });
9138 }
9139 combined
9140 };
9141
9142 let with_aspect = if verb_aspect == Aspect::Progressive {
9144 if verb_class == crate::lexicon::VerbClass::Semelfactive {
9146 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9147 operator: AspectOperator::Iterative,
9148 body: with_pps,
9149 })
9150 } else {
9151 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9153 operator: AspectOperator::Progressive,
9154 body: with_pps,
9155 })
9156 }
9157 } else if verb_aspect == Aspect::Perfect {
9158 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9159 operator: AspectOperator::Perfect,
9160 body: with_pps,
9161 })
9162 } else if effective_time == Time::Present && verb_aspect == Aspect::Simple {
9163 if !verb_class.is_stative() {
9165 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9166 operator: AspectOperator::Habitual,
9167 body: with_pps,
9168 })
9169 } else {
9170 with_pps
9172 }
9173 } else {
9174 with_pps
9175 };
9176
9177 let with_adverbs = with_aspect;
9178
9179 let with_temporal = if self.check_temporal_adverb() {
9181 let anchor = if let TokenType::TemporalAdverb(adv) = self.advance().kind.clone() {
9182 adv
9183 } else {
9184 panic!("Expected temporal adverb");
9185 };
9186 self.ctx.exprs.alloc(LogicExpr::TemporalAnchor {
9187 anchor,
9188 body: with_adverbs,
9189 })
9190 } else {
9191 with_adverbs
9192 };
9193
9194 let wrapped = self.wrap_with_definiteness_full(&subject, with_temporal)?;
9195
9196 if let Some((adj, noun)) = object_superlative {
9198 let superlative_expr = self.ctx.exprs.alloc(LogicExpr::Superlative {
9199 adjective: adj,
9200 subject: self.ctx.terms.alloc(Term::Constant(noun)),
9201 domain: noun,
9202 });
9203 return Ok(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9204 left: wrapped,
9205 op: TokenType::And,
9206 right: superlative_expr,
9207 }));
9208 }
9209
9210 return Ok(wrapped);
9211 }
9212
9213 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(subject.noun)))
9214 }
9215
9216 fn check_preposition(&self) -> bool {
9217 matches!(self.peek().kind, TokenType::Preposition(_))
9218 }
9219
9220 fn check_by_preposition(&self) -> bool {
9221 if let TokenType::Preposition(p) = self.peek().kind {
9222 p.is(self.interner, "by")
9223 } else {
9224 false
9225 }
9226 }
9227
9228 fn check_preposition_is(&self, word: &str) -> bool {
9229 if let TokenType::Preposition(p) = self.peek().kind {
9230 p.is(self.interner, word)
9231 } else {
9232 false
9233 }
9234 }
9235
9236 fn check_word(&self, word: &str) -> bool {
9238 let token = self.peek();
9239 let lexeme = self.interner.resolve(token.lexeme);
9240 lexeme.eq_ignore_ascii_case(word)
9241 }
9242
9243 fn peek_word_at(&self, offset: usize, word: &str) -> bool {
9244 if self.current + offset >= self.tokens.len() {
9245 return false;
9246 }
9247 let token = &self.tokens[self.current + offset];
9248 let lexeme = self.interner.resolve(token.lexeme);
9249 lexeme.eq_ignore_ascii_case(word)
9250 }
9251
9252 fn check_to_preposition(&self) -> bool {
9253 match self.peek().kind {
9254 TokenType::To => true,
9255 TokenType::Preposition(p) => p.is(self.interner, "to"),
9256 _ => false,
9257 }
9258 }
9259
9260 fn check_content_word(&self) -> bool {
9261 match &self.peek().kind {
9262 TokenType::Noun(_)
9263 | TokenType::Adjective(_)
9264 | TokenType::NonIntersectiveAdjective(_)
9265 | TokenType::Verb { .. }
9266 | TokenType::ProperName(_)
9267 | TokenType::Article(_) => true,
9268 TokenType::Ambiguous { primary, alternatives } => {
9269 Self::is_content_word_type(primary)
9270 || alternatives.iter().any(Self::is_content_word_type)
9271 }
9272 _ => false,
9273 }
9274 }
9275
9276 fn is_content_word_type(t: &TokenType) -> bool {
9277 matches!(
9278 t,
9279 TokenType::Noun(_)
9280 | TokenType::Adjective(_)
9281 | TokenType::NonIntersectiveAdjective(_)
9282 | TokenType::Verb { .. }
9283 | TokenType::ProperName(_)
9284 | TokenType::Article(_)
9285 )
9286 }
9287
9288 fn check_verb(&self) -> bool {
9289 match &self.peek().kind {
9290 TokenType::Verb { .. } => true,
9291 TokenType::Ambiguous { primary, alternatives } => {
9292 if self.noun_priority_mode {
9293 return false;
9294 }
9295 matches!(**primary, TokenType::Verb { .. })
9296 || alternatives.iter().any(|t| matches!(t, TokenType::Verb { .. }))
9297 }
9298 _ => false,
9299 }
9300 }
9301
9302 fn check_adverb(&self) -> bool {
9303 matches!(self.peek().kind, TokenType::Adverb(_))
9304 }
9305
9306 fn check_performative(&self) -> bool {
9307 matches!(self.peek().kind, TokenType::Performative(_))
9308 }
9309
9310 fn collect_adverbs(&mut self) -> Vec<Symbol> {
9311 let mut adverbs = Vec::new();
9312 while self.check_adverb() {
9313 if let TokenType::Adverb(adv) = self.advance().kind.clone() {
9314 adverbs.push(adv);
9315 }
9316 if self.check(&TokenType::And) {
9318 self.advance();
9319 }
9320 }
9321 adverbs
9322 }
9323
9324 fn check_auxiliary(&self) -> bool {
9325 matches!(self.peek().kind, TokenType::Auxiliary(_))
9326 }
9327
9328 fn is_true_auxiliary_usage(&self) -> bool {
9335 if self.current + 1 >= self.tokens.len() {
9336 return false;
9337 }
9338
9339 let next_token = &self.tokens[self.current + 1].kind;
9340
9341 if matches!(next_token, TokenType::Not) {
9343 return true;
9344 }
9345
9346 if matches!(next_token, TokenType::Verb { .. }) {
9348 return true;
9349 }
9350
9351 if matches!(
9353 next_token,
9354 TokenType::Pronoun { .. }
9355 | TokenType::Article(_)
9356 | TokenType::Noun(_)
9357 | TokenType::ProperName(_)
9358 ) {
9359 return false;
9360 }
9361
9362 true
9364 }
9365
9366 fn check_auxiliary_as_main_verb(&self) -> bool {
9369 if let TokenType::Auxiliary(Time::Past) = self.peek().kind {
9370 if self.current + 1 < self.tokens.len() {
9372 let next = &self.tokens[self.current + 1].kind;
9373 matches!(
9374 next,
9375 TokenType::Pronoun { .. }
9376 | TokenType::Article(_)
9377 | TokenType::Noun(_)
9378 | TokenType::ProperName(_)
9379 )
9380 } else {
9381 false
9382 }
9383 } else {
9384 false
9385 }
9386 }
9387
9388 fn parse_do_as_main_verb(&mut self, subject_term: Term<'a>) -> ParseResult<&'a LogicExpr<'a>> {
9391 let aux_token = self.advance();
9393 let verb_time = if let TokenType::Auxiliary(time) = aux_token.kind {
9394 time
9395 } else {
9396 Time::Past
9397 };
9398
9399 let verb = self.interner.intern("Do");
9401
9402 let object_term = if let TokenType::Pronoun { .. } = self.peek().kind {
9404 self.advance();
9406 let it_sym = self.interner.intern("it");
9409 Term::Constant(it_sym)
9410 } else {
9411 let object = self.parse_noun_phrase(false)?;
9412 self.noun_phrase_to_term(&object)
9413 };
9414
9415 let event_var = self.get_event_var();
9417 let suppress_existential = self.drs.in_conditional_antecedent();
9418
9419 let mut modifiers = Vec::new();
9420 if verb_time == Time::Past {
9421 modifiers.push(self.interner.intern("Past"));
9422 } else if verb_time == Time::Future {
9423 modifiers.push(self.interner.intern("Future"));
9424 }
9425
9426 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
9427 event_var,
9428 verb,
9429 roles: self.ctx.roles.alloc_slice(vec![
9430 (ThematicRole::Agent, subject_term),
9431 (ThematicRole::Theme, object_term),
9432 ]),
9433 modifiers: self.ctx.syms.alloc_slice(modifiers),
9434 suppress_existential,
9435 world: None,
9436 })));
9437
9438 Ok(neo_event)
9439 }
9440
9441 fn check_to(&self) -> bool {
9442 matches!(self.peek().kind, TokenType::To)
9443 }
9444
9445 fn has_modal_subordination_ahead(&self) -> bool {
9449 for i in self.current..self.tokens.len() {
9452 match &self.tokens[i].kind {
9453 TokenType::Would | TokenType::Could | TokenType::Should | TokenType::Might => {
9454 return true;
9455 }
9456 TokenType::Period | TokenType::EOF => break,
9458 _ => {}
9459 }
9460 }
9461 false
9462 }
9463
9464 fn consume_verb(&mut self) -> Symbol {
9465 let t = self.advance().clone();
9466 match t.kind {
9467 TokenType::Verb { lemma, .. } => lemma,
9468 TokenType::Ambiguous { primary, .. } => match *primary {
9469 TokenType::Verb { lemma, .. } => lemma,
9470 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
9471 },
9472 _ => panic!("Expected verb, got {:?}", t.kind),
9473 }
9474 }
9475
9476 fn consume_verb_with_metadata(&mut self) -> (Symbol, Time, Aspect, VerbClass) {
9477 let t = self.advance().clone();
9478 match t.kind {
9479 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
9480 TokenType::Ambiguous { primary, .. } => match *primary {
9481 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
9482 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
9483 },
9484 _ => panic!("Expected verb, got {:?}", t.kind),
9485 }
9486 }
9487
9488 fn match_token(&mut self, types: &[TokenType]) -> bool {
9489 for t in types {
9490 if self.check(t) {
9491 self.advance();
9492 return true;
9493 }
9494 }
9495 false
9496 }
9497
9498 fn check_quantifier(&self) -> bool {
9499 matches!(
9500 self.peek().kind,
9501 TokenType::All
9502 | TokenType::No
9503 | TokenType::Some
9504 | TokenType::Any
9505 | TokenType::Most
9506 | TokenType::Few
9507 | TokenType::Many
9508 | TokenType::Cardinal(_)
9509 | TokenType::AtLeast(_)
9510 | TokenType::AtMost(_)
9511 )
9512 }
9513
9514 fn check_npi_quantifier(&self) -> bool {
9515 matches!(
9516 self.peek().kind,
9517 TokenType::Nobody | TokenType::Nothing | TokenType::NoOne
9518 )
9519 }
9520
9521 fn check_npi_object(&self) -> bool {
9522 matches!(
9523 self.peek().kind,
9524 TokenType::Anything | TokenType::Anyone
9525 )
9526 }
9527
9528 fn check_temporal_npi(&self) -> bool {
9529 matches!(
9530 self.peek().kind,
9531 TokenType::Ever | TokenType::Never
9532 )
9533 }
9534
9535 fn parse_npi_quantified(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9536 let npi_token = self.advance().kind.clone();
9537 let var_name = self.next_var_name();
9538
9539 let (restriction_name, is_person) = match npi_token {
9540 TokenType::Nobody | TokenType::NoOne => ("Person", true),
9541 TokenType::Nothing => ("Thing", false),
9542 _ => ("Thing", false),
9543 };
9544
9545 let restriction_sym = self.interner.intern(restriction_name);
9546 let subject_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9547 name: restriction_sym,
9548 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9549 world: None,
9550 });
9551
9552 self.negative_depth += 1;
9553
9554 let verb = self.consume_verb();
9555
9556 if self.check_npi_object() {
9557 let obj_npi_token = self.advance().kind.clone();
9558 let obj_var = self.next_var_name();
9559
9560 let obj_restriction_name = match obj_npi_token {
9561 TokenType::Anything => "Thing",
9562 TokenType::Anyone => "Person",
9563 _ => "Thing",
9564 };
9565
9566 let obj_restriction_sym = self.interner.intern(obj_restriction_name);
9567 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
9568 name: obj_restriction_sym,
9569 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
9570 world: None,
9571 });
9572
9573 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9574 name: verb,
9575 args: self.ctx.terms.alloc_slice([Term::Variable(var_name), Term::Variable(obj_var)]),
9576 world: None,
9577 });
9578
9579 let verb_and_obj = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9580 left: obj_restriction,
9581 op: TokenType::And,
9582 right: verb_pred,
9583 });
9584
9585 let inner_existential = self.ctx.exprs.alloc(LogicExpr::Quantifier {
9586 kind: crate::ast::QuantifierKind::Existential,
9587 variable: obj_var,
9588 body: verb_and_obj,
9589 island_id: self.current_island,
9590 });
9591
9592 self.negative_depth -= 1;
9593
9594 let negated = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9595 op: TokenType::Not,
9596 operand: inner_existential,
9597 });
9598
9599 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9600 left: subject_pred,
9601 op: TokenType::Implies,
9602 right: negated,
9603 });
9604
9605 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9606 kind: crate::ast::QuantifierKind::Universal,
9607 variable: var_name,
9608 body,
9609 island_id: self.current_island,
9610 }));
9611 }
9612
9613 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9614 name: verb,
9615 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9616 world: None,
9617 });
9618
9619 self.negative_depth -= 1;
9620
9621 let negated_verb = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9622 op: TokenType::Not,
9623 operand: verb_pred,
9624 });
9625
9626 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9627 left: subject_pred,
9628 op: TokenType::Implies,
9629 right: negated_verb,
9630 });
9631
9632 Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9633 kind: crate::ast::QuantifierKind::Universal,
9634 variable: var_name,
9635 body,
9636 island_id: self.current_island,
9637 }))
9638 }
9639
9640 fn parse_temporal_npi(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9641 let npi_token = self.advance().kind.clone();
9642 let is_never = matches!(npi_token, TokenType::Never);
9643
9644 let subject = self.parse_noun_phrase(true)?;
9645
9646 if is_never {
9647 self.negative_depth += 1;
9648 }
9649
9650 let verb = self.consume_verb();
9651 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9652 name: verb,
9653 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
9654 world: None,
9655 });
9656
9657 if is_never {
9658 self.negative_depth -= 1;
9659 Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9660 op: TokenType::Not,
9661 operand: verb_pred,
9662 }))
9663 } else {
9664 Ok(verb_pred)
9665 }
9666 }
9667
9668 fn check(&self, kind: &TokenType) -> bool {
9669 if self.is_at_end() {
9670 return false;
9671 }
9672 std::mem::discriminant(&self.peek().kind) == std::mem::discriminant(kind)
9673 }
9674
9675 fn check_any(&self, kinds: &[TokenType]) -> bool {
9676 if self.is_at_end() {
9677 return false;
9678 }
9679 let current = std::mem::discriminant(&self.peek().kind);
9680 kinds.iter().any(|k| std::mem::discriminant(k) == current)
9681 }
9682
9683 fn check_article(&self) -> bool {
9684 matches!(self.peek().kind, TokenType::Article(_))
9685 }
9686
9687 fn advance(&mut self) -> &Token {
9688 if !self.is_at_end() {
9689 self.current += 1;
9690 }
9691 self.previous()
9692 }
9693
9694 fn is_at_end(&self) -> bool {
9695 self.peek().kind == TokenType::EOF
9696 }
9697
9698 fn peek(&self) -> &Token {
9699 &self.tokens[self.current]
9700 }
9701
9702 fn peek_next_is_string_literal(&self) -> bool {
9705 self.tokens.get(self.current + 1)
9706 .map(|t| matches!(t.kind, TokenType::StringLiteral(_)))
9707 .unwrap_or(false)
9708 }
9709
9710 fn previous(&self) -> &Token {
9711 &self.tokens[self.current - 1]
9712 }
9713
9714 fn current_span(&self) -> crate::token::Span {
9715 self.peek().span
9716 }
9717
9718 fn consume(&mut self, kind: TokenType) -> ParseResult<&Token> {
9719 if self.check(&kind) {
9720 Ok(self.advance())
9721 } else {
9722 Err(ParseError {
9723 kind: ParseErrorKind::UnexpectedToken {
9724 expected: kind,
9725 found: self.peek().kind.clone(),
9726 },
9727 span: self.current_span(),
9728 })
9729 }
9730 }
9731
9732 fn consume_content_word(&mut self) -> ParseResult<Symbol> {
9733 let t = self.advance().clone();
9734 match t.kind {
9735 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9736 TokenType::Article(_) => Ok(t.lexeme),
9738 TokenType::Number(s) => Ok(s),
9740 TokenType::ProperName(s) => {
9741 if self.mode == ParserMode::Imperative {
9743 if !self.drs.has_referent_by_variable(s) {
9744 return Err(ParseError {
9745 kind: ParseErrorKind::UndefinedVariable {
9746 name: self.interner.resolve(s).to_string()
9747 },
9748 span: t.span,
9749 });
9750 }
9751 return Ok(s);
9752 }
9753
9754 let s_str = self.interner.resolve(s);
9756 let gender = Self::infer_gender(s_str);
9757
9758 self.drs.introduce_proper_name(s, s, gender);
9760
9761 Ok(s)
9762 }
9763 TokenType::Verb { lemma, .. } => Ok(lemma),
9764 TokenType::Ambiguous { primary, .. } => {
9765 match *primary {
9766 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9767 TokenType::Verb { lemma, .. } => Ok(lemma),
9768 TokenType::ProperName(s) => {
9769 if self.mode == ParserMode::Imperative {
9771 if !self.drs.has_referent_by_variable(s) {
9772 return Err(ParseError {
9773 kind: ParseErrorKind::UndefinedVariable {
9774 name: self.interner.resolve(s).to_string()
9775 },
9776 span: t.span,
9777 });
9778 }
9779 return Ok(s);
9780 }
9781 let s_str = self.interner.resolve(s);
9783 let gender = Self::infer_gender(s_str);
9784 self.drs.introduce_proper_name(s, s, gender);
9785 Ok(s)
9786 }
9787 _ => Err(ParseError {
9788 kind: ParseErrorKind::ExpectedContentWord { found: *primary },
9789 span: self.current_span(),
9790 }),
9791 }
9792 }
9793 other => Err(ParseError {
9794 kind: ParseErrorKind::ExpectedContentWord { found: other },
9795 span: self.current_span(),
9796 }),
9797 }
9798 }
9799
9800 fn consume_copula(&mut self) -> ParseResult<()> {
9801 if self.match_token(&[TokenType::Is, TokenType::Are, TokenType::Was, TokenType::Were]) {
9802 Ok(())
9803 } else {
9804 Err(ParseError {
9805 kind: ParseErrorKind::ExpectedCopula,
9806 span: self.current_span(),
9807 })
9808 }
9809 }
9810
9811 fn check_comparative(&self) -> bool {
9812 matches!(self.peek().kind, TokenType::Comparative(_))
9813 }
9814
9815 fn is_contact_clause_pattern(&self) -> bool {
9816 let mut pos = self.current;
9819
9820 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Article(_)) {
9822 pos += 1;
9823 } else {
9824 return false;
9825 }
9826
9827 while pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Adjective(_)) {
9829 pos += 1;
9830 }
9831
9832 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Adjective(_)) {
9834 pos += 1;
9835 } else {
9836 return false;
9837 }
9838
9839 pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Verb { .. } | TokenType::Article(_))
9841 }
9842
9843 fn check_superlative(&self) -> bool {
9844 matches!(self.peek().kind, TokenType::Superlative(_))
9845 }
9846
9847 fn check_scopal_adverb(&self) -> bool {
9848 matches!(self.peek().kind, TokenType::ScopalAdverb(_))
9849 }
9850
9851 fn check_temporal_adverb(&self) -> bool {
9852 matches!(self.peek().kind, TokenType::TemporalAdverb(_))
9853 }
9854
9855 fn check_non_intersective_adjective(&self) -> bool {
9856 matches!(self.peek().kind, TokenType::NonIntersectiveAdjective(_))
9857 }
9858
9859 fn check_focus(&self) -> bool {
9860 matches!(self.peek().kind, TokenType::Focus(_))
9861 }
9862
9863 fn check_measure(&self) -> bool {
9864 matches!(self.peek().kind, TokenType::Measure(_))
9865 }
9866
9867 fn check_presup_trigger(&self) -> bool {
9868 match &self.peek().kind {
9869 TokenType::PresupTrigger(_) => true,
9870 TokenType::Verb { lemma, .. } => {
9871 let s = self.interner.resolve(*lemma).to_lowercase();
9872 crate::lexicon::lookup_presup_trigger(&s).is_some()
9873 }
9874 _ => false,
9875 }
9876 }
9877
9878 fn is_followed_by_np_object(&self) -> bool {
9879 if self.current + 1 >= self.tokens.len() {
9880 return false;
9881 }
9882 let next = &self.tokens[self.current + 1].kind;
9883 matches!(next,
9884 TokenType::ProperName(_) |
9885 TokenType::Article(_) |
9886 TokenType::Noun(_) |
9887 TokenType::Pronoun { .. } |
9888 TokenType::Reflexive |
9889 TokenType::Who |
9890 TokenType::What |
9891 TokenType::Where |
9892 TokenType::When |
9893 TokenType::Why
9894 )
9895 }
9896
9897 fn is_followed_by_gerund(&self) -> bool {
9898 if self.current + 1 >= self.tokens.len() {
9899 return false;
9900 }
9901 matches!(self.tokens[self.current + 1].kind, TokenType::Verb { .. })
9902 }
9903
9904 fn parse_spawn_statement(&mut self) -> ParseResult<Stmt<'a>> {
9910 self.advance(); if !self.check_article() {
9914 return Err(ParseError {
9915 kind: ParseErrorKind::ExpectedKeyword { keyword: "a/an".to_string() },
9916 span: self.current_span(),
9917 });
9918 }
9919 self.advance(); let agent_type = match &self.tokens[self.current].kind {
9923 TokenType::Noun(sym) | TokenType::ProperName(sym) => {
9924 let s = *sym;
9925 self.advance();
9926 s
9927 }
9928 _ => {
9929 return Err(ParseError {
9930 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent type".to_string() },
9931 span: self.current_span(),
9932 });
9933 }
9934 };
9935
9936 if !self.check(&TokenType::Called) {
9938 return Err(ParseError {
9939 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
9940 span: self.current_span(),
9941 });
9942 }
9943 self.advance(); let name = if let TokenType::StringLiteral(sym) = &self.tokens[self.current].kind {
9947 let s = *sym;
9948 self.advance();
9949 s
9950 } else {
9951 return Err(ParseError {
9952 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent name".to_string() },
9953 span: self.current_span(),
9954 });
9955 };
9956
9957 Ok(Stmt::Spawn { agent_type, name })
9958 }
9959
9960 fn parse_send_statement(&mut self) -> ParseResult<Stmt<'a>> {
9962 self.advance(); let message = self.parse_imperative_expr()?;
9966
9967 if !self.check_preposition_is("to") {
9969 return Err(ParseError {
9970 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9971 span: self.current_span(),
9972 });
9973 }
9974 self.advance(); let destination = self.parse_imperative_expr()?;
9978
9979 Ok(Stmt::SendMessage { message, destination })
9980 }
9981
9982 fn parse_await_statement(&mut self) -> ParseResult<Stmt<'a>> {
9984 self.advance(); if self.check_word("response") {
9988 self.advance();
9989 }
9990
9991 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
9993 return Err(ParseError {
9994 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
9995 span: self.current_span(),
9996 });
9997 }
9998 self.advance(); let source = self.parse_imperative_expr()?;
10002
10003 if !self.check_word("into") {
10005 return Err(ParseError {
10006 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
10007 span: self.current_span(),
10008 });
10009 }
10010 self.advance(); let into = match &self.tokens[self.current].kind {
10014 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
10015 let s = *sym;
10016 self.advance();
10017 s
10018 }
10019 _ if self.check_content_word() => {
10021 let sym = self.tokens[self.current].lexeme;
10022 self.advance();
10023 sym
10024 }
10025 _ => {
10026 return Err(ParseError {
10027 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
10028 span: self.current_span(),
10029 });
10030 }
10031 };
10032
10033 Ok(Stmt::AwaitMessage { source, into })
10034 }
10035
10036 fn parse_merge_statement(&mut self) -> ParseResult<Stmt<'a>> {
10042 self.advance(); let source = self.parse_imperative_expr()?;
10046
10047 if !self.check_word("into") {
10049 return Err(ParseError {
10050 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
10051 span: self.current_span(),
10052 });
10053 }
10054 self.advance(); let target = self.parse_imperative_expr()?;
10058
10059 Ok(Stmt::MergeCrdt { source, target })
10060 }
10061
10062 fn parse_increase_statement(&mut self) -> ParseResult<Stmt<'a>> {
10064 self.advance(); let expr = self.parse_imperative_expr()?;
10068
10069 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
10071 (object, field)
10072 } else {
10073 return Err(ParseError {
10074 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
10075 span: self.current_span(),
10076 });
10077 };
10078
10079 if !self.check_preposition_is("by") {
10081 return Err(ParseError {
10082 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
10083 span: self.current_span(),
10084 });
10085 }
10086 self.advance(); let amount = self.parse_imperative_expr()?;
10090
10091 Ok(Stmt::IncreaseCrdt { object, field: *field, amount })
10092 }
10093
10094 fn parse_decrease_statement(&mut self) -> ParseResult<Stmt<'a>> {
10096 self.advance(); let expr = self.parse_imperative_expr()?;
10100
10101 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
10103 (object, field)
10104 } else {
10105 return Err(ParseError {
10106 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
10107 span: self.current_span(),
10108 });
10109 };
10110
10111 if !self.check_preposition_is("by") {
10113 return Err(ParseError {
10114 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
10115 span: self.current_span(),
10116 });
10117 }
10118 self.advance(); let amount = self.parse_imperative_expr()?;
10122
10123 Ok(Stmt::DecreaseCrdt { object, field: *field, amount })
10124 }
10125
10126 fn parse_append_statement(&mut self) -> ParseResult<Stmt<'a>> {
10128 self.advance(); let value = self.parse_imperative_expr()?;
10132
10133 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
10135 return Err(ParseError {
10136 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
10137 span: self.current_span(),
10138 });
10139 }
10140 self.advance(); let sequence = self.parse_imperative_expr()?;
10144
10145 Ok(Stmt::AppendToSequence { sequence, value })
10146 }
10147
10148 fn parse_resolve_statement(&mut self) -> ParseResult<Stmt<'a>> {
10150 self.advance(); let expr = self.parse_imperative_expr()?;
10154
10155 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
10157 (object, field)
10158 } else {
10159 return Err(ParseError {
10160 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's title')".to_string() },
10161 span: self.current_span(),
10162 });
10163 };
10164
10165 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
10167 return Err(ParseError {
10168 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
10169 span: self.current_span(),
10170 });
10171 }
10172 self.advance(); let value = self.parse_imperative_expr()?;
10176
10177 Ok(Stmt::ResolveConflict { object, field: *field, value })
10178 }
10179
10180}
10181