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};
77use crate::ast::stmt::{ReadSource, Pattern};
78use crate::drs::{Case, Gender, Number, ReferentSource};
79use crate::drs::{Drs, BoxType, WorldState};
80use crate::error::{ParseError, ParseErrorKind};
81use logicaffeine_base::{Interner, Symbol, SymbolEq};
82use crate::lexer::Lexer;
83use crate::lexicon::{self, Aspect, Definiteness, Time, VerbClass};
84use crate::token::{BlockType, FocusKind, Token, TokenType};
85
86pub(super) type ParseResult<T> = Result<T, ParseError>;
87
88use std::ops::{Deref, DerefMut};
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
92pub enum ParserMode {
93 #[default]
95 Declarative,
96 Imperative,
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
105pub enum NegativeScopeMode {
106 #[default]
109 Narrow,
110 Wide,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
123pub enum ModalPreference {
124 #[default]
126 Default,
127 Epistemic,
129 Deontic,
131}
132
133#[derive(Debug, Clone, Copy)]
138pub enum ResolvedPronoun {
139 Variable(Symbol),
141 Constant(Symbol),
143}
144
145#[derive(Clone)]
146struct ParserCheckpoint {
147 pos: usize,
148 var_counter: usize,
149 bindings_len: usize,
150 island: u32,
151 time: Option<Time>,
152 negative_depth: u32,
153}
154
155pub struct ParserGuard<'p, 'a, 'ctx, 'int> {
188 parser: &'p mut Parser<'a, 'ctx, 'int>,
189 checkpoint: ParserCheckpoint,
190 committed: bool,
191}
192
193impl<'p, 'a, 'ctx, 'int> ParserGuard<'p, 'a, 'ctx, 'int> {
194 pub fn commit(mut self) {
196 self.committed = true;
197 }
198}
199
200impl<'p, 'a, 'ctx, 'int> Drop for ParserGuard<'p, 'a, 'ctx, 'int> {
201 fn drop(&mut self) {
202 if !self.committed {
203 self.parser.restore(self.checkpoint.clone());
204 }
205 }
206}
207
208impl<'p, 'a, 'ctx, 'int> Deref for ParserGuard<'p, 'a, 'ctx, 'int> {
209 type Target = Parser<'a, 'ctx, 'int>;
210 fn deref(&self) -> &Self::Target {
211 self.parser
212 }
213}
214
215impl<'p, 'a, 'ctx, 'int> DerefMut for ParserGuard<'p, 'a, 'ctx, 'int> {
216 fn deref_mut(&mut self) -> &mut Self::Target {
217 self.parser
218 }
219}
220
221#[derive(Clone, Debug)]
226pub struct EventTemplate<'a> {
227 pub verb: Symbol,
229 pub non_agent_roles: Vec<(ThematicRole, Term<'a>)>,
231 pub modifiers: Vec<Symbol>,
233}
234
235pub struct Parser<'a, 'ctx, 'int> {
252 pub(super) tokens: Vec<Token>,
254 pub(super) current: usize,
256 pub(super) var_counter: usize,
258 pub(super) pending_time: Option<Time>,
260 pub(super) donkey_bindings: Vec<(Symbol, Symbol, bool, bool)>,
262 pub(super) interner: &'int mut Interner,
264 pub(super) ctx: AstContext<'a>,
266 pub(super) current_island: u32,
268 pub(super) pp_attach_to_noun: bool,
270 pub(super) filler_gap: Option<Symbol>,
272 pub(super) negative_depth: u32,
274 pub(super) discourse_event_var: Option<Symbol>,
276 pub(super) last_event_template: Option<EventTemplate<'a>>,
278 pub(super) noun_priority_mode: bool,
280 pub(super) collective_mode: bool,
282 pub(super) pending_cardinal: Option<u32>,
284 pub(super) mode: ParserMode,
286 pub(super) type_registry: Option<TypeRegistry>,
288 pub(super) event_reading_mode: bool,
290 pub(super) drs: Drs,
292 pub(super) negative_scope_mode: NegativeScopeMode,
294 pub(super) modal_preference: ModalPreference,
296 pub(super) world_state: &'ctx mut WorldState,
298 pub(super) in_negative_quantifier: bool,
300}
301
302impl<'a, 'ctx, 'int> Parser<'a, 'ctx, 'int> {
303 pub fn new(
307 tokens: Vec<Token>,
308 world_state: &'ctx mut WorldState,
309 interner: &'int mut Interner,
310 ctx: AstContext<'a>,
311 types: TypeRegistry,
312 ) -> Self {
313 Parser {
314 tokens,
315 current: 0,
316 var_counter: 0,
317 pending_time: None,
318 donkey_bindings: Vec::new(),
319 interner,
320 ctx,
321 current_island: 0,
322 pp_attach_to_noun: false,
323 filler_gap: None,
324 negative_depth: 0,
325 discourse_event_var: None,
326 last_event_template: None,
327 noun_priority_mode: false,
328 collective_mode: false,
329 pending_cardinal: None,
330 mode: ParserMode::Declarative,
331 type_registry: Some(types),
332 event_reading_mode: false,
333 drs: Drs::new(), negative_scope_mode: NegativeScopeMode::default(),
335 modal_preference: ModalPreference::default(),
336 world_state,
337 in_negative_quantifier: false,
338 }
339 }
340
341 pub fn set_discourse_event_var(&mut self, var: Symbol) {
342 self.discourse_event_var = Some(var);
343 }
344
345 pub fn drs_mut(&mut self) -> &mut Drs {
347 &mut self.world_state.drs
348 }
349
350 pub fn drs_ref(&self) -> &Drs {
352 &self.world_state.drs
353 }
354
355 pub fn swap_drs_with_world_state(&mut self) {
359 std::mem::swap(&mut self.drs, &mut self.world_state.drs);
360 }
361
362 pub fn has_world_state(&self) -> bool {
364 true
365 }
366
367 pub fn mode(&self) -> ParserMode {
368 self.mode
369 }
370
371 pub fn is_known_type(&self, sym: Symbol) -> bool {
374 self.type_registry
375 .as_ref()
376 .map(|r| r.is_type(sym))
377 .unwrap_or(false)
378 }
379
380 pub fn is_generic_type(&self, sym: Symbol) -> bool {
383 self.type_registry
384 .as_ref()
385 .map(|r| r.is_generic(sym))
386 .unwrap_or(false)
387 }
388
389 fn get_generic_param_count(&self, sym: Symbol) -> Option<usize> {
391 use crate::analysis::TypeDef;
392 self.type_registry.as_ref().and_then(|r| {
393 match r.get(sym) {
394 Some(TypeDef::Generic { param_count }) => Some(*param_count),
395 _ => None,
396 }
397 })
398 }
399
400 fn find_variant(&self, sym: Symbol) -> Option<Symbol> {
402 self.type_registry
403 .as_ref()
404 .and_then(|r| r.find_variant(sym).map(|(enum_name, _)| enum_name))
405 }
406
407 fn consume_type_name(&mut self) -> ParseResult<Symbol> {
409 let t = self.advance().clone();
410 match t.kind {
411 TokenType::Noun(s) | TokenType::Adjective(s) => Ok(s),
412 TokenType::ProperName(s) => Ok(s),
413 TokenType::Verb { .. } => Ok(t.lexeme),
415 TokenType::Tally => Ok(self.interner.intern("Tally")),
417 TokenType::SharedSet => Ok(self.interner.intern("SharedSet")),
418 TokenType::SharedSequence => Ok(self.interner.intern("SharedSequence")),
419 TokenType::CollaborativeSequence => Ok(self.interner.intern("CollaborativeSequence")),
420 TokenType::SharedMap => Ok(self.interner.intern("SharedMap")),
421 TokenType::Divergent => Ok(self.interner.intern("Divergent")),
422 other => Err(ParseError {
423 kind: ParseErrorKind::ExpectedContentWord { found: other },
424 span: self.current_span(),
425 }),
426 }
427 }
428
429 fn parse_type_expression(&mut self) -> ParseResult<TypeExpr<'a>> {
433 use noun::NounParsing;
434
435 if self.check(&TokenType::LParen) {
437 self.advance(); let inner = self.parse_type_expression()?;
439 if !self.check(&TokenType::RParen) {
440 return Err(ParseError {
441 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
442 span: self.current_span(),
443 });
444 }
445 self.advance(); return Ok(inner);
447 }
448
449 if self.check(&TokenType::Persistent) {
451 self.advance(); let inner = self.parse_type_expression()?;
453 let inner_ref = self.ctx.alloc_type_expr(inner);
454 return Ok(TypeExpr::Persistent { inner: inner_ref });
455 }
456
457 let mut base = self.consume_type_name()?;
459
460 let base_name = self.interner.resolve(base);
462 if base_name == "SharedSet" || base_name == "ORSet" {
463 if self.check(&TokenType::LParen) {
464 self.advance(); if self.check(&TokenType::RemoveWins) {
466 self.advance(); base = self.interner.intern("SharedSet_RemoveWins");
468 } else if self.check(&TokenType::AddWins) {
469 self.advance(); base = self.interner.intern("SharedSet_AddWins");
472 }
473 if !self.check(&TokenType::RParen) {
474 return Err(ParseError {
475 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
476 span: self.current_span(),
477 });
478 }
479 self.advance(); }
481 }
482
483 let base_name = self.interner.resolve(base);
485 if base_name == "SharedSequence" || base_name == "RGA" {
486 if self.check(&TokenType::LParen) {
487 self.advance(); if self.check(&TokenType::YATA) {
489 self.advance(); base = self.interner.intern("SharedSequence_YATA");
491 }
492 if !self.check(&TokenType::RParen) {
493 return Err(ParseError {
494 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
495 span: self.current_span(),
496 });
497 }
498 self.advance(); }
500 }
501
502 let base_type = if self.check(&TokenType::From) {
504 self.advance(); let module_name = self.consume_type_name()?;
506 let module_str = self.interner.resolve(module_name);
507 let base_str = self.interner.resolve(base);
508 let qualified = format!("{}::{}", module_str, base_str);
509 let qualified_sym = self.interner.intern(&qualified);
510 TypeExpr::Named(qualified_sym)
511 } else {
512 let base_name = self.interner.resolve(base);
514 let param_count = self.get_generic_param_count(base)
515 .or_else(|| match base_name {
516 "Result" => Some(2), "Option" => 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),
526 "SharedSequence" | "RGA" | "SharedSequence_YATA" | "CollaborativeSequence" => Some(1),
527 "SharedMap" | "ORMap" => Some(2), "Divergent" | "MVRegister" => Some(1), _ => None,
530 });
531
532 if let Some(count) = param_count {
534 if self.check_of_preposition() || self.check_preposition_is("from") {
535 self.advance(); let mut params = Vec::new();
538 for i in 0..count {
539 if i > 0 {
540 if self.check(&TokenType::And) || self.check_to_preposition() || self.check(&TokenType::Comma) {
542 self.advance();
543 }
544 }
545 let param = self.parse_type_expression()?;
546 params.push(param);
547 }
548
549 let params_slice = self.ctx.alloc_type_exprs(params);
550 TypeExpr::Generic { base, params: params_slice }
551 } else {
552 let is_primitive = self.type_registry.as_ref().map(|r| r.is_type(base)).unwrap_or(false)
554 || matches!(base_name, "Int" | "Nat" | "Text" | "Bool" | "Boolean" | "Real" | "Unit");
555 if is_primitive {
556 TypeExpr::Primitive(base)
557 } else {
558 TypeExpr::Named(base)
559 }
560 }
561 } else {
562 let is_primitive = self.type_registry.as_ref().map(|r| r.is_type(base)).unwrap_or(false)
564 || matches!(base_name, "Int" | "Nat" | "Text" | "Bool" | "Boolean" | "Real" | "Unit");
565 if is_primitive {
566 TypeExpr::Primitive(base)
567 } else {
568 TypeExpr::Named(base)
570 }
571 }
572 };
573
574 if self.check(&TokenType::Where) {
576 self.advance(); let predicate_expr = self.parse_condition()?;
580
581 let bound_var = self.extract_bound_var(&predicate_expr)
583 .unwrap_or_else(|| self.interner.intern("it"));
584
585 let predicate = self.expr_to_logic_predicate(&predicate_expr, bound_var)
587 .ok_or_else(|| ParseError {
588 kind: ParseErrorKind::InvalidRefinementPredicate,
589 span: self.peek().span,
590 })?;
591
592 let base_alloc = self.ctx.alloc_type_expr(base_type);
594
595 return Ok(TypeExpr::Refinement { base: base_alloc, var: bound_var, predicate });
596 }
597
598 Ok(base_type)
599 }
600
601 fn extract_bound_var(&self, expr: &Expr<'a>) -> Option<Symbol> {
603 match expr {
604 Expr::Identifier(sym) => Some(*sym),
605 Expr::BinaryOp { left, .. } => self.extract_bound_var(left),
606 _ => None,
607 }
608 }
609
610 fn expr_to_logic_predicate(&mut self, expr: &Expr<'a>, bound_var: Symbol) -> Option<&'a LogicExpr<'a>> {
613 match expr {
614 Expr::BinaryOp { op, left, right } => {
615 let pred_name = match op {
617 BinaryOpKind::Gt => "Greater",
618 BinaryOpKind::Lt => "Less",
619 BinaryOpKind::GtEq => "GreaterEqual",
620 BinaryOpKind::LtEq => "LessEqual",
621 BinaryOpKind::Eq => "Equal",
622 BinaryOpKind::NotEq => "NotEqual",
623 BinaryOpKind::And => {
624 let left_logic = self.expr_to_logic_predicate(left, bound_var)?;
626 let right_logic = self.expr_to_logic_predicate(right, bound_var)?;
627 return Some(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
628 left: left_logic,
629 op: TokenType::And,
630 right: right_logic,
631 }));
632 }
633 BinaryOpKind::Or => {
634 let left_logic = self.expr_to_logic_predicate(left, bound_var)?;
635 let right_logic = self.expr_to_logic_predicate(right, bound_var)?;
636 return Some(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
637 left: left_logic,
638 op: TokenType::Or,
639 right: right_logic,
640 }));
641 }
642 _ => return None, };
644 let pred_sym = self.interner.intern(pred_name);
645
646 let left_term = self.expr_to_term(left)?;
648 let right_term = self.expr_to_term(right)?;
649
650 let args = self.ctx.terms.alloc_slice([left_term, right_term]);
651 Some(self.ctx.exprs.alloc(LogicExpr::Predicate { name: pred_sym, args, world: None }))
652 }
653 _ => None,
654 }
655 }
656
657 fn expr_to_term(&mut self, expr: &Expr<'a>) -> Option<Term<'a>> {
659 match expr {
660 Expr::Identifier(sym) => Some(Term::Variable(*sym)),
661 Expr::Literal(lit) => {
662 match lit {
663 Literal::Number(n) => Some(Term::Value {
664 kind: NumberKind::Integer(*n),
665 unit: None,
666 dimension: None,
667 }),
668 Literal::Boolean(b) => {
669 let sym = self.interner.intern(if *b { "true" } else { "false" });
670 Some(Term::Constant(sym))
671 }
672 _ => None, }
674 }
675 _ => None,
676 }
677 }
678
679 pub fn process_block_headers(&mut self) {
680 use crate::token::BlockType;
681
682 while self.current < self.tokens.len() {
683 if let TokenType::BlockHeader { block_type } = &self.tokens[self.current].kind {
684 self.mode = match block_type {
685 BlockType::Main | BlockType::Function => ParserMode::Imperative,
686 BlockType::Theorem | BlockType::Definition | BlockType::Proof |
687 BlockType::Example | BlockType::Logic | BlockType::Note | BlockType::TypeDef |
688 BlockType::Policy | BlockType::Requires => ParserMode::Declarative,
689 };
690 self.current += 1;
691 } else {
692 break;
693 }
694 }
695 }
696
697 pub fn get_event_var(&mut self) -> Symbol {
698 self.discourse_event_var.unwrap_or_else(|| self.interner.intern("e"))
699 }
700
701 pub fn capture_event_template(&mut self, verb: Symbol, roles: &[(ThematicRole, Term<'a>)], modifiers: &[Symbol]) {
702 let non_agent_roles: Vec<_> = roles.iter()
703 .filter(|(role, _)| *role != ThematicRole::Agent)
704 .cloned()
705 .collect();
706 self.last_event_template = Some(EventTemplate {
707 verb,
708 non_agent_roles,
709 modifiers: modifiers.to_vec(),
710 });
711 }
712
713 fn parse_embedded_wh_clause(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
714 let var_name = self.interner.intern("x");
716 let var_term = Term::Variable(var_name);
717
718 if self.check_verb() {
719 let verb = self.consume_verb();
721 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
722 name: verb,
723 args: self.ctx.terms.alloc_slice([var_term]),
724 world: None,
725 });
726 return Ok(body);
727 }
728
729 if self.check_content_word() || self.check_article() {
730 let subject = self.parse_noun_phrase(true)?;
732 if self.check_verb() {
733 let verb = self.consume_verb();
734 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
735 name: verb,
736 args: self.ctx.terms.alloc_slice([
737 Term::Constant(subject.noun),
738 var_term,
739 ]),
740 world: None,
741 });
742 return Ok(body);
743 }
744 }
745
746 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(var_name)))
748 }
749
750 pub fn set_pp_attachment_mode(&mut self, attach_to_noun: bool) {
751 self.pp_attach_to_noun = attach_to_noun;
752 }
753
754 pub fn set_noun_priority_mode(&mut self, mode: bool) {
755 self.noun_priority_mode = mode;
756 }
757
758 pub fn set_collective_mode(&mut self, mode: bool) {
759 self.collective_mode = mode;
760 }
761
762 pub fn set_event_reading_mode(&mut self, mode: bool) {
763 self.event_reading_mode = mode;
764 }
765
766 pub fn set_negative_scope_mode(&mut self, mode: NegativeScopeMode) {
767 self.negative_scope_mode = mode;
768 }
769
770 pub fn set_modal_preference(&mut self, pref: ModalPreference) {
771 self.modal_preference = pref;
772 }
773
774 fn checkpoint(&self) -> ParserCheckpoint {
775 ParserCheckpoint {
776 pos: self.current,
777 var_counter: self.var_counter,
778 bindings_len: self.donkey_bindings.len(),
779 island: self.current_island,
780 time: self.pending_time,
781 negative_depth: self.negative_depth,
782 }
783 }
784
785 fn restore(&mut self, cp: ParserCheckpoint) {
786 self.current = cp.pos;
787 self.var_counter = cp.var_counter;
788 self.donkey_bindings.truncate(cp.bindings_len);
789 self.current_island = cp.island;
790 self.pending_time = cp.time;
791 self.negative_depth = cp.negative_depth;
792 }
793
794 fn is_negative_context(&self) -> bool {
795 self.negative_depth % 2 == 1
796 }
797
798 pub fn guard(&mut self) -> ParserGuard<'_, 'a, 'ctx, 'int> {
799 ParserGuard {
800 checkpoint: self.checkpoint(),
801 parser: self,
802 committed: false,
803 }
804 }
805
806 pub(super) fn try_parse<F, T>(&mut self, op: F) -> Option<T>
807 where
808 F: FnOnce(&mut Self) -> ParseResult<T>,
809 {
810 let cp = self.checkpoint();
811 match op(self) {
812 Ok(res) => Some(res),
813 Err(_) => {
814 self.restore(cp);
815 None
816 }
817 }
818 }
819
820 fn resolve_pronoun(&mut self, gender: Gender, number: Number) -> ParseResult<ResolvedPronoun> {
821 if self.world_state.in_discourse_mode() && self.world_state.has_prior_modal_context() {
826 if let Some(candidate) = self.world_state.resolve_via_telescope(gender) {
829 return Ok(ResolvedPronoun::Variable(candidate.variable));
830 }
831 let blocked_candidates: Vec<_> = self.world_state.telescope_candidates()
835 .iter()
836 .filter(|c| c.in_modal_scope)
837 .collect();
838 if !blocked_candidates.is_empty() {
839 let has_upcoming_modal = self.has_modal_subordination_ahead();
842 if has_upcoming_modal {
843 if let Some(candidate) = blocked_candidates.into_iter().find(|c| {
845 c.gender == gender || gender == Gender::Unknown || c.gender == Gender::Unknown
846 }) {
847 return Ok(ResolvedPronoun::Variable(candidate.variable));
848 }
849 }
850 return Err(ParseError {
852 kind: ParseErrorKind::ScopeViolation(
853 "Cannot access hypothetical entity from reality. Use modal subordination (e.g., 'would') to continue a hypothetical context.".to_string()
854 ),
855 span: self.current_span(),
856 });
857 }
858 }
860
861 let current_box = self.drs.current_box_index();
863 match self.drs.resolve_pronoun(current_box, gender, number) {
864 Ok(sym) => return Ok(ResolvedPronoun::Variable(sym)),
865 Err(crate::drs::ScopeError::InaccessibleReferent { gender: g, reason, .. }) => {
866 if self.world_state.in_discourse_mode() {
870 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
871 return Ok(ResolvedPronoun::Variable(candidate.variable));
872 }
873 }
874 return Err(ParseError {
876 kind: ParseErrorKind::ScopeViolation(reason),
877 span: self.current_span(),
878 });
879 }
880 Err(crate::drs::ScopeError::NoMatchingReferent { gender: g, number: n }) => {
881 if !self.world_state.has_prior_modal_context() {
883 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
884 return Ok(ResolvedPronoun::Variable(candidate.variable));
885 }
886 }
887
888 if self.world_state.in_discourse_mode() {
890 return Err(ParseError {
891 kind: ParseErrorKind::UnresolvedPronoun {
892 gender: g,
893 number: n,
894 },
895 span: self.current_span(),
896 });
897 }
898
899 let deictic_name = match (g, n) {
902 (Gender::Male, Number::Singular) => "Him",
903 (Gender::Female, Number::Singular) => "Her",
904 (Gender::Neuter, Number::Singular) => "It",
905 (Gender::Male, Number::Plural) | (Gender::Female, Number::Plural) => "Them",
906 (Gender::Neuter, Number::Plural) => "Them",
907 (Gender::Unknown, _) => "Someone",
908 };
909 let sym = self.interner.intern(deictic_name);
910 self.drs.introduce_referent(sym, sym, g, n);
912 return Ok(ResolvedPronoun::Constant(sym));
913 }
914 }
915 }
916
917 fn resolve_donkey_pronoun(&mut self, gender: Gender) -> Option<Symbol> {
918 for (noun_class, var_name, used, _wide_neg) in self.donkey_bindings.iter_mut().rev() {
919 let noun_str = self.interner.resolve(*noun_class);
920 let noun_gender = Self::infer_noun_gender(noun_str);
921 if noun_gender == gender || gender == Gender::Neuter || noun_gender == Gender::Unknown {
922 *used = true; return Some(*var_name);
924 }
925 }
926 None
927 }
928
929 fn infer_noun_gender(noun: &str) -> Gender {
930 let lower = noun.to_lowercase();
931 if lexicon::is_female_noun(&lower) {
932 Gender::Female
933 } else if lexicon::is_male_noun(&lower) {
934 Gender::Male
935 } else if lexicon::is_neuter_noun(&lower) {
936 Gender::Neuter
937 } else {
938 Gender::Unknown
939 }
940 }
941
942 fn is_plural_noun(noun: &str) -> bool {
943 let lower = noun.to_lowercase();
944 if lexicon::is_proper_name(&lower) {
946 return false;
947 }
948 if lexicon::is_irregular_plural(&lower) {
949 return true;
950 }
951 lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2
952 }
953
954 fn singularize_noun(noun: &str) -> String {
955 let lower = noun.to_lowercase();
956 if let Some(singular) = lexicon::singularize(&lower) {
957 return singular.to_string();
958 }
959 if lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2 {
960 let base = &lower[..lower.len() - 1];
961 let mut chars: Vec<char> = base.chars().collect();
962 if !chars.is_empty() {
963 chars[0] = chars[0].to_uppercase().next().unwrap();
964 }
965 return chars.into_iter().collect();
966 }
967 let mut chars: Vec<char> = lower.chars().collect();
968 if !chars.is_empty() {
969 chars[0] = chars[0].to_uppercase().next().unwrap();
970 }
971 chars.into_iter().collect()
972 }
973
974 fn infer_gender(name: &str) -> Gender {
975 let lower = name.to_lowercase();
976 if lexicon::is_male_name(&lower) {
977 Gender::Male
978 } else if lexicon::is_female_name(&lower) {
979 Gender::Female
980 } else {
981 Gender::Unknown
982 }
983 }
984
985
986 fn next_var_name(&mut self) -> Symbol {
987 const VARS: &[&str] = &["x", "y", "z", "w", "v", "u"];
988 let idx = self.var_counter;
989 self.var_counter += 1;
990 if idx < VARS.len() {
991 self.interner.intern(VARS[idx])
992 } else {
993 let name = format!("x{}", idx - VARS.len() + 1);
994 self.interner.intern(&name)
995 }
996 }
997
998 pub fn parse(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
1015 let mut result = self.parse_sentence()?;
1016
1017 while self.check(&TokenType::Period) || self.check(&TokenType::Exclamation) {
1020 self.advance(); if !self.is_at_end() {
1022 let next = self.parse_sentence()?;
1023 result = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1024 left: result,
1025 op: TokenType::And,
1026 right: next,
1027 });
1028 }
1029 }
1030
1031 Ok(result)
1032 }
1033
1034 pub fn parse_program(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
1052 let mut statements = Vec::new();
1053 let mut in_definition_block = false;
1054
1055 if self.mode == ParserMode::Declarative {
1057 }
1061
1062 while !self.is_at_end() {
1063 if let Some(Token { kind: TokenType::BlockHeader { block_type }, .. }) = self.tokens.get(self.current) {
1065 match block_type {
1066 BlockType::Definition => {
1067 in_definition_block = true;
1068 self.mode = ParserMode::Declarative;
1069 self.advance();
1070 continue;
1071 }
1072 BlockType::Main => {
1073 in_definition_block = false;
1074 self.mode = ParserMode::Imperative;
1075 self.advance();
1076 continue;
1077 }
1078 BlockType::Function => {
1079 in_definition_block = false;
1080 self.mode = ParserMode::Imperative;
1081 self.advance();
1082 let func_def = self.parse_function_def()?;
1084 statements.push(func_def);
1085 continue;
1086 }
1087 BlockType::TypeDef => {
1088 self.advance();
1091 self.skip_type_def_content();
1092 continue;
1093 }
1094 BlockType::Policy => {
1095 in_definition_block = true; self.mode = ParserMode::Declarative;
1099 self.advance();
1100 continue;
1101 }
1102 BlockType::Theorem => {
1103 in_definition_block = false;
1105 self.mode = ParserMode::Declarative;
1106 self.advance();
1107 let theorem = self.parse_theorem_block()?;
1108 statements.push(theorem);
1109 continue;
1110 }
1111 BlockType::Requires => {
1112 in_definition_block = false;
1113 self.mode = ParserMode::Declarative;
1114 self.advance();
1115 let deps = self.parse_requires_block()?;
1116 statements.extend(deps);
1117 continue;
1118 }
1119 _ => {
1120 in_definition_block = false;
1122 self.mode = ParserMode::Declarative;
1123 self.advance();
1124 continue;
1125 }
1126 }
1127 }
1128
1129 if in_definition_block {
1131 self.advance();
1132 continue;
1133 }
1134
1135 if self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) || self.check(&TokenType::Newline) {
1137 self.advance();
1138 continue;
1139 }
1140
1141 if self.mode == ParserMode::Imperative {
1143 let stmt = self.parse_statement()?;
1144 statements.push(stmt);
1145
1146 if self.check(&TokenType::Period) {
1147 self.advance();
1148 }
1149 } else {
1150 self.advance();
1152 }
1153 }
1154
1155 Ok(statements)
1156 }
1157
1158 fn parse_statement(&mut self) -> ParseResult<Stmt<'a>> {
1159 if self.check(&TokenType::To) || self.check_preposition_is("to") {
1162 return self.parse_function_def();
1163 }
1164 if self.check(&TokenType::Let) {
1165 return self.parse_let_statement();
1166 }
1167 if self.check(&TokenType::Mut) {
1170 return self.parse_equals_assignment(true);
1171 }
1172 if self.peek_equals_assignment() {
1175 return self.parse_equals_assignment(false);
1176 }
1177 if self.check(&TokenType::Set) {
1178 return self.parse_set_statement();
1179 }
1180 if self.check(&TokenType::Return) {
1181 return self.parse_return_statement();
1182 }
1183 if self.check(&TokenType::If) {
1184 return self.parse_if_statement();
1185 }
1186 if self.check(&TokenType::Assert) {
1187 return self.parse_assert_statement();
1188 }
1189 if self.check(&TokenType::Trust) {
1191 return self.parse_trust_statement();
1192 }
1193 if self.check(&TokenType::Check) {
1195 return self.parse_check_statement();
1196 }
1197 if self.check(&TokenType::Listen) {
1199 return self.parse_listen_statement();
1200 }
1201 if self.check(&TokenType::NetConnect) {
1202 return self.parse_connect_statement();
1203 }
1204 if self.check(&TokenType::Sleep) {
1205 return self.parse_sleep_statement();
1206 }
1207 if self.check(&TokenType::Sync) {
1209 return self.parse_sync_statement();
1210 }
1211 if self.check(&TokenType::Mount) {
1213 return self.parse_mount_statement();
1214 }
1215 if self.check(&TokenType::While) {
1216 return self.parse_while_statement();
1217 }
1218 if self.check(&TokenType::Repeat) {
1219 return self.parse_repeat_statement();
1220 }
1221 if self.check(&TokenType::For) {
1223 return self.parse_for_statement();
1224 }
1225 if self.check(&TokenType::Call) {
1226 return self.parse_call_statement();
1227 }
1228 if self.check(&TokenType::Give) {
1229 return self.parse_give_statement();
1230 }
1231 if self.check(&TokenType::Show) {
1232 return self.parse_show_statement();
1233 }
1234 if self.check(&TokenType::Inspect) {
1236 return self.parse_inspect_statement();
1237 }
1238
1239 if self.check(&TokenType::Push) {
1241 return self.parse_push_statement();
1242 }
1243 if self.check(&TokenType::Pop) {
1244 return self.parse_pop_statement();
1245 }
1246 if self.check(&TokenType::Add) {
1248 return self.parse_add_statement();
1249 }
1250 if self.check(&TokenType::Remove) {
1251 return self.parse_remove_statement();
1252 }
1253
1254 if self.check(&TokenType::Inside) {
1256 return self.parse_zone_statement();
1257 }
1258
1259 if self.check(&TokenType::Attempt) {
1261 return self.parse_concurrent_block();
1262 }
1263 if self.check(&TokenType::Simultaneously) {
1264 return self.parse_parallel_block();
1265 }
1266
1267 if self.check(&TokenType::Read) {
1269 return self.parse_read_statement();
1270 }
1271 if self.check(&TokenType::Write) {
1272 return self.parse_write_statement();
1273 }
1274
1275 if self.check(&TokenType::Spawn) {
1277 return self.parse_spawn_statement();
1278 }
1279 if self.check(&TokenType::Send) {
1280 if self.lookahead_contains_into() {
1282 return self.parse_send_pipe_statement();
1283 }
1284 return self.parse_send_statement();
1285 }
1286 if self.check(&TokenType::Await) {
1287 if self.lookahead_is_first_of() {
1289 return self.parse_select_statement();
1290 }
1291 return self.parse_await_statement();
1292 }
1293
1294 if self.check(&TokenType::Merge) {
1296 return self.parse_merge_statement();
1297 }
1298 if self.check(&TokenType::Increase) {
1299 return self.parse_increase_statement();
1300 }
1301 if self.check(&TokenType::Decrease) {
1303 return self.parse_decrease_statement();
1304 }
1305 if self.check(&TokenType::Append) {
1306 return self.parse_append_statement();
1307 }
1308 if self.check(&TokenType::Resolve) {
1309 return self.parse_resolve_statement();
1310 }
1311
1312 if self.check(&TokenType::Launch) {
1314 return self.parse_launch_statement();
1315 }
1316 if self.check(&TokenType::Stop) {
1317 return self.parse_stop_statement();
1318 }
1319 if self.check(&TokenType::Try) {
1320 return self.parse_try_statement();
1321 }
1322 if self.check(&TokenType::Receive) {
1323 return self.parse_receive_pipe_statement();
1324 }
1325
1326 if self.check(&TokenType::Escape) {
1328 return self.parse_escape_statement();
1329 }
1330
1331 if self.tokens.get(self.current + 1)
1335 .map(|t| matches!(t.kind, TokenType::LParen))
1336 .unwrap_or(false)
1337 {
1338 let function = self.peek().lexeme;
1340 self.advance(); let expr = self.parse_call_expr(function)?;
1344 if let Expr::Call { function, args } = expr {
1345 return Ok(Stmt::Call { function: *function, args: args.clone() });
1346 }
1347 }
1348
1349 Err(ParseError {
1350 kind: ParseErrorKind::ExpectedStatement,
1351 span: self.current_span(),
1352 })
1353 }
1354
1355 fn parse_if_statement(&mut self) -> ParseResult<Stmt<'a>> {
1356 self.advance(); let cond = self.parse_condition()?;
1360
1361 if self.check(&TokenType::Then) {
1363 self.advance();
1364 }
1365
1366 if !self.check(&TokenType::Colon) {
1368 return Err(ParseError {
1369 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1370 span: self.current_span(),
1371 });
1372 }
1373 self.advance(); if !self.check(&TokenType::Indent) {
1377 return Err(ParseError {
1378 kind: ParseErrorKind::ExpectedStatement,
1379 span: self.current_span(),
1380 });
1381 }
1382 self.advance(); let mut then_stmts = Vec::new();
1386 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1387 let stmt = self.parse_statement()?;
1388 then_stmts.push(stmt);
1389 if self.check(&TokenType::Period) {
1390 self.advance();
1391 }
1392 }
1393
1394 if self.check(&TokenType::Dedent) {
1396 self.advance();
1397 }
1398
1399 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1401 .alloc_slice(then_stmts.into_iter());
1402
1403 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1405 self.advance(); if self.check(&TokenType::If) {
1409 let nested_if = self.parse_if_statement()?;
1411 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1412 .alloc_slice(std::iter::once(nested_if));
1413 Some(nested_slice)
1414 } else {
1415 if !self.check(&TokenType::Colon) {
1417 return Err(ParseError {
1418 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1419 span: self.current_span(),
1420 });
1421 }
1422 self.advance(); if !self.check(&TokenType::Indent) {
1425 return Err(ParseError {
1426 kind: ParseErrorKind::ExpectedStatement,
1427 span: self.current_span(),
1428 });
1429 }
1430 self.advance(); let mut else_stmts = Vec::new();
1433 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1434 let stmt = self.parse_statement()?;
1435 else_stmts.push(stmt);
1436 if self.check(&TokenType::Period) {
1437 self.advance();
1438 }
1439 }
1440
1441 if self.check(&TokenType::Dedent) {
1442 self.advance();
1443 }
1444
1445 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1446 .alloc_slice(else_stmts.into_iter()))
1447 }
1448 } else if self.check(&TokenType::Elif) {
1449 self.advance(); let nested_if = self.parse_elif_as_if()?;
1453 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1454 .alloc_slice(std::iter::once(nested_if));
1455 Some(nested_slice)
1456 } else {
1457 None
1458 };
1459
1460 Ok(Stmt::If {
1461 cond,
1462 then_block,
1463 else_block,
1464 })
1465 }
1466
1467 fn parse_elif_as_if(&mut self) -> ParseResult<Stmt<'a>> {
1470 let cond = self.parse_condition()?;
1472
1473 if !self.check(&TokenType::Colon) {
1475 return Err(ParseError {
1476 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1477 span: self.current_span(),
1478 });
1479 }
1480 self.advance(); if !self.check(&TokenType::Indent) {
1484 return Err(ParseError {
1485 kind: ParseErrorKind::ExpectedStatement,
1486 span: self.current_span(),
1487 });
1488 }
1489 self.advance(); let mut then_stmts = Vec::new();
1493 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1494 let stmt = self.parse_statement()?;
1495 then_stmts.push(stmt);
1496 if self.check(&TokenType::Period) {
1497 self.advance();
1498 }
1499 }
1500
1501 if self.check(&TokenType::Dedent) {
1503 self.advance();
1504 }
1505
1506 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1508 .alloc_slice(then_stmts.into_iter());
1509
1510 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1512 self.advance(); if self.check(&TokenType::If) {
1516 let nested_if = self.parse_if_statement()?;
1517 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1518 .alloc_slice(std::iter::once(nested_if));
1519 Some(nested_slice)
1520 } else {
1521 if !self.check(&TokenType::Colon) {
1523 return Err(ParseError {
1524 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1525 span: self.current_span(),
1526 });
1527 }
1528 self.advance(); if !self.check(&TokenType::Indent) {
1531 return Err(ParseError {
1532 kind: ParseErrorKind::ExpectedStatement,
1533 span: self.current_span(),
1534 });
1535 }
1536 self.advance(); let mut else_stmts = Vec::new();
1539 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1540 let stmt = self.parse_statement()?;
1541 else_stmts.push(stmt);
1542 if self.check(&TokenType::Period) {
1543 self.advance();
1544 }
1545 }
1546
1547 if self.check(&TokenType::Dedent) {
1548 self.advance();
1549 }
1550
1551 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1552 .alloc_slice(else_stmts.into_iter()))
1553 }
1554 } else if self.check(&TokenType::Elif) {
1555 self.advance(); let nested_if = self.parse_elif_as_if()?;
1557 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1558 .alloc_slice(std::iter::once(nested_if));
1559 Some(nested_slice)
1560 } else {
1561 None
1562 };
1563
1564 Ok(Stmt::If {
1565 cond,
1566 then_block,
1567 else_block,
1568 })
1569 }
1570
1571 fn parse_while_statement(&mut self) -> ParseResult<Stmt<'a>> {
1572 self.advance(); let cond = self.parse_condition()?;
1575
1576 let decreasing = if self.check(&TokenType::LParen) {
1578 self.advance(); if !self.check_word("decreasing") {
1582 return Err(ParseError {
1583 kind: ParseErrorKind::ExpectedKeyword { keyword: "decreasing".to_string() },
1584 span: self.current_span(),
1585 });
1586 }
1587 self.advance(); let variant = self.parse_imperative_expr()?;
1590
1591 if !self.check(&TokenType::RParen) {
1592 return Err(ParseError {
1593 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1594 span: self.current_span(),
1595 });
1596 }
1597 self.advance(); Some(variant)
1600 } else {
1601 None
1602 };
1603
1604 if !self.check(&TokenType::Colon) {
1605 return Err(ParseError {
1606 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1607 span: self.current_span(),
1608 });
1609 }
1610 self.advance(); if !self.check(&TokenType::Indent) {
1613 return Err(ParseError {
1614 kind: ParseErrorKind::ExpectedStatement,
1615 span: self.current_span(),
1616 });
1617 }
1618 self.advance(); let mut body_stmts = Vec::new();
1621 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1622 let stmt = self.parse_statement()?;
1623 body_stmts.push(stmt);
1624 if self.check(&TokenType::Period) {
1625 self.advance();
1626 }
1627 }
1628
1629 if self.check(&TokenType::Dedent) {
1630 self.advance();
1631 }
1632
1633 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1634 .alloc_slice(body_stmts.into_iter());
1635
1636 Ok(Stmt::While { cond, body, decreasing })
1637 }
1638
1639 fn parse_loop_pattern(&mut self) -> ParseResult<Pattern> {
1642 use crate::ast::stmt::Pattern;
1643
1644 if self.check(&TokenType::LParen) {
1646 self.advance(); let mut identifiers = Vec::new();
1649 loop {
1650 let id = self.expect_identifier()?;
1651 identifiers.push(id);
1652
1653 if self.check(&TokenType::Comma) {
1655 self.advance(); continue;
1657 }
1658 break;
1659 }
1660
1661 if !self.check(&TokenType::RParen) {
1663 return Err(ParseError {
1664 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1665 span: self.current_span(),
1666 });
1667 }
1668 self.advance(); Ok(Pattern::Tuple(identifiers))
1671 } else {
1672 let id = self.expect_identifier()?;
1674 Ok(Pattern::Identifier(id))
1675 }
1676 }
1677
1678 fn parse_repeat_statement(&mut self) -> ParseResult<Stmt<'a>> {
1679 self.advance(); if self.check(&TokenType::For) {
1683 self.advance();
1684 }
1685
1686 let pattern = self.parse_loop_pattern()?;
1688
1689 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1691 self.advance(); let start = self.parse_imperative_expr()?;
1693
1694 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1696 return Err(ParseError {
1697 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1698 span: self.current_span(),
1699 });
1700 }
1701 self.advance();
1702
1703 let end = self.parse_imperative_expr()?;
1704 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1705 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1706 self.advance(); self.parse_imperative_expr()?
1708 } else {
1709 return Err(ParseError {
1710 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1711 span: self.current_span(),
1712 });
1713 };
1714
1715 if !self.check(&TokenType::Colon) {
1717 return Err(ParseError {
1718 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1719 span: self.current_span(),
1720 });
1721 }
1722 self.advance();
1723
1724 if !self.check(&TokenType::Indent) {
1726 return Err(ParseError {
1727 kind: ParseErrorKind::ExpectedStatement,
1728 span: self.current_span(),
1729 });
1730 }
1731 self.advance();
1732
1733 let mut body_stmts = Vec::new();
1735 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1736 let stmt = self.parse_statement()?;
1737 body_stmts.push(stmt);
1738 if self.check(&TokenType::Period) {
1739 self.advance();
1740 }
1741 }
1742
1743 if self.check(&TokenType::Dedent) {
1744 self.advance();
1745 }
1746
1747 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1748 .alloc_slice(body_stmts.into_iter());
1749
1750 Ok(Stmt::Repeat { pattern, iterable, body })
1751 }
1752
1753 fn parse_for_statement(&mut self) -> ParseResult<Stmt<'a>> {
1756 self.advance(); let pattern = self.parse_loop_pattern()?;
1760
1761 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1763 self.advance(); let start = self.parse_imperative_expr()?;
1765
1766 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1768 return Err(ParseError {
1769 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1770 span: self.current_span(),
1771 });
1772 }
1773 self.advance();
1774
1775 let end = self.parse_imperative_expr()?;
1776 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1777 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1778 self.advance(); self.parse_imperative_expr()?
1780 } else {
1781 return Err(ParseError {
1782 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1783 span: self.current_span(),
1784 });
1785 };
1786
1787 if !self.check(&TokenType::Colon) {
1789 return Err(ParseError {
1790 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1791 span: self.current_span(),
1792 });
1793 }
1794 self.advance();
1795
1796 if !self.check(&TokenType::Indent) {
1798 return Err(ParseError {
1799 kind: ParseErrorKind::ExpectedStatement,
1800 span: self.current_span(),
1801 });
1802 }
1803 self.advance();
1804
1805 let mut body_stmts = Vec::new();
1807 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1808 let stmt = self.parse_statement()?;
1809 body_stmts.push(stmt);
1810 if self.check(&TokenType::Period) {
1811 self.advance();
1812 }
1813 }
1814
1815 if self.check(&TokenType::Dedent) {
1816 self.advance();
1817 }
1818
1819 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1820 .alloc_slice(body_stmts.into_iter());
1821
1822 Ok(Stmt::Repeat { pattern, iterable, body })
1823 }
1824
1825 fn parse_call_statement(&mut self) -> ParseResult<Stmt<'a>> {
1826 self.advance(); let function = match &self.peek().kind {
1832 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
1833 let s = *sym;
1834 self.advance();
1835 s
1836 }
1837 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
1838 let s = self.peek().lexeme;
1840 self.advance();
1841 s
1842 }
1843 _ => {
1844 return Err(ParseError {
1845 kind: ParseErrorKind::ExpectedIdentifier,
1846 span: self.current_span(),
1847 });
1848 }
1849 };
1850
1851 let args = if self.check_preposition_is("with") {
1853 self.advance(); self.parse_call_arguments()?
1855 } else {
1856 Vec::new()
1857 };
1858
1859 Ok(Stmt::Call { function, args })
1860 }
1861
1862 fn parse_call_arguments(&mut self) -> ParseResult<Vec<&'a Expr<'a>>> {
1863 let mut args = Vec::new();
1864
1865 let arg = self.parse_call_arg()?;
1867 args.push(arg);
1868
1869 while self.check(&TokenType::And) || self.check(&TokenType::Comma) {
1871 self.advance(); let arg = self.parse_call_arg()?;
1873 args.push(arg);
1874 }
1875
1876 Ok(args)
1877 }
1878
1879 fn parse_call_arg(&mut self) -> ParseResult<&'a Expr<'a>> {
1880 if self.check(&TokenType::Give) {
1882 self.advance(); let value = self.parse_imperative_expr()?;
1884 return Ok(self.ctx.alloc_imperative_expr(Expr::Give { value }));
1885 }
1886
1887 self.parse_imperative_expr()
1889 }
1890
1891 fn parse_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1892 self.parse_or_condition()
1895 }
1896
1897 fn parse_or_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1899 let mut left = self.parse_and_condition()?;
1900
1901 while self.check(&TokenType::Or) || self.check_word("or") {
1902 self.advance();
1903 let right = self.parse_and_condition()?;
1904 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
1905 op: BinaryOpKind::Or,
1906 left,
1907 right,
1908 });
1909 }
1910
1911 Ok(left)
1912 }
1913
1914 fn parse_and_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1916 let mut left = self.parse_comparison()?;
1917
1918 while self.check(&TokenType::And) || self.check_word("and") {
1919 self.advance();
1920 let right = self.parse_comparison()?;
1921 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
1922 op: BinaryOpKind::And,
1923 left,
1924 right,
1925 });
1926 }
1927
1928 Ok(left)
1929 }
1930
1931 fn parse_comparison(&mut self) -> ParseResult<&'a Expr<'a>> {
1933 if self.check(&TokenType::Not) || self.check_word("not") {
1935 self.advance(); let operand = self.parse_comparison()?; return Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp {
1939 op: BinaryOpKind::Eq,
1940 left: operand,
1941 right: self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(false))),
1942 }));
1943 }
1944
1945 let left = self.parse_imperative_expr()?;
1946
1947 let op = if self.check(&TokenType::Equals) {
1949 self.advance();
1950 Some(BinaryOpKind::Eq)
1951 } else if self.check(&TokenType::Identity) {
1952 self.advance();
1954 Some(BinaryOpKind::Eq)
1955 } else if self.check_word("is") {
1956 let saved_pos = self.current;
1958 self.advance(); if self.check_word("greater") {
1961 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
1963 self.advance(); Some(BinaryOpKind::Gt)
1965 } else {
1966 self.current = saved_pos;
1967 None
1968 }
1969 } else if self.check_word("less") {
1970 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
1972 self.advance(); Some(BinaryOpKind::Lt)
1974 } else {
1975 self.current = saved_pos;
1976 None
1977 }
1978 } else if self.check_word("at") {
1979 self.advance(); if self.check_word("least") {
1981 self.advance(); Some(BinaryOpKind::GtEq)
1983 } else if self.check_word("most") {
1984 self.advance(); Some(BinaryOpKind::LtEq)
1986 } else {
1987 self.current = saved_pos;
1988 None
1989 }
1990 } else if self.check_word("not") || self.check(&TokenType::Not) {
1991 self.advance(); Some(BinaryOpKind::NotEq)
1994 } else if self.check_word("equal") {
1995 self.advance(); if self.check_preposition_is("to") {
1998 self.advance(); Some(BinaryOpKind::Eq)
2000 } else {
2001 self.current = saved_pos;
2002 None
2003 }
2004 } else {
2005 self.current = saved_pos;
2006 None
2007 }
2008 } else if self.check(&TokenType::Lt) {
2009 self.advance();
2010 Some(BinaryOpKind::Lt)
2011 } else if self.check(&TokenType::Gt) {
2012 self.advance();
2013 Some(BinaryOpKind::Gt)
2014 } else if self.check(&TokenType::LtEq) {
2015 self.advance();
2016 Some(BinaryOpKind::LtEq)
2017 } else if self.check(&TokenType::GtEq) {
2018 self.advance();
2019 Some(BinaryOpKind::GtEq)
2020 } else if self.check(&TokenType::EqEq) || self.check(&TokenType::Assign) {
2021 self.advance();
2022 Some(BinaryOpKind::Eq)
2023 } else if self.check(&TokenType::NotEq) {
2024 self.advance();
2025 Some(BinaryOpKind::NotEq)
2026 } else {
2027 None
2028 };
2029
2030 if let Some(op) = op {
2031 let right = self.parse_imperative_expr()?;
2032 Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp { op, left, right }))
2033 } else {
2034 Ok(left)
2035 }
2036 }
2037
2038 fn parse_let_statement(&mut self) -> ParseResult<Stmt<'a>> {
2039 self.advance(); let mutable = if self.check_mutable_keyword() {
2043 self.advance();
2044 true
2045 } else {
2046 false
2047 };
2048
2049 let var = self.expect_identifier()?;
2051
2052 let ty = if self.check(&TokenType::Colon) {
2054 self.advance(); let type_expr = self.parse_type_expression()?;
2056 Some(self.ctx.alloc_type_expr(type_expr))
2057 } else {
2058 None
2059 };
2060
2061 if !self.check(&TokenType::Be) && !self.check(&TokenType::Assign) {
2063 return Err(ParseError {
2064 kind: ParseErrorKind::ExpectedKeyword { keyword: "be or =".to_string() },
2065 span: self.current_span(),
2066 });
2067 }
2068 self.advance(); if self.check_word("mounted") {
2072 self.advance(); if !self.check(&TokenType::At) && !self.check_preposition_is("at") {
2074 return Err(ParseError {
2075 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2076 span: self.current_span(),
2077 });
2078 }
2079 self.advance(); let path = self.parse_imperative_expr()?;
2081 return Ok(Stmt::Mount { var, path });
2082 }
2083
2084 if self.check_article() {
2086 let saved_pos = self.current;
2087 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = self.peek().kind {
2091 let word = self.interner.resolve(sym).to_lowercase();
2092 if word == "peeragent" {
2093 self.advance(); if self.check(&TokenType::At) || self.check_preposition_is("at") {
2097 self.advance(); let address = self.parse_imperative_expr()?;
2101
2102 return Ok(Stmt::LetPeerAgent { var, address });
2103 }
2104 }
2105 }
2106 self.current = saved_pos;
2108 }
2109
2110 if self.check_article() {
2112 let saved_pos = self.current;
2113 self.advance(); if self.check(&TokenType::Pipe) {
2116 self.advance(); if !self.check_word("of") {
2120 return Err(ParseError {
2121 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
2122 span: self.current_span(),
2123 });
2124 }
2125 self.advance(); let element_type = self.expect_identifier()?;
2129
2130 return Ok(Stmt::CreatePipe { var, element_type, capacity: None });
2133 }
2134 self.current = saved_pos;
2136 }
2137
2138 if self.check(&TokenType::Launch) {
2140 self.advance(); if !self.check_article() {
2144 return Err(ParseError {
2145 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2146 span: self.current_span(),
2147 });
2148 }
2149 self.advance();
2150
2151 if !self.check(&TokenType::Task) {
2153 return Err(ParseError {
2154 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2155 span: self.current_span(),
2156 });
2157 }
2158 self.advance();
2159
2160 if !self.check(&TokenType::To) && !self.check_word("to") {
2162 return Err(ParseError {
2163 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2164 span: self.current_span(),
2165 });
2166 }
2167 self.advance();
2168
2169 let function = self.expect_identifier()?;
2171
2172 let args = if self.check_word("with") {
2174 self.advance();
2175 self.parse_call_arguments()?
2176 } else {
2177 vec![]
2178 };
2179
2180 return Ok(Stmt::LaunchTaskWithHandle { handle: var, function, args });
2181 }
2182
2183 let value = self.parse_imperative_expr()?;
2185
2186 if let Some(declared_ty) = &ty {
2188 if let Some(inferred) = self.infer_literal_type(value) {
2189 if !self.check_type_compatibility(declared_ty, inferred) {
2190 let expected = match declared_ty {
2191 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2192 self.interner.resolve(*sym).to_string()
2193 }
2194 _ => "unknown".to_string(),
2195 };
2196 return Err(ParseError {
2197 kind: ParseErrorKind::TypeMismatch {
2198 expected,
2199 found: inferred.to_string(),
2200 },
2201 span: self.current_span(),
2202 });
2203 }
2204 }
2205 }
2206
2207 let value = if self.check_word("with") {
2209 let saved = self.current;
2210 self.advance(); if self.check_word("capacity") {
2212 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2214 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2215 } else {
2216 self.current = saved; value
2218 }
2219 } else {
2220 value
2221 };
2222
2223 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2225
2226 Ok(Stmt::Let { var, ty, value, mutable })
2227 }
2228
2229 fn check_mutable_keyword(&self) -> bool {
2230 if matches!(self.peek().kind, TokenType::Mut) {
2232 return true;
2233 }
2234 if let TokenType::Noun(sym) | TokenType::Adjective(sym) = self.peek().kind {
2236 let word = self.interner.resolve(sym).to_lowercase();
2237 word == "mutable" || word == "mut"
2238 } else {
2239 false
2240 }
2241 }
2242
2243 fn infer_literal_type(&self, expr: &Expr<'_>) -> Option<&'static str> {
2245 match expr {
2246 Expr::Literal(lit) => match lit {
2247 crate::ast::Literal::Number(_) => Some("Int"),
2248 crate::ast::Literal::Float(_) => Some("Real"),
2249 crate::ast::Literal::Text(_) => Some("Text"),
2250 crate::ast::Literal::Boolean(_) => Some("Bool"),
2251 crate::ast::Literal::Nothing => Some("Unit"),
2252 crate::ast::Literal::Char(_) => Some("Char"),
2253 crate::ast::Literal::Duration(_) => Some("Duration"),
2254 crate::ast::Literal::Date(_) => Some("Date"),
2255 crate::ast::Literal::Moment(_) => Some("Moment"),
2256 crate::ast::Literal::Span { .. } => Some("Span"),
2257 crate::ast::Literal::Time(_) => Some("Time"),
2258 },
2259 _ => None, }
2261 }
2262
2263 fn check_type_compatibility(&self, declared: &TypeExpr<'_>, inferred: &str) -> bool {
2265 match declared {
2266 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2267 let declared_name = self.interner.resolve(*sym);
2268 declared_name.eq_ignore_ascii_case(inferred)
2270 || (declared_name.eq_ignore_ascii_case("Nat") && inferred == "Int")
2271 || (declared_name.eq_ignore_ascii_case("Byte") && inferred == "Int")
2272 }
2273 _ => true, }
2275 }
2276
2277 fn peek_equals_assignment(&self) -> bool {
2284 let is_identifier = matches!(
2288 self.peek().kind,
2289 TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Identifier
2290 | TokenType::Adjective(_) | TokenType::Verb { .. }
2291 | TokenType::Particle(_) | TokenType::Ambiguous { .. }
2292 | TokenType::Pronoun { .. }
2293 );
2294 if !is_identifier {
2295 return false;
2296 }
2297
2298 if self.current + 1 >= self.tokens.len() {
2300 return false;
2301 }
2302
2303 let next = &self.tokens[self.current + 1].kind;
2304
2305 if matches!(next, TokenType::Assign) {
2307 return true;
2308 }
2309
2310 if matches!(next, TokenType::Colon) {
2313 let mut offset = 2;
2314 while self.current + offset < self.tokens.len() {
2315 let tok = &self.tokens[self.current + offset].kind;
2316 if matches!(tok, TokenType::Assign) {
2317 return true;
2318 }
2319 if matches!(tok, TokenType::Period | TokenType::Newline | TokenType::EOF) {
2320 return false;
2321 }
2322 offset += 1;
2323 }
2324 }
2325
2326 false
2327 }
2328
2329 fn parse_equals_assignment(&mut self, explicit_mutable: bool) -> ParseResult<Stmt<'a>> {
2331 if explicit_mutable {
2333 self.advance(); }
2335
2336 let var = self.expect_identifier()?;
2338
2339 let ty = if self.check(&TokenType::Colon) {
2341 self.advance(); let type_expr = self.parse_type_expression()?;
2343 Some(self.ctx.alloc_type_expr(type_expr))
2344 } else {
2345 None
2346 };
2347
2348 if !self.check(&TokenType::Assign) {
2350 return Err(ParseError {
2351 kind: ParseErrorKind::ExpectedKeyword { keyword: "=".to_string() },
2352 span: self.current_span(),
2353 });
2354 }
2355 self.advance(); let value = self.parse_imperative_expr()?;
2359
2360 let value = if self.check_word("with") {
2362 let saved = self.current;
2363 self.advance(); if self.check_word("capacity") {
2365 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2367 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2368 } else {
2369 self.current = saved; value
2371 }
2372 } else {
2373 value
2374 };
2375
2376 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2378
2379 Ok(Stmt::Let { var, ty, value, mutable: explicit_mutable })
2380 }
2381
2382 fn parse_set_statement(&mut self) -> ParseResult<Stmt<'a>> {
2383 use crate::ast::Expr;
2384 self.advance(); let target_expr = self.parse_imperative_expr()?;
2388
2389 let target_expr = if self.check(&TokenType::At) {
2391 self.advance(); let key = self.parse_imperative_expr()?;
2393 self.ctx.alloc_imperative_expr(Expr::Index { collection: target_expr, index: key })
2394 } else {
2395 target_expr
2396 };
2397
2398 let is_to = self.check(&TokenType::To) || matches!(
2400 &self.peek().kind,
2401 TokenType::Preposition(sym) if self.interner.resolve(*sym) == "to"
2402 );
2403 if !is_to {
2404 return Err(ParseError {
2405 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2406 span: self.current_span(),
2407 });
2408 }
2409 self.advance(); let value = self.parse_imperative_expr()?;
2413
2414 match target_expr {
2417 Expr::FieldAccess { object, field } => {
2418 Ok(Stmt::SetField { object: *object, field: *field, value })
2419 }
2420 Expr::Identifier(target) => {
2421 Ok(Stmt::Set { target: *target, value })
2422 }
2423 Expr::Index { collection, index } => {
2424 Ok(Stmt::SetIndex { collection: *collection, index: *index, value })
2425 }
2426 _ => Err(ParseError {
2427 kind: ParseErrorKind::ExpectedIdentifier,
2428 span: self.current_span(),
2429 })
2430 }
2431 }
2432
2433 fn parse_return_statement(&mut self) -> ParseResult<Stmt<'a>> {
2434 self.advance(); if self.check(&TokenType::Period) || self.is_at_end() {
2438 return Ok(Stmt::Return { value: None });
2439 }
2440
2441 let value = self.parse_comparison()?;
2443 Ok(Stmt::Return { value: Some(value) })
2444 }
2445
2446 fn parse_assert_statement(&mut self) -> ParseResult<Stmt<'a>> {
2447 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2451 self.advance();
2452 }
2453
2454 let condition = self.parse_condition()?;
2457
2458 Ok(Stmt::RuntimeAssert { condition })
2459 }
2460
2461 fn parse_trust_statement(&mut self) -> ParseResult<Stmt<'a>> {
2464 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2468 self.advance();
2469 }
2470
2471 let saved_mode = self.mode;
2473 self.mode = ParserMode::Declarative;
2474
2475 let proposition = self.parse()?;
2477
2478 self.mode = saved_mode;
2480
2481 if !self.check(&TokenType::Because) {
2483 return Err(ParseError {
2484 kind: ParseErrorKind::UnexpectedToken {
2485 expected: TokenType::Because,
2486 found: self.peek().kind.clone(),
2487 },
2488 span: self.current_span(),
2489 });
2490 }
2491 self.advance(); let justification = match &self.peek().kind {
2495 TokenType::StringLiteral(sym) => {
2496 let s = *sym;
2497 self.advance();
2498 s
2499 }
2500 _ => {
2501 return Err(ParseError {
2502 kind: ParseErrorKind::UnexpectedToken {
2503 expected: TokenType::StringLiteral(self.interner.intern("")),
2504 found: self.peek().kind.clone(),
2505 },
2506 span: self.current_span(),
2507 });
2508 }
2509 };
2510
2511 Ok(Stmt::Trust { proposition, justification })
2512 }
2513
2514 fn parse_check_statement(&mut self) -> ParseResult<Stmt<'a>> {
2518 let start_span = self.current_span();
2519 self.advance(); if self.check(&TokenType::That) {
2523 self.advance();
2524 }
2525
2526 if matches!(self.peek().kind, TokenType::Article(_)) {
2528 self.advance();
2529 }
2530
2531 let subject = match &self.peek().kind {
2533 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2534 let s = *sym;
2535 self.advance();
2536 s
2537 }
2538 _ => {
2539 let tok = self.peek();
2541 let s = tok.lexeme;
2542 self.advance();
2543 s
2544 }
2545 };
2546
2547 let is_capability;
2549 let predicate;
2550 let object;
2551
2552 if self.check(&TokenType::Is) || self.check(&TokenType::Are) {
2553 is_capability = false;
2555 self.advance(); predicate = match &self.peek().kind {
2559 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2560 let s = *sym;
2561 self.advance();
2562 s
2563 }
2564 _ => {
2565 let tok = self.peek();
2566 let s = tok.lexeme;
2567 self.advance();
2568 s
2569 }
2570 };
2571 object = None;
2572 } else if self.check(&TokenType::Can) {
2573 is_capability = true;
2575 self.advance(); predicate = match &self.peek().kind {
2579 TokenType::Verb { lemma, .. } => {
2580 let s = *lemma;
2581 self.advance();
2582 s
2583 }
2584 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2585 let s = *sym;
2586 self.advance();
2587 s
2588 }
2589 _ => {
2590 let tok = self.peek();
2591 let s = tok.lexeme;
2592 self.advance();
2593 s
2594 }
2595 };
2596
2597 if matches!(self.peek().kind, TokenType::Article(_)) {
2599 self.advance();
2600 }
2601
2602 let obj = match &self.peek().kind {
2604 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2605 let s = *sym;
2606 self.advance();
2607 s
2608 }
2609 _ => {
2610 let tok = self.peek();
2611 let s = tok.lexeme;
2612 self.advance();
2613 s
2614 }
2615 };
2616 object = Some(obj);
2617 } else {
2618 return Err(ParseError {
2619 kind: ParseErrorKind::ExpectedKeyword { keyword: "is/can".to_string() },
2620 span: self.current_span(),
2621 });
2622 }
2623
2624 let source_text = if is_capability {
2626 let obj_name = self.interner.resolve(object.unwrap());
2627 let pred_name = self.interner.resolve(predicate);
2628 let subj_name = self.interner.resolve(subject);
2629 format!("{} can {} the {}", subj_name, pred_name, obj_name)
2630 } else {
2631 let pred_name = self.interner.resolve(predicate);
2632 let subj_name = self.interner.resolve(subject);
2633 format!("{} is {}", subj_name, pred_name)
2634 };
2635
2636 Ok(Stmt::Check {
2637 subject,
2638 predicate,
2639 is_capability,
2640 object,
2641 source_text,
2642 span: start_span,
2643 })
2644 }
2645
2646 fn parse_listen_statement(&mut self) -> ParseResult<Stmt<'a>> {
2649 self.advance(); if !self.check_preposition_is("on") {
2653 return Err(ParseError {
2654 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2655 span: self.current_span(),
2656 });
2657 }
2658 self.advance(); let address = self.parse_imperative_expr()?;
2662
2663 Ok(Stmt::Listen { address })
2664 }
2665
2666 fn parse_connect_statement(&mut self) -> ParseResult<Stmt<'a>> {
2669 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2673 return Err(ParseError {
2674 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2675 span: self.current_span(),
2676 });
2677 }
2678 self.advance(); let address = self.parse_imperative_expr()?;
2682
2683 Ok(Stmt::ConnectTo { address })
2684 }
2685
2686 fn parse_sleep_statement(&mut self) -> ParseResult<Stmt<'a>> {
2689 self.advance(); let milliseconds = self.parse_imperative_expr()?;
2693
2694 Ok(Stmt::Sleep { milliseconds })
2695 }
2696
2697 fn parse_sync_statement(&mut self) -> ParseResult<Stmt<'a>> {
2700 self.advance(); let var = match &self.tokens[self.current].kind {
2705 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2706 let s = *sym;
2707 self.advance();
2708 s
2709 }
2710 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2711 let s = self.tokens[self.current].lexeme;
2712 self.advance();
2713 s
2714 }
2715 _ => {
2716 return Err(ParseError {
2717 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2718 span: self.current_span(),
2719 });
2720 }
2721 };
2722
2723 if !self.check_preposition_is("on") {
2725 return Err(ParseError {
2726 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2727 span: self.current_span(),
2728 });
2729 }
2730 self.advance(); let topic = self.parse_imperative_expr()?;
2734
2735 Ok(Stmt::Sync { var, topic })
2736 }
2737
2738 fn parse_mount_statement(&mut self) -> ParseResult<Stmt<'a>> {
2742 self.advance(); let var = match &self.tokens[self.current].kind {
2747 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2748 let s = *sym;
2749 self.advance();
2750 s
2751 }
2752 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2753 let s = self.tokens[self.current].lexeme;
2754 self.advance();
2755 s
2756 }
2757 _ => {
2758 return Err(ParseError {
2759 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2760 span: self.current_span(),
2761 });
2762 }
2763 };
2764
2765 if !self.check(&TokenType::At) {
2767 return Err(ParseError {
2768 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2769 span: self.current_span(),
2770 });
2771 }
2772 self.advance(); let path = self.parse_imperative_expr()?;
2776
2777 Ok(Stmt::Mount { var, path })
2778 }
2779
2780 fn lookahead_contains_into(&self) -> bool {
2786 for i in self.current..std::cmp::min(self.current + 5, self.tokens.len()) {
2787 if matches!(self.tokens[i].kind, TokenType::Into) {
2788 return true;
2789 }
2790 }
2791 false
2792 }
2793
2794 fn lookahead_is_first_of(&self) -> bool {
2796 self.current + 3 < self.tokens.len()
2798 && matches!(self.tokens.get(self.current + 1), Some(t) if matches!(t.kind, TokenType::Article(_)))
2799 && self.tokens.get(self.current + 2)
2800 .map(|t| self.interner.resolve(t.lexeme).to_lowercase() == "first")
2801 .unwrap_or(false)
2802 }
2803
2804 fn parse_launch_statement(&mut self) -> ParseResult<Stmt<'a>> {
2807 self.advance(); if !self.check_article() {
2811 return Err(ParseError {
2812 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2813 span: self.current_span(),
2814 });
2815 }
2816 self.advance();
2817
2818 if !self.check(&TokenType::Task) {
2820 return Err(ParseError {
2821 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2822 span: self.current_span(),
2823 });
2824 }
2825 self.advance();
2826
2827 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2829 return Err(ParseError {
2830 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2831 span: self.current_span(),
2832 });
2833 }
2834 self.advance();
2835
2836 let function = match &self.tokens[self.current].kind {
2839 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2840 let s = *sym;
2841 self.advance();
2842 s
2843 }
2844 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2845 let s = self.tokens[self.current].lexeme;
2846 self.advance();
2847 s
2848 }
2849 _ => {
2850 return Err(ParseError {
2851 kind: ParseErrorKind::ExpectedKeyword { keyword: "function name".to_string() },
2852 span: self.current_span(),
2853 });
2854 }
2855 };
2856
2857 let args = if self.check(&TokenType::LParen) {
2859 self.parse_call_arguments()?
2860 } else if self.check_word("with") {
2861 self.advance(); let mut args = Vec::new();
2863 let arg = self.parse_imperative_expr()?;
2864 args.push(arg);
2865 while self.check(&TokenType::And) {
2867 self.advance();
2868 let arg = self.parse_imperative_expr()?;
2869 args.push(arg);
2870 }
2871 args
2872 } else {
2873 Vec::new()
2874 };
2875
2876 Ok(Stmt::LaunchTask { function, args })
2877 }
2878
2879 fn parse_send_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2882 self.advance(); let value = self.parse_imperative_expr()?;
2886
2887 if !self.check(&TokenType::Into) {
2889 return Err(ParseError {
2890 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
2891 span: self.current_span(),
2892 });
2893 }
2894 self.advance();
2895
2896 let pipe = self.parse_imperative_expr()?;
2898
2899 Ok(Stmt::SendPipe { value, pipe })
2900 }
2901
2902 fn parse_receive_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2905 self.advance(); let var = self.expect_identifier()?;
2909
2910 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
2912 return Err(ParseError {
2913 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
2914 span: self.current_span(),
2915 });
2916 }
2917 self.advance();
2918
2919 let pipe = self.parse_imperative_expr()?;
2921
2922 Ok(Stmt::ReceivePipe { var, pipe })
2923 }
2924
2925 fn parse_try_statement(&mut self) -> ParseResult<Stmt<'a>> {
2928 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2932 return Err(ParseError {
2933 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2934 span: self.current_span(),
2935 });
2936 }
2937 self.advance();
2938
2939 if self.check(&TokenType::Send) {
2941 self.advance(); let value = self.parse_imperative_expr()?;
2943
2944 if !self.check(&TokenType::Into) {
2945 return Err(ParseError {
2946 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
2947 span: self.current_span(),
2948 });
2949 }
2950 self.advance();
2951
2952 let pipe = self.parse_imperative_expr()?;
2953 Ok(Stmt::TrySendPipe { value, pipe, result: None })
2954 } else if self.check(&TokenType::Receive) {
2955 self.advance(); let var = self.expect_identifier()?;
2958
2959 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
2960 return Err(ParseError {
2961 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
2962 span: self.current_span(),
2963 });
2964 }
2965 self.advance();
2966
2967 let pipe = self.parse_imperative_expr()?;
2968 Ok(Stmt::TryReceivePipe { var, pipe })
2969 } else {
2970 Err(ParseError {
2971 kind: ParseErrorKind::ExpectedKeyword { keyword: "send or receive".to_string() },
2972 span: self.current_span(),
2973 })
2974 }
2975 }
2976
2977 fn parse_escape_body(&mut self) -> ParseResult<(crate::intern::Symbol, crate::intern::Symbol, crate::token::Span)> {
2980 let start_span = self.current_span();
2981 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2985 return Err(ParseError {
2986 kind: ParseErrorKind::Custom(
2987 "Expected 'to' after 'Escape'. Syntax: Escape to Rust:".to_string()
2988 ),
2989 span: self.current_span(),
2990 });
2991 }
2992 self.advance(); let language = match &self.peek().kind {
2996 TokenType::ProperName(sym) => {
2997 let s = *sym;
2998 self.advance();
2999 s
3000 }
3001 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3002 let s = *sym;
3003 self.advance();
3004 s
3005 }
3006 _ => {
3007 return Err(ParseError {
3008 kind: ParseErrorKind::Custom(
3009 "Expected language name after 'Escape to'. Currently only 'Rust' is supported.".to_string()
3010 ),
3011 span: self.current_span(),
3012 });
3013 }
3014 };
3015
3016 if !language.is(self.interner, "Rust") {
3018 let lang_str = self.interner.resolve(language);
3019 return Err(ParseError {
3020 kind: ParseErrorKind::Custom(
3021 format!("Unsupported escape target '{}'. Only 'Rust' is supported.", lang_str)
3022 ),
3023 span: self.current_span(),
3024 });
3025 }
3026
3027 if !self.check(&TokenType::Colon) {
3029 return Err(ParseError {
3030 kind: ParseErrorKind::Custom(
3031 "Expected ':' after 'Escape to Rust'. Syntax: Escape to Rust:".to_string()
3032 ),
3033 span: self.current_span(),
3034 });
3035 }
3036 self.advance(); if !self.check(&TokenType::Indent) {
3040 return Err(ParseError {
3041 kind: ParseErrorKind::Custom(
3042 "Expected indented block after 'Escape to Rust:'.".to_string()
3043 ),
3044 span: self.current_span(),
3045 });
3046 }
3047 self.advance(); let code = match &self.peek().kind {
3051 TokenType::EscapeBlock(sym) => {
3052 let s = *sym;
3053 self.advance();
3054 s
3055 }
3056 _ => {
3057 return Err(ParseError {
3058 kind: ParseErrorKind::Custom(
3059 "Escape block body is empty or malformed.".to_string()
3060 ),
3061 span: self.current_span(),
3062 });
3063 }
3064 };
3065
3066 if self.check(&TokenType::Dedent) {
3068 self.advance();
3069 }
3070
3071 let end_span = self.previous().span;
3072 Ok((language, code, crate::token::Span::new(start_span.start, end_span.end)))
3073 }
3074
3075 fn parse_escape_statement(&mut self) -> ParseResult<Stmt<'a>> {
3077 let (language, code, span) = self.parse_escape_body()?;
3078 Ok(Stmt::Escape { language, code, span })
3079 }
3080
3081 fn parse_escape_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
3084 let (language, code, _span) = self.parse_escape_body()?;
3085 Ok(self.ctx.alloc_imperative_expr(Expr::Escape { language, code }))
3086 }
3087
3088 fn parse_requires_block(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
3091 let mut deps = Vec::new();
3092
3093 loop {
3094 if self.is_at_end() {
3096 break;
3097 }
3098 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
3099 break;
3100 }
3101
3102 if self.check(&TokenType::Indent)
3104 || self.check(&TokenType::Dedent)
3105 || self.check(&TokenType::Newline)
3106 {
3107 self.advance();
3108 continue;
3109 }
3110
3111 if matches!(self.peek().kind, TokenType::Article(_)) {
3113 let dep = self.parse_require_line()?;
3114 deps.push(dep);
3115 continue;
3116 }
3117
3118 self.advance();
3120 }
3121
3122 Ok(deps)
3123 }
3124
3125 fn parse_require_line(&mut self) -> ParseResult<Stmt<'a>> {
3128 let start_span = self.current_span();
3129
3130 if !matches!(self.peek().kind, TokenType::Article(_)) {
3132 return Err(crate::error::ParseError {
3133 kind: crate::error::ParseErrorKind::Custom(
3134 "Expected 'The' to begin a dependency declaration.".to_string(),
3135 ),
3136 span: self.current_span(),
3137 });
3138 }
3139 self.advance(); let crate_name = if let TokenType::StringLiteral(sym) = self.peek().kind {
3143 let s = sym;
3144 self.advance();
3145 s
3146 } else {
3147 return Err(crate::error::ParseError {
3148 kind: crate::error::ParseErrorKind::Custom(
3149 "Expected a string literal for the crate name, e.g. \"serde\".".to_string(),
3150 ),
3151 span: self.current_span(),
3152 });
3153 };
3154
3155 if !self.check_word("crate") {
3157 return Err(crate::error::ParseError {
3158 kind: crate::error::ParseErrorKind::Custom(
3159 "Expected the word 'crate' after the crate name.".to_string(),
3160 ),
3161 span: self.current_span(),
3162 });
3163 }
3164 self.advance(); if !self.check_word("version") {
3168 return Err(crate::error::ParseError {
3169 kind: crate::error::ParseErrorKind::Custom(
3170 "Expected 'version' after 'crate'.".to_string(),
3171 ),
3172 span: self.current_span(),
3173 });
3174 }
3175 self.advance(); let version = if let TokenType::StringLiteral(sym) = self.peek().kind {
3179 let s = sym;
3180 self.advance();
3181 s
3182 } else {
3183 return Err(crate::error::ParseError {
3184 kind: crate::error::ParseErrorKind::Custom(
3185 "Expected a string literal for the version, e.g. \"1.0\".".to_string(),
3186 ),
3187 span: self.current_span(),
3188 });
3189 };
3190
3191 let mut features = Vec::new();
3193 if self.check_preposition_is("with") {
3194 self.advance(); if !self.check_word("features") {
3198 return Err(crate::error::ParseError {
3199 kind: crate::error::ParseErrorKind::Custom(
3200 "Expected 'features' after 'with'.".to_string(),
3201 ),
3202 span: self.current_span(),
3203 });
3204 }
3205 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3209 features.push(sym);
3210 self.advance();
3211 } else {
3212 return Err(crate::error::ParseError {
3213 kind: crate::error::ParseErrorKind::Custom(
3214 "Expected a string literal for a feature name.".to_string(),
3215 ),
3216 span: self.current_span(),
3217 });
3218 }
3219
3220 while self.check(&TokenType::And) {
3222 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3224 features.push(sym);
3225 self.advance();
3226 } else {
3227 return Err(crate::error::ParseError {
3228 kind: crate::error::ParseErrorKind::Custom(
3229 "Expected a string literal for a feature name after 'and'.".to_string(),
3230 ),
3231 span: self.current_span(),
3232 });
3233 }
3234 }
3235 }
3236
3237 if self.check(&TokenType::For) {
3239 self.advance(); while !self.check(&TokenType::Period) && !self.check(&TokenType::EOF)
3241 && !self.check(&TokenType::Newline)
3242 && !matches!(self.peek().kind, TokenType::BlockHeader { .. })
3243 {
3244 self.advance();
3245 }
3246 }
3247
3248 if self.check(&TokenType::Period) {
3250 self.advance();
3251 }
3252
3253 let end_span = self.previous().span;
3254
3255 Ok(Stmt::Require {
3256 crate_name,
3257 version,
3258 features,
3259 span: crate::token::Span::new(start_span.start, end_span.end),
3260 })
3261 }
3262
3263 fn parse_stop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3266 self.advance(); let handle = self.parse_imperative_expr()?;
3269
3270 Ok(Stmt::StopTask { handle })
3271 }
3272
3273 fn parse_select_statement(&mut self) -> ParseResult<Stmt<'a>> {
3281 use crate::ast::stmt::SelectBranch;
3282
3283 self.advance(); if !self.check_article() {
3287 return Err(ParseError {
3288 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
3289 span: self.current_span(),
3290 });
3291 }
3292 self.advance();
3293
3294 if !self.check_word("first") {
3296 return Err(ParseError {
3297 kind: ParseErrorKind::ExpectedKeyword { keyword: "first".to_string() },
3298 span: self.current_span(),
3299 });
3300 }
3301 self.advance();
3302
3303 if !self.check_preposition_is("of") {
3305 return Err(ParseError {
3306 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3307 span: self.current_span(),
3308 });
3309 }
3310 self.advance();
3311
3312 if !self.check(&TokenType::Colon) {
3314 return Err(ParseError {
3315 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3316 span: self.current_span(),
3317 });
3318 }
3319 self.advance();
3320
3321 if !self.check(&TokenType::Indent) {
3323 return Err(ParseError {
3324 kind: ParseErrorKind::ExpectedStatement,
3325 span: self.current_span(),
3326 });
3327 }
3328 self.advance();
3329
3330 let mut branches = Vec::new();
3332 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3333 let branch = self.parse_select_branch()?;
3334 branches.push(branch);
3335 }
3336
3337 if self.check(&TokenType::Dedent) {
3339 self.advance();
3340 }
3341
3342 Ok(Stmt::Select { branches })
3343 }
3344
3345 fn parse_select_branch(&mut self) -> ParseResult<crate::ast::stmt::SelectBranch<'a>> {
3347 use crate::ast::stmt::SelectBranch;
3348
3349 if self.check(&TokenType::Receive) {
3350 self.advance(); let var = match &self.tokens[self.current].kind {
3353 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3354 let s = *sym;
3355 self.advance();
3356 s
3357 }
3358 _ => {
3359 return Err(ParseError {
3360 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
3361 span: self.current_span(),
3362 });
3363 }
3364 };
3365
3366 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3367 return Err(ParseError {
3368 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3369 span: self.current_span(),
3370 });
3371 }
3372 self.advance();
3373
3374 let pipe = self.parse_imperative_expr()?;
3375
3376 if !self.check(&TokenType::Colon) {
3378 return Err(ParseError {
3379 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3380 span: self.current_span(),
3381 });
3382 }
3383 self.advance();
3384
3385 let body = self.parse_indented_block()?;
3387
3388 Ok(SelectBranch::Receive { var, pipe, body })
3389 } else if self.check_word("after") {
3390 self.advance(); let milliseconds = self.parse_imperative_expr()?;
3393
3394 if self.check_word("seconds") || self.check_word("milliseconds") {
3396 self.advance();
3397 }
3398
3399 if !self.check(&TokenType::Colon) {
3401 return Err(ParseError {
3402 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3403 span: self.current_span(),
3404 });
3405 }
3406 self.advance();
3407
3408 let body = self.parse_indented_block()?;
3410
3411 Ok(SelectBranch::Timeout { milliseconds, body })
3412 } else {
3413 Err(ParseError {
3414 kind: ParseErrorKind::ExpectedKeyword { keyword: "Receive or After".to_string() },
3415 span: self.current_span(),
3416 })
3417 }
3418 }
3419
3420 fn parse_indented_block(&mut self) -> ParseResult<crate::ast::stmt::Block<'a>> {
3422 if !self.check(&TokenType::Indent) {
3424 return Err(ParseError {
3425 kind: ParseErrorKind::ExpectedStatement,
3426 span: self.current_span(),
3427 });
3428 }
3429 self.advance();
3430
3431 let mut stmts = Vec::new();
3432 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3433 let stmt = self.parse_statement()?;
3434 stmts.push(stmt);
3435 if self.check(&TokenType::Period) {
3436 self.advance();
3437 }
3438 }
3439
3440 if self.check(&TokenType::Dedent) {
3442 self.advance();
3443 }
3444
3445 let block = self.ctx.stmts.expect("imperative arenas not initialized")
3446 .alloc_slice(stmts.into_iter());
3447
3448 Ok(block)
3449 }
3450
3451 fn parse_give_statement(&mut self) -> ParseResult<Stmt<'a>> {
3452 self.advance(); let object = self.parse_imperative_expr()?;
3456
3457 if !self.check_to_preposition() {
3459 return Err(ParseError {
3460 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3461 span: self.current_span(),
3462 });
3463 }
3464 self.advance(); let recipient = self.parse_imperative_expr()?;
3468
3469 if let Expr::Identifier(sym) = object {
3471 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Moved);
3472 }
3473
3474 Ok(Stmt::Give { object, recipient })
3475 }
3476
3477 fn parse_show_statement(&mut self) -> ParseResult<Stmt<'a>> {
3478 self.advance(); let object = self.parse_condition()?;
3483
3484 let recipient = if self.check_to_preposition() {
3488 self.advance(); if self.check_article() {
3493 self.advance(); }
3495 if self.check(&TokenType::Console) {
3496 self.advance(); let show_sym = self.interner.intern("show");
3498 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3499 } else {
3500 self.parse_imperative_expr()?
3502 }
3503 } else {
3504 let show_sym = self.interner.intern("show");
3506 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3507 };
3508
3509 if let Expr::Identifier(sym) = object {
3511 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Borrowed);
3512 }
3513
3514 Ok(Stmt::Show { object, recipient })
3515 }
3516
3517 fn parse_push_statement(&mut self) -> ParseResult<Stmt<'a>> {
3520 self.advance(); let value = self.parse_imperative_expr()?;
3524
3525 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3527 return Err(ParseError {
3528 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3529 span: self.current_span(),
3530 });
3531 }
3532 self.advance(); let collection = self.parse_imperative_expr()?;
3536
3537 Ok(Stmt::Push { value, collection })
3538 }
3539
3540 fn parse_pop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3543 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3547 return Err(ParseError {
3548 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3549 span: self.current_span(),
3550 });
3551 }
3552 self.advance(); let collection = self.parse_imperative_expr()?;
3556
3557 let into = if self.check(&TokenType::Into) || self.check_preposition_is("into") {
3559 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = &self.peek().kind {
3563 let sym = *sym;
3564 self.advance();
3565 Some(sym)
3566 } else if let Some(token) = self.tokens.get(self.current) {
3567 let sym = token.lexeme;
3569 self.advance();
3570 Some(sym)
3571 } else {
3572 return Err(ParseError {
3573 kind: ParseErrorKind::ExpectedIdentifier,
3574 span: self.current_span(),
3575 });
3576 }
3577 } else {
3578 None
3579 };
3580
3581 Ok(Stmt::Pop { collection, into })
3582 }
3583
3584 fn parse_add_statement(&mut self) -> ParseResult<Stmt<'a>> {
3587 self.advance(); let value = self.parse_imperative_expr()?;
3591
3592 if !self.check_preposition_is("to") && !self.check(&TokenType::To) {
3594 return Err(ParseError {
3595 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3596 span: self.current_span(),
3597 });
3598 }
3599 self.advance(); let collection = self.parse_imperative_expr()?;
3603
3604 Ok(Stmt::Add { value, collection })
3605 }
3606
3607 fn parse_remove_statement(&mut self) -> ParseResult<Stmt<'a>> {
3610 self.advance(); let value = self.parse_imperative_expr()?;
3614
3615 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3617 return Err(ParseError {
3618 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3619 span: self.current_span(),
3620 });
3621 }
3622 self.advance(); let collection = self.parse_imperative_expr()?;
3626
3627 Ok(Stmt::Remove { value, collection })
3628 }
3629
3630 fn parse_read_statement(&mut self) -> ParseResult<Stmt<'a>> {
3634 self.advance(); let var = self.expect_identifier()?;
3638
3639 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3641 return Err(ParseError {
3642 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3643 span: self.current_span(),
3644 });
3645 }
3646 self.advance(); if self.check_article() {
3650 self.advance();
3651 }
3652
3653 let source = if self.check(&TokenType::Console) {
3655 self.advance(); ReadSource::Console
3657 } else if self.check(&TokenType::File) {
3658 self.advance(); let path = self.parse_imperative_expr()?;
3660 ReadSource::File(path)
3661 } else {
3662 return Err(ParseError {
3663 kind: ParseErrorKind::ExpectedKeyword { keyword: "console or file".to_string() },
3664 span: self.current_span(),
3665 });
3666 };
3667
3668 Ok(Stmt::ReadFrom { var, source })
3669 }
3670
3671 fn parse_write_statement(&mut self) -> ParseResult<Stmt<'a>> {
3674 self.advance(); let content = self.parse_imperative_expr()?;
3678
3679 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3681 return Err(ParseError {
3682 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3683 span: self.current_span(),
3684 });
3685 }
3686 self.advance(); if !self.check(&TokenType::File) {
3690 return Err(ParseError {
3691 kind: ParseErrorKind::ExpectedKeyword { keyword: "file".to_string() },
3692 span: self.current_span(),
3693 });
3694 }
3695 self.advance(); let path = self.parse_imperative_expr()?;
3699
3700 Ok(Stmt::WriteFile { content, path })
3701 }
3702
3703 fn parse_zone_statement(&mut self) -> ParseResult<Stmt<'a>> {
3709 self.advance(); if self.check_article() {
3713 self.advance();
3714 }
3715
3716 if self.check(&TokenType::New) {
3718 self.advance();
3719 }
3720
3721 if !self.check(&TokenType::Zone) {
3723 return Err(ParseError {
3724 kind: ParseErrorKind::ExpectedKeyword { keyword: "zone".to_string() },
3725 span: self.current_span(),
3726 });
3727 }
3728 self.advance(); if !self.check(&TokenType::Called) {
3732 return Err(ParseError {
3733 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
3734 span: self.current_span(),
3735 });
3736 }
3737 self.advance(); let name = match &self.peek().kind {
3741 TokenType::StringLiteral(sym) => {
3742 let s = *sym;
3743 self.advance();
3744 s
3745 }
3746 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3747 let s = *sym;
3748 self.advance();
3749 s
3750 }
3751 _ => {
3752 let token = self.peek().clone();
3754 self.advance();
3755 token.lexeme
3756 }
3757 };
3758
3759 let mut capacity = None;
3760 let mut source_file = None;
3761
3762 if self.check(&TokenType::Mapped) {
3764 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3768 return Err(ParseError {
3769 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3770 span: self.current_span(),
3771 });
3772 }
3773 self.advance(); if let TokenType::StringLiteral(path) = &self.peek().kind {
3777 source_file = Some(*path);
3778 self.advance();
3779 } else {
3780 return Err(ParseError {
3781 kind: ParseErrorKind::ExpectedKeyword { keyword: "file path string".to_string() },
3782 span: self.current_span(),
3783 });
3784 }
3785 }
3786 else if self.check_of_preposition() {
3788 self.advance(); if !self.check(&TokenType::Size) {
3792 return Err(ParseError {
3793 kind: ParseErrorKind::ExpectedKeyword { keyword: "size".to_string() },
3794 span: self.current_span(),
3795 });
3796 }
3797 self.advance(); let size_value = match &self.peek().kind {
3801 TokenType::Number(sym) => {
3802 let num_str = self.interner.resolve(*sym);
3803 let val = num_str.replace('_', "").parse::<usize>().unwrap_or(0);
3804 self.advance();
3805 val
3806 }
3807 TokenType::Cardinal(n) => {
3808 let val = *n as usize;
3809 self.advance();
3810 val
3811 }
3812 _ => {
3813 return Err(ParseError {
3814 kind: ParseErrorKind::ExpectedNumber,
3815 span: self.current_span(),
3816 });
3817 }
3818 };
3819
3820 let unit_multiplier = self.parse_size_unit()?;
3822 capacity = Some(size_value * unit_multiplier);
3823 }
3824
3825 if !self.check(&TokenType::Colon) {
3827 return Err(ParseError {
3828 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3829 span: self.current_span(),
3830 });
3831 }
3832 self.advance(); if !self.check(&TokenType::Indent) {
3836 return Err(ParseError {
3837 kind: ParseErrorKind::ExpectedStatement,
3838 span: self.current_span(),
3839 });
3840 }
3841 self.advance(); let mut body_stmts = Vec::new();
3845 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3846 let stmt = self.parse_statement()?;
3847 body_stmts.push(stmt);
3848 if self.check(&TokenType::Period) {
3849 self.advance();
3850 }
3851 }
3852
3853 if self.check(&TokenType::Dedent) {
3855 self.advance();
3856 }
3857
3858 let body = self.ctx.stmts.expect("imperative arenas not initialized")
3859 .alloc_slice(body_stmts.into_iter());
3860
3861 Ok(Stmt::Zone { name, capacity, source_file, body })
3862 }
3863
3864 fn parse_size_unit(&mut self) -> ParseResult<usize> {
3866 let token = self.peek().clone();
3867 let unit_str = self.interner.resolve(token.lexeme).to_uppercase();
3868 self.advance();
3869
3870 match unit_str.as_str() {
3871 "B" | "BYTES" | "BYTE" => Ok(1),
3872 "KB" | "KILOBYTE" | "KILOBYTES" => Ok(1024),
3873 "MB" | "MEGABYTE" | "MEGABYTES" => Ok(1024 * 1024),
3874 "GB" | "GIGABYTE" | "GIGABYTES" => Ok(1024 * 1024 * 1024),
3875 _ => Err(ParseError {
3876 kind: ParseErrorKind::ExpectedKeyword {
3877 keyword: "size unit (B, KB, MB, GB)".to_string(),
3878 },
3879 span: token.span,
3880 }),
3881 }
3882 }
3883
3884 fn parse_concurrent_block(&mut self) -> ParseResult<Stmt<'a>> {
3893 self.advance(); if !self.check(&TokenType::All) {
3897 return Err(ParseError {
3898 kind: ParseErrorKind::ExpectedKeyword { keyword: "all".to_string() },
3899 span: self.current_span(),
3900 });
3901 }
3902 self.advance(); if !self.check_of_preposition() {
3906 return Err(ParseError {
3907 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3908 span: self.current_span(),
3909 });
3910 }
3911 self.advance(); if !self.check_article() {
3915 return Err(ParseError {
3916 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
3917 span: self.current_span(),
3918 });
3919 }
3920 self.advance(); if !self.check(&TokenType::Following) {
3924 return Err(ParseError {
3925 kind: ParseErrorKind::ExpectedKeyword { keyword: "following".to_string() },
3926 span: self.current_span(),
3927 });
3928 }
3929 self.advance(); if !self.check(&TokenType::Colon) {
3933 return Err(ParseError {
3934 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3935 span: self.current_span(),
3936 });
3937 }
3938 self.advance(); if !self.check(&TokenType::Indent) {
3942 return Err(ParseError {
3943 kind: ParseErrorKind::ExpectedStatement,
3944 span: self.current_span(),
3945 });
3946 }
3947 self.advance(); let mut task_stmts = Vec::new();
3951 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3952 let stmt = self.parse_statement()?;
3953 task_stmts.push(stmt);
3954 if self.check(&TokenType::Period) {
3955 self.advance();
3956 }
3957 }
3958
3959 if self.check(&TokenType::Dedent) {
3961 self.advance();
3962 }
3963
3964 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
3965 .alloc_slice(task_stmts.into_iter());
3966
3967 Ok(Stmt::Concurrent { tasks })
3968 }
3969
3970 fn parse_parallel_block(&mut self) -> ParseResult<Stmt<'a>> {
3979 self.advance(); if !self.check(&TokenType::Colon) {
3983 return Err(ParseError {
3984 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3985 span: self.current_span(),
3986 });
3987 }
3988 self.advance(); if !self.check(&TokenType::Indent) {
3992 return Err(ParseError {
3993 kind: ParseErrorKind::ExpectedStatement,
3994 span: self.current_span(),
3995 });
3996 }
3997 self.advance(); let mut task_stmts = Vec::new();
4001 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4002 let stmt = self.parse_statement()?;
4003 task_stmts.push(stmt);
4004 if self.check(&TokenType::Period) {
4005 self.advance();
4006 }
4007 }
4008
4009 if self.check(&TokenType::Dedent) {
4011 self.advance();
4012 }
4013
4014 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
4015 .alloc_slice(task_stmts.into_iter());
4016
4017 Ok(Stmt::Parallel { tasks })
4018 }
4019
4020 fn parse_inspect_statement(&mut self) -> ParseResult<Stmt<'a>> {
4027 self.advance(); let target = self.parse_imperative_expr()?;
4031
4032 if !self.check(&TokenType::Colon) {
4034 return Err(ParseError {
4035 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4036 span: self.current_span(),
4037 });
4038 }
4039 self.advance(); if !self.check(&TokenType::Indent) {
4043 return Err(ParseError {
4044 kind: ParseErrorKind::ExpectedStatement,
4045 span: self.current_span(),
4046 });
4047 }
4048 self.advance(); let mut arms = Vec::new();
4051 let mut has_otherwise = false;
4052
4053 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4055 if self.check(&TokenType::Otherwise) {
4056 self.advance(); if !self.check(&TokenType::Colon) {
4060 return Err(ParseError {
4061 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4062 span: self.current_span(),
4063 });
4064 }
4065 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4069 self.advance(); let mut stmts = Vec::new();
4071 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4072 let stmt = self.parse_statement()?;
4073 stmts.push(stmt);
4074 if self.check(&TokenType::Period) {
4075 self.advance();
4076 }
4077 }
4078 if self.check(&TokenType::Dedent) {
4079 self.advance();
4080 }
4081 stmts
4082 } else {
4083 let stmt = self.parse_statement()?;
4085 if self.check(&TokenType::Period) {
4086 self.advance();
4087 }
4088 vec![stmt]
4089 };
4090
4091 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4092 .alloc_slice(body_stmts.into_iter());
4093
4094 arms.push(MatchArm { enum_name: None, variant: None, bindings: vec![], body });
4095 has_otherwise = true;
4096 break;
4097 }
4098
4099 if self.check(&TokenType::If) {
4100 let arm = self.parse_match_arm()?;
4102 arms.push(arm);
4103 } else if self.check(&TokenType::When) || self.check_word("When") {
4104 let arm = self.parse_when_arm()?;
4106 arms.push(arm);
4107 } else if self.check(&TokenType::Newline) {
4108 self.advance();
4110 } else {
4111 self.advance();
4113 }
4114 }
4115
4116 if self.check(&TokenType::Dedent) {
4118 self.advance();
4119 }
4120
4121 Ok(Stmt::Inspect { target, arms, has_otherwise })
4122 }
4123
4124 fn parse_match_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4126 self.advance(); if !self.check_word("it") {
4130 return Err(ParseError {
4131 kind: ParseErrorKind::ExpectedKeyword { keyword: "it".to_string() },
4132 span: self.current_span(),
4133 });
4134 }
4135 self.advance(); if !self.check(&TokenType::Is) {
4139 return Err(ParseError {
4140 kind: ParseErrorKind::ExpectedKeyword { keyword: "is".to_string() },
4141 span: self.current_span(),
4142 });
4143 }
4144 self.advance(); if self.check_article() {
4148 self.advance();
4149 }
4150
4151 let variant = self.expect_identifier()?;
4153
4154 let enum_name = self.find_variant(variant);
4156
4157 let bindings = if self.check(&TokenType::LParen) {
4159 self.parse_pattern_bindings()?
4160 } else {
4161 vec![]
4162 };
4163
4164 if !self.check(&TokenType::Colon) {
4166 return Err(ParseError {
4167 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4168 span: self.current_span(),
4169 });
4170 }
4171 self.advance(); if !self.check(&TokenType::Indent) {
4175 return Err(ParseError {
4176 kind: ParseErrorKind::ExpectedStatement,
4177 span: self.current_span(),
4178 });
4179 }
4180 self.advance(); let mut body_stmts = Vec::new();
4184 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4185 let stmt = self.parse_statement()?;
4186 body_stmts.push(stmt);
4187 if self.check(&TokenType::Period) {
4188 self.advance();
4189 }
4190 }
4191
4192 if self.check(&TokenType::Dedent) {
4194 self.advance();
4195 }
4196
4197 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4198 .alloc_slice(body_stmts.into_iter());
4199
4200 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4201 }
4202
4203 fn parse_when_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4205 self.advance(); let variant = self.expect_identifier()?;
4209
4210 let (enum_name, variant_fields) = self.type_registry
4212 .as_ref()
4213 .and_then(|r| r.find_variant(variant).map(|(enum_name, vdef)| {
4214 let fields: Vec<_> = vdef.fields.iter().map(|f| f.name).collect();
4215 (Some(enum_name), fields)
4216 }))
4217 .unwrap_or((None, vec![]));
4218
4219 let bindings = if self.check(&TokenType::LParen) {
4221 let raw_bindings = self.parse_when_bindings()?;
4222 raw_bindings.into_iter().enumerate().map(|(i, binding)| {
4224 let field = variant_fields.get(i).copied().unwrap_or(binding);
4225 (field, binding)
4226 }).collect()
4227 } else {
4228 vec![]
4229 };
4230
4231 if !self.check(&TokenType::Colon) {
4233 return Err(ParseError {
4234 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4235 span: self.current_span(),
4236 });
4237 }
4238 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4242 self.advance(); let mut stmts = Vec::new();
4244 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4245 let stmt = self.parse_statement()?;
4246 stmts.push(stmt);
4247 if self.check(&TokenType::Period) {
4248 self.advance();
4249 }
4250 }
4251 if self.check(&TokenType::Dedent) {
4252 self.advance();
4253 }
4254 stmts
4255 } else {
4256 let stmt = self.parse_statement()?;
4258 if self.check(&TokenType::Period) {
4259 self.advance();
4260 }
4261 vec![stmt]
4262 };
4263
4264 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4265 .alloc_slice(body_stmts.into_iter());
4266
4267 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4268 }
4269
4270 fn parse_when_bindings(&mut self) -> ParseResult<Vec<Symbol>> {
4272 self.advance(); let mut bindings = Vec::new();
4274
4275 loop {
4276 let binding = self.expect_identifier()?;
4277 bindings.push(binding);
4278
4279 if !self.check(&TokenType::Comma) {
4280 break;
4281 }
4282 self.advance(); }
4284
4285 if !self.check(&TokenType::RParen) {
4286 return Err(ParseError {
4287 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4288 span: self.current_span(),
4289 });
4290 }
4291 self.advance(); Ok(bindings)
4294 }
4295
4296 fn parse_pattern_bindings(&mut self) -> ParseResult<Vec<(Symbol, Symbol)>> {
4298 self.advance(); let mut bindings = Vec::new();
4300
4301 loop {
4302 let field = self.expect_identifier()?;
4303 let binding = if self.check(&TokenType::Colon) {
4304 self.advance(); self.expect_identifier()?
4306 } else {
4307 field };
4309 bindings.push((field, binding));
4310
4311 if !self.check(&TokenType::Comma) {
4312 break;
4313 }
4314 self.advance(); }
4316
4317 if !self.check(&TokenType::RParen) {
4318 return Err(ParseError {
4319 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4320 span: self.current_span(),
4321 });
4322 }
4323 self.advance(); Ok(bindings)
4326 }
4327
4328 fn parse_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4332 use crate::ast::Expr;
4333 let mut fields = Vec::new();
4334
4335 self.advance();
4337
4338 loop {
4339 let field_name = self.expect_identifier()?;
4341
4342 let value = self.parse_imperative_expr()?;
4344
4345 fields.push((field_name, value));
4346
4347 if self.check(&TokenType::And) {
4349 self.advance(); continue;
4351 }
4352 break;
4353 }
4354
4355 Ok(fields)
4356 }
4357
4358 fn parse_variant_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4360 self.parse_constructor_fields()
4361 }
4362
4363 fn parse_struct_init_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4365 self.parse_constructor_fields()
4366 }
4367
4368 fn parse_generic_type_args(&mut self, type_name: Symbol) -> ParseResult<Vec<TypeExpr<'a>>> {
4372 if !self.is_generic_type(type_name) {
4374 return Ok(vec![]);
4375 }
4376
4377 if !self.check_preposition_is("of") {
4379 return Ok(vec![]); }
4381 self.advance(); let mut type_args = Vec::new();
4384 loop {
4385 let type_arg = self.parse_type_expression()?;
4387 type_args.push(type_arg);
4388
4389 if self.check(&TokenType::And) || self.check_to_preposition() {
4391 self.advance(); continue;
4393 }
4394 break;
4395 }
4396
4397 Ok(type_args)
4398 }
4399
4400 fn skip_type_def_content(&mut self) {
4404 while !self.is_at_end() {
4405 if matches!(
4407 self.tokens.get(self.current),
4408 Some(Token { kind: TokenType::BlockHeader { .. }, .. })
4409 ) {
4410 break;
4411 }
4412 self.advance();
4413 }
4414 }
4415
4416 fn parse_theorem_block(&mut self) -> ParseResult<Stmt<'a>> {
4424 use crate::ast::theorem::{TheoremBlock, ProofStrategy};
4425
4426 self.skip_whitespace_tokens();
4428
4429 if self.check(&TokenType::Colon) {
4434 self.advance();
4435 }
4436
4437 self.skip_whitespace_tokens();
4439
4440 let name = if let Some(token) = self.tokens.get(self.current) {
4442 match &token.kind {
4443 TokenType::Noun(_)
4444 | TokenType::ProperName(_)
4445 | TokenType::Verb { .. }
4446 | TokenType::Adjective(_) => {
4447 let name = self.interner.resolve(token.lexeme).to_string();
4448 self.advance();
4449 name
4450 }
4451 _ => {
4452 let lexeme = self.interner.resolve(token.lexeme);
4454 if !lexeme.is_empty() && lexeme.chars().next().map(|c| c.is_alphanumeric()).unwrap_or(false) {
4455 let name = lexeme.to_string();
4456 self.advance();
4457 name
4458 } else {
4459 "Anonymous".to_string()
4460 }
4461 }
4462 }
4463 } else {
4464 "Anonymous".to_string()
4465 };
4466
4467 self.skip_whitespace_tokens();
4468
4469 if self.check(&TokenType::Period) {
4471 self.advance();
4472 }
4473
4474 self.skip_whitespace_tokens();
4475
4476 let mut premises = Vec::new();
4479 while self.check(&TokenType::Given) {
4480 self.advance(); if self.check(&TokenType::Colon) {
4484 self.advance();
4485 }
4486
4487 self.skip_whitespace_tokens();
4488
4489 let premise_expr = self.parse_sentence()?;
4491 premises.push(premise_expr);
4492
4493 self.world_state.end_sentence();
4496
4497 if self.check(&TokenType::Period) {
4499 self.advance();
4500 }
4501
4502 self.skip_whitespace_tokens();
4503 }
4504
4505 let goal = if self.check(&TokenType::Prove) {
4507 self.advance(); if self.check(&TokenType::Colon) {
4510 self.advance();
4511 }
4512
4513 self.skip_whitespace_tokens();
4514
4515 let goal_expr = self.parse_sentence()?;
4516
4517 if self.check(&TokenType::Period) {
4518 self.advance();
4519 }
4520
4521 goal_expr
4522 } else {
4523 return Err(ParseError {
4524 kind: ParseErrorKind::ExpectedKeyword { keyword: "Prove".to_string() },
4525 span: self.current_span(),
4526 });
4527 };
4528
4529 self.skip_whitespace_tokens();
4530
4531 let strategy = if self.check(&TokenType::BlockHeader { block_type: crate::token::BlockType::Proof }) {
4533 self.advance();
4534 self.skip_whitespace_tokens();
4535
4536 if self.check(&TokenType::Colon) {
4537 self.advance();
4538 }
4539
4540 self.skip_whitespace_tokens();
4541
4542 if self.check(&TokenType::Auto) {
4543 self.advance();
4544 ProofStrategy::Auto
4545 } else {
4546 ProofStrategy::Auto
4548 }
4549 } else {
4550 ProofStrategy::Auto
4552 };
4553
4554 if self.check(&TokenType::Period) {
4556 self.advance();
4557 }
4558
4559 let theorem = TheoremBlock {
4560 name,
4561 premises,
4562 goal,
4563 strategy,
4564 };
4565
4566 Ok(Stmt::Theorem(theorem))
4567 }
4568
4569 fn skip_whitespace_tokens(&mut self) {
4571 while self.check(&TokenType::Newline) || self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) {
4572 self.advance();
4573 }
4574 }
4575
4576 fn parse_function_def(&mut self) -> ParseResult<Stmt<'a>> {
4581 if self.check(&TokenType::To) || self.check_preposition_is("to") {
4583 self.advance();
4584 }
4585
4586 let mut is_native = if self.check(&TokenType::Native) {
4588 self.advance(); true
4590 } else {
4591 false
4592 };
4593
4594 let name = self.expect_identifier()?;
4596
4597 let mut params = Vec::new();
4599 while self.check(&TokenType::LParen) {
4600 self.advance(); if self.check(&TokenType::RParen) {
4604 self.advance(); break;
4606 }
4607
4608 loop {
4610 let param_name = self.expect_identifier()?;
4611
4612 if !self.check(&TokenType::Colon) {
4614 return Err(ParseError {
4615 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4616 span: self.current_span(),
4617 });
4618 }
4619 self.advance(); let param_type_expr = self.parse_type_expression()?;
4623 let param_type = self.ctx.alloc_type_expr(param_type_expr);
4624
4625 params.push((param_name, param_type));
4626
4627 if self.check(&TokenType::Comma) {
4629 self.advance(); continue;
4631 }
4632 break;
4633 }
4634
4635 if !self.check(&TokenType::RParen) {
4637 return Err(ParseError {
4638 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4639 span: self.current_span(),
4640 });
4641 }
4642 self.advance(); if self.check_word("and") || self.check_preposition() || self.check(&TokenType::From) {
4647 self.advance();
4648 }
4649 }
4650
4651 let return_type = if self.check(&TokenType::Arrow) {
4653 self.advance(); let ret_type_expr = self.parse_type_expression()?;
4655 Some(self.ctx.alloc_type_expr(ret_type_expr))
4656 } else {
4657 None
4658 };
4659
4660 let mut native_path: Option<Symbol> = None;
4662 let mut is_exported = false;
4663 let mut export_target: Option<Symbol> = None;
4664
4665 if self.check_word("is") {
4666 self.advance(); if self.check(&TokenType::Native) {
4668 self.advance(); is_native = true;
4671 if let TokenType::StringLiteral(sym) = self.peek().kind {
4672 native_path = Some(sym);
4673 self.advance(); } else {
4675 return Err(ParseError {
4676 kind: ParseErrorKind::Custom(
4677 "Expected a string literal for native function path (e.g., is native \"reqwest::blocking::get\")".to_string()
4678 ),
4679 span: self.current_span(),
4680 });
4681 }
4682 } else if self.check_word("exported") {
4683 self.advance(); is_exported = true;
4686 if self.check_word("for") {
4687 self.advance(); let target_sym = self.expect_identifier()?;
4689 let target_str = self.interner.resolve(target_sym);
4690 if !target_str.eq_ignore_ascii_case("c") && !target_str.eq_ignore_ascii_case("wasm") {
4691 return Err(ParseError {
4692 kind: ParseErrorKind::Custom(
4693 format!("Unsupported export target \"{}\". Supported targets are \"c\" and \"wasm\".", target_str)
4694 ),
4695 span: self.current_span(),
4696 });
4697 }
4698 export_target = Some(target_sym);
4699 }
4700 }
4701 }
4702
4703 if is_native {
4705 if self.check(&TokenType::Period) {
4707 self.advance();
4708 }
4709 if self.check(&TokenType::Newline) {
4710 self.advance();
4711 }
4712
4713 let empty_body = self.ctx.stmts.expect("imperative arenas not initialized")
4715 .alloc_slice(std::iter::empty());
4716
4717 return Ok(Stmt::FunctionDef {
4718 name,
4719 params,
4720 body: empty_body,
4721 return_type,
4722 is_native: true,
4723 native_path,
4724 is_exported: false,
4725 export_target: None,
4726 });
4727 }
4728
4729 if !self.check(&TokenType::Colon) {
4731 return Err(ParseError {
4732 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4733 span: self.current_span(),
4734 });
4735 }
4736 self.advance(); if !self.check(&TokenType::Indent) {
4740 return Err(ParseError {
4741 kind: ParseErrorKind::ExpectedStatement,
4742 span: self.current_span(),
4743 });
4744 }
4745 self.advance(); let mut body_stmts = Vec::new();
4749 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4750 if self.check(&TokenType::Newline) {
4752 self.advance();
4753 continue;
4754 }
4755 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
4757 break;
4758 }
4759 let stmt = self.parse_statement()?;
4760 body_stmts.push(stmt);
4761 if self.check(&TokenType::Period) {
4762 self.advance();
4763 }
4764 }
4765
4766 if self.check(&TokenType::Dedent) {
4768 self.advance();
4769 }
4770
4771 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4773 .alloc_slice(body_stmts.into_iter());
4774
4775 Ok(Stmt::FunctionDef {
4776 name,
4777 params,
4778 body,
4779 return_type,
4780 is_native: false,
4781 native_path: None,
4782 is_exported,
4783 export_target,
4784 })
4785 }
4786
4787 fn parse_primary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
4789 use crate::ast::{Expr, Literal};
4790
4791 let token = self.peek().clone();
4792 match &token.kind {
4793 TokenType::New => {
4797 self.advance(); let base_type_name = self.expect_identifier()?;
4799
4800 let type_name = if self.check(&TokenType::From) {
4802 self.advance(); let module_name = self.expect_identifier()?;
4804 let module_str = self.interner.resolve(module_name);
4805 let base_str = self.interner.resolve(base_type_name);
4806 let qualified = format!("{}::{}", module_str, base_str);
4807 self.interner.intern(&qualified)
4808 } else {
4809 base_type_name
4810 };
4811
4812 if let Some(enum_name) = self.find_variant(type_name) {
4814 let fields = if self.check_word("with") {
4816 self.parse_variant_constructor_fields()?
4817 } else {
4818 vec![]
4819 };
4820 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
4821 enum_name,
4822 variant: type_name,
4823 fields,
4824 });
4825 return self.parse_field_access_chain(base);
4826 }
4827
4828 let type_args = self.parse_generic_type_args(type_name)?;
4830
4831 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
4834 self.parse_struct_init_fields()?
4835 } else {
4836 vec![]
4837 };
4838
4839 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
4840 return self.parse_field_access_chain(base);
4841 }
4842
4843 TokenType::Article(_) => {
4847 if let Some(next) = self.tokens.get(self.current + 1) {
4850 if matches!(next.kind, TokenType::Manifest) {
4851 self.advance(); return self.parse_primary_expr();
4854 }
4855 if matches!(next.kind, TokenType::Chunk) {
4856 self.advance(); return self.parse_primary_expr();
4859 }
4860 if matches!(next.kind, TokenType::Length) {
4861 self.advance(); return self.parse_primary_expr();
4863 }
4864 }
4865 if let Some(next) = self.tokens.get(self.current + 1) {
4867 if matches!(next.kind, TokenType::New) {
4868 self.advance(); self.advance(); let base_type_name = self.expect_identifier()?;
4871
4872 let type_name = if self.check(&TokenType::From) {
4874 self.advance(); let module_name = self.expect_identifier()?;
4876 let module_str = self.interner.resolve(module_name);
4877 let base_str = self.interner.resolve(base_type_name);
4878 let qualified = format!("{}::{}", module_str, base_str);
4879 self.interner.intern(&qualified)
4880 } else {
4881 base_type_name
4882 };
4883
4884 if let Some(enum_name) = self.find_variant(type_name) {
4886 let fields = if self.check_word("with") {
4888 self.parse_variant_constructor_fields()?
4889 } else {
4890 vec![]
4891 };
4892 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
4893 enum_name,
4894 variant: type_name,
4895 fields,
4896 });
4897 return self.parse_field_access_chain(base);
4898 }
4899
4900 let type_args = self.parse_generic_type_args(type_name)?;
4902
4903 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
4906 self.parse_struct_init_fields()?
4907 } else {
4908 vec![]
4909 };
4910
4911 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
4912 return self.parse_field_access_chain(base);
4913 }
4914 }
4915 let sym = token.lexeme;
4917 self.advance();
4918 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
4919 return self.parse_field_access_chain(base);
4920 }
4921
4922 TokenType::Item => {
4924 self.advance(); let index = if let TokenType::Number(sym) = &self.peek().kind {
4928 let sym = *sym;
4930 self.advance();
4931 let num_str = self.interner.resolve(sym);
4932 let index_val = num_str.parse::<i64>().unwrap_or(0);
4933
4934 if index_val == 0 {
4936 return Err(ParseError {
4937 kind: ParseErrorKind::ZeroIndex,
4938 span: self.current_span(),
4939 });
4940 }
4941
4942 self.ctx.alloc_imperative_expr(
4943 Expr::Literal(crate::ast::Literal::Number(index_val))
4944 )
4945 } else if self.check(&TokenType::LParen) {
4946 self.advance(); let inner = self.parse_imperative_expr()?;
4949 if !self.check(&TokenType::RParen) {
4950 return Err(ParseError {
4951 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4952 span: self.current_span(),
4953 });
4954 }
4955 self.advance(); inner
4957 } else if let TokenType::StringLiteral(sym) = self.peek().kind {
4958 let sym = sym;
4960 self.advance();
4961 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Text(sym)))
4962 } else if !self.check_preposition_is("of") {
4963 let word = self.interner.resolve(self.peek().lexeme);
4965 if word == "true" {
4966 self.advance();
4967 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(true)))
4968 } else if word == "false" {
4969 self.advance();
4970 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(false)))
4971 } else {
4972 let sym = self.peek().lexeme;
4974 self.advance();
4975 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
4976 }
4977 } else {
4978 return Err(ParseError {
4979 kind: ParseErrorKind::ExpectedExpression,
4980 span: self.current_span(),
4981 });
4982 };
4983
4984 if !self.check_preposition_is("of") {
4986 return Err(ParseError {
4987 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
4988 span: self.current_span(),
4989 });
4990 }
4991 self.advance(); let collection = self.parse_primary_expr()?;
4996
4997 Ok(self.ctx.alloc_imperative_expr(Expr::Index {
4998 collection,
4999 index,
5000 }))
5001 }
5002
5003 TokenType::Items => {
5006 let is_slice_syntax = if let Some(next) = self.tokens.get(self.current + 1) {
5010 matches!(next.kind, TokenType::Number(_) | TokenType::LParen)
5011 } else {
5012 false
5013 };
5014
5015 if !is_slice_syntax {
5016 let sym = token.lexeme;
5018 self.advance();
5019 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5020 return self.parse_field_access_chain(base);
5021 }
5022
5023 self.advance(); let start = if let TokenType::Number(sym) = &self.peek().kind {
5027 let sym = *sym;
5029 self.advance();
5030 let num_str = self.interner.resolve(sym);
5031 let start_val = num_str.parse::<i64>().unwrap_or(0);
5032
5033 if start_val == 0 {
5035 return Err(ParseError {
5036 kind: ParseErrorKind::ZeroIndex,
5037 span: self.current_span(),
5038 });
5039 }
5040
5041 self.ctx.alloc_imperative_expr(
5042 Expr::Literal(crate::ast::Literal::Number(start_val))
5043 )
5044 } else if self.check(&TokenType::LParen) {
5045 self.advance(); let inner = self.parse_imperative_expr()?;
5048 if !self.check(&TokenType::RParen) {
5049 return Err(ParseError {
5050 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5051 span: self.current_span(),
5052 });
5053 }
5054 self.advance(); inner
5056 } else if !self.check_preposition_is("through") {
5057 let sym = self.peek().lexeme;
5059 self.advance();
5060 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5061 } else {
5062 return Err(ParseError {
5063 kind: ParseErrorKind::ExpectedExpression,
5064 span: self.current_span(),
5065 });
5066 };
5067
5068 if !self.check_preposition_is("through") {
5070 return Err(ParseError {
5071 kind: ParseErrorKind::ExpectedKeyword { keyword: "through".to_string() },
5072 span: self.current_span(),
5073 });
5074 }
5075 self.advance(); let end = if let TokenType::Number(sym) = &self.peek().kind {
5079 let sym = *sym;
5081 self.advance();
5082 let num_str = self.interner.resolve(sym);
5083 let end_val = num_str.parse::<i64>().unwrap_or(0);
5084
5085 if end_val == 0 {
5087 return Err(ParseError {
5088 kind: ParseErrorKind::ZeroIndex,
5089 span: self.current_span(),
5090 });
5091 }
5092
5093 self.ctx.alloc_imperative_expr(
5094 Expr::Literal(crate::ast::Literal::Number(end_val))
5095 )
5096 } else if self.check(&TokenType::LParen) {
5097 self.advance(); let inner = self.parse_imperative_expr()?;
5100 if !self.check(&TokenType::RParen) {
5101 return Err(ParseError {
5102 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5103 span: self.current_span(),
5104 });
5105 }
5106 self.advance(); inner
5108 } else if !self.check_preposition_is("of") {
5109 let sym = self.peek().lexeme;
5111 self.advance();
5112 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5113 } else {
5114 return Err(ParseError {
5115 kind: ParseErrorKind::ExpectedExpression,
5116 span: self.current_span(),
5117 });
5118 };
5119
5120 let collection = if self.check_preposition_is("of") {
5123 self.advance(); self.parse_imperative_expr()?
5125 } else {
5126 let items_sym = self.interner.intern("items");
5129 self.ctx.alloc_imperative_expr(Expr::Identifier(items_sym))
5130 };
5131
5132 Ok(self.ctx.alloc_imperative_expr(Expr::Slice {
5133 collection,
5134 start,
5135 end,
5136 }))
5137 }
5138
5139 TokenType::LBracket => {
5141 self.advance(); let mut items = Vec::new();
5144 if !self.check(&TokenType::RBracket) {
5145 loop {
5146 items.push(self.parse_imperative_expr()?);
5147 if !self.check(&TokenType::Comma) {
5148 break;
5149 }
5150 self.advance(); }
5152 }
5153
5154 if !self.check(&TokenType::RBracket) {
5155 return Err(ParseError {
5156 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
5157 span: self.current_span(),
5158 });
5159 }
5160 self.advance(); if items.is_empty() && self.check_word("of") {
5164 self.advance(); let type_name = self.expect_identifier()?;
5166 let seq_sym = self.interner.intern("Seq");
5168 return Ok(self.ctx.alloc_imperative_expr(Expr::New {
5169 type_name: seq_sym,
5170 type_args: vec![TypeExpr::Named(type_name)],
5171 init_fields: vec![],
5172 }));
5173 }
5174
5175 Ok(self.ctx.alloc_imperative_expr(Expr::List(items)))
5176 }
5177
5178 TokenType::Number(sym) => {
5179 let num_str = self.interner.resolve(*sym).to_string();
5180 self.advance();
5181
5182 if let TokenType::CalendarUnit(unit) = self.peek().kind {
5184 return self.parse_span_literal_from_num(&num_str);
5185 }
5186
5187 if num_str.contains('.') {
5189 let num = num_str.parse::<f64>().unwrap_or(0.0);
5190 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Float(num))))
5191 } else {
5192 let num = num_str.parse::<i64>().unwrap_or(0);
5193 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(num))))
5194 }
5195 }
5196
5197 TokenType::StringLiteral(sym) => {
5199 self.advance();
5200 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Text(*sym))))
5201 }
5202
5203 TokenType::CharLiteral(sym) => {
5205 let char_str = self.interner.resolve(*sym);
5206 let ch = char_str.chars().next().unwrap_or('\0');
5207 self.advance();
5208 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Char(ch))))
5209 }
5210
5211 TokenType::DurationLiteral { nanos, .. } => {
5213 let nanos = *nanos;
5214 self.advance();
5215 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Duration(nanos))))
5216 }
5217
5218 TokenType::DateLiteral { days } => {
5221 let days = *days;
5222 self.advance();
5223
5224 if self.check(&TokenType::At) {
5226 self.advance(); if let TokenType::TimeLiteral { nanos_from_midnight } = self.peek().kind {
5230 let time_nanos = nanos_from_midnight;
5231 self.advance(); let moment_nanos = (days as i64) * 86_400_000_000_000 + time_nanos;
5235 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Moment(moment_nanos))));
5236 } else {
5237 return Err(ParseError {
5238 kind: ParseErrorKind::ExpectedExpression,
5239 span: self.current_span(),
5240 });
5241 }
5242 }
5243
5244 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Date(days))))
5245 }
5246
5247 TokenType::TimeLiteral { nanos_from_midnight } => {
5249 let nanos = *nanos_from_midnight;
5250 self.advance();
5251 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Time(nanos))))
5252 }
5253
5254 TokenType::Nothing => {
5256 self.advance();
5257 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)))
5258 }
5259
5260 TokenType::Some => {
5262 self.advance(); let value = self.parse_imperative_expr()?;
5264 Ok(self.ctx.alloc_imperative_expr(Expr::OptionSome { value }))
5265 }
5266
5267 TokenType::Length => {
5269 let func_name = self.peek().lexeme;
5270
5271 if self.tokens.get(self.current + 1)
5273 .map(|t| matches!(t.kind, TokenType::LParen))
5274 .unwrap_or(false)
5275 {
5276 self.advance(); return self.parse_call_expr(func_name);
5278 }
5279
5280 self.advance(); if !self.check_preposition_is("of") {
5284 return Err(ParseError {
5285 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5286 span: self.current_span(),
5287 });
5288 }
5289 self.advance(); let collection = self.parse_imperative_expr()?;
5292 Ok(self.ctx.alloc_imperative_expr(Expr::Length { collection }))
5293 }
5294
5295 TokenType::Copy => {
5297 let func_name = self.peek().lexeme;
5298
5299 if self.tokens.get(self.current + 1)
5301 .map(|t| matches!(t.kind, TokenType::LParen))
5302 .unwrap_or(false)
5303 {
5304 self.advance(); return self.parse_call_expr(func_name);
5306 }
5307
5308 self.advance(); if !self.check_preposition_is("of") {
5312 return Err(ParseError {
5313 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5314 span: self.current_span(),
5315 });
5316 }
5317 self.advance(); let expr = self.parse_imperative_expr()?;
5320 Ok(self.ctx.alloc_imperative_expr(Expr::Copy { expr }))
5321 }
5322
5323 TokenType::Manifest => {
5325 self.advance(); if !self.check_preposition_is("of") {
5329 return Err(ParseError {
5330 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5331 span: self.current_span(),
5332 });
5333 }
5334 self.advance(); let zone = self.parse_imperative_expr()?;
5337 Ok(self.ctx.alloc_imperative_expr(Expr::ManifestOf { zone }))
5338 }
5339
5340 TokenType::Chunk => {
5342 self.advance(); if !self.check(&TokenType::At) {
5346 return Err(ParseError {
5347 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
5348 span: self.current_span(),
5349 });
5350 }
5351 self.advance(); let index = self.parse_imperative_expr()?;
5354
5355 if !self.check_preposition_is("in") && !self.check(&TokenType::In) {
5357 return Err(ParseError {
5358 kind: ParseErrorKind::ExpectedKeyword { keyword: "in".to_string() },
5359 span: self.current_span(),
5360 });
5361 }
5362 self.advance(); let zone = self.parse_imperative_expr()?;
5365 Ok(self.ctx.alloc_imperative_expr(Expr::ChunkAt { index, zone }))
5366 }
5367
5368 TokenType::Verb { lemma, .. } => {
5372 let word = self.interner.resolve(*lemma).to_lowercase();
5373 if word == "empty" {
5374 self.advance();
5375 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5376 }
5377 let sym = token.lexeme;
5379 self.advance();
5380 if self.check(&TokenType::LParen) {
5381 return self.parse_call_expr(sym);
5382 }
5383 self.verify_identifier_access(sym)?;
5385 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5386 self.parse_field_access_chain(base)
5387 }
5388
5389 TokenType::TemporalAdverb(_) | TokenType::ScopalAdverb(_) | TokenType::Adverb(_) => {
5391 let sym = token.lexeme;
5392 self.advance();
5393 if self.check(&TokenType::LParen) {
5394 return self.parse_call_expr(sym);
5395 }
5396 self.verify_identifier_access(sym)?;
5398 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5399 self.parse_field_access_chain(base)
5400 }
5401
5402 TokenType::Read | TokenType::Write | TokenType::File | TokenType::Console |
5405 TokenType::Add | TokenType::Remove => {
5406 let sym = token.lexeme;
5407 self.advance();
5408 if self.check(&TokenType::LParen) {
5409 return self.parse_call_expr(sym);
5410 }
5411 self.verify_identifier_access(sym)?;
5413 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5414 self.parse_field_access_chain(base)
5415 }
5416
5417 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
5420 let sym = *sym;
5421 let word = self.interner.resolve(sym);
5422
5423 if word == "true" {
5425 self.advance();
5426 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(true))));
5427 }
5428 if word == "false" {
5429 self.advance();
5430 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(false))));
5431 }
5432
5433 if word == "empty" {
5435 self.advance();
5436 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5437 }
5438
5439 if word == "none" {
5441 self.advance();
5442 return Ok(self.ctx.alloc_imperative_expr(Expr::OptionNone));
5443 }
5444
5445 self.advance();
5447
5448 if self.check(&TokenType::LParen) {
5450 return self.parse_call_expr(sym);
5451 }
5452
5453 if let Some(enum_name) = self.find_variant(sym) {
5455 let fields = if self.check_word("with") {
5456 self.parse_variant_constructor_fields()?
5457 } else {
5458 vec![]
5459 };
5460 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
5461 enum_name,
5462 variant: sym,
5463 fields,
5464 });
5465 return self.parse_field_access_chain(base);
5466 }
5467
5468 self.verify_identifier_access(sym)?;
5470 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5471 self.parse_field_access_chain(base)
5473 }
5474
5475 TokenType::Pronoun { .. } => {
5477 let sym = token.lexeme;
5478 self.advance();
5479 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5480 self.parse_field_access_chain(base)
5482 }
5483
5484 TokenType::Merge | TokenType::Increase => {
5486 let sym = token.lexeme;
5487 self.advance();
5488
5489 if self.check(&TokenType::LParen) {
5491 return self.parse_call_expr(sym);
5492 }
5493
5494 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5495 self.parse_field_access_chain(base)
5496 }
5497
5498 TokenType::Escape => {
5502 if self.tokens.get(self.current + 1).map_or(false, |t|
5503 matches!(t.kind, TokenType::To) || {
5504 if let TokenType::Preposition(sym) = t.kind {
5505 sym.is(self.interner, "to")
5506 } else {
5507 false
5508 }
5509 }
5510 ) {
5511 return self.parse_escape_expr();
5512 }
5513 let sym = token.lexeme;
5515 self.advance();
5516 if self.check(&TokenType::LParen) {
5517 return self.parse_call_expr(sym);
5518 }
5519 self.verify_identifier_access(sym)?;
5520 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5521 self.parse_field_access_chain(base)
5522 }
5523
5524 TokenType::Values | TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared => { let sym = token.lexeme;
5533 self.advance();
5534
5535 if self.check(&TokenType::LParen) {
5537 return self.parse_call_expr(sym);
5538 }
5539
5540 self.verify_identifier_access(sym)?;
5541 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5542 self.parse_field_access_chain(base)
5543 }
5544
5545 TokenType::Ambiguous { primary, alternatives } => {
5547 let sym = token.lexeme;
5550
5551 let is_identifier_token = match &**primary {
5553 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5554 TokenType::Verb { .. } => true,
5555 _ => alternatives.iter().any(|t| matches!(t,
5556 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5557 TokenType::Verb { .. }
5558 ))
5559 };
5560
5561 if is_identifier_token {
5562 self.advance();
5563
5564 if self.check(&TokenType::LParen) {
5566 return self.parse_call_expr(sym);
5567 }
5568
5569 self.verify_identifier_access(sym)?;
5570 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5571 self.parse_field_access_chain(base)
5573 } else {
5574 Err(ParseError {
5575 kind: ParseErrorKind::ExpectedExpression,
5576 span: self.current_span(),
5577 })
5578 }
5579 }
5580
5581 TokenType::LParen => {
5583 self.advance(); let first = self.parse_imperative_expr()?;
5585
5586 if self.check(&TokenType::Comma) {
5588 let mut items = vec![first];
5590 while self.check(&TokenType::Comma) {
5591 self.advance(); items.push(self.parse_imperative_expr()?);
5593 }
5594
5595 if !self.check(&TokenType::RParen) {
5596 return Err(ParseError {
5597 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5598 span: self.current_span(),
5599 });
5600 }
5601 self.advance(); let base = self.ctx.alloc_imperative_expr(Expr::Tuple(items));
5604 self.parse_field_access_chain(base)
5605 } else {
5606 if !self.check(&TokenType::RParen) {
5608 return Err(ParseError {
5609 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5610 span: self.current_span(),
5611 });
5612 }
5613 self.advance(); Ok(first)
5615 }
5616 }
5617
5618 TokenType::Call => {
5620 self.advance(); let function = match &self.peek().kind {
5622 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
5623 let s = *sym;
5624 self.advance();
5625 s
5626 }
5627 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
5628 let s = self.peek().lexeme;
5629 self.advance();
5630 s
5631 }
5632 _ => {
5633 return Err(ParseError {
5634 kind: ParseErrorKind::ExpectedIdentifier,
5635 span: self.current_span(),
5636 });
5637 }
5638 };
5639 let args = if self.check_preposition_is("with") {
5640 self.advance(); self.parse_call_arguments()?
5642 } else {
5643 Vec::new()
5644 };
5645 Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
5646 }
5647
5648 _ => {
5649 Err(ParseError {
5650 kind: ParseErrorKind::ExpectedExpression,
5651 span: self.current_span(),
5652 })
5653 }
5654 }
5655 }
5656
5657 fn parse_imperative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5660 self.parse_additive_expr()
5661 }
5662
5663 fn parse_additive_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5665 let mut left = self.parse_multiplicative_expr()?;
5666
5667 loop {
5668 match &self.peek().kind {
5669 TokenType::Plus => {
5670 self.advance();
5671 let right = self.parse_multiplicative_expr()?;
5672 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5673 op: BinaryOpKind::Add,
5674 left,
5675 right,
5676 });
5677 }
5678 TokenType::Minus => {
5679 self.advance();
5680 let right = self.parse_multiplicative_expr()?;
5681 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5682 op: BinaryOpKind::Subtract,
5683 left,
5684 right,
5685 });
5686 }
5687 TokenType::Combined => {
5689 self.advance(); if !self.check_preposition_is("with") {
5692 return Err(ParseError {
5693 kind: ParseErrorKind::ExpectedKeyword { keyword: "with".to_string() },
5694 span: self.current_span(),
5695 });
5696 }
5697 self.advance(); let right = self.parse_multiplicative_expr()?;
5699 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5700 op: BinaryOpKind::Concat,
5701 left,
5702 right,
5703 });
5704 }
5705 TokenType::Union => {
5707 self.advance(); let right = self.parse_multiplicative_expr()?;
5709 left = self.ctx.alloc_imperative_expr(Expr::Union {
5710 left,
5711 right,
5712 });
5713 }
5714 TokenType::Intersection => {
5715 self.advance(); let right = self.parse_multiplicative_expr()?;
5717 left = self.ctx.alloc_imperative_expr(Expr::Intersection {
5718 left,
5719 right,
5720 });
5721 }
5722 TokenType::Contains => {
5724 self.advance(); let value = self.parse_multiplicative_expr()?;
5726 left = self.ctx.alloc_imperative_expr(Expr::Contains {
5727 collection: left,
5728 value,
5729 });
5730 }
5731 _ => break,
5732 }
5733 }
5734
5735 Ok(left)
5736 }
5737
5738 fn parse_unary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5740 use crate::ast::{Expr, Literal};
5741
5742 if self.check(&TokenType::Minus) {
5743 self.advance(); let operand = self.parse_unary_expr()?; return Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5747 op: BinaryOpKind::Subtract,
5748 left: self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(0))),
5749 right: operand,
5750 }));
5751 }
5752 self.parse_primary_expr()
5753 }
5754
5755 fn parse_multiplicative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5757 let mut left = self.parse_unary_expr()?;
5758
5759 loop {
5760 let op = match &self.peek().kind {
5761 TokenType::Star => {
5762 self.advance();
5763 BinaryOpKind::Multiply
5764 }
5765 TokenType::Slash => {
5766 self.advance();
5767 BinaryOpKind::Divide
5768 }
5769 TokenType::Percent => {
5770 self.advance();
5771 BinaryOpKind::Modulo
5772 }
5773 _ => break,
5774 };
5775 let right = self.parse_unary_expr()?;
5776 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5777 op,
5778 left,
5779 right,
5780 });
5781 }
5782
5783 Ok(left)
5784 }
5785
5786 fn try_parse_binary_op(&mut self) -> Option<BinaryOpKind> {
5788 match &self.peek().kind {
5789 TokenType::Plus => {
5790 self.advance();
5791 Some(BinaryOpKind::Add)
5792 }
5793 TokenType::Minus => {
5794 self.advance();
5795 Some(BinaryOpKind::Subtract)
5796 }
5797 TokenType::Star => {
5798 self.advance();
5799 Some(BinaryOpKind::Multiply)
5800 }
5801 TokenType::Slash => {
5802 self.advance();
5803 Some(BinaryOpKind::Divide)
5804 }
5805 _ => None,
5806 }
5807 }
5808
5809 fn parse_span_literal_from_num(&mut self, first_num_str: &str) -> ParseResult<&'a Expr<'a>> {
5812 use crate::ast::Literal;
5813 use crate::token::CalendarUnit;
5814
5815 let first_num = first_num_str.parse::<i32>().unwrap_or(0);
5816
5817 let unit = match self.peek().kind {
5819 TokenType::CalendarUnit(u) => u,
5820 _ => {
5821 return Err(ParseError {
5822 kind: ParseErrorKind::ExpectedKeyword { keyword: "calendar unit (day, week, month, year)".to_string() },
5823 span: self.current_span(),
5824 });
5825 }
5826 };
5827 self.advance(); let mut total_months: i32 = 0;
5831 let mut total_days: i32 = 0;
5832
5833 match unit {
5835 CalendarUnit::Day => total_days += first_num,
5836 CalendarUnit::Week => total_days += first_num * 7,
5837 CalendarUnit::Month => total_months += first_num,
5838 CalendarUnit::Year => total_months += first_num * 12,
5839 }
5840
5841 while self.check(&TokenType::And) {
5843 self.advance(); let next_num = match &self.peek().kind {
5847 TokenType::Number(sym) => {
5848 let num_str = self.interner.resolve(*sym).to_string();
5849 self.advance();
5850 num_str.parse::<i32>().unwrap_or(0)
5851 }
5852 _ => break, };
5854
5855 let next_unit = match self.peek().kind {
5857 TokenType::CalendarUnit(u) => {
5858 self.advance();
5859 u
5860 }
5861 _ => break, };
5863
5864 match next_unit {
5866 CalendarUnit::Day => total_days += next_num,
5867 CalendarUnit::Week => total_days += next_num * 7,
5868 CalendarUnit::Month => total_months += next_num,
5869 CalendarUnit::Year => total_months += next_num * 12,
5870 }
5871 }
5872
5873 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Span {
5874 months: total_months,
5875 days: total_days,
5876 })))
5877 }
5878
5879 fn parse_call_expr(&mut self, function: Symbol) -> ParseResult<&'a Expr<'a>> {
5881 use crate::ast::Expr;
5882
5883 self.advance(); let mut args = Vec::new();
5886 if !self.check(&TokenType::RParen) {
5887 loop {
5888 args.push(self.parse_imperative_expr()?);
5889 if !self.check(&TokenType::Comma) {
5890 break;
5891 }
5892 self.advance(); }
5894 }
5895
5896 if !self.check(&TokenType::RParen) {
5897 return Err(ParseError {
5898 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5899 span: self.current_span(),
5900 });
5901 }
5902 self.advance(); Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
5905 }
5906
5907 fn parse_field_access_chain(&mut self, base: &'a Expr<'a>) -> ParseResult<&'a Expr<'a>> {
5910 use crate::ast::Expr;
5911
5912 let mut result = base;
5913
5914 loop {
5916 if self.check(&TokenType::Possessive) {
5917 self.advance(); let field = self.expect_identifier()?;
5920 result = self.ctx.alloc_imperative_expr(Expr::FieldAccess {
5921 object: result,
5922 field,
5923 });
5924 } else if self.check(&TokenType::LBracket) {
5925 self.advance(); let index = self.parse_imperative_expr()?;
5928
5929 if !self.check(&TokenType::RBracket) {
5930 return Err(ParseError {
5931 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
5932 span: self.current_span(),
5933 });
5934 }
5935 self.advance(); result = self.ctx.alloc_imperative_expr(Expr::Index {
5938 collection: result,
5939 index,
5940 });
5941 } else {
5942 break;
5943 }
5944 }
5945
5946 Ok(result)
5947 }
5948
5949 fn verify_identifier_access(&self, sym: Symbol) -> ParseResult<()> {
5952 if self.mode != ParserMode::Imperative {
5953 return Ok(());
5954 }
5955
5956 if let Some(crate::drs::OwnershipState::Moved) = self.world_state.get_ownership_by_var(sym) {
5958 return Err(ParseError {
5959 kind: ParseErrorKind::UseAfterMove {
5960 name: self.interner.resolve(sym).to_string()
5961 },
5962 span: self.current_span(),
5963 });
5964 }
5965
5966 Ok(())
5967 }
5968
5969 fn expect_identifier(&mut self) -> ParseResult<Symbol> {
5970 let token = self.peek().clone();
5971 match &token.kind {
5972 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
5974 self.advance();
5975 Ok(*sym)
5976 }
5977 TokenType::Verb { .. } => {
5980 let sym = token.lexeme;
5981 self.advance();
5982 Ok(sym)
5983 }
5984 TokenType::Article(_) => {
5986 let sym = token.lexeme;
5987 self.advance();
5988 Ok(sym)
5989 }
5990 TokenType::Pronoun { .. } | TokenType::Items | TokenType::Values | TokenType::Item | TokenType::Nothing | TokenType::TemporalAdverb(_) |
5998 TokenType::ScopalAdverb(_) |
5999 TokenType::Adverb(_) |
6000 TokenType::Read |
6002 TokenType::Write |
6003 TokenType::File |
6004 TokenType::Console |
6005 TokenType::Merge |
6007 TokenType::Increase |
6008 TokenType::Decrease |
6009 TokenType::Tally |
6011 TokenType::SharedSet |
6012 TokenType::SharedSequence |
6013 TokenType::CollaborativeSequence |
6014 TokenType::Add |
6017 TokenType::Remove |
6018 TokenType::First |
6019 TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared | TokenType::CalendarUnit(_) |
6026 TokenType::Focus(_) |
6028 TokenType::Escape => {
6030 let sym = token.lexeme;
6032 self.advance();
6033 Ok(sym)
6034 }
6035 TokenType::Ambiguous { .. } => {
6036 let sym = token.lexeme;
6039 self.advance();
6040 Ok(sym)
6041 }
6042 _ => Err(ParseError {
6043 kind: ParseErrorKind::ExpectedIdentifier,
6044 span: self.current_span(),
6045 }),
6046 }
6047 }
6048
6049 fn consume_content_word_for_relative(&mut self) -> ParseResult<Symbol> {
6050 let t = self.advance().clone();
6051 match t.kind {
6052 TokenType::Noun(s) | TokenType::Adjective(s) => Ok(s),
6053 TokenType::ProperName(s) => Ok(s),
6054 TokenType::Verb { lemma, .. } => Ok(lemma),
6055 other => Err(ParseError {
6056 kind: ParseErrorKind::ExpectedContentWord { found: other },
6057 span: self.current_span(),
6058 }),
6059 }
6060 }
6061
6062 fn check_modal(&self) -> bool {
6063 matches!(
6064 self.peek().kind,
6065 TokenType::Must
6066 | TokenType::Shall
6067 | TokenType::Should
6068 | TokenType::Can
6069 | TokenType::May
6070 | TokenType::Cannot
6071 | TokenType::Could
6072 | TokenType::Would
6073 | TokenType::Might
6074 )
6075 }
6076
6077 fn check_pronoun(&self) -> bool {
6078 match &self.peek().kind {
6079 TokenType::Pronoun { case, .. } => {
6080 if self.noun_priority_mode && matches!(case, Case::Possessive) {
6082 return false;
6083 }
6084 true
6085 }
6086 TokenType::Ambiguous { primary, alternatives } => {
6087 if self.noun_priority_mode {
6089 let has_possessive = matches!(**primary, TokenType::Pronoun { case: Case::Possessive, .. })
6090 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { case: Case::Possessive, .. }));
6091 if has_possessive {
6092 return false;
6093 }
6094 }
6095 matches!(**primary, TokenType::Pronoun { .. })
6096 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { .. }))
6097 }
6098 _ => false,
6099 }
6100 }
6101
6102 fn parse_atom(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
6103 if self.check_focus() {
6105 return self.parse_focus();
6106 }
6107
6108 if self.check_measure() {
6110 return self.parse_measure();
6111 }
6112
6113 if self.check_quantifier() {
6114 self.advance();
6115 return self.parse_quantified();
6116 }
6117
6118 if self.check_npi_quantifier() {
6119 return self.parse_npi_quantified();
6120 }
6121
6122 if self.check_temporal_npi() {
6123 return self.parse_temporal_npi();
6124 }
6125
6126 if self.match_token(&[TokenType::LParen]) {
6127 let expr = self.parse_sentence()?;
6128 self.consume(TokenType::RParen)?;
6129 return Ok(expr);
6130 }
6131
6132 if self.check_pronoun() {
6134 let token = self.advance().clone();
6135 let (gender, number) = match &token.kind {
6136 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
6137 TokenType::Ambiguous { primary, alternatives } => {
6138 if let TokenType::Pronoun { gender, number, .. } = **primary {
6139 (gender, number)
6140 } else {
6141 alternatives.iter().find_map(|t| {
6142 if let TokenType::Pronoun { gender, number, .. } = t {
6143 Some((*gender, *number))
6144 } else {
6145 None
6146 }
6147 }).unwrap_or((Gender::Unknown, Number::Singular))
6148 }
6149 }
6150 _ => (Gender::Unknown, Number::Singular),
6151 };
6152
6153 let token_text = self.interner.resolve(token.lexeme);
6154
6155 if token_text.eq_ignore_ascii_case("it") && self.check_verb() {
6158 if let TokenType::Verb { lemma, time, .. } = &self.peek().kind {
6159 let lemma_str = self.interner.resolve(*lemma);
6160 if Lexer::is_weather_verb(lemma_str) {
6161 let verb = *lemma;
6162 let verb_time = *time;
6163 self.advance(); let event_var = self.get_event_var();
6166 let suppress_existential = self.drs.in_conditional_antecedent();
6167 if suppress_existential {
6168 let event_class = self.interner.intern("Event");
6169 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
6170 }
6171 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6172 event_var,
6173 verb,
6174 roles: self.ctx.roles.alloc_slice(vec![]), modifiers: self.ctx.syms.alloc_slice(vec![]),
6176 suppress_existential,
6177 world: None,
6178 })));
6179
6180 return Ok(match verb_time {
6181 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
6182 operator: TemporalOperator::Past,
6183 body: neo_event,
6184 }),
6185 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
6186 operator: TemporalOperator::Future,
6187 body: neo_event,
6188 }),
6189 _ => neo_event,
6190 });
6191 }
6192 }
6193 }
6194
6195 let resolved = if token_text.eq_ignore_ascii_case("i") {
6197 ResolvedPronoun::Constant(self.interner.intern("Speaker"))
6198 } else if token_text.eq_ignore_ascii_case("you") {
6199 ResolvedPronoun::Constant(self.interner.intern("Addressee"))
6200 } else {
6201 self.resolve_pronoun(gender, number)?
6203 };
6204
6205 if self.check_performative() {
6207 if let TokenType::Performative(act) = self.advance().kind.clone() {
6208 let sym = match resolved {
6209 ResolvedPronoun::Variable(s) | ResolvedPronoun::Constant(s) => s,
6210 };
6211 if self.check(&TokenType::To) {
6213 self.advance(); if self.check_verb() {
6216 let infinitive_verb = self.consume_verb();
6217
6218 let content = self.ctx.exprs.alloc(LogicExpr::Predicate {
6219 name: infinitive_verb,
6220 args: self.ctx.terms.alloc_slice([Term::Constant(sym)]),
6221 world: None,
6222 });
6223
6224 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6225 performer: sym,
6226 act_type: act,
6227 content,
6228 }));
6229 }
6230 }
6231
6232 if self.check(&TokenType::That) {
6234 self.advance();
6235 }
6236 let content = self.parse_sentence()?;
6237 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6238 performer: sym,
6239 act_type: act,
6240 content,
6241 }));
6242 }
6243 }
6244
6245 return match resolved {
6248 ResolvedPronoun::Variable(sym) => self.parse_predicate_with_subject_as_var(sym),
6249 ResolvedPronoun::Constant(sym) => self.parse_predicate_with_subject(sym),
6250 };
6251 }
6252
6253 let _had_both = self.match_token(&[TokenType::Both]);
6256
6257 let subject = self.parse_noun_phrase(true)?;
6258
6259 if subject.definiteness == Some(Definiteness::Indefinite)
6265 || subject.definiteness == Some(Definiteness::Distal) {
6266 let gender = Self::infer_noun_gender(self.interner.resolve(subject.noun));
6267 let number = if Self::is_plural_noun(self.interner.resolve(subject.noun)) {
6268 Number::Plural
6269 } else {
6270 Number::Singular
6271 };
6272 self.drs.introduce_referent(subject.noun, subject.noun, gender, number);
6274 }
6275
6276 if self.check(&TokenType::And) {
6278 match self.try_parse_plural_subject(&subject) {
6279 Ok(Some(result)) => return Ok(result),
6280 Ok(None) => {} Err(e) => return Err(e), }
6283 }
6284
6285 if self.check_scopal_adverb() {
6287 return self.parse_scopal_adverb(&subject);
6288 }
6289
6290 if self.check(&TokenType::Comma) {
6292 let saved_pos = self.current;
6293 self.advance(); if self.check_pronoun() {
6297 let topic_attempt = self.try_parse(|p| {
6298 let token = p.peek().clone();
6299 let pronoun_features = match &token.kind {
6300 TokenType::Pronoun { gender, number, .. } => Some((*gender, *number)),
6301 TokenType::Ambiguous { primary, alternatives } => {
6302 if let TokenType::Pronoun { gender, number, .. } = **primary {
6303 Some((gender, number))
6304 } else {
6305 alternatives.iter().find_map(|t| {
6306 if let TokenType::Pronoun { gender, number, .. } = t {
6307 Some((*gender, *number))
6308 } else {
6309 None
6310 }
6311 })
6312 }
6313 }
6314 _ => None,
6315 };
6316
6317 if let Some((gender, number)) = pronoun_features {
6318 p.advance(); let resolved = p.resolve_pronoun(gender, number)?;
6320 let resolved_term = match resolved {
6321 ResolvedPronoun::Variable(s) => Term::Variable(s),
6322 ResolvedPronoun::Constant(s) => Term::Constant(s),
6323 };
6324
6325 if p.check_verb() {
6326 let verb = p.consume_verb();
6327 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6328 name: verb,
6329 args: p.ctx.terms.alloc_slice([
6330 resolved_term,
6331 Term::Constant(subject.noun),
6332 ]),
6333 world: None,
6334 });
6335 p.wrap_with_definiteness_full(&subject, predicate)
6336 } else {
6337 Err(ParseError {
6338 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6339 span: p.current_span(),
6340 })
6341 }
6342 } else {
6343 Err(ParseError {
6344 kind: ParseErrorKind::ExpectedContentWord { found: token.kind },
6345 span: p.current_span(),
6346 })
6347 }
6348 });
6349
6350 if let Some(result) = topic_attempt {
6351 return Ok(result);
6352 }
6353 }
6354
6355 if self.check_content_word() {
6357 let topic_attempt = self.try_parse(|p| {
6358 let real_subject = p.parse_noun_phrase(true)?;
6359 if p.check_verb() {
6360 let verb = p.consume_verb();
6361 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6362 name: verb,
6363 args: p.ctx.terms.alloc_slice([
6364 Term::Constant(real_subject.noun),
6365 Term::Constant(subject.noun),
6366 ]),
6367 world: None,
6368 });
6369 p.wrap_with_definiteness_full(&subject, predicate)
6370 } else {
6371 Err(ParseError {
6372 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6373 span: p.current_span(),
6374 })
6375 }
6376 });
6377
6378 if let Some(result) = topic_attempt {
6379 return Ok(result);
6380 }
6381 }
6382
6383 self.current = saved_pos;
6385 }
6386
6387 let mut relative_clause: Option<(Symbol, &'a LogicExpr<'a>)> = None;
6389 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
6390 self.advance();
6391 let var_name = self.next_var_name();
6392 let rel_pred = self.parse_relative_clause(var_name)?;
6393 relative_clause = Some((var_name, rel_pred));
6394 } else if matches!(self.peek().kind, TokenType::Article(_)) && self.is_contact_clause_pattern() {
6395 let var_name = self.next_var_name();
6398 let rel_pred = self.parse_relative_clause(var_name)?;
6399 relative_clause = Some((var_name, rel_pred));
6400 }
6401
6402 if let Some((var_name, rel_clause)) = relative_clause {
6404 if self.check_verb() {
6405 let (verb, verb_time, _, _) = self.consume_verb_with_metadata();
6406 let var_term = Term::Variable(var_name);
6407
6408 let event_var = self.get_event_var();
6409 let suppress_existential = self.drs.in_conditional_antecedent();
6410 let mut modifiers = vec![];
6411 if verb_time == Time::Past {
6412 modifiers.push(self.interner.intern("Past"));
6413 }
6414 let main_pred = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6415 event_var,
6416 verb,
6417 roles: self.ctx.roles.alloc_slice(vec![
6418 (ThematicRole::Agent, var_term),
6419 ]),
6420 modifiers: self.ctx.syms.alloc_slice(modifiers),
6421 suppress_existential,
6422 world: None,
6423 })));
6424
6425 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6426 name: subject.noun,
6427 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6428 world: None,
6429 });
6430
6431 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6432 left: type_pred,
6433 op: TokenType::And,
6434 right: rel_clause,
6435 });
6436
6437 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6438 left: inner,
6439 op: TokenType::And,
6440 right: main_pred,
6441 });
6442
6443 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6444 kind: QuantifierKind::Existential,
6445 variable: var_name,
6446 body,
6447 island_id: self.current_island,
6448 }));
6449 }
6450
6451 if self.is_at_end() || self.check(&TokenType::Period) || self.check(&TokenType::Comma) {
6454 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6455 name: subject.noun,
6456 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6457 world: None,
6458 });
6459
6460 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6461 left: type_pred,
6462 op: TokenType::And,
6463 right: rel_clause,
6464 });
6465
6466 let uniqueness_body = if subject.definiteness == Some(Definiteness::Definite) {
6468 let y_var = self.next_var_name();
6469 let type_pred_y = self.ctx.exprs.alloc(LogicExpr::Predicate {
6470 name: subject.noun,
6471 args: self.ctx.terms.alloc_slice([Term::Variable(y_var)]),
6472 world: None,
6473 });
6474 let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
6475 left: self.ctx.terms.alloc(Term::Variable(y_var)),
6476 right: self.ctx.terms.alloc(Term::Variable(var_name)),
6477 });
6478 let uniqueness_cond = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6479 left: type_pred_y,
6480 op: TokenType::If,
6481 right: identity,
6482 });
6483 let uniqueness = self.ctx.exprs.alloc(LogicExpr::Quantifier {
6484 kind: QuantifierKind::Universal,
6485 variable: y_var,
6486 body: uniqueness_cond,
6487 island_id: self.current_island,
6488 });
6489 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6490 left: body,
6491 op: TokenType::And,
6492 right: uniqueness,
6493 })
6494 } else {
6495 body
6496 };
6497
6498 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6499 kind: QuantifierKind::Existential,
6500 variable: var_name,
6501 body: uniqueness_body,
6502 island_id: self.current_island,
6503 }));
6504 }
6505
6506 relative_clause = Some((var_name, rel_clause));
6508 }
6509
6510 if self.check(&TokenType::Identity) {
6512 self.advance();
6513 let right = self.consume_content_word()?;
6514 return Ok(self.ctx.exprs.alloc(LogicExpr::Identity {
6515 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6516 right: self.ctx.terms.alloc(Term::Constant(right)),
6517 }));
6518 }
6519
6520 if self.check_modal() {
6521 if let Some((var_name, rel_clause)) = relative_clause {
6522 let modal_pred = self.parse_aspect_chain_with_term(Term::Variable(var_name))?;
6523
6524 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6525 name: subject.noun,
6526 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6527 world: None,
6528 });
6529
6530 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6531 left: type_pred,
6532 op: TokenType::And,
6533 right: rel_clause,
6534 });
6535
6536 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6537 left: inner,
6538 op: TokenType::And,
6539 right: modal_pred,
6540 });
6541
6542 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6543 kind: QuantifierKind::Existential,
6544 variable: var_name,
6545 body,
6546 island_id: self.current_island,
6547 }));
6548 }
6549
6550 let modal_pred = self.parse_aspect_chain(subject.noun)?;
6551 return self.wrap_with_definiteness_full(&subject, modal_pred);
6552 }
6553
6554 if self.check(&TokenType::Is) || self.check(&TokenType::Are)
6555 || self.check(&TokenType::Was) || self.check(&TokenType::Were)
6556 {
6557 let copula_time = if self.check(&TokenType::Was) || self.check(&TokenType::Were) {
6558 Time::Past
6559 } else {
6560 Time::Present
6561 };
6562 self.advance();
6563
6564 let is_negated = self.check(&TokenType::Not);
6566 if is_negated {
6567 self.advance(); }
6569
6570 if self.check_number() {
6573 let measure = self.parse_measure_phrase()?;
6574
6575 if self.check_comparative() {
6577 return self.parse_comparative(&subject, copula_time, Some(measure));
6578 }
6579
6580 if self.check_content_word() {
6582 let adj = self.consume_content_word()?;
6583 let result = self.ctx.exprs.alloc(LogicExpr::Predicate {
6584 name: adj,
6585 args: self.ctx.terms.alloc_slice([
6586 Term::Constant(subject.noun),
6587 *measure,
6588 ]),
6589 world: None,
6590 });
6591 return self.wrap_with_definiteness_full(&subject, result);
6592 }
6593
6594 if self.check(&TokenType::Period) || self.is_at_end() {
6597 if self.mode == ParserMode::Imperative {
6599 let variable = self.interner.resolve(subject.noun).to_string();
6600 let value = if let Term::Value { kind, .. } = measure {
6601 format!("{:?}", kind)
6602 } else {
6603 "value".to_string()
6604 };
6605 return Err(ParseError {
6606 kind: ParseErrorKind::IsValueEquality { variable, value },
6607 span: self.current_span(),
6608 });
6609 }
6610 let result = self.ctx.exprs.alloc(LogicExpr::Identity {
6611 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6612 right: measure,
6613 });
6614 return self.wrap_with_definiteness_full(&subject, result);
6615 }
6616 }
6617
6618 if self.check_comparative() {
6620 return self.parse_comparative(&subject, copula_time, None);
6621 }
6622
6623 if self.check(&TokenType::Period) || self.is_at_end() {
6625 let var = self.next_var_name();
6626 let body = self.ctx.exprs.alloc(LogicExpr::Identity {
6627 left: self.ctx.terms.alloc(Term::Variable(var)),
6628 right: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6629 });
6630 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6631 kind: QuantifierKind::Existential,
6632 variable: var,
6633 body,
6634 island_id: self.current_island,
6635 }));
6636 }
6637
6638 if self.check(&TokenType::Article(Definiteness::Definite)) {
6640 let saved_pos = self.current;
6641 self.advance();
6642 if self.check_superlative() {
6643 return self.parse_superlative(&subject);
6644 }
6645 self.current = saved_pos;
6646 }
6647
6648 if self.check_article() {
6650 let predicate_np = self.parse_noun_phrase(true)?;
6651 let predicate_noun = predicate_np.noun;
6652
6653 if self.event_reading_mode {
6656 let noun_str = self.interner.resolve(predicate_noun);
6657 if let Some(base_verb) = lexicon::lookup_agentive_noun(noun_str) {
6658 let event_adj = predicate_np.adjectives.iter().find(|adj| {
6660 lexicon::is_event_modifier_adjective(self.interner.resolve(**adj))
6661 });
6662
6663 if let Some(&adj_sym) = event_adj {
6664 let verb_sym = self.interner.intern(base_verb);
6666 let event_var = self.get_event_var();
6667
6668 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6669 name: verb_sym,
6670 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
6671 world: None,
6672 });
6673
6674 let agent_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6675 name: self.interner.intern("Agent"),
6676 args: self.ctx.terms.alloc_slice([
6677 Term::Variable(event_var),
6678 Term::Constant(subject.noun),
6679 ]),
6680 world: None,
6681 });
6682
6683 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6684 name: adj_sym,
6685 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
6686 world: None,
6687 });
6688
6689 let verb_agent = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6691 left: verb_pred,
6692 op: TokenType::And,
6693 right: agent_pred,
6694 });
6695
6696 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6698 left: verb_agent,
6699 op: TokenType::And,
6700 right: adj_pred,
6701 });
6702
6703 let event_reading = self.ctx.exprs.alloc(LogicExpr::Quantifier {
6705 kind: QuantifierKind::Existential,
6706 variable: event_var,
6707 body,
6708 island_id: self.current_island,
6709 });
6710
6711 return self.wrap_with_definiteness(subject.definiteness, subject.noun, event_reading);
6712 }
6713 }
6714 }
6715
6716 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
6717 let predicate_sort = lexicon::lookup_sort(self.interner.resolve(predicate_noun));
6718
6719 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
6720 if !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
6721 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
6722 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6723 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_noun)),
6724 });
6725 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
6726 }
6727 }
6728
6729 let mut predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
6732
6733 for &adj_sym in predicate_np.adjectives {
6735 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6736 name: adj_sym,
6737 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
6738 world: None,
6739 });
6740 predicates.push(adj_pred);
6741 }
6742
6743 let noun_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6745 name: predicate_noun,
6746 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
6747 world: None,
6748 });
6749 predicates.push(noun_pred);
6750
6751 let result = if predicates.len() == 1 {
6753 predicates[0]
6754 } else {
6755 let mut combined = predicates[0];
6756 for pred in &predicates[1..] {
6757 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6758 left: combined,
6759 op: TokenType::And,
6760 right: *pred,
6761 });
6762 }
6763 combined
6764 };
6765
6766 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
6767 }
6768
6769 let prefer_adjective = if let TokenType::Ambiguous { primary, alternatives } = &self.peek().kind {
6772 let is_simple_verb = if let TokenType::Verb { aspect, .. } = **primary {
6773 aspect == Aspect::Simple
6774 } else {
6775 false
6776 };
6777 let has_adj_alt = alternatives.iter().any(|t| matches!(t, TokenType::Adjective(_)));
6778 is_simple_verb && has_adj_alt
6779 } else {
6780 false
6781 };
6782
6783 if !prefer_adjective && self.check_verb() {
6784 let (verb, _verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
6785
6786 if verb_class.is_stative() && verb_aspect == Aspect::Progressive {
6788 return Err(ParseError {
6789 kind: ParseErrorKind::StativeProgressiveConflict,
6790 span: self.current_span(),
6791 });
6792 }
6793
6794 let mut goal_args: Vec<Term<'a>> = Vec::new();
6797 while self.check_to_preposition() {
6798 self.advance(); let goal = self.parse_noun_phrase(true)?;
6800 goal_args.push(self.noun_phrase_to_term(&goal));
6801 }
6802
6803 if self.check_by_preposition() {
6805 self.advance(); let agent = self.parse_noun_phrase(true)?;
6807
6808 let mut args = vec![
6810 self.noun_phrase_to_term(&agent),
6811 self.noun_phrase_to_term(&subject),
6812 ];
6813 args.extend(goal_args);
6814
6815 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
6816 name: verb,
6817 args: self.ctx.terms.alloc_slice(args),
6818 world: None,
6819 });
6820
6821 let with_time = if copula_time == Time::Past {
6822 self.ctx.exprs.alloc(LogicExpr::Temporal {
6823 operator: TemporalOperator::Past,
6824 body: predicate,
6825 })
6826 } else {
6827 predicate
6828 };
6829
6830 return self.wrap_with_definiteness(subject.definiteness, subject.noun, with_time);
6831 }
6832
6833 if copula_time == Time::Past && verb_aspect == Aspect::Simple
6838 && subject.definiteness != Some(Definiteness::Definite) {
6839 let var_name = self.next_var_name();
6841 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
6842 name: verb,
6843 args: self.ctx.terms.alloc_slice([
6844 Term::Variable(var_name),
6845 Term::Constant(subject.noun),
6846 ]),
6847 world: None,
6848 });
6849
6850 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6851 name: subject.noun,
6852 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6853 world: None,
6854 });
6855
6856 let temporal = self.ctx.exprs.alloc(LogicExpr::Temporal {
6857 operator: TemporalOperator::Past,
6858 body: predicate,
6859 });
6860
6861 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6862 left: type_pred,
6863 op: TokenType::And,
6864 right: temporal,
6865 });
6866
6867 let result = self.ctx.exprs.alloc(LogicExpr::Quantifier {
6868 kind: QuantifierKind::Existential,
6869 variable: var_name,
6870 body,
6871 island_id: self.current_island,
6872 });
6873
6874 if is_negated {
6876 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
6877 op: TokenType::Not,
6878 operand: result,
6879 }));
6880 }
6881 return Ok(result);
6882 }
6883
6884 let verb_str = self.interner.resolve(verb).to_lowercase();
6887 let subject_term = if lexicon::is_intensional_predicate(&verb_str) {
6888 Term::Intension(subject.noun)
6889 } else {
6890 Term::Constant(subject.noun)
6891 };
6892
6893 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
6894 name: verb,
6895 args: self.ctx.terms.alloc_slice([subject_term]),
6896 world: None,
6897 });
6898
6899 let with_aspect = if verb_aspect == Aspect::Progressive {
6900 let operator = if verb_class == VerbClass::Semelfactive {
6902 AspectOperator::Iterative
6903 } else {
6904 AspectOperator::Progressive
6905 };
6906 self.ctx.exprs.alloc(LogicExpr::Aspectual {
6907 operator,
6908 body: predicate,
6909 })
6910 } else {
6911 predicate
6912 };
6913
6914 let with_time = if copula_time == Time::Past {
6915 self.ctx.exprs.alloc(LogicExpr::Temporal {
6916 operator: TemporalOperator::Past,
6917 body: with_aspect,
6918 })
6919 } else {
6920 with_aspect
6921 };
6922
6923 let final_expr = if is_negated {
6924 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
6925 op: TokenType::Not,
6926 operand: with_time,
6927 })
6928 } else {
6929 with_time
6930 };
6931
6932 if subject.definiteness == Some(Definiteness::Definite) {
6936 return Ok(final_expr);
6937 }
6938
6939 return self.wrap_with_definiteness(subject.definiteness, subject.noun, final_expr);
6940 }
6941
6942 if let Some((var_name, rel_clause)) = relative_clause {
6944 let var_term = Term::Variable(var_name);
6945 let pred_word = self.consume_content_word()?;
6946
6947 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6948 name: pred_word,
6949 args: self.ctx.terms.alloc_slice([var_term]),
6950 world: None,
6951 });
6952
6953 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6954 name: subject.noun,
6955 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6956 world: None,
6957 });
6958
6959 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6960 left: type_pred,
6961 op: TokenType::And,
6962 right: rel_clause,
6963 });
6964
6965 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6966 left: inner,
6967 op: TokenType::And,
6968 right: main_pred,
6969 });
6970
6971 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6972 kind: QuantifierKind::Existential,
6973 variable: var_name,
6974 body,
6975 island_id: self.current_island,
6976 }));
6977 }
6978
6979 if let TokenType::ProperName(predicate_name) = self.peek().kind {
6984 self.advance(); let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
6986 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6987 right: self.ctx.terms.alloc(Term::Constant(predicate_name)),
6988 });
6989 let result = if is_negated {
6990 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
6991 op: TokenType::Not,
6992 operand: identity,
6993 })
6994 } else {
6995 identity
6996 };
6997 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
6998 }
6999
7000 let predicate_name = self.consume_content_word()?;
7003
7004 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7006 let predicate_str = self.interner.resolve(predicate_name);
7007
7008 if let Some(s_sort) = subject_sort {
7010 if !crate::ontology::check_sort_compatibility(predicate_str, s_sort) {
7011 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7012 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7013 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7014 });
7015 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7016 }
7017 }
7018
7019 let predicate_sort = lexicon::lookup_sort(predicate_str);
7021 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
7022 if s_sort != p_sort && !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
7023 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7024 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7025 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7026 });
7027 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7028 }
7029 }
7030
7031 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7032 name: predicate_name,
7033 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7034 world: None,
7035 });
7036
7037 let result = if is_negated {
7039 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7040 op: TokenType::Not,
7041 operand: predicate,
7042 })
7043 } else {
7044 predicate
7045 };
7046 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7047 }
7048
7049 if self.check_auxiliary() && self.is_true_auxiliary_usage() {
7053 let aux_time = if let TokenType::Auxiliary(time) = self.advance().kind {
7054 time
7055 } else {
7056 Time::None
7057 };
7058 self.pending_time = Some(aux_time);
7059
7060 if self.match_token(&[TokenType::Not]) {
7062 self.negative_depth += 1;
7063
7064 if self.check(&TokenType::Ever) {
7066 self.advance();
7067 }
7068
7069 if self.check_verb() || self.check(&TokenType::Do) {
7071 let verb = if self.check(&TokenType::Do) {
7072 self.advance(); self.interner.intern("Do")
7074 } else {
7075 self.consume_verb()
7076 };
7077 let subject_term = self.noun_phrase_to_term(&subject);
7078
7079 if self.check_npi_object() {
7081 let npi_token = self.advance().kind.clone();
7082 let obj_var = self.next_var_name();
7083
7084 let restriction_name = match npi_token {
7085 TokenType::Anything => "Thing",
7086 TokenType::Anyone => "Person",
7087 _ => "Thing",
7088 };
7089
7090 let restriction_sym = self.interner.intern(restriction_name);
7091 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7092 name: restriction_sym,
7093 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7094 world: None,
7095 });
7096
7097 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7098 name: verb,
7099 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7100 world: None,
7101 });
7102
7103 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7104 left: obj_restriction,
7105 op: TokenType::And,
7106 right: verb_pred,
7107 });
7108
7109 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7110 kind: QuantifierKind::Existential,
7111 variable: obj_var,
7112 body,
7113 island_id: self.current_island,
7114 });
7115
7116 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7117 let with_time = match effective_time {
7118 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7119 operator: TemporalOperator::Past,
7120 body: quantified,
7121 }),
7122 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7123 operator: TemporalOperator::Future,
7124 body: quantified,
7125 }),
7126 _ => quantified,
7127 };
7128
7129 self.negative_depth -= 1;
7130 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7131 op: TokenType::Not,
7132 operand: with_time,
7133 }));
7134 }
7135
7136 if self.check_quantifier() {
7138 let quantifier_token = self.advance().kind.clone();
7139 let object_np = self.parse_noun_phrase(false)?;
7140 let obj_var = self.next_var_name();
7141
7142 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7143 name: object_np.noun,
7144 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7145 world: None,
7146 });
7147
7148 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7149 name: verb,
7150 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7151 world: None,
7152 });
7153
7154 let (kind, body) = match quantifier_token {
7155 TokenType::Any => {
7156 if self.is_negative_context() {
7157 (
7158 QuantifierKind::Existential,
7159 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7160 left: obj_restriction,
7161 op: TokenType::And,
7162 right: verb_pred,
7163 }),
7164 )
7165 } else {
7166 (
7167 QuantifierKind::Universal,
7168 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7169 left: obj_restriction,
7170 op: TokenType::If,
7171 right: verb_pred,
7172 }),
7173 )
7174 }
7175 }
7176 TokenType::Some => (
7177 QuantifierKind::Existential,
7178 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7179 left: obj_restriction,
7180 op: TokenType::And,
7181 right: verb_pred,
7182 }),
7183 ),
7184 TokenType::All => (
7185 QuantifierKind::Universal,
7186 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7187 left: obj_restriction,
7188 op: TokenType::If,
7189 right: verb_pred,
7190 }),
7191 ),
7192 _ => (
7193 QuantifierKind::Existential,
7194 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7195 left: obj_restriction,
7196 op: TokenType::And,
7197 right: verb_pred,
7198 }),
7199 ),
7200 };
7201
7202 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7203 kind,
7204 variable: obj_var,
7205 body,
7206 island_id: self.current_island,
7207 });
7208
7209 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7210 let with_time = match effective_time {
7211 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7212 operator: TemporalOperator::Past,
7213 body: quantified,
7214 }),
7215 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7216 operator: TemporalOperator::Future,
7217 body: quantified,
7218 }),
7219 _ => quantified,
7220 };
7221
7222 self.negative_depth -= 1;
7223 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7224 op: TokenType::Not,
7225 operand: with_time,
7226 }));
7227 }
7228
7229 let mut roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
7230
7231 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7233 let mut modifiers: Vec<Symbol> = vec![];
7234 match effective_time {
7235 Time::Past => modifiers.push(self.interner.intern("Past")),
7236 Time::Future => modifiers.push(self.interner.intern("Future")),
7237 _ => {}
7238 }
7239
7240 if self.check_content_word() || self.check_article() || self.check_pronoun() {
7242 if self.check_pronoun() {
7243 let pronoun_token = self.advance();
7245 let pronoun_sym = pronoun_token.lexeme;
7246 roles.push((ThematicRole::Theme, Term::Constant(pronoun_sym)));
7247 } else {
7248 let object = self.parse_noun_phrase(false)?;
7249 let object_term = self.noun_phrase_to_term(&object);
7250 roles.push((ThematicRole::Theme, object_term));
7251 }
7252 }
7253
7254 let event_var = self.get_event_var();
7255 let suppress_existential = self.drs.in_conditional_antecedent();
7256 if suppress_existential {
7257 let event_class = self.interner.intern("Event");
7258 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7259 }
7260 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7261 event_var,
7262 verb,
7263 roles: self.ctx.roles.alloc_slice(roles),
7264 modifiers: self.ctx.syms.alloc_slice(modifiers),
7265 suppress_existential,
7266 world: None,
7267 })));
7268
7269 self.negative_depth -= 1;
7270 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7271 op: TokenType::Not,
7272 operand: neo_event,
7273 }));
7274 }
7275
7276 self.negative_depth -= 1;
7277 }
7278 }
7280
7281 if self.check_presup_trigger() && !self.is_followed_by_np_object() && self.is_followed_by_gerund() {
7287 let presup_kind = match self.advance().kind {
7288 TokenType::PresupTrigger(kind) => kind,
7289 TokenType::Verb { lemma, .. } => {
7290 let s = self.interner.resolve(lemma).to_lowercase();
7291 crate::lexicon::lookup_presup_trigger(&s)
7292 .expect("Lexicon mismatch: Verb flagged as trigger but lookup failed")
7293 }
7294 _ => panic!("Expected presupposition trigger"),
7295 };
7296 return self.parse_presupposition(&subject, presup_kind);
7297 }
7298
7299 let noun_str = self.interner.resolve(subject.noun);
7301 let is_bare_plural = subject.definiteness.is_none()
7302 && subject.possessor.is_none()
7303 && Self::is_plural_noun(noun_str)
7304 && self.check_verb();
7305
7306 if is_bare_plural {
7307 let var_name = self.next_var_name();
7308 let (verb, verb_time, verb_aspect, _) = self.consume_verb_with_metadata();
7309
7310 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7311 name: subject.noun,
7312 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7313 world: None,
7314 });
7315
7316 let mut args = vec![Term::Variable(var_name)];
7317 if self.check_content_word() {
7318 let object = self.parse_noun_phrase(false)?;
7319 args.push(self.noun_phrase_to_term(&object));
7320 }
7321
7322 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7323 name: verb,
7324 args: self.ctx.terms.alloc_slice(args),
7325 world: None,
7326 });
7327
7328 let effective_time = self.pending_time.take().unwrap_or(verb_time);
7329 let with_time = match effective_time {
7330 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7331 operator: TemporalOperator::Past,
7332 body: verb_pred,
7333 }),
7334 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7335 operator: TemporalOperator::Future,
7336 body: verb_pred,
7337 }),
7338 _ => verb_pred,
7339 };
7340
7341 let with_aspect = if verb_aspect == Aspect::Progressive {
7342 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7343 operator: AspectOperator::Progressive,
7344 body: with_time,
7345 })
7346 } else {
7347 with_time
7348 };
7349
7350 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7351 left: type_pred,
7352 op: TokenType::If,
7353 right: with_aspect,
7354 });
7355
7356 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7357 kind: QuantifierKind::Generic,
7358 variable: var_name,
7359 body,
7360 island_id: self.current_island,
7361 }));
7362 }
7363
7364 if self.check(&TokenType::Does) || self.check(&TokenType::Do) {
7366 self.advance(); let is_negated = self.match_token(&[TokenType::Not]);
7368
7369 if self.check_verb() {
7370 let verb = self.consume_verb();
7371 let verb_lemma = self.interner.resolve(verb).to_lowercase();
7372
7373 if self.check_wh_word() {
7375 let wh_token = self.advance().kind.clone();
7376 let is_who = matches!(wh_token, TokenType::Who);
7377 let is_what = matches!(wh_token, TokenType::What);
7378
7379 let is_sluicing = self.is_at_end() ||
7380 self.check(&TokenType::Period) ||
7381 self.check(&TokenType::Comma);
7382
7383 if is_sluicing {
7384 if let Some(template) = self.last_event_template.clone() {
7385 let wh_var = self.next_var_name();
7386 let subject_term = self.noun_phrase_to_term(&subject);
7387
7388 let roles: Vec<_> = if is_who {
7389 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7390 .chain(template.non_agent_roles.iter().cloned())
7391 .collect()
7392 } else if is_what {
7393 vec![
7394 (ThematicRole::Agent, subject_term.clone()),
7395 (ThematicRole::Theme, Term::Variable(wh_var)),
7396 ]
7397 } else {
7398 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7399 .chain(template.non_agent_roles.iter().cloned())
7400 .collect()
7401 };
7402
7403 let event_var = self.get_event_var();
7404 let suppress_existential = self.drs.in_conditional_antecedent();
7405 if suppress_existential {
7406 let event_class = self.interner.intern("Event");
7407 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7408 }
7409 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7410 event_var,
7411 verb: template.verb,
7412 roles: self.ctx.roles.alloc_slice(roles),
7413 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
7414 suppress_existential,
7415 world: None,
7416 })));
7417
7418 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7419 wh_variable: wh_var,
7420 body: reconstructed,
7421 });
7422
7423 let know_event_var = self.get_event_var();
7424 let suppress_existential2 = self.drs.in_conditional_antecedent();
7425 if suppress_existential2 {
7426 let event_class = self.interner.intern("Event");
7427 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
7428 }
7429 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7430 event_var: know_event_var,
7431 verb,
7432 roles: self.ctx.roles.alloc_slice(vec![
7433 (ThematicRole::Agent, subject_term),
7434 (ThematicRole::Theme, Term::Proposition(question)),
7435 ]),
7436 modifiers: self.ctx.syms.alloc_slice(vec![]),
7437 suppress_existential: suppress_existential2,
7438 world: None,
7439 })));
7440
7441 let result = if is_negated {
7442 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7443 op: TokenType::Not,
7444 operand: know_event,
7445 })
7446 } else {
7447 know_event
7448 };
7449
7450 return self.wrap_with_definiteness_full(&subject, result);
7451 }
7452 }
7453 }
7454
7455 if verb_lemma == "exist" && is_negated {
7457 let var_name = self.next_var_name();
7459 let restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7460 name: subject.noun,
7461 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7462 world: None,
7463 });
7464 let exists = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7465 kind: QuantifierKind::Existential,
7466 variable: var_name,
7467 body: restriction,
7468 island_id: self.current_island,
7469 });
7470 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7471 op: TokenType::Not,
7472 operand: exists,
7473 }));
7474 }
7475
7476 let subject_term = self.noun_phrase_to_term(&subject);
7479 let modifiers: Vec<Symbol> = vec![];
7480
7481 if self.check(&TokenType::Reflexive) {
7483 self.advance();
7484 let roles = vec![
7485 (ThematicRole::Agent, subject_term.clone()),
7486 (ThematicRole::Theme, subject_term),
7487 ];
7488 let event_var = self.get_event_var();
7489 let suppress_existential = self.drs.in_conditional_antecedent();
7490 if suppress_existential {
7491 let event_class = self.interner.intern("Event");
7492 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7493 }
7494 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7495 event_var,
7496 verb,
7497 roles: self.ctx.roles.alloc_slice(roles),
7498 modifiers: self.ctx.syms.alloc_slice(modifiers),
7499 suppress_existential,
7500 world: None,
7501 })));
7502
7503 let result = if is_negated {
7504 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7505 op: TokenType::Not,
7506 operand: neo_event,
7507 })
7508 } else {
7509 neo_event
7510 };
7511 return self.wrap_with_definiteness_full(&subject, result);
7512 }
7513
7514 if self.check_npi_quantifier() || self.check_quantifier() || self.check_article() {
7516 let (obj_quantifier, was_definite_article) = if self.check_npi_quantifier() {
7517 let tok = self.advance().kind.clone();
7519 (Some(tok), false)
7520 } else if self.check_quantifier() {
7521 (Some(self.advance().kind.clone()), false)
7522 } else {
7523 let art = self.advance().kind.clone();
7524 if let TokenType::Article(def) = art {
7525 if def == Definiteness::Indefinite {
7526 (Some(TokenType::Some), false)
7527 } else {
7528 (None, true)
7529 }
7530 } else {
7531 (None, false)
7532 }
7533 };
7534
7535 let object_np = self.parse_noun_phrase(false)?;
7536 let obj_var = self.next_var_name();
7537
7538 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7539 name: object_np.noun,
7540 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7541 world: None,
7542 });
7543
7544 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
7546 self.advance();
7547 let rel_clause = self.parse_relative_clause(obj_var)?;
7548 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7549 left: type_pred,
7550 op: TokenType::And,
7551 right: rel_clause,
7552 })
7553 } else {
7554 type_pred
7555 };
7556
7557 let event_var = self.get_event_var();
7558 let suppress_existential = self.drs.in_conditional_antecedent();
7559 if suppress_existential {
7560 let event_class = self.interner.intern("Event");
7561 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7562 }
7563
7564 let roles = vec![
7565 (ThematicRole::Agent, subject_term),
7566 (ThematicRole::Theme, Term::Variable(obj_var)),
7567 ];
7568
7569 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7570 event_var,
7571 verb,
7572 roles: self.ctx.roles.alloc_slice(roles),
7573 modifiers: self.ctx.syms.alloc_slice(modifiers),
7574 suppress_existential,
7575 world: None,
7576 })));
7577
7578 let quantifier_kind = match &obj_quantifier {
7582 Some(TokenType::Any) if is_negated => QuantifierKind::Existential,
7583 Some(TokenType::All) => QuantifierKind::Universal,
7584 Some(TokenType::No) => QuantifierKind::Universal,
7585 _ => QuantifierKind::Existential,
7586 };
7587
7588 let obj_body = match &obj_quantifier {
7589 Some(TokenType::All) => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7590 left: obj_restriction,
7591 op: TokenType::If,
7592 right: neo_event,
7593 }),
7594 Some(TokenType::No) => {
7595 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7596 op: TokenType::Not,
7597 operand: neo_event,
7598 });
7599 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7600 left: obj_restriction,
7601 op: TokenType::If,
7602 right: neg,
7603 })
7604 }
7605 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7606 left: obj_restriction,
7607 op: TokenType::And,
7608 right: neo_event,
7609 }),
7610 };
7611
7612 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7613 kind: quantifier_kind,
7614 variable: obj_var,
7615 body: obj_body,
7616 island_id: self.current_island,
7617 });
7618
7619 let result = if is_negated && matches!(obj_quantifier, Some(TokenType::Any)) {
7621 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7622 op: TokenType::Not,
7623 operand: obj_quantified,
7624 })
7625 } else if is_negated {
7626 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7628 op: TokenType::Not,
7629 operand: obj_quantified,
7630 })
7631 } else {
7632 obj_quantified
7633 };
7634
7635 return self.wrap_with_definiteness_full(&subject, result);
7636 }
7637
7638 let roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
7640 let event_var = self.get_event_var();
7641 let suppress_existential = self.drs.in_conditional_antecedent();
7642 if suppress_existential {
7643 let event_class = self.interner.intern("Event");
7644 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7645 }
7646
7647 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7648 event_var,
7649 verb,
7650 roles: self.ctx.roles.alloc_slice(roles),
7651 modifiers: self.ctx.syms.alloc_slice(modifiers),
7652 suppress_existential,
7653 world: None,
7654 })));
7655
7656 if is_negated {
7657 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7658 op: TokenType::Not,
7659 operand: neo_event,
7660 }));
7661 }
7662 return Ok(neo_event);
7663 }
7664 }
7665
7666 let is_perfect_aux = if self.check_verb() {
7672 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
7673 word == "has" || word == "have" || word == "had"
7674 } else {
7675 false
7676 };
7677 if subject.definiteness == Some(Definiteness::Definite) && self.check_verb() && self.pending_time.is_none() && !is_perfect_aux {
7678 let saved_pos = self.current;
7679
7680 if let Some(garden_path_result) = self.try_parse(|p| {
7682 let (modifier_verb, _modifier_time, _, _) = p.consume_verb_with_metadata();
7683
7684 let mut pp_mods: Vec<&'a LogicExpr<'a>> = Vec::new();
7686 while p.check_preposition() {
7687 let prep = if let TokenType::Preposition(prep) = p.advance().kind {
7688 prep
7689 } else {
7690 break;
7691 };
7692 if p.check_article() || p.check_content_word() {
7693 let pp_obj = p.parse_noun_phrase(false)?;
7694 let pp_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7695 name: prep,
7696 args: p.ctx.terms.alloc_slice([Term::Variable(p.interner.intern("x")), Term::Constant(pp_obj.noun)]),
7697 world: None,
7698 });
7699 pp_mods.push(pp_pred);
7700 }
7701 }
7702
7703 if !p.check_verb() {
7705 return Err(ParseError {
7706 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
7707 span: p.current_span(),
7708 });
7709 }
7710
7711 let (main_verb, main_time, _, _) = p.consume_verb_with_metadata();
7712
7713 let var = p.interner.intern("x");
7715
7716 let type_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7718 name: subject.noun,
7719 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
7720 world: None,
7721 });
7722
7723 let mod_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7725 name: modifier_verb,
7726 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
7727 world: None,
7728 });
7729
7730 let main_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7732 name: main_verb,
7733 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
7734 world: None,
7735 });
7736
7737 let mut body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
7739 left: type_pred,
7740 op: TokenType::And,
7741 right: mod_pred,
7742 });
7743
7744 for pp in pp_mods {
7746 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
7747 left: body,
7748 op: TokenType::And,
7749 right: pp,
7750 });
7751 }
7752
7753 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
7755 left: body,
7756 op: TokenType::And,
7757 right: main_pred,
7758 });
7759
7760 let with_time = match main_time {
7762 Time::Past => p.ctx.exprs.alloc(LogicExpr::Temporal {
7763 operator: TemporalOperator::Past,
7764 body,
7765 }),
7766 Time::Future => p.ctx.exprs.alloc(LogicExpr::Temporal {
7767 operator: TemporalOperator::Future,
7768 body,
7769 }),
7770 _ => body,
7771 };
7772
7773 Ok(p.ctx.exprs.alloc(LogicExpr::Quantifier {
7775 kind: QuantifierKind::Existential,
7776 variable: var,
7777 body: with_time,
7778 island_id: p.current_island,
7779 }))
7780 }) {
7781 return Ok(garden_path_result);
7782 }
7783
7784 self.current = saved_pos;
7786 }
7787
7788 if self.check_modal() {
7789 return self.parse_aspect_chain(subject.noun);
7790 }
7791
7792 if self.check_content_word() {
7794 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
7795 if word == "has" || word == "have" || word == "had" {
7796 let is_perfect_aspect = if self.current + 1 < self.tokens.len() {
7798 let next_token = &self.tokens[self.current + 1].kind;
7799 matches!(
7800 next_token,
7801 TokenType::Verb { .. } | TokenType::Not
7802 ) && !matches!(next_token, TokenType::Number(_))
7803 } else {
7804 false
7805 };
7806 if is_perfect_aspect {
7807 return self.parse_aspect_chain(subject.noun);
7808 }
7809 }
7811 }
7812
7813 if self.check(&TokenType::Had) {
7815 return self.parse_aspect_chain(subject.noun);
7816 }
7817
7818 if self.check(&TokenType::Never) {
7820 self.advance();
7821 let verb = self.consume_verb();
7822 let subject_term = self.noun_phrase_to_term(&subject);
7823 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7824 name: verb,
7825 args: self.ctx.terms.alloc_slice([subject_term]),
7826 world: None,
7827 });
7828 let result = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7829 op: TokenType::Not,
7830 operand: verb_pred,
7831 });
7832 return self.wrap_with_definiteness_full(&subject, result);
7833 }
7834
7835 if self.check_verb() {
7836 let (mut verb, verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
7837
7838 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7840 let verb_str = self.interner.resolve(verb);
7841 if let Some(s_sort) = subject_sort {
7842 if !crate::ontology::check_sort_compatibility(verb_str, s_sort) {
7843 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7844 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7845 vehicle: self.ctx.terms.alloc(Term::Constant(verb)),
7846 });
7847 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7848 }
7849 }
7850
7851 if self.is_control_verb(verb) {
7853 return self.parse_control_structure(&subject, verb, verb_time);
7854 }
7855
7856 if let Some((var_name, rel_clause)) = relative_clause {
7858 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7859 name: verb,
7860 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7861 world: None,
7862 });
7863
7864 let effective_time = self.pending_time.take().unwrap_or(verb_time);
7865 let with_time = match effective_time {
7866 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7867 operator: TemporalOperator::Past,
7868 body: main_pred,
7869 }),
7870 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7871 operator: TemporalOperator::Future,
7872 body: main_pred,
7873 }),
7874 _ => main_pred,
7875 };
7876
7877 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7879 name: subject.noun,
7880 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7881 world: None,
7882 });
7883
7884 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7885 left: type_pred,
7886 op: TokenType::And,
7887 right: rel_clause,
7888 });
7889
7890 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7891 left: inner,
7892 op: TokenType::And,
7893 right: with_time,
7894 });
7895
7896 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7897 kind: QuantifierKind::Existential,
7898 variable: var_name,
7899 body,
7900 island_id: self.current_island,
7901 }));
7902 }
7903
7904 let subject_term = self.noun_phrase_to_term(&subject);
7905 let mut args = vec![subject_term.clone()];
7906
7907 let unknown = self.interner.intern("?");
7908
7909 if self.check_wh_word() {
7911 let wh_token = self.advance().kind.clone();
7912
7913 let is_who = matches!(wh_token, TokenType::Who);
7915 let is_what = matches!(wh_token, TokenType::What);
7916
7917 let is_sluicing = self.is_at_end() ||
7919 self.check(&TokenType::Period) ||
7920 self.check(&TokenType::Comma);
7921
7922 if is_sluicing {
7923 if let Some(template) = self.last_event_template.clone() {
7925 let wh_var = self.next_var_name();
7926
7927 let roles: Vec<_> = if is_who {
7929 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7931 .chain(template.non_agent_roles.iter().cloned())
7932 .collect()
7933 } else if is_what {
7934 vec![
7936 (ThematicRole::Agent, subject_term.clone()),
7937 (ThematicRole::Theme, Term::Variable(wh_var)),
7938 ]
7939 } else {
7940 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7942 .chain(template.non_agent_roles.iter().cloned())
7943 .collect()
7944 };
7945
7946 let event_var = self.get_event_var();
7947 let suppress_existential = self.drs.in_conditional_antecedent();
7948 if suppress_existential {
7949 let event_class = self.interner.intern("Event");
7950 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7951 }
7952 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7953 event_var,
7954 verb: template.verb,
7955 roles: self.ctx.roles.alloc_slice(roles),
7956 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
7957 suppress_existential,
7958 world: None,
7959 })));
7960
7961 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7962 wh_variable: wh_var,
7963 body: reconstructed,
7964 });
7965
7966 let know_event_var = self.get_event_var();
7968 let suppress_existential2 = self.drs.in_conditional_antecedent();
7969 if suppress_existential2 {
7970 let event_class = self.interner.intern("Event");
7971 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
7972 }
7973 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7974 event_var: know_event_var,
7975 verb,
7976 roles: self.ctx.roles.alloc_slice(vec![
7977 (ThematicRole::Agent, subject_term),
7978 (ThematicRole::Theme, Term::Proposition(question)),
7979 ]),
7980 modifiers: self.ctx.syms.alloc_slice(vec![]),
7981 suppress_existential: suppress_existential2,
7982 world: None,
7983 })));
7984
7985 return self.wrap_with_definiteness_full(&subject, know_event);
7986 }
7987 }
7988
7989 let embedded = self.parse_embedded_wh_clause()?;
7991 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7992 wh_variable: self.interner.intern("x"),
7993 body: embedded,
7994 });
7995
7996 let know_event_var = self.get_event_var();
7998 let suppress_existential = self.drs.in_conditional_antecedent();
7999 if suppress_existential {
8000 let event_class = self.interner.intern("Event");
8001 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8002 }
8003 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8004 event_var: know_event_var,
8005 verb,
8006 roles: self.ctx.roles.alloc_slice(vec![
8007 (ThematicRole::Agent, subject_term),
8008 (ThematicRole::Theme, Term::Proposition(question)),
8009 ]),
8010 modifiers: self.ctx.syms.alloc_slice(vec![]),
8011 suppress_existential,
8012 world: None,
8013 })));
8014
8015 return self.wrap_with_definiteness_full(&subject, know_event);
8016 }
8017
8018 let mut object_term: Option<Term<'a>> = None;
8019 let mut second_object_term: Option<Term<'a>> = None;
8020 let mut object_superlative: Option<(Symbol, Symbol)> = None; if self.check(&TokenType::Reflexive) {
8022 self.advance();
8023 let term = self.noun_phrase_to_term(&subject);
8024 object_term = Some(term.clone());
8025 args.push(term);
8026
8027 if let TokenType::Particle(particle_sym) = self.peek().kind {
8029 let verb_str = self.interner.resolve(verb).to_lowercase();
8030 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8031 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8032 self.advance();
8033 verb = self.interner.intern(phrasal_lemma);
8034 }
8035 }
8036 } else if self.check_pronoun() {
8037 let token = self.advance().clone();
8038 if let TokenType::Pronoun { gender, number, .. } = token.kind {
8039 let resolved = self.resolve_pronoun(gender, number)?;
8040 let term = match resolved {
8041 ResolvedPronoun::Variable(s) => Term::Variable(s),
8042 ResolvedPronoun::Constant(s) => Term::Constant(s),
8043 };
8044 object_term = Some(term.clone());
8045 args.push(term);
8046
8047 if let TokenType::Particle(particle_sym) = self.peek().kind {
8049 let verb_str = self.interner.resolve(verb).to_lowercase();
8050 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8051 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8052 self.advance();
8053 verb = self.interner.intern(phrasal_lemma);
8054 }
8055 }
8056 }
8057 } else if self.check_quantifier() || self.check_article() {
8058 let (obj_quantifier, was_definite_article) = if self.check_quantifier() {
8060 (Some(self.advance().kind.clone()), false)
8061 } else {
8062 let art = self.advance().kind.clone();
8063 if let TokenType::Article(def) = art {
8064 if def == Definiteness::Indefinite {
8065 (Some(TokenType::Some), false)
8066 } else {
8067 (None, true) }
8069 } else {
8070 (None, false)
8071 }
8072 };
8073
8074 let object_np = self.parse_noun_phrase(false)?;
8075
8076 if let Some(adj) = object_np.superlative {
8078 object_superlative = Some((adj, object_np.noun));
8079 }
8080
8081 if let TokenType::Particle(particle_sym) = self.peek().kind {
8083 let verb_str = self.interner.resolve(verb).to_lowercase();
8084 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8085 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8086 self.advance(); verb = self.interner.intern(phrasal_lemma);
8088 }
8089 }
8090
8091 if let Some(obj_q) = obj_quantifier {
8092 let verb_str = self.interner.resolve(verb).to_lowercase();
8096 let is_opaque = lexicon::lookup_verb_db(&verb_str)
8097 .map(|meta| meta.features.contains(&lexicon::Feature::Opaque))
8098 .unwrap_or(false);
8099
8100 if is_opaque && matches!(obj_q, TokenType::Some) {
8101 let intension_term = Term::Intension(object_np.noun);
8103
8104 let event_var = self.get_event_var();
8106 let mut modifiers = self.collect_adverbs();
8107 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8108 match effective_time {
8109 Time::Past => modifiers.push(self.interner.intern("Past")),
8110 Time::Future => modifiers.push(self.interner.intern("Future")),
8111 _ => {}
8112 }
8113
8114 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8115 let roles = vec![
8116 (ThematicRole::Agent, subject_term_for_event),
8117 (ThematicRole::Theme, intension_term),
8118 ];
8119
8120 let suppress_existential = self.drs.in_conditional_antecedent();
8121 if suppress_existential {
8122 let event_class = self.interner.intern("Event");
8123 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8124 }
8125 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8126 event_var,
8127 verb,
8128 roles: self.ctx.roles.alloc_slice(roles),
8129 modifiers: self.ctx.syms.alloc_slice(modifiers),
8130 suppress_existential,
8131 world: None,
8132 })));
8133
8134 return self.wrap_with_definiteness_full(&subject, neo_event);
8135 }
8136
8137 let obj_var = self.next_var_name();
8138
8139 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8141 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8142 Number::Plural
8143 } else {
8144 Number::Singular
8145 };
8146 if object_np.definiteness == Some(Definiteness::Definite) {
8148 self.drs.introduce_referent_with_source(obj_var, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8149 } else {
8150 self.drs.introduce_referent(obj_var, object_np.noun, obj_gender, obj_number);
8151 }
8152
8153 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8154 name: object_np.noun,
8155 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8156 world: None,
8157 });
8158
8159 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8160 self.advance();
8161 let rel_clause = self.parse_relative_clause(obj_var)?;
8162 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8163 left: type_pred,
8164 op: TokenType::And,
8165 right: rel_clause,
8166 })
8167 } else {
8168 type_pred
8169 };
8170
8171 let event_var = self.get_event_var();
8172 let mut modifiers = self.collect_adverbs();
8173 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8174 match effective_time {
8175 Time::Past => modifiers.push(self.interner.intern("Past")),
8176 Time::Future => modifiers.push(self.interner.intern("Future")),
8177 _ => {}
8178 }
8179
8180 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8181 let roles = vec![
8182 (ThematicRole::Agent, subject_term_for_event),
8183 (ThematicRole::Theme, Term::Variable(obj_var)),
8184 ];
8185
8186 let template_roles = vec![
8189 (ThematicRole::Agent, subject_term_for_event),
8190 (ThematicRole::Theme, Term::Constant(object_np.noun)),
8191 ];
8192 self.capture_event_template(verb, &template_roles, &modifiers);
8193
8194 let suppress_existential = self.drs.in_conditional_antecedent();
8195 if suppress_existential {
8196 let event_class = self.interner.intern("Event");
8197 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8198 }
8199 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8200 event_var,
8201 verb,
8202 roles: self.ctx.roles.alloc_slice(roles),
8203 modifiers: self.ctx.syms.alloc_slice(modifiers),
8204 suppress_existential,
8205 world: None,
8206 })));
8207
8208 let obj_kind = match obj_q {
8209 TokenType::All => QuantifierKind::Universal,
8210 TokenType::Some => QuantifierKind::Existential,
8211 TokenType::No => QuantifierKind::Universal,
8212 TokenType::Most => QuantifierKind::Most,
8213 TokenType::Few => QuantifierKind::Few,
8214 TokenType::Many => QuantifierKind::Many,
8215 TokenType::Cardinal(n) => QuantifierKind::Cardinal(n),
8216 TokenType::AtLeast(n) => QuantifierKind::AtLeast(n),
8217 TokenType::AtMost(n) => QuantifierKind::AtMost(n),
8218 _ => QuantifierKind::Existential,
8219 };
8220
8221 let obj_body = match obj_q {
8222 TokenType::All => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8223 left: obj_restriction,
8224 op: TokenType::If,
8225 right: neo_event,
8226 }),
8227 TokenType::No => {
8228 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8229 op: TokenType::Not,
8230 operand: neo_event,
8231 });
8232 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8233 left: obj_restriction,
8234 op: TokenType::If,
8235 right: neg,
8236 })
8237 }
8238 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8239 left: obj_restriction,
8240 op: TokenType::And,
8241 right: neo_event,
8242 }),
8243 };
8244
8245 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8247 kind: obj_kind,
8248 variable: obj_var,
8249 body: obj_body,
8250 island_id: self.current_island,
8251 });
8252
8253 return self.wrap_with_definiteness_full(&subject, obj_quantified);
8255 } else {
8256 if was_definite_article {
8261 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8262 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8263 Number::Plural
8264 } else {
8265 Number::Singular
8266 };
8267 self.drs.introduce_referent_with_source(object_np.noun, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8269 }
8270
8271 let term = self.noun_phrase_to_term(&object_np);
8272 object_term = Some(term.clone());
8273 args.push(term);
8274 }
8275 } else if self.check_focus() {
8276 let focus_kind = if let TokenType::Focus(k) = self.advance().kind {
8277 k
8278 } else {
8279 FocusKind::Only
8280 };
8281
8282 let event_var = self.get_event_var();
8283 let mut modifiers = self.collect_adverbs();
8284 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8285 match effective_time {
8286 Time::Past => modifiers.push(self.interner.intern("Past")),
8287 Time::Future => modifiers.push(self.interner.intern("Future")),
8288 _ => {}
8289 }
8290
8291 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8292
8293 if self.check_preposition() {
8294 let prep_token = self.advance().clone();
8295 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8296 sym
8297 } else {
8298 self.interner.intern("to")
8299 };
8300 let pp_obj = self.parse_noun_phrase(false)?;
8301 let pp_obj_term = Term::Constant(pp_obj.noun);
8302
8303 let roles = vec![(ThematicRole::Agent, subject_term_for_event)];
8304 let suppress_existential = self.drs.in_conditional_antecedent();
8305 if suppress_existential {
8306 let event_class = self.interner.intern("Event");
8307 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8308 }
8309 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8310 event_var,
8311 verb,
8312 roles: self.ctx.roles.alloc_slice(roles),
8313 modifiers: self.ctx.syms.alloc_slice(modifiers),
8314 suppress_existential,
8315 world: None,
8316 })));
8317
8318 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8319 name: prep_name,
8320 args: self.ctx.terms.alloc_slice([Term::Variable(event_var), pp_obj_term]),
8321 world: None,
8322 });
8323
8324 let with_pp = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8325 left: neo_event,
8326 op: TokenType::And,
8327 right: pp_pred,
8328 });
8329
8330 let focused_ref = self.ctx.terms.alloc(pp_obj_term);
8331 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8332 kind: focus_kind,
8333 focused: focused_ref,
8334 scope: with_pp,
8335 }));
8336 }
8337
8338 let focused_np = self.parse_noun_phrase(false)?;
8339 let focused_term = self.noun_phrase_to_term(&focused_np);
8340 args.push(focused_term.clone());
8341
8342 let roles = vec![
8343 (ThematicRole::Agent, subject_term_for_event),
8344 (ThematicRole::Theme, focused_term.clone()),
8345 ];
8346
8347 let suppress_existential = self.drs.in_conditional_antecedent();
8348 if suppress_existential {
8349 let event_class = self.interner.intern("Event");
8350 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8351 }
8352 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8353 event_var,
8354 verb,
8355 roles: self.ctx.roles.alloc_slice(roles),
8356 modifiers: self.ctx.syms.alloc_slice(modifiers),
8357 suppress_existential,
8358 world: None,
8359 })));
8360
8361 let focused_ref = self.ctx.terms.alloc(focused_term);
8362 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8363 kind: focus_kind,
8364 focused: focused_ref,
8365 scope: neo_event,
8366 }));
8367 } else if self.check_number() {
8368 let measure = self.parse_measure_phrase()?;
8370
8371 if self.check_content_word() {
8373 let noun_sym = self.consume_content_word()?;
8374 let count_term = *measure;
8376 object_term = Some(count_term.clone());
8377 args.push(count_term);
8378 second_object_term = Some(Term::Constant(noun_sym));
8379 args.push(Term::Constant(noun_sym));
8380 } else {
8381 object_term = Some(*measure);
8383 args.push(*measure);
8384 }
8385 } else if self.check_content_word() || self.check_article() {
8386 let object = self.parse_noun_phrase(false)?;
8387 if let Some(adj) = object.superlative {
8388 object_superlative = Some((adj, object.noun));
8389 }
8390
8391 let mut all_objects: Vec<Symbol> = vec![object.noun];
8393
8394 while self.check(&TokenType::And) {
8396 let saved = self.current;
8397 self.advance(); if self.check_content_word() || self.check_article() {
8399 let next_obj = match self.parse_noun_phrase(false) {
8400 Ok(np) => np,
8401 Err(_) => {
8402 self.current = saved;
8403 break;
8404 }
8405 };
8406 all_objects.push(next_obj.noun);
8407 } else {
8408 self.current = saved;
8409 break;
8410 }
8411 }
8412
8413 if self.check(&TokenType::Respectively) {
8415 let respectively_span = self.peek().span;
8416 if all_objects.len() > 1 {
8418 return Err(ParseError {
8419 kind: ParseErrorKind::RespectivelyLengthMismatch {
8420 subject_count: 1,
8421 object_count: all_objects.len(),
8422 },
8423 span: respectively_span,
8424 });
8425 }
8426 self.advance(); }
8429
8430 let term = self.noun_phrase_to_term(&object);
8432 object_term = Some(term.clone());
8433 args.push(term.clone());
8434
8435 if all_objects.len() > 1 {
8437 let obj_members: Vec<Term<'a>> = all_objects.iter()
8438 .map(|o| Term::Constant(*o))
8439 .collect();
8440 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
8441 args.pop();
8443 args.push(obj_group);
8444 }
8445
8446 if let TokenType::Particle(particle_sym) = self.peek().kind {
8448 let verb_str = self.interner.resolve(verb).to_lowercase();
8449 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8450 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8451 self.advance(); verb = self.interner.intern(phrasal_lemma);
8453 }
8454 }
8455
8456 if self.check_number() {
8458 let measure = self.parse_measure_phrase()?;
8459 second_object_term = Some(*measure);
8460 args.push(*measure);
8461 }
8462 else {
8464 let verb_str = self.interner.resolve(verb);
8465 if Lexer::is_ditransitive_verb(verb_str) && (self.check_content_word() || self.check_article()) {
8466 let second_np = self.parse_noun_phrase(false)?;
8467 let second_term = self.noun_phrase_to_term(&second_np);
8468 second_object_term = Some(second_term.clone());
8469 args.push(second_term);
8470 }
8471 }
8472 }
8473
8474 let mut pp_predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
8475 while self.check_preposition() || self.check_to() {
8476 let prep_token = self.advance().clone();
8477 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8478 sym
8479 } else if matches!(prep_token.kind, TokenType::To) {
8480 self.interner.intern("To")
8481 } else {
8482 continue;
8483 };
8484
8485 let pp_obj_term = if self.check(&TokenType::Reflexive) {
8486 self.advance();
8487 self.noun_phrase_to_term(&subject)
8488 } else if self.check_pronoun() {
8489 let token = self.advance().clone();
8490 if let TokenType::Pronoun { gender, number, .. } = token.kind {
8491 let resolved = self.resolve_pronoun(gender, number)?;
8492 match resolved {
8493 ResolvedPronoun::Variable(s) => Term::Variable(s),
8494 ResolvedPronoun::Constant(s) => Term::Constant(s),
8495 }
8496 } else {
8497 continue;
8498 }
8499 } else if self.check_content_word() || self.check_article() {
8500 let prep_obj = self.parse_noun_phrase(false)?;
8501 self.noun_phrase_to_term(&prep_obj)
8502 } else {
8503 continue;
8504 };
8505
8506 if self.pp_attach_to_noun {
8507 if let Some(ref obj) = object_term {
8508 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8510 name: prep_name,
8511 args: self.ctx.terms.alloc_slice([obj.clone(), pp_obj_term]),
8512 world: None,
8513 });
8514 pp_predicates.push(pp_pred);
8515 } else {
8516 args.push(pp_obj_term);
8517 }
8518 } else {
8519 let event_sym = self.get_event_var();
8521 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8522 name: prep_name,
8523 args: self.ctx.terms.alloc_slice([Term::Variable(event_sym), pp_obj_term]),
8524 world: None,
8525 });
8526 pp_predicates.push(pp_pred);
8527 }
8528 }
8529
8530 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8532 self.advance();
8533 let rel_var = self.next_var_name();
8534 let rel_pred = self.parse_relative_clause(rel_var)?;
8535 pp_predicates.push(rel_pred);
8536 }
8537
8538 let mut modifiers = self.collect_adverbs();
8540
8541 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8543 match effective_time {
8544 Time::Past => modifiers.push(self.interner.intern("Past")),
8545 Time::Future => modifiers.push(self.interner.intern("Future")),
8546 _ => {}
8547 }
8548
8549 if verb_aspect == Aspect::Progressive {
8551 modifiers.push(self.interner.intern("Progressive"));
8552 } else if verb_aspect == Aspect::Perfect {
8553 modifiers.push(self.interner.intern("Perfect"));
8554 }
8555
8556 let mut roles: Vec<(ThematicRole, Term<'a>)> = Vec::new();
8558
8559 let verb_str_for_check = self.interner.resolve(verb).to_lowercase();
8561 let is_unaccusative = crate::lexicon::lookup_verb_db(&verb_str_for_check)
8562 .map(|meta| meta.features.contains(&crate::lexicon::Feature::Unaccusative))
8563 .unwrap_or(false);
8564
8565 let has_object = object_term.is_some() || second_object_term.is_some();
8567 let subject_role = if is_unaccusative && !has_object {
8568 ThematicRole::Theme
8569 } else {
8570 ThematicRole::Agent
8571 };
8572
8573 roles.push((subject_role, subject_term));
8574 if let Some(second_obj) = second_object_term {
8575 if let Some(first_obj) = object_term {
8577 roles.push((ThematicRole::Recipient, first_obj));
8578 }
8579 roles.push((ThematicRole::Theme, second_obj));
8580 } else if let Some(obj) = object_term {
8581 roles.push((ThematicRole::Theme, obj));
8583 }
8584
8585 let event_var = self.get_event_var();
8587
8588 self.capture_event_template(verb, &roles, &modifiers);
8590
8591 let suppress_existential = self.drs.in_conditional_antecedent();
8593 if suppress_existential {
8594 let event_class = self.interner.intern("Event");
8595 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8596 }
8597 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8598 event_var,
8599 verb,
8600 roles: self.ctx.roles.alloc_slice(roles),
8601 modifiers: self.ctx.syms.alloc_slice(modifiers),
8602 suppress_existential,
8603 world: None,
8604 })));
8605
8606 let with_pps = if pp_predicates.is_empty() {
8608 neo_event
8609 } else {
8610 let mut combined = neo_event;
8611 for pp in pp_predicates {
8612 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8613 left: combined,
8614 op: TokenType::And,
8615 right: pp,
8616 });
8617 }
8618 combined
8619 };
8620
8621 let with_aspect = if verb_aspect == Aspect::Progressive {
8623 if verb_class == crate::lexicon::VerbClass::Semelfactive {
8625 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8626 operator: AspectOperator::Iterative,
8627 body: with_pps,
8628 })
8629 } else {
8630 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8632 operator: AspectOperator::Progressive,
8633 body: with_pps,
8634 })
8635 }
8636 } else if verb_aspect == Aspect::Perfect {
8637 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8638 operator: AspectOperator::Perfect,
8639 body: with_pps,
8640 })
8641 } else if effective_time == Time::Present && verb_aspect == Aspect::Simple {
8642 if !verb_class.is_stative() {
8644 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8645 operator: AspectOperator::Habitual,
8646 body: with_pps,
8647 })
8648 } else {
8649 with_pps
8651 }
8652 } else {
8653 with_pps
8654 };
8655
8656 let with_adverbs = with_aspect;
8657
8658 let with_temporal = if self.check_temporal_adverb() {
8660 let anchor = if let TokenType::TemporalAdverb(adv) = self.advance().kind.clone() {
8661 adv
8662 } else {
8663 panic!("Expected temporal adverb");
8664 };
8665 self.ctx.exprs.alloc(LogicExpr::TemporalAnchor {
8666 anchor,
8667 body: with_adverbs,
8668 })
8669 } else {
8670 with_adverbs
8671 };
8672
8673 let wrapped = self.wrap_with_definiteness_full(&subject, with_temporal)?;
8674
8675 if let Some((adj, noun)) = object_superlative {
8677 let superlative_expr = self.ctx.exprs.alloc(LogicExpr::Superlative {
8678 adjective: adj,
8679 subject: self.ctx.terms.alloc(Term::Constant(noun)),
8680 domain: noun,
8681 });
8682 return Ok(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8683 left: wrapped,
8684 op: TokenType::And,
8685 right: superlative_expr,
8686 }));
8687 }
8688
8689 return Ok(wrapped);
8690 }
8691
8692 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(subject.noun)))
8693 }
8694
8695 fn check_preposition(&self) -> bool {
8696 matches!(self.peek().kind, TokenType::Preposition(_))
8697 }
8698
8699 fn check_by_preposition(&self) -> bool {
8700 if let TokenType::Preposition(p) = self.peek().kind {
8701 p.is(self.interner, "by")
8702 } else {
8703 false
8704 }
8705 }
8706
8707 fn check_preposition_is(&self, word: &str) -> bool {
8708 if let TokenType::Preposition(p) = self.peek().kind {
8709 p.is(self.interner, word)
8710 } else {
8711 false
8712 }
8713 }
8714
8715 fn check_word(&self, word: &str) -> bool {
8717 let token = self.peek();
8718 let lexeme = self.interner.resolve(token.lexeme);
8719 lexeme.eq_ignore_ascii_case(word)
8720 }
8721
8722 fn peek_word_at(&self, offset: usize, word: &str) -> bool {
8723 if self.current + offset >= self.tokens.len() {
8724 return false;
8725 }
8726 let token = &self.tokens[self.current + offset];
8727 let lexeme = self.interner.resolve(token.lexeme);
8728 lexeme.eq_ignore_ascii_case(word)
8729 }
8730
8731 fn check_to_preposition(&self) -> bool {
8732 match self.peek().kind {
8733 TokenType::To => true,
8734 TokenType::Preposition(p) => p.is(self.interner, "to"),
8735 _ => false,
8736 }
8737 }
8738
8739 fn check_content_word(&self) -> bool {
8740 match &self.peek().kind {
8741 TokenType::Noun(_)
8742 | TokenType::Adjective(_)
8743 | TokenType::NonIntersectiveAdjective(_)
8744 | TokenType::Verb { .. }
8745 | TokenType::ProperName(_)
8746 | TokenType::Article(_) => true,
8747 TokenType::Ambiguous { primary, alternatives } => {
8748 Self::is_content_word_type(primary)
8749 || alternatives.iter().any(Self::is_content_word_type)
8750 }
8751 _ => false,
8752 }
8753 }
8754
8755 fn is_content_word_type(t: &TokenType) -> bool {
8756 matches!(
8757 t,
8758 TokenType::Noun(_)
8759 | TokenType::Adjective(_)
8760 | TokenType::NonIntersectiveAdjective(_)
8761 | TokenType::Verb { .. }
8762 | TokenType::ProperName(_)
8763 | TokenType::Article(_)
8764 )
8765 }
8766
8767 fn check_verb(&self) -> bool {
8768 match &self.peek().kind {
8769 TokenType::Verb { .. } => true,
8770 TokenType::Ambiguous { primary, alternatives } => {
8771 if self.noun_priority_mode {
8772 return false;
8773 }
8774 matches!(**primary, TokenType::Verb { .. })
8775 || alternatives.iter().any(|t| matches!(t, TokenType::Verb { .. }))
8776 }
8777 _ => false,
8778 }
8779 }
8780
8781 fn check_adverb(&self) -> bool {
8782 matches!(self.peek().kind, TokenType::Adverb(_))
8783 }
8784
8785 fn check_performative(&self) -> bool {
8786 matches!(self.peek().kind, TokenType::Performative(_))
8787 }
8788
8789 fn collect_adverbs(&mut self) -> Vec<Symbol> {
8790 let mut adverbs = Vec::new();
8791 while self.check_adverb() {
8792 if let TokenType::Adverb(adv) = self.advance().kind.clone() {
8793 adverbs.push(adv);
8794 }
8795 if self.check(&TokenType::And) {
8797 self.advance();
8798 }
8799 }
8800 adverbs
8801 }
8802
8803 fn check_auxiliary(&self) -> bool {
8804 matches!(self.peek().kind, TokenType::Auxiliary(_))
8805 }
8806
8807 fn is_true_auxiliary_usage(&self) -> bool {
8814 if self.current + 1 >= self.tokens.len() {
8815 return false;
8816 }
8817
8818 let next_token = &self.tokens[self.current + 1].kind;
8819
8820 if matches!(next_token, TokenType::Not) {
8822 return true;
8823 }
8824
8825 if matches!(next_token, TokenType::Verb { .. }) {
8827 return true;
8828 }
8829
8830 if matches!(
8832 next_token,
8833 TokenType::Pronoun { .. }
8834 | TokenType::Article(_)
8835 | TokenType::Noun(_)
8836 | TokenType::ProperName(_)
8837 ) {
8838 return false;
8839 }
8840
8841 true
8843 }
8844
8845 fn check_auxiliary_as_main_verb(&self) -> bool {
8848 if let TokenType::Auxiliary(Time::Past) = self.peek().kind {
8849 if self.current + 1 < self.tokens.len() {
8851 let next = &self.tokens[self.current + 1].kind;
8852 matches!(
8853 next,
8854 TokenType::Pronoun { .. }
8855 | TokenType::Article(_)
8856 | TokenType::Noun(_)
8857 | TokenType::ProperName(_)
8858 )
8859 } else {
8860 false
8861 }
8862 } else {
8863 false
8864 }
8865 }
8866
8867 fn parse_do_as_main_verb(&mut self, subject_term: Term<'a>) -> ParseResult<&'a LogicExpr<'a>> {
8870 let aux_token = self.advance();
8872 let verb_time = if let TokenType::Auxiliary(time) = aux_token.kind {
8873 time
8874 } else {
8875 Time::Past
8876 };
8877
8878 let verb = self.interner.intern("Do");
8880
8881 let object_term = if let TokenType::Pronoun { .. } = self.peek().kind {
8883 self.advance();
8885 let it_sym = self.interner.intern("it");
8888 Term::Constant(it_sym)
8889 } else {
8890 let object = self.parse_noun_phrase(false)?;
8891 self.noun_phrase_to_term(&object)
8892 };
8893
8894 let event_var = self.get_event_var();
8896 let suppress_existential = self.drs.in_conditional_antecedent();
8897
8898 let mut modifiers = Vec::new();
8899 if verb_time == Time::Past {
8900 modifiers.push(self.interner.intern("Past"));
8901 } else if verb_time == Time::Future {
8902 modifiers.push(self.interner.intern("Future"));
8903 }
8904
8905 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8906 event_var,
8907 verb,
8908 roles: self.ctx.roles.alloc_slice(vec![
8909 (ThematicRole::Agent, subject_term),
8910 (ThematicRole::Theme, object_term),
8911 ]),
8912 modifiers: self.ctx.syms.alloc_slice(modifiers),
8913 suppress_existential,
8914 world: None,
8915 })));
8916
8917 Ok(neo_event)
8918 }
8919
8920 fn check_to(&self) -> bool {
8921 matches!(self.peek().kind, TokenType::To)
8922 }
8923
8924 fn has_modal_subordination_ahead(&self) -> bool {
8928 for i in self.current..self.tokens.len() {
8931 match &self.tokens[i].kind {
8932 TokenType::Would | TokenType::Could | TokenType::Should | TokenType::Might => {
8933 return true;
8934 }
8935 TokenType::Period | TokenType::EOF => break,
8937 _ => {}
8938 }
8939 }
8940 false
8941 }
8942
8943 fn consume_verb(&mut self) -> Symbol {
8944 let t = self.advance().clone();
8945 match t.kind {
8946 TokenType::Verb { lemma, .. } => lemma,
8947 TokenType::Ambiguous { primary, .. } => match *primary {
8948 TokenType::Verb { lemma, .. } => lemma,
8949 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
8950 },
8951 _ => panic!("Expected verb, got {:?}", t.kind),
8952 }
8953 }
8954
8955 fn consume_verb_with_metadata(&mut self) -> (Symbol, Time, Aspect, VerbClass) {
8956 let t = self.advance().clone();
8957 match t.kind {
8958 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
8959 TokenType::Ambiguous { primary, .. } => match *primary {
8960 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
8961 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
8962 },
8963 _ => panic!("Expected verb, got {:?}", t.kind),
8964 }
8965 }
8966
8967 fn match_token(&mut self, types: &[TokenType]) -> bool {
8968 for t in types {
8969 if self.check(t) {
8970 self.advance();
8971 return true;
8972 }
8973 }
8974 false
8975 }
8976
8977 fn check_quantifier(&self) -> bool {
8978 matches!(
8979 self.peek().kind,
8980 TokenType::All
8981 | TokenType::No
8982 | TokenType::Some
8983 | TokenType::Any
8984 | TokenType::Most
8985 | TokenType::Few
8986 | TokenType::Many
8987 | TokenType::Cardinal(_)
8988 | TokenType::AtLeast(_)
8989 | TokenType::AtMost(_)
8990 )
8991 }
8992
8993 fn check_npi_quantifier(&self) -> bool {
8994 matches!(
8995 self.peek().kind,
8996 TokenType::Nobody | TokenType::Nothing | TokenType::NoOne
8997 )
8998 }
8999
9000 fn check_npi_object(&self) -> bool {
9001 matches!(
9002 self.peek().kind,
9003 TokenType::Anything | TokenType::Anyone
9004 )
9005 }
9006
9007 fn check_temporal_npi(&self) -> bool {
9008 matches!(
9009 self.peek().kind,
9010 TokenType::Ever | TokenType::Never
9011 )
9012 }
9013
9014 fn parse_npi_quantified(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9015 let npi_token = self.advance().kind.clone();
9016 let var_name = self.next_var_name();
9017
9018 let (restriction_name, is_person) = match npi_token {
9019 TokenType::Nobody | TokenType::NoOne => ("Person", true),
9020 TokenType::Nothing => ("Thing", false),
9021 _ => ("Thing", false),
9022 };
9023
9024 let restriction_sym = self.interner.intern(restriction_name);
9025 let subject_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9026 name: restriction_sym,
9027 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9028 world: None,
9029 });
9030
9031 self.negative_depth += 1;
9032
9033 let verb = self.consume_verb();
9034
9035 if self.check_npi_object() {
9036 let obj_npi_token = self.advance().kind.clone();
9037 let obj_var = self.next_var_name();
9038
9039 let obj_restriction_name = match obj_npi_token {
9040 TokenType::Anything => "Thing",
9041 TokenType::Anyone => "Person",
9042 _ => "Thing",
9043 };
9044
9045 let obj_restriction_sym = self.interner.intern(obj_restriction_name);
9046 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
9047 name: obj_restriction_sym,
9048 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
9049 world: None,
9050 });
9051
9052 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9053 name: verb,
9054 args: self.ctx.terms.alloc_slice([Term::Variable(var_name), Term::Variable(obj_var)]),
9055 world: None,
9056 });
9057
9058 let verb_and_obj = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9059 left: obj_restriction,
9060 op: TokenType::And,
9061 right: verb_pred,
9062 });
9063
9064 let inner_existential = self.ctx.exprs.alloc(LogicExpr::Quantifier {
9065 kind: crate::ast::QuantifierKind::Existential,
9066 variable: obj_var,
9067 body: verb_and_obj,
9068 island_id: self.current_island,
9069 });
9070
9071 self.negative_depth -= 1;
9072
9073 let negated = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9074 op: TokenType::Not,
9075 operand: inner_existential,
9076 });
9077
9078 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9079 left: subject_pred,
9080 op: TokenType::If,
9081 right: negated,
9082 });
9083
9084 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9085 kind: crate::ast::QuantifierKind::Universal,
9086 variable: var_name,
9087 body,
9088 island_id: self.current_island,
9089 }));
9090 }
9091
9092 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9093 name: verb,
9094 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9095 world: None,
9096 });
9097
9098 self.negative_depth -= 1;
9099
9100 let negated_verb = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9101 op: TokenType::Not,
9102 operand: verb_pred,
9103 });
9104
9105 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9106 left: subject_pred,
9107 op: TokenType::If,
9108 right: negated_verb,
9109 });
9110
9111 Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9112 kind: crate::ast::QuantifierKind::Universal,
9113 variable: var_name,
9114 body,
9115 island_id: self.current_island,
9116 }))
9117 }
9118
9119 fn parse_temporal_npi(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9120 let npi_token = self.advance().kind.clone();
9121 let is_never = matches!(npi_token, TokenType::Never);
9122
9123 let subject = self.parse_noun_phrase(true)?;
9124
9125 if is_never {
9126 self.negative_depth += 1;
9127 }
9128
9129 let verb = self.consume_verb();
9130 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9131 name: verb,
9132 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
9133 world: None,
9134 });
9135
9136 if is_never {
9137 self.negative_depth -= 1;
9138 Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9139 op: TokenType::Not,
9140 operand: verb_pred,
9141 }))
9142 } else {
9143 Ok(verb_pred)
9144 }
9145 }
9146
9147 fn check(&self, kind: &TokenType) -> bool {
9148 if self.is_at_end() {
9149 return false;
9150 }
9151 std::mem::discriminant(&self.peek().kind) == std::mem::discriminant(kind)
9152 }
9153
9154 fn check_any(&self, kinds: &[TokenType]) -> bool {
9155 if self.is_at_end() {
9156 return false;
9157 }
9158 let current = std::mem::discriminant(&self.peek().kind);
9159 kinds.iter().any(|k| std::mem::discriminant(k) == current)
9160 }
9161
9162 fn check_article(&self) -> bool {
9163 matches!(self.peek().kind, TokenType::Article(_))
9164 }
9165
9166 fn advance(&mut self) -> &Token {
9167 if !self.is_at_end() {
9168 self.current += 1;
9169 }
9170 self.previous()
9171 }
9172
9173 fn is_at_end(&self) -> bool {
9174 self.peek().kind == TokenType::EOF
9175 }
9176
9177 fn peek(&self) -> &Token {
9178 &self.tokens[self.current]
9179 }
9180
9181 fn peek_next_is_string_literal(&self) -> bool {
9184 self.tokens.get(self.current + 1)
9185 .map(|t| matches!(t.kind, TokenType::StringLiteral(_)))
9186 .unwrap_or(false)
9187 }
9188
9189 fn previous(&self) -> &Token {
9190 &self.tokens[self.current - 1]
9191 }
9192
9193 fn current_span(&self) -> crate::token::Span {
9194 self.peek().span
9195 }
9196
9197 fn consume(&mut self, kind: TokenType) -> ParseResult<&Token> {
9198 if self.check(&kind) {
9199 Ok(self.advance())
9200 } else {
9201 Err(ParseError {
9202 kind: ParseErrorKind::UnexpectedToken {
9203 expected: kind,
9204 found: self.peek().kind.clone(),
9205 },
9206 span: self.current_span(),
9207 })
9208 }
9209 }
9210
9211 fn consume_content_word(&mut self) -> ParseResult<Symbol> {
9212 let t = self.advance().clone();
9213 match t.kind {
9214 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9215 TokenType::Article(_) => Ok(t.lexeme),
9217 TokenType::Number(s) => Ok(s),
9219 TokenType::ProperName(s) => {
9220 if self.mode == ParserMode::Imperative {
9222 if !self.drs.has_referent_by_variable(s) {
9223 return Err(ParseError {
9224 kind: ParseErrorKind::UndefinedVariable {
9225 name: self.interner.resolve(s).to_string()
9226 },
9227 span: t.span,
9228 });
9229 }
9230 return Ok(s);
9231 }
9232
9233 let s_str = self.interner.resolve(s);
9235 let gender = Self::infer_gender(s_str);
9236
9237 self.drs.introduce_proper_name(s, s, gender);
9239
9240 Ok(s)
9241 }
9242 TokenType::Verb { lemma, .. } => Ok(lemma),
9243 TokenType::Ambiguous { primary, .. } => {
9244 match *primary {
9245 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9246 TokenType::Verb { lemma, .. } => Ok(lemma),
9247 TokenType::ProperName(s) => {
9248 if self.mode == ParserMode::Imperative {
9250 if !self.drs.has_referent_by_variable(s) {
9251 return Err(ParseError {
9252 kind: ParseErrorKind::UndefinedVariable {
9253 name: self.interner.resolve(s).to_string()
9254 },
9255 span: t.span,
9256 });
9257 }
9258 return Ok(s);
9259 }
9260 let s_str = self.interner.resolve(s);
9262 let gender = Self::infer_gender(s_str);
9263 self.drs.introduce_proper_name(s, s, gender);
9264 Ok(s)
9265 }
9266 _ => Err(ParseError {
9267 kind: ParseErrorKind::ExpectedContentWord { found: *primary },
9268 span: self.current_span(),
9269 }),
9270 }
9271 }
9272 other => Err(ParseError {
9273 kind: ParseErrorKind::ExpectedContentWord { found: other },
9274 span: self.current_span(),
9275 }),
9276 }
9277 }
9278
9279 fn consume_copula(&mut self) -> ParseResult<()> {
9280 if self.match_token(&[TokenType::Is, TokenType::Are, TokenType::Was, TokenType::Were]) {
9281 Ok(())
9282 } else {
9283 Err(ParseError {
9284 kind: ParseErrorKind::ExpectedCopula,
9285 span: self.current_span(),
9286 })
9287 }
9288 }
9289
9290 fn check_comparative(&self) -> bool {
9291 matches!(self.peek().kind, TokenType::Comparative(_))
9292 }
9293
9294 fn is_contact_clause_pattern(&self) -> bool {
9295 let mut pos = self.current;
9298
9299 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Article(_)) {
9301 pos += 1;
9302 } else {
9303 return false;
9304 }
9305
9306 while pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Adjective(_)) {
9308 pos += 1;
9309 }
9310
9311 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Adjective(_)) {
9313 pos += 1;
9314 } else {
9315 return false;
9316 }
9317
9318 pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Verb { .. } | TokenType::Article(_))
9320 }
9321
9322 fn check_superlative(&self) -> bool {
9323 matches!(self.peek().kind, TokenType::Superlative(_))
9324 }
9325
9326 fn check_scopal_adverb(&self) -> bool {
9327 matches!(self.peek().kind, TokenType::ScopalAdverb(_))
9328 }
9329
9330 fn check_temporal_adverb(&self) -> bool {
9331 matches!(self.peek().kind, TokenType::TemporalAdverb(_))
9332 }
9333
9334 fn check_non_intersective_adjective(&self) -> bool {
9335 matches!(self.peek().kind, TokenType::NonIntersectiveAdjective(_))
9336 }
9337
9338 fn check_focus(&self) -> bool {
9339 matches!(self.peek().kind, TokenType::Focus(_))
9340 }
9341
9342 fn check_measure(&self) -> bool {
9343 matches!(self.peek().kind, TokenType::Measure(_))
9344 }
9345
9346 fn check_presup_trigger(&self) -> bool {
9347 match &self.peek().kind {
9348 TokenType::PresupTrigger(_) => true,
9349 TokenType::Verb { lemma, .. } => {
9350 let s = self.interner.resolve(*lemma).to_lowercase();
9351 crate::lexicon::lookup_presup_trigger(&s).is_some()
9352 }
9353 _ => false,
9354 }
9355 }
9356
9357 fn is_followed_by_np_object(&self) -> bool {
9358 if self.current + 1 >= self.tokens.len() {
9359 return false;
9360 }
9361 let next = &self.tokens[self.current + 1].kind;
9362 matches!(next,
9363 TokenType::ProperName(_) |
9364 TokenType::Article(_) |
9365 TokenType::Noun(_) |
9366 TokenType::Pronoun { .. } |
9367 TokenType::Reflexive |
9368 TokenType::Who |
9369 TokenType::What |
9370 TokenType::Where |
9371 TokenType::When |
9372 TokenType::Why
9373 )
9374 }
9375
9376 fn is_followed_by_gerund(&self) -> bool {
9377 if self.current + 1 >= self.tokens.len() {
9378 return false;
9379 }
9380 matches!(self.tokens[self.current + 1].kind, TokenType::Verb { .. })
9381 }
9382
9383 fn parse_spawn_statement(&mut self) -> ParseResult<Stmt<'a>> {
9389 self.advance(); if !self.check_article() {
9393 return Err(ParseError {
9394 kind: ParseErrorKind::ExpectedKeyword { keyword: "a/an".to_string() },
9395 span: self.current_span(),
9396 });
9397 }
9398 self.advance(); let agent_type = match &self.tokens[self.current].kind {
9402 TokenType::Noun(sym) | TokenType::ProperName(sym) => {
9403 let s = *sym;
9404 self.advance();
9405 s
9406 }
9407 _ => {
9408 return Err(ParseError {
9409 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent type".to_string() },
9410 span: self.current_span(),
9411 });
9412 }
9413 };
9414
9415 if !self.check(&TokenType::Called) {
9417 return Err(ParseError {
9418 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
9419 span: self.current_span(),
9420 });
9421 }
9422 self.advance(); let name = if let TokenType::StringLiteral(sym) = &self.tokens[self.current].kind {
9426 let s = *sym;
9427 self.advance();
9428 s
9429 } else {
9430 return Err(ParseError {
9431 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent name".to_string() },
9432 span: self.current_span(),
9433 });
9434 };
9435
9436 Ok(Stmt::Spawn { agent_type, name })
9437 }
9438
9439 fn parse_send_statement(&mut self) -> ParseResult<Stmt<'a>> {
9441 self.advance(); let message = self.parse_imperative_expr()?;
9445
9446 if !self.check_preposition_is("to") {
9448 return Err(ParseError {
9449 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9450 span: self.current_span(),
9451 });
9452 }
9453 self.advance(); let destination = self.parse_imperative_expr()?;
9457
9458 Ok(Stmt::SendMessage { message, destination })
9459 }
9460
9461 fn parse_await_statement(&mut self) -> ParseResult<Stmt<'a>> {
9463 self.advance(); if self.check_word("response") {
9467 self.advance();
9468 }
9469
9470 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
9472 return Err(ParseError {
9473 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
9474 span: self.current_span(),
9475 });
9476 }
9477 self.advance(); let source = self.parse_imperative_expr()?;
9481
9482 if !self.check_word("into") {
9484 return Err(ParseError {
9485 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
9486 span: self.current_span(),
9487 });
9488 }
9489 self.advance(); let into = match &self.tokens[self.current].kind {
9493 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
9494 let s = *sym;
9495 self.advance();
9496 s
9497 }
9498 _ if self.check_content_word() => {
9500 let sym = self.tokens[self.current].lexeme;
9501 self.advance();
9502 sym
9503 }
9504 _ => {
9505 return Err(ParseError {
9506 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
9507 span: self.current_span(),
9508 });
9509 }
9510 };
9511
9512 Ok(Stmt::AwaitMessage { source, into })
9513 }
9514
9515 fn parse_merge_statement(&mut self) -> ParseResult<Stmt<'a>> {
9521 self.advance(); let source = self.parse_imperative_expr()?;
9525
9526 if !self.check_word("into") {
9528 return Err(ParseError {
9529 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
9530 span: self.current_span(),
9531 });
9532 }
9533 self.advance(); let target = self.parse_imperative_expr()?;
9537
9538 Ok(Stmt::MergeCrdt { source, target })
9539 }
9540
9541 fn parse_increase_statement(&mut self) -> ParseResult<Stmt<'a>> {
9543 self.advance(); let expr = self.parse_imperative_expr()?;
9547
9548 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
9550 (object, field)
9551 } else {
9552 return Err(ParseError {
9553 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
9554 span: self.current_span(),
9555 });
9556 };
9557
9558 if !self.check_preposition_is("by") {
9560 return Err(ParseError {
9561 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
9562 span: self.current_span(),
9563 });
9564 }
9565 self.advance(); let amount = self.parse_imperative_expr()?;
9569
9570 Ok(Stmt::IncreaseCrdt { object, field: *field, amount })
9571 }
9572
9573 fn parse_decrease_statement(&mut self) -> ParseResult<Stmt<'a>> {
9575 self.advance(); let expr = self.parse_imperative_expr()?;
9579
9580 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
9582 (object, field)
9583 } else {
9584 return Err(ParseError {
9585 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
9586 span: self.current_span(),
9587 });
9588 };
9589
9590 if !self.check_preposition_is("by") {
9592 return Err(ParseError {
9593 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
9594 span: self.current_span(),
9595 });
9596 }
9597 self.advance(); let amount = self.parse_imperative_expr()?;
9601
9602 Ok(Stmt::DecreaseCrdt { object, field: *field, amount })
9603 }
9604
9605 fn parse_append_statement(&mut self) -> ParseResult<Stmt<'a>> {
9607 self.advance(); let value = self.parse_imperative_expr()?;
9611
9612 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
9614 return Err(ParseError {
9615 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9616 span: self.current_span(),
9617 });
9618 }
9619 self.advance(); let sequence = self.parse_imperative_expr()?;
9623
9624 Ok(Stmt::AppendToSequence { sequence, value })
9625 }
9626
9627 fn parse_resolve_statement(&mut self) -> ParseResult<Stmt<'a>> {
9629 self.advance(); let expr = self.parse_imperative_expr()?;
9633
9634 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
9636 (object, field)
9637 } else {
9638 return Err(ParseError {
9639 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's title')".to_string() },
9640 span: self.current_span(),
9641 });
9642 };
9643
9644 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
9646 return Err(ParseError {
9647 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9648 span: self.current_span(),
9649 });
9650 }
9651 self.advance(); let value = self.parse_imperative_expr()?;
9655
9656 Ok(Stmt::ResolveConflict { object, field: *field, value })
9657 }
9658
9659}
9660