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 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2209
2210 Ok(Stmt::Let { var, ty, value, mutable })
2211 }
2212
2213 fn check_mutable_keyword(&self) -> bool {
2214 if matches!(self.peek().kind, TokenType::Mut) {
2216 return true;
2217 }
2218 if let TokenType::Noun(sym) | TokenType::Adjective(sym) = self.peek().kind {
2220 let word = self.interner.resolve(sym).to_lowercase();
2221 word == "mutable" || word == "mut"
2222 } else {
2223 false
2224 }
2225 }
2226
2227 fn infer_literal_type(&self, expr: &Expr<'_>) -> Option<&'static str> {
2229 match expr {
2230 Expr::Literal(lit) => match lit {
2231 crate::ast::Literal::Number(_) => Some("Int"),
2232 crate::ast::Literal::Float(_) => Some("Real"),
2233 crate::ast::Literal::Text(_) => Some("Text"),
2234 crate::ast::Literal::Boolean(_) => Some("Bool"),
2235 crate::ast::Literal::Nothing => Some("Unit"),
2236 crate::ast::Literal::Char(_) => Some("Char"),
2237 crate::ast::Literal::Duration(_) => Some("Duration"),
2238 crate::ast::Literal::Date(_) => Some("Date"),
2239 crate::ast::Literal::Moment(_) => Some("Moment"),
2240 crate::ast::Literal::Span { .. } => Some("Span"),
2241 crate::ast::Literal::Time(_) => Some("Time"),
2242 },
2243 _ => None, }
2245 }
2246
2247 fn check_type_compatibility(&self, declared: &TypeExpr<'_>, inferred: &str) -> bool {
2249 match declared {
2250 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2251 let declared_name = self.interner.resolve(*sym);
2252 declared_name.eq_ignore_ascii_case(inferred)
2254 || (declared_name.eq_ignore_ascii_case("Nat") && inferred == "Int")
2255 || (declared_name.eq_ignore_ascii_case("Byte") && inferred == "Int")
2256 }
2257 _ => true, }
2259 }
2260
2261 fn peek_equals_assignment(&self) -> bool {
2268 let is_identifier = matches!(
2272 self.peek().kind,
2273 TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Identifier
2274 | TokenType::Adjective(_) | TokenType::Verb { .. }
2275 | TokenType::Particle(_) | TokenType::Ambiguous { .. }
2276 | TokenType::Pronoun { .. }
2277 );
2278 if !is_identifier {
2279 return false;
2280 }
2281
2282 if self.current + 1 >= self.tokens.len() {
2284 return false;
2285 }
2286
2287 let next = &self.tokens[self.current + 1].kind;
2288
2289 if matches!(next, TokenType::Assign) {
2291 return true;
2292 }
2293
2294 if matches!(next, TokenType::Colon) {
2297 let mut offset = 2;
2298 while self.current + offset < self.tokens.len() {
2299 let tok = &self.tokens[self.current + offset].kind;
2300 if matches!(tok, TokenType::Assign) {
2301 return true;
2302 }
2303 if matches!(tok, TokenType::Period | TokenType::Newline | TokenType::EOF) {
2304 return false;
2305 }
2306 offset += 1;
2307 }
2308 }
2309
2310 false
2311 }
2312
2313 fn parse_equals_assignment(&mut self, explicit_mutable: bool) -> ParseResult<Stmt<'a>> {
2315 if explicit_mutable {
2317 self.advance(); }
2319
2320 let var = self.expect_identifier()?;
2322
2323 let ty = if self.check(&TokenType::Colon) {
2325 self.advance(); let type_expr = self.parse_type_expression()?;
2327 Some(self.ctx.alloc_type_expr(type_expr))
2328 } else {
2329 None
2330 };
2331
2332 if !self.check(&TokenType::Assign) {
2334 return Err(ParseError {
2335 kind: ParseErrorKind::ExpectedKeyword { keyword: "=".to_string() },
2336 span: self.current_span(),
2337 });
2338 }
2339 self.advance(); let value = self.parse_imperative_expr()?;
2343
2344 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2346
2347 Ok(Stmt::Let { var, ty, value, mutable: explicit_mutable })
2348 }
2349
2350 fn parse_set_statement(&mut self) -> ParseResult<Stmt<'a>> {
2351 use crate::ast::Expr;
2352 self.advance(); let target_expr = self.parse_imperative_expr()?;
2356
2357 let is_to = self.check(&TokenType::To) || matches!(
2359 &self.peek().kind,
2360 TokenType::Preposition(sym) if self.interner.resolve(*sym) == "to"
2361 );
2362 if !is_to {
2363 return Err(ParseError {
2364 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2365 span: self.current_span(),
2366 });
2367 }
2368 self.advance(); let value = self.parse_imperative_expr()?;
2372
2373 match target_expr {
2376 Expr::FieldAccess { object, field } => {
2377 Ok(Stmt::SetField { object, field: *field, value })
2378 }
2379 Expr::Identifier(target) => {
2380 Ok(Stmt::Set { target: *target, value })
2381 }
2382 Expr::Index { collection, index } => {
2383 Ok(Stmt::SetIndex { collection, index, value })
2384 }
2385 _ => Err(ParseError {
2386 kind: ParseErrorKind::ExpectedIdentifier,
2387 span: self.current_span(),
2388 })
2389 }
2390 }
2391
2392 fn parse_return_statement(&mut self) -> ParseResult<Stmt<'a>> {
2393 self.advance(); if self.check(&TokenType::Period) || self.is_at_end() {
2397 return Ok(Stmt::Return { value: None });
2398 }
2399
2400 let value = self.parse_comparison()?;
2402 Ok(Stmt::Return { value: Some(value) })
2403 }
2404
2405 fn parse_assert_statement(&mut self) -> ParseResult<Stmt<'a>> {
2406 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2410 self.advance();
2411 }
2412
2413 let condition = self.parse_condition()?;
2416
2417 Ok(Stmt::RuntimeAssert { condition })
2418 }
2419
2420 fn parse_trust_statement(&mut self) -> ParseResult<Stmt<'a>> {
2423 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2427 self.advance();
2428 }
2429
2430 let saved_mode = self.mode;
2432 self.mode = ParserMode::Declarative;
2433
2434 let proposition = self.parse()?;
2436
2437 self.mode = saved_mode;
2439
2440 if !self.check(&TokenType::Because) {
2442 return Err(ParseError {
2443 kind: ParseErrorKind::UnexpectedToken {
2444 expected: TokenType::Because,
2445 found: self.peek().kind.clone(),
2446 },
2447 span: self.current_span(),
2448 });
2449 }
2450 self.advance(); let justification = match &self.peek().kind {
2454 TokenType::StringLiteral(sym) => {
2455 let s = *sym;
2456 self.advance();
2457 s
2458 }
2459 _ => {
2460 return Err(ParseError {
2461 kind: ParseErrorKind::UnexpectedToken {
2462 expected: TokenType::StringLiteral(self.interner.intern("")),
2463 found: self.peek().kind.clone(),
2464 },
2465 span: self.current_span(),
2466 });
2467 }
2468 };
2469
2470 Ok(Stmt::Trust { proposition, justification })
2471 }
2472
2473 fn parse_check_statement(&mut self) -> ParseResult<Stmt<'a>> {
2477 let start_span = self.current_span();
2478 self.advance(); if self.check(&TokenType::That) {
2482 self.advance();
2483 }
2484
2485 if matches!(self.peek().kind, TokenType::Article(_)) {
2487 self.advance();
2488 }
2489
2490 let subject = match &self.peek().kind {
2492 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2493 let s = *sym;
2494 self.advance();
2495 s
2496 }
2497 _ => {
2498 let tok = self.peek();
2500 let s = tok.lexeme;
2501 self.advance();
2502 s
2503 }
2504 };
2505
2506 let is_capability;
2508 let predicate;
2509 let object;
2510
2511 if self.check(&TokenType::Is) || self.check(&TokenType::Are) {
2512 is_capability = false;
2514 self.advance(); predicate = match &self.peek().kind {
2518 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2519 let s = *sym;
2520 self.advance();
2521 s
2522 }
2523 _ => {
2524 let tok = self.peek();
2525 let s = tok.lexeme;
2526 self.advance();
2527 s
2528 }
2529 };
2530 object = None;
2531 } else if self.check(&TokenType::Can) {
2532 is_capability = true;
2534 self.advance(); predicate = match &self.peek().kind {
2538 TokenType::Verb { lemma, .. } => {
2539 let s = *lemma;
2540 self.advance();
2541 s
2542 }
2543 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2544 let s = *sym;
2545 self.advance();
2546 s
2547 }
2548 _ => {
2549 let tok = self.peek();
2550 let s = tok.lexeme;
2551 self.advance();
2552 s
2553 }
2554 };
2555
2556 if matches!(self.peek().kind, TokenType::Article(_)) {
2558 self.advance();
2559 }
2560
2561 let obj = match &self.peek().kind {
2563 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2564 let s = *sym;
2565 self.advance();
2566 s
2567 }
2568 _ => {
2569 let tok = self.peek();
2570 let s = tok.lexeme;
2571 self.advance();
2572 s
2573 }
2574 };
2575 object = Some(obj);
2576 } else {
2577 return Err(ParseError {
2578 kind: ParseErrorKind::ExpectedKeyword { keyword: "is/can".to_string() },
2579 span: self.current_span(),
2580 });
2581 }
2582
2583 let source_text = if is_capability {
2585 let obj_name = self.interner.resolve(object.unwrap());
2586 let pred_name = self.interner.resolve(predicate);
2587 let subj_name = self.interner.resolve(subject);
2588 format!("{} can {} the {}", subj_name, pred_name, obj_name)
2589 } else {
2590 let pred_name = self.interner.resolve(predicate);
2591 let subj_name = self.interner.resolve(subject);
2592 format!("{} is {}", subj_name, pred_name)
2593 };
2594
2595 Ok(Stmt::Check {
2596 subject,
2597 predicate,
2598 is_capability,
2599 object,
2600 source_text,
2601 span: start_span,
2602 })
2603 }
2604
2605 fn parse_listen_statement(&mut self) -> ParseResult<Stmt<'a>> {
2608 self.advance(); if !self.check_preposition_is("on") {
2612 return Err(ParseError {
2613 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2614 span: self.current_span(),
2615 });
2616 }
2617 self.advance(); let address = self.parse_imperative_expr()?;
2621
2622 Ok(Stmt::Listen { address })
2623 }
2624
2625 fn parse_connect_statement(&mut self) -> ParseResult<Stmt<'a>> {
2628 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2632 return Err(ParseError {
2633 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2634 span: self.current_span(),
2635 });
2636 }
2637 self.advance(); let address = self.parse_imperative_expr()?;
2641
2642 Ok(Stmt::ConnectTo { address })
2643 }
2644
2645 fn parse_sleep_statement(&mut self) -> ParseResult<Stmt<'a>> {
2648 self.advance(); let milliseconds = self.parse_imperative_expr()?;
2652
2653 Ok(Stmt::Sleep { milliseconds })
2654 }
2655
2656 fn parse_sync_statement(&mut self) -> ParseResult<Stmt<'a>> {
2659 self.advance(); let var = match &self.tokens[self.current].kind {
2664 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2665 let s = *sym;
2666 self.advance();
2667 s
2668 }
2669 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2670 let s = self.tokens[self.current].lexeme;
2671 self.advance();
2672 s
2673 }
2674 _ => {
2675 return Err(ParseError {
2676 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2677 span: self.current_span(),
2678 });
2679 }
2680 };
2681
2682 if !self.check_preposition_is("on") {
2684 return Err(ParseError {
2685 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2686 span: self.current_span(),
2687 });
2688 }
2689 self.advance(); let topic = self.parse_imperative_expr()?;
2693
2694 Ok(Stmt::Sync { var, topic })
2695 }
2696
2697 fn parse_mount_statement(&mut self) -> ParseResult<Stmt<'a>> {
2701 self.advance(); let var = match &self.tokens[self.current].kind {
2706 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2707 let s = *sym;
2708 self.advance();
2709 s
2710 }
2711 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2712 let s = self.tokens[self.current].lexeme;
2713 self.advance();
2714 s
2715 }
2716 _ => {
2717 return Err(ParseError {
2718 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2719 span: self.current_span(),
2720 });
2721 }
2722 };
2723
2724 if !self.check(&TokenType::At) {
2726 return Err(ParseError {
2727 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2728 span: self.current_span(),
2729 });
2730 }
2731 self.advance(); let path = self.parse_imperative_expr()?;
2735
2736 Ok(Stmt::Mount { var, path })
2737 }
2738
2739 fn lookahead_contains_into(&self) -> bool {
2745 for i in self.current..std::cmp::min(self.current + 5, self.tokens.len()) {
2746 if matches!(self.tokens[i].kind, TokenType::Into) {
2747 return true;
2748 }
2749 }
2750 false
2751 }
2752
2753 fn lookahead_is_first_of(&self) -> bool {
2755 self.current + 3 < self.tokens.len()
2757 && matches!(self.tokens.get(self.current + 1), Some(t) if matches!(t.kind, TokenType::Article(_)))
2758 && self.tokens.get(self.current + 2)
2759 .map(|t| self.interner.resolve(t.lexeme).to_lowercase() == "first")
2760 .unwrap_or(false)
2761 }
2762
2763 fn parse_launch_statement(&mut self) -> ParseResult<Stmt<'a>> {
2766 self.advance(); if !self.check_article() {
2770 return Err(ParseError {
2771 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2772 span: self.current_span(),
2773 });
2774 }
2775 self.advance();
2776
2777 if !self.check(&TokenType::Task) {
2779 return Err(ParseError {
2780 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2781 span: self.current_span(),
2782 });
2783 }
2784 self.advance();
2785
2786 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2788 return Err(ParseError {
2789 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2790 span: self.current_span(),
2791 });
2792 }
2793 self.advance();
2794
2795 let function = match &self.tokens[self.current].kind {
2798 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2799 let s = *sym;
2800 self.advance();
2801 s
2802 }
2803 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2804 let s = self.tokens[self.current].lexeme;
2805 self.advance();
2806 s
2807 }
2808 _ => {
2809 return Err(ParseError {
2810 kind: ParseErrorKind::ExpectedKeyword { keyword: "function name".to_string() },
2811 span: self.current_span(),
2812 });
2813 }
2814 };
2815
2816 let args = if self.check(&TokenType::LParen) {
2818 self.parse_call_arguments()?
2819 } else if self.check_word("with") {
2820 self.advance(); let mut args = Vec::new();
2822 let arg = self.parse_imperative_expr()?;
2823 args.push(arg);
2824 while self.check(&TokenType::And) {
2826 self.advance();
2827 let arg = self.parse_imperative_expr()?;
2828 args.push(arg);
2829 }
2830 args
2831 } else {
2832 Vec::new()
2833 };
2834
2835 Ok(Stmt::LaunchTask { function, args })
2836 }
2837
2838 fn parse_send_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2841 self.advance(); let value = self.parse_imperative_expr()?;
2845
2846 if !self.check(&TokenType::Into) {
2848 return Err(ParseError {
2849 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
2850 span: self.current_span(),
2851 });
2852 }
2853 self.advance();
2854
2855 let pipe = self.parse_imperative_expr()?;
2857
2858 Ok(Stmt::SendPipe { value, pipe })
2859 }
2860
2861 fn parse_receive_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2864 self.advance(); let var = self.expect_identifier()?;
2868
2869 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
2871 return Err(ParseError {
2872 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
2873 span: self.current_span(),
2874 });
2875 }
2876 self.advance();
2877
2878 let pipe = self.parse_imperative_expr()?;
2880
2881 Ok(Stmt::ReceivePipe { var, pipe })
2882 }
2883
2884 fn parse_try_statement(&mut self) -> ParseResult<Stmt<'a>> {
2887 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2891 return Err(ParseError {
2892 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2893 span: self.current_span(),
2894 });
2895 }
2896 self.advance();
2897
2898 if self.check(&TokenType::Send) {
2900 self.advance(); let value = self.parse_imperative_expr()?;
2902
2903 if !self.check(&TokenType::Into) {
2904 return Err(ParseError {
2905 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
2906 span: self.current_span(),
2907 });
2908 }
2909 self.advance();
2910
2911 let pipe = self.parse_imperative_expr()?;
2912 Ok(Stmt::TrySendPipe { value, pipe, result: None })
2913 } else if self.check(&TokenType::Receive) {
2914 self.advance(); let var = self.expect_identifier()?;
2917
2918 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
2919 return Err(ParseError {
2920 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
2921 span: self.current_span(),
2922 });
2923 }
2924 self.advance();
2925
2926 let pipe = self.parse_imperative_expr()?;
2927 Ok(Stmt::TryReceivePipe { var, pipe })
2928 } else {
2929 Err(ParseError {
2930 kind: ParseErrorKind::ExpectedKeyword { keyword: "send or receive".to_string() },
2931 span: self.current_span(),
2932 })
2933 }
2934 }
2935
2936 fn parse_escape_body(&mut self) -> ParseResult<(crate::intern::Symbol, crate::intern::Symbol, crate::token::Span)> {
2939 let start_span = self.current_span();
2940 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2944 return Err(ParseError {
2945 kind: ParseErrorKind::Custom(
2946 "Expected 'to' after 'Escape'. Syntax: Escape to Rust:".to_string()
2947 ),
2948 span: self.current_span(),
2949 });
2950 }
2951 self.advance(); let language = match &self.peek().kind {
2955 TokenType::ProperName(sym) => {
2956 let s = *sym;
2957 self.advance();
2958 s
2959 }
2960 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2961 let s = *sym;
2962 self.advance();
2963 s
2964 }
2965 _ => {
2966 return Err(ParseError {
2967 kind: ParseErrorKind::Custom(
2968 "Expected language name after 'Escape to'. Currently only 'Rust' is supported.".to_string()
2969 ),
2970 span: self.current_span(),
2971 });
2972 }
2973 };
2974
2975 if !language.is(self.interner, "Rust") {
2977 let lang_str = self.interner.resolve(language);
2978 return Err(ParseError {
2979 kind: ParseErrorKind::Custom(
2980 format!("Unsupported escape target '{}'. Only 'Rust' is supported.", lang_str)
2981 ),
2982 span: self.current_span(),
2983 });
2984 }
2985
2986 if !self.check(&TokenType::Colon) {
2988 return Err(ParseError {
2989 kind: ParseErrorKind::Custom(
2990 "Expected ':' after 'Escape to Rust'. Syntax: Escape to Rust:".to_string()
2991 ),
2992 span: self.current_span(),
2993 });
2994 }
2995 self.advance(); if !self.check(&TokenType::Indent) {
2999 return Err(ParseError {
3000 kind: ParseErrorKind::Custom(
3001 "Expected indented block after 'Escape to Rust:'.".to_string()
3002 ),
3003 span: self.current_span(),
3004 });
3005 }
3006 self.advance(); let code = match &self.peek().kind {
3010 TokenType::EscapeBlock(sym) => {
3011 let s = *sym;
3012 self.advance();
3013 s
3014 }
3015 _ => {
3016 return Err(ParseError {
3017 kind: ParseErrorKind::Custom(
3018 "Escape block body is empty or malformed.".to_string()
3019 ),
3020 span: self.current_span(),
3021 });
3022 }
3023 };
3024
3025 if self.check(&TokenType::Dedent) {
3027 self.advance();
3028 }
3029
3030 let end_span = self.previous().span;
3031 Ok((language, code, crate::token::Span::new(start_span.start, end_span.end)))
3032 }
3033
3034 fn parse_escape_statement(&mut self) -> ParseResult<Stmt<'a>> {
3036 let (language, code, span) = self.parse_escape_body()?;
3037 Ok(Stmt::Escape { language, code, span })
3038 }
3039
3040 fn parse_escape_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
3043 let (language, code, _span) = self.parse_escape_body()?;
3044 Ok(self.ctx.alloc_imperative_expr(Expr::Escape { language, code }))
3045 }
3046
3047 fn parse_requires_block(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
3050 let mut deps = Vec::new();
3051
3052 loop {
3053 if self.is_at_end() {
3055 break;
3056 }
3057 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
3058 break;
3059 }
3060
3061 if self.check(&TokenType::Indent)
3063 || self.check(&TokenType::Dedent)
3064 || self.check(&TokenType::Newline)
3065 {
3066 self.advance();
3067 continue;
3068 }
3069
3070 if matches!(self.peek().kind, TokenType::Article(_)) {
3072 let dep = self.parse_require_line()?;
3073 deps.push(dep);
3074 continue;
3075 }
3076
3077 self.advance();
3079 }
3080
3081 Ok(deps)
3082 }
3083
3084 fn parse_require_line(&mut self) -> ParseResult<Stmt<'a>> {
3087 let start_span = self.current_span();
3088
3089 if !matches!(self.peek().kind, TokenType::Article(_)) {
3091 return Err(crate::error::ParseError {
3092 kind: crate::error::ParseErrorKind::Custom(
3093 "Expected 'The' to begin a dependency declaration.".to_string(),
3094 ),
3095 span: self.current_span(),
3096 });
3097 }
3098 self.advance(); let crate_name = if let TokenType::StringLiteral(sym) = self.peek().kind {
3102 let s = sym;
3103 self.advance();
3104 s
3105 } else {
3106 return Err(crate::error::ParseError {
3107 kind: crate::error::ParseErrorKind::Custom(
3108 "Expected a string literal for the crate name, e.g. \"serde\".".to_string(),
3109 ),
3110 span: self.current_span(),
3111 });
3112 };
3113
3114 if !self.check_word("crate") {
3116 return Err(crate::error::ParseError {
3117 kind: crate::error::ParseErrorKind::Custom(
3118 "Expected the word 'crate' after the crate name.".to_string(),
3119 ),
3120 span: self.current_span(),
3121 });
3122 }
3123 self.advance(); if !self.check_word("version") {
3127 return Err(crate::error::ParseError {
3128 kind: crate::error::ParseErrorKind::Custom(
3129 "Expected 'version' after 'crate'.".to_string(),
3130 ),
3131 span: self.current_span(),
3132 });
3133 }
3134 self.advance(); let version = if let TokenType::StringLiteral(sym) = self.peek().kind {
3138 let s = sym;
3139 self.advance();
3140 s
3141 } else {
3142 return Err(crate::error::ParseError {
3143 kind: crate::error::ParseErrorKind::Custom(
3144 "Expected a string literal for the version, e.g. \"1.0\".".to_string(),
3145 ),
3146 span: self.current_span(),
3147 });
3148 };
3149
3150 let mut features = Vec::new();
3152 if self.check_preposition_is("with") {
3153 self.advance(); if !self.check_word("features") {
3157 return Err(crate::error::ParseError {
3158 kind: crate::error::ParseErrorKind::Custom(
3159 "Expected 'features' after 'with'.".to_string(),
3160 ),
3161 span: self.current_span(),
3162 });
3163 }
3164 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3168 features.push(sym);
3169 self.advance();
3170 } else {
3171 return Err(crate::error::ParseError {
3172 kind: crate::error::ParseErrorKind::Custom(
3173 "Expected a string literal for a feature name.".to_string(),
3174 ),
3175 span: self.current_span(),
3176 });
3177 }
3178
3179 while self.check(&TokenType::And) {
3181 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3183 features.push(sym);
3184 self.advance();
3185 } else {
3186 return Err(crate::error::ParseError {
3187 kind: crate::error::ParseErrorKind::Custom(
3188 "Expected a string literal for a feature name after 'and'.".to_string(),
3189 ),
3190 span: self.current_span(),
3191 });
3192 }
3193 }
3194 }
3195
3196 if self.check(&TokenType::For) {
3198 self.advance(); while !self.check(&TokenType::Period) && !self.check(&TokenType::EOF)
3200 && !self.check(&TokenType::Newline)
3201 && !matches!(self.peek().kind, TokenType::BlockHeader { .. })
3202 {
3203 self.advance();
3204 }
3205 }
3206
3207 if self.check(&TokenType::Period) {
3209 self.advance();
3210 }
3211
3212 let end_span = self.previous().span;
3213
3214 Ok(Stmt::Require {
3215 crate_name,
3216 version,
3217 features,
3218 span: crate::token::Span::new(start_span.start, end_span.end),
3219 })
3220 }
3221
3222 fn parse_stop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3225 self.advance(); let handle = self.parse_imperative_expr()?;
3228
3229 Ok(Stmt::StopTask { handle })
3230 }
3231
3232 fn parse_select_statement(&mut self) -> ParseResult<Stmt<'a>> {
3240 use crate::ast::stmt::SelectBranch;
3241
3242 self.advance(); if !self.check_article() {
3246 return Err(ParseError {
3247 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
3248 span: self.current_span(),
3249 });
3250 }
3251 self.advance();
3252
3253 if !self.check_word("first") {
3255 return Err(ParseError {
3256 kind: ParseErrorKind::ExpectedKeyword { keyword: "first".to_string() },
3257 span: self.current_span(),
3258 });
3259 }
3260 self.advance();
3261
3262 if !self.check_preposition_is("of") {
3264 return Err(ParseError {
3265 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3266 span: self.current_span(),
3267 });
3268 }
3269 self.advance();
3270
3271 if !self.check(&TokenType::Colon) {
3273 return Err(ParseError {
3274 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3275 span: self.current_span(),
3276 });
3277 }
3278 self.advance();
3279
3280 if !self.check(&TokenType::Indent) {
3282 return Err(ParseError {
3283 kind: ParseErrorKind::ExpectedStatement,
3284 span: self.current_span(),
3285 });
3286 }
3287 self.advance();
3288
3289 let mut branches = Vec::new();
3291 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3292 let branch = self.parse_select_branch()?;
3293 branches.push(branch);
3294 }
3295
3296 if self.check(&TokenType::Dedent) {
3298 self.advance();
3299 }
3300
3301 Ok(Stmt::Select { branches })
3302 }
3303
3304 fn parse_select_branch(&mut self) -> ParseResult<crate::ast::stmt::SelectBranch<'a>> {
3306 use crate::ast::stmt::SelectBranch;
3307
3308 if self.check(&TokenType::Receive) {
3309 self.advance(); let var = match &self.tokens[self.current].kind {
3312 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3313 let s = *sym;
3314 self.advance();
3315 s
3316 }
3317 _ => {
3318 return Err(ParseError {
3319 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
3320 span: self.current_span(),
3321 });
3322 }
3323 };
3324
3325 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3326 return Err(ParseError {
3327 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3328 span: self.current_span(),
3329 });
3330 }
3331 self.advance();
3332
3333 let pipe = self.parse_imperative_expr()?;
3334
3335 if !self.check(&TokenType::Colon) {
3337 return Err(ParseError {
3338 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3339 span: self.current_span(),
3340 });
3341 }
3342 self.advance();
3343
3344 let body = self.parse_indented_block()?;
3346
3347 Ok(SelectBranch::Receive { var, pipe, body })
3348 } else if self.check_word("after") {
3349 self.advance(); let milliseconds = self.parse_imperative_expr()?;
3352
3353 if self.check_word("seconds") || self.check_word("milliseconds") {
3355 self.advance();
3356 }
3357
3358 if !self.check(&TokenType::Colon) {
3360 return Err(ParseError {
3361 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3362 span: self.current_span(),
3363 });
3364 }
3365 self.advance();
3366
3367 let body = self.parse_indented_block()?;
3369
3370 Ok(SelectBranch::Timeout { milliseconds, body })
3371 } else {
3372 Err(ParseError {
3373 kind: ParseErrorKind::ExpectedKeyword { keyword: "Receive or After".to_string() },
3374 span: self.current_span(),
3375 })
3376 }
3377 }
3378
3379 fn parse_indented_block(&mut self) -> ParseResult<crate::ast::stmt::Block<'a>> {
3381 if !self.check(&TokenType::Indent) {
3383 return Err(ParseError {
3384 kind: ParseErrorKind::ExpectedStatement,
3385 span: self.current_span(),
3386 });
3387 }
3388 self.advance();
3389
3390 let mut stmts = Vec::new();
3391 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3392 let stmt = self.parse_statement()?;
3393 stmts.push(stmt);
3394 if self.check(&TokenType::Period) {
3395 self.advance();
3396 }
3397 }
3398
3399 if self.check(&TokenType::Dedent) {
3401 self.advance();
3402 }
3403
3404 let block = self.ctx.stmts.expect("imperative arenas not initialized")
3405 .alloc_slice(stmts.into_iter());
3406
3407 Ok(block)
3408 }
3409
3410 fn parse_give_statement(&mut self) -> ParseResult<Stmt<'a>> {
3411 self.advance(); let object = self.parse_imperative_expr()?;
3415
3416 if !self.check_to_preposition() {
3418 return Err(ParseError {
3419 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3420 span: self.current_span(),
3421 });
3422 }
3423 self.advance(); let recipient = self.parse_imperative_expr()?;
3427
3428 if let Expr::Identifier(sym) = object {
3430 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Moved);
3431 }
3432
3433 Ok(Stmt::Give { object, recipient })
3434 }
3435
3436 fn parse_show_statement(&mut self) -> ParseResult<Stmt<'a>> {
3437 self.advance(); let object = self.parse_condition()?;
3442
3443 let recipient = if self.check_to_preposition() {
3447 self.advance(); if self.check_article() {
3452 self.advance(); }
3454 if self.check(&TokenType::Console) {
3455 self.advance(); let show_sym = self.interner.intern("show");
3457 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3458 } else {
3459 self.parse_imperative_expr()?
3461 }
3462 } else {
3463 let show_sym = self.interner.intern("show");
3465 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3466 };
3467
3468 if let Expr::Identifier(sym) = object {
3470 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Borrowed);
3471 }
3472
3473 Ok(Stmt::Show { object, recipient })
3474 }
3475
3476 fn parse_push_statement(&mut self) -> ParseResult<Stmt<'a>> {
3479 self.advance(); let value = self.parse_imperative_expr()?;
3483
3484 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3486 return Err(ParseError {
3487 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3488 span: self.current_span(),
3489 });
3490 }
3491 self.advance(); let collection = self.parse_imperative_expr()?;
3495
3496 Ok(Stmt::Push { value, collection })
3497 }
3498
3499 fn parse_pop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3502 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3506 return Err(ParseError {
3507 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3508 span: self.current_span(),
3509 });
3510 }
3511 self.advance(); let collection = self.parse_imperative_expr()?;
3515
3516 let into = if self.check(&TokenType::Into) || self.check_preposition_is("into") {
3518 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = &self.peek().kind {
3522 let sym = *sym;
3523 self.advance();
3524 Some(sym)
3525 } else if let Some(token) = self.tokens.get(self.current) {
3526 let sym = token.lexeme;
3528 self.advance();
3529 Some(sym)
3530 } else {
3531 return Err(ParseError {
3532 kind: ParseErrorKind::ExpectedIdentifier,
3533 span: self.current_span(),
3534 });
3535 }
3536 } else {
3537 None
3538 };
3539
3540 Ok(Stmt::Pop { collection, into })
3541 }
3542
3543 fn parse_add_statement(&mut self) -> ParseResult<Stmt<'a>> {
3546 self.advance(); let value = self.parse_imperative_expr()?;
3550
3551 if !self.check_preposition_is("to") && !self.check(&TokenType::To) {
3553 return Err(ParseError {
3554 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3555 span: self.current_span(),
3556 });
3557 }
3558 self.advance(); let collection = self.parse_imperative_expr()?;
3562
3563 Ok(Stmt::Add { value, collection })
3564 }
3565
3566 fn parse_remove_statement(&mut self) -> ParseResult<Stmt<'a>> {
3569 self.advance(); let value = self.parse_imperative_expr()?;
3573
3574 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3576 return Err(ParseError {
3577 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3578 span: self.current_span(),
3579 });
3580 }
3581 self.advance(); let collection = self.parse_imperative_expr()?;
3585
3586 Ok(Stmt::Remove { value, collection })
3587 }
3588
3589 fn parse_read_statement(&mut self) -> ParseResult<Stmt<'a>> {
3593 self.advance(); let var = self.expect_identifier()?;
3597
3598 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3600 return Err(ParseError {
3601 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3602 span: self.current_span(),
3603 });
3604 }
3605 self.advance(); if self.check_article() {
3609 self.advance();
3610 }
3611
3612 let source = if self.check(&TokenType::Console) {
3614 self.advance(); ReadSource::Console
3616 } else if self.check(&TokenType::File) {
3617 self.advance(); let path = self.parse_imperative_expr()?;
3619 ReadSource::File(path)
3620 } else {
3621 return Err(ParseError {
3622 kind: ParseErrorKind::ExpectedKeyword { keyword: "console or file".to_string() },
3623 span: self.current_span(),
3624 });
3625 };
3626
3627 Ok(Stmt::ReadFrom { var, source })
3628 }
3629
3630 fn parse_write_statement(&mut self) -> ParseResult<Stmt<'a>> {
3633 self.advance(); let content = self.parse_imperative_expr()?;
3637
3638 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3640 return Err(ParseError {
3641 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3642 span: self.current_span(),
3643 });
3644 }
3645 self.advance(); if !self.check(&TokenType::File) {
3649 return Err(ParseError {
3650 kind: ParseErrorKind::ExpectedKeyword { keyword: "file".to_string() },
3651 span: self.current_span(),
3652 });
3653 }
3654 self.advance(); let path = self.parse_imperative_expr()?;
3658
3659 Ok(Stmt::WriteFile { content, path })
3660 }
3661
3662 fn parse_zone_statement(&mut self) -> ParseResult<Stmt<'a>> {
3668 self.advance(); if self.check_article() {
3672 self.advance();
3673 }
3674
3675 if self.check(&TokenType::New) {
3677 self.advance();
3678 }
3679
3680 if !self.check(&TokenType::Zone) {
3682 return Err(ParseError {
3683 kind: ParseErrorKind::ExpectedKeyword { keyword: "zone".to_string() },
3684 span: self.current_span(),
3685 });
3686 }
3687 self.advance(); if !self.check(&TokenType::Called) {
3691 return Err(ParseError {
3692 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
3693 span: self.current_span(),
3694 });
3695 }
3696 self.advance(); let name = match &self.peek().kind {
3700 TokenType::StringLiteral(sym) => {
3701 let s = *sym;
3702 self.advance();
3703 s
3704 }
3705 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3706 let s = *sym;
3707 self.advance();
3708 s
3709 }
3710 _ => {
3711 let token = self.peek().clone();
3713 self.advance();
3714 token.lexeme
3715 }
3716 };
3717
3718 let mut capacity = None;
3719 let mut source_file = None;
3720
3721 if self.check(&TokenType::Mapped) {
3723 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3727 return Err(ParseError {
3728 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3729 span: self.current_span(),
3730 });
3731 }
3732 self.advance(); if let TokenType::StringLiteral(path) = &self.peek().kind {
3736 source_file = Some(*path);
3737 self.advance();
3738 } else {
3739 return Err(ParseError {
3740 kind: ParseErrorKind::ExpectedKeyword { keyword: "file path string".to_string() },
3741 span: self.current_span(),
3742 });
3743 }
3744 }
3745 else if self.check_of_preposition() {
3747 self.advance(); if !self.check(&TokenType::Size) {
3751 return Err(ParseError {
3752 kind: ParseErrorKind::ExpectedKeyword { keyword: "size".to_string() },
3753 span: self.current_span(),
3754 });
3755 }
3756 self.advance(); let size_value = match &self.peek().kind {
3760 TokenType::Number(sym) => {
3761 let num_str = self.interner.resolve(*sym);
3762 let val = num_str.replace('_', "").parse::<usize>().unwrap_or(0);
3763 self.advance();
3764 val
3765 }
3766 TokenType::Cardinal(n) => {
3767 let val = *n as usize;
3768 self.advance();
3769 val
3770 }
3771 _ => {
3772 return Err(ParseError {
3773 kind: ParseErrorKind::ExpectedNumber,
3774 span: self.current_span(),
3775 });
3776 }
3777 };
3778
3779 let unit_multiplier = self.parse_size_unit()?;
3781 capacity = Some(size_value * unit_multiplier);
3782 }
3783
3784 if !self.check(&TokenType::Colon) {
3786 return Err(ParseError {
3787 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3788 span: self.current_span(),
3789 });
3790 }
3791 self.advance(); if !self.check(&TokenType::Indent) {
3795 return Err(ParseError {
3796 kind: ParseErrorKind::ExpectedStatement,
3797 span: self.current_span(),
3798 });
3799 }
3800 self.advance(); let mut body_stmts = Vec::new();
3804 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3805 let stmt = self.parse_statement()?;
3806 body_stmts.push(stmt);
3807 if self.check(&TokenType::Period) {
3808 self.advance();
3809 }
3810 }
3811
3812 if self.check(&TokenType::Dedent) {
3814 self.advance();
3815 }
3816
3817 let body = self.ctx.stmts.expect("imperative arenas not initialized")
3818 .alloc_slice(body_stmts.into_iter());
3819
3820 Ok(Stmt::Zone { name, capacity, source_file, body })
3821 }
3822
3823 fn parse_size_unit(&mut self) -> ParseResult<usize> {
3825 let token = self.peek().clone();
3826 let unit_str = self.interner.resolve(token.lexeme).to_uppercase();
3827 self.advance();
3828
3829 match unit_str.as_str() {
3830 "B" | "BYTES" | "BYTE" => Ok(1),
3831 "KB" | "KILOBYTE" | "KILOBYTES" => Ok(1024),
3832 "MB" | "MEGABYTE" | "MEGABYTES" => Ok(1024 * 1024),
3833 "GB" | "GIGABYTE" | "GIGABYTES" => Ok(1024 * 1024 * 1024),
3834 _ => Err(ParseError {
3835 kind: ParseErrorKind::ExpectedKeyword {
3836 keyword: "size unit (B, KB, MB, GB)".to_string(),
3837 },
3838 span: token.span,
3839 }),
3840 }
3841 }
3842
3843 fn parse_concurrent_block(&mut self) -> ParseResult<Stmt<'a>> {
3852 self.advance(); if !self.check(&TokenType::All) {
3856 return Err(ParseError {
3857 kind: ParseErrorKind::ExpectedKeyword { keyword: "all".to_string() },
3858 span: self.current_span(),
3859 });
3860 }
3861 self.advance(); if !self.check_of_preposition() {
3865 return Err(ParseError {
3866 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3867 span: self.current_span(),
3868 });
3869 }
3870 self.advance(); if !self.check_article() {
3874 return Err(ParseError {
3875 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
3876 span: self.current_span(),
3877 });
3878 }
3879 self.advance(); if !self.check(&TokenType::Following) {
3883 return Err(ParseError {
3884 kind: ParseErrorKind::ExpectedKeyword { keyword: "following".to_string() },
3885 span: self.current_span(),
3886 });
3887 }
3888 self.advance(); if !self.check(&TokenType::Colon) {
3892 return Err(ParseError {
3893 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3894 span: self.current_span(),
3895 });
3896 }
3897 self.advance(); if !self.check(&TokenType::Indent) {
3901 return Err(ParseError {
3902 kind: ParseErrorKind::ExpectedStatement,
3903 span: self.current_span(),
3904 });
3905 }
3906 self.advance(); let mut task_stmts = Vec::new();
3910 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3911 let stmt = self.parse_statement()?;
3912 task_stmts.push(stmt);
3913 if self.check(&TokenType::Period) {
3914 self.advance();
3915 }
3916 }
3917
3918 if self.check(&TokenType::Dedent) {
3920 self.advance();
3921 }
3922
3923 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
3924 .alloc_slice(task_stmts.into_iter());
3925
3926 Ok(Stmt::Concurrent { tasks })
3927 }
3928
3929 fn parse_parallel_block(&mut self) -> ParseResult<Stmt<'a>> {
3938 self.advance(); if !self.check(&TokenType::Colon) {
3942 return Err(ParseError {
3943 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3944 span: self.current_span(),
3945 });
3946 }
3947 self.advance(); if !self.check(&TokenType::Indent) {
3951 return Err(ParseError {
3952 kind: ParseErrorKind::ExpectedStatement,
3953 span: self.current_span(),
3954 });
3955 }
3956 self.advance(); let mut task_stmts = Vec::new();
3960 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3961 let stmt = self.parse_statement()?;
3962 task_stmts.push(stmt);
3963 if self.check(&TokenType::Period) {
3964 self.advance();
3965 }
3966 }
3967
3968 if self.check(&TokenType::Dedent) {
3970 self.advance();
3971 }
3972
3973 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
3974 .alloc_slice(task_stmts.into_iter());
3975
3976 Ok(Stmt::Parallel { tasks })
3977 }
3978
3979 fn parse_inspect_statement(&mut self) -> ParseResult<Stmt<'a>> {
3986 self.advance(); let target = self.parse_imperative_expr()?;
3990
3991 if !self.check(&TokenType::Colon) {
3993 return Err(ParseError {
3994 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3995 span: self.current_span(),
3996 });
3997 }
3998 self.advance(); if !self.check(&TokenType::Indent) {
4002 return Err(ParseError {
4003 kind: ParseErrorKind::ExpectedStatement,
4004 span: self.current_span(),
4005 });
4006 }
4007 self.advance(); let mut arms = Vec::new();
4010 let mut has_otherwise = false;
4011
4012 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4014 if self.check(&TokenType::Otherwise) {
4015 self.advance(); if !self.check(&TokenType::Colon) {
4019 return Err(ParseError {
4020 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4021 span: self.current_span(),
4022 });
4023 }
4024 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4028 self.advance(); let mut stmts = Vec::new();
4030 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4031 let stmt = self.parse_statement()?;
4032 stmts.push(stmt);
4033 if self.check(&TokenType::Period) {
4034 self.advance();
4035 }
4036 }
4037 if self.check(&TokenType::Dedent) {
4038 self.advance();
4039 }
4040 stmts
4041 } else {
4042 let stmt = self.parse_statement()?;
4044 if self.check(&TokenType::Period) {
4045 self.advance();
4046 }
4047 vec![stmt]
4048 };
4049
4050 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4051 .alloc_slice(body_stmts.into_iter());
4052
4053 arms.push(MatchArm { enum_name: None, variant: None, bindings: vec![], body });
4054 has_otherwise = true;
4055 break;
4056 }
4057
4058 if self.check(&TokenType::If) {
4059 let arm = self.parse_match_arm()?;
4061 arms.push(arm);
4062 } else if self.check(&TokenType::When) || self.check_word("When") {
4063 let arm = self.parse_when_arm()?;
4065 arms.push(arm);
4066 } else if self.check(&TokenType::Newline) {
4067 self.advance();
4069 } else {
4070 self.advance();
4072 }
4073 }
4074
4075 if self.check(&TokenType::Dedent) {
4077 self.advance();
4078 }
4079
4080 Ok(Stmt::Inspect { target, arms, has_otherwise })
4081 }
4082
4083 fn parse_match_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4085 self.advance(); if !self.check_word("it") {
4089 return Err(ParseError {
4090 kind: ParseErrorKind::ExpectedKeyword { keyword: "it".to_string() },
4091 span: self.current_span(),
4092 });
4093 }
4094 self.advance(); if !self.check(&TokenType::Is) {
4098 return Err(ParseError {
4099 kind: ParseErrorKind::ExpectedKeyword { keyword: "is".to_string() },
4100 span: self.current_span(),
4101 });
4102 }
4103 self.advance(); if self.check_article() {
4107 self.advance();
4108 }
4109
4110 let variant = self.expect_identifier()?;
4112
4113 let enum_name = self.find_variant(variant);
4115
4116 let bindings = if self.check(&TokenType::LParen) {
4118 self.parse_pattern_bindings()?
4119 } else {
4120 vec![]
4121 };
4122
4123 if !self.check(&TokenType::Colon) {
4125 return Err(ParseError {
4126 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4127 span: self.current_span(),
4128 });
4129 }
4130 self.advance(); if !self.check(&TokenType::Indent) {
4134 return Err(ParseError {
4135 kind: ParseErrorKind::ExpectedStatement,
4136 span: self.current_span(),
4137 });
4138 }
4139 self.advance(); let mut body_stmts = Vec::new();
4143 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4144 let stmt = self.parse_statement()?;
4145 body_stmts.push(stmt);
4146 if self.check(&TokenType::Period) {
4147 self.advance();
4148 }
4149 }
4150
4151 if self.check(&TokenType::Dedent) {
4153 self.advance();
4154 }
4155
4156 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4157 .alloc_slice(body_stmts.into_iter());
4158
4159 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4160 }
4161
4162 fn parse_when_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4164 self.advance(); let variant = self.expect_identifier()?;
4168
4169 let (enum_name, variant_fields) = self.type_registry
4171 .as_ref()
4172 .and_then(|r| r.find_variant(variant).map(|(enum_name, vdef)| {
4173 let fields: Vec<_> = vdef.fields.iter().map(|f| f.name).collect();
4174 (Some(enum_name), fields)
4175 }))
4176 .unwrap_or((None, vec![]));
4177
4178 let bindings = if self.check(&TokenType::LParen) {
4180 let raw_bindings = self.parse_when_bindings()?;
4181 raw_bindings.into_iter().enumerate().map(|(i, binding)| {
4183 let field = variant_fields.get(i).copied().unwrap_or(binding);
4184 (field, binding)
4185 }).collect()
4186 } else {
4187 vec![]
4188 };
4189
4190 if !self.check(&TokenType::Colon) {
4192 return Err(ParseError {
4193 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4194 span: self.current_span(),
4195 });
4196 }
4197 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4201 self.advance(); let mut stmts = Vec::new();
4203 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4204 let stmt = self.parse_statement()?;
4205 stmts.push(stmt);
4206 if self.check(&TokenType::Period) {
4207 self.advance();
4208 }
4209 }
4210 if self.check(&TokenType::Dedent) {
4211 self.advance();
4212 }
4213 stmts
4214 } else {
4215 let stmt = self.parse_statement()?;
4217 if self.check(&TokenType::Period) {
4218 self.advance();
4219 }
4220 vec![stmt]
4221 };
4222
4223 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4224 .alloc_slice(body_stmts.into_iter());
4225
4226 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4227 }
4228
4229 fn parse_when_bindings(&mut self) -> ParseResult<Vec<Symbol>> {
4231 self.advance(); let mut bindings = Vec::new();
4233
4234 loop {
4235 let binding = self.expect_identifier()?;
4236 bindings.push(binding);
4237
4238 if !self.check(&TokenType::Comma) {
4239 break;
4240 }
4241 self.advance(); }
4243
4244 if !self.check(&TokenType::RParen) {
4245 return Err(ParseError {
4246 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4247 span: self.current_span(),
4248 });
4249 }
4250 self.advance(); Ok(bindings)
4253 }
4254
4255 fn parse_pattern_bindings(&mut self) -> ParseResult<Vec<(Symbol, Symbol)>> {
4257 self.advance(); let mut bindings = Vec::new();
4259
4260 loop {
4261 let field = self.expect_identifier()?;
4262 let binding = if self.check(&TokenType::Colon) {
4263 self.advance(); self.expect_identifier()?
4265 } else {
4266 field };
4268 bindings.push((field, binding));
4269
4270 if !self.check(&TokenType::Comma) {
4271 break;
4272 }
4273 self.advance(); }
4275
4276 if !self.check(&TokenType::RParen) {
4277 return Err(ParseError {
4278 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4279 span: self.current_span(),
4280 });
4281 }
4282 self.advance(); Ok(bindings)
4285 }
4286
4287 fn parse_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4291 use crate::ast::Expr;
4292 let mut fields = Vec::new();
4293
4294 self.advance();
4296
4297 loop {
4298 let field_name = self.expect_identifier()?;
4300
4301 let value = self.parse_imperative_expr()?;
4303
4304 fields.push((field_name, value));
4305
4306 if self.check(&TokenType::And) {
4308 self.advance(); continue;
4310 }
4311 break;
4312 }
4313
4314 Ok(fields)
4315 }
4316
4317 fn parse_variant_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4319 self.parse_constructor_fields()
4320 }
4321
4322 fn parse_struct_init_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4324 self.parse_constructor_fields()
4325 }
4326
4327 fn parse_generic_type_args(&mut self, type_name: Symbol) -> ParseResult<Vec<TypeExpr<'a>>> {
4331 if !self.is_generic_type(type_name) {
4333 return Ok(vec![]);
4334 }
4335
4336 if !self.check_preposition_is("of") {
4338 return Ok(vec![]); }
4340 self.advance(); let mut type_args = Vec::new();
4343 loop {
4344 let type_arg = self.parse_type_expression()?;
4346 type_args.push(type_arg);
4347
4348 if self.check(&TokenType::And) || self.check_to_preposition() {
4350 self.advance(); continue;
4352 }
4353 break;
4354 }
4355
4356 Ok(type_args)
4357 }
4358
4359 fn skip_type_def_content(&mut self) {
4363 while !self.is_at_end() {
4364 if matches!(
4366 self.tokens.get(self.current),
4367 Some(Token { kind: TokenType::BlockHeader { .. }, .. })
4368 ) {
4369 break;
4370 }
4371 self.advance();
4372 }
4373 }
4374
4375 fn parse_theorem_block(&mut self) -> ParseResult<Stmt<'a>> {
4383 use crate::ast::theorem::{TheoremBlock, ProofStrategy};
4384
4385 self.skip_whitespace_tokens();
4387
4388 if self.check(&TokenType::Colon) {
4393 self.advance();
4394 }
4395
4396 self.skip_whitespace_tokens();
4398
4399 let name = if let Some(token) = self.tokens.get(self.current) {
4401 match &token.kind {
4402 TokenType::Noun(_)
4403 | TokenType::ProperName(_)
4404 | TokenType::Verb { .. }
4405 | TokenType::Adjective(_) => {
4406 let name = self.interner.resolve(token.lexeme).to_string();
4407 self.advance();
4408 name
4409 }
4410 _ => {
4411 let lexeme = self.interner.resolve(token.lexeme);
4413 if !lexeme.is_empty() && lexeme.chars().next().map(|c| c.is_alphanumeric()).unwrap_or(false) {
4414 let name = lexeme.to_string();
4415 self.advance();
4416 name
4417 } else {
4418 "Anonymous".to_string()
4419 }
4420 }
4421 }
4422 } else {
4423 "Anonymous".to_string()
4424 };
4425
4426 self.skip_whitespace_tokens();
4427
4428 if self.check(&TokenType::Period) {
4430 self.advance();
4431 }
4432
4433 self.skip_whitespace_tokens();
4434
4435 let mut premises = Vec::new();
4438 while self.check(&TokenType::Given) {
4439 self.advance(); if self.check(&TokenType::Colon) {
4443 self.advance();
4444 }
4445
4446 self.skip_whitespace_tokens();
4447
4448 let premise_expr = self.parse_sentence()?;
4450 premises.push(premise_expr);
4451
4452 self.world_state.end_sentence();
4455
4456 if self.check(&TokenType::Period) {
4458 self.advance();
4459 }
4460
4461 self.skip_whitespace_tokens();
4462 }
4463
4464 let goal = if self.check(&TokenType::Prove) {
4466 self.advance(); if self.check(&TokenType::Colon) {
4469 self.advance();
4470 }
4471
4472 self.skip_whitespace_tokens();
4473
4474 let goal_expr = self.parse_sentence()?;
4475
4476 if self.check(&TokenType::Period) {
4477 self.advance();
4478 }
4479
4480 goal_expr
4481 } else {
4482 return Err(ParseError {
4483 kind: ParseErrorKind::ExpectedKeyword { keyword: "Prove".to_string() },
4484 span: self.current_span(),
4485 });
4486 };
4487
4488 self.skip_whitespace_tokens();
4489
4490 let strategy = if self.check(&TokenType::BlockHeader { block_type: crate::token::BlockType::Proof }) {
4492 self.advance();
4493 self.skip_whitespace_tokens();
4494
4495 if self.check(&TokenType::Colon) {
4496 self.advance();
4497 }
4498
4499 self.skip_whitespace_tokens();
4500
4501 if self.check(&TokenType::Auto) {
4502 self.advance();
4503 ProofStrategy::Auto
4504 } else {
4505 ProofStrategy::Auto
4507 }
4508 } else {
4509 ProofStrategy::Auto
4511 };
4512
4513 if self.check(&TokenType::Period) {
4515 self.advance();
4516 }
4517
4518 let theorem = TheoremBlock {
4519 name,
4520 premises,
4521 goal,
4522 strategy,
4523 };
4524
4525 Ok(Stmt::Theorem(theorem))
4526 }
4527
4528 fn skip_whitespace_tokens(&mut self) {
4530 while self.check(&TokenType::Newline) || self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) {
4531 self.advance();
4532 }
4533 }
4534
4535 fn parse_function_def(&mut self) -> ParseResult<Stmt<'a>> {
4540 if self.check(&TokenType::To) || self.check_preposition_is("to") {
4542 self.advance();
4543 }
4544
4545 let mut is_native = if self.check(&TokenType::Native) {
4547 self.advance(); true
4549 } else {
4550 false
4551 };
4552
4553 let name = self.expect_identifier()?;
4555
4556 let mut params = Vec::new();
4558 while self.check(&TokenType::LParen) {
4559 self.advance(); if self.check(&TokenType::RParen) {
4563 self.advance(); break;
4565 }
4566
4567 loop {
4569 let param_name = self.expect_identifier()?;
4570
4571 if !self.check(&TokenType::Colon) {
4573 return Err(ParseError {
4574 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4575 span: self.current_span(),
4576 });
4577 }
4578 self.advance(); let param_type_expr = self.parse_type_expression()?;
4582 let param_type = self.ctx.alloc_type_expr(param_type_expr);
4583
4584 params.push((param_name, param_type));
4585
4586 if self.check(&TokenType::Comma) {
4588 self.advance(); continue;
4590 }
4591 break;
4592 }
4593
4594 if !self.check(&TokenType::RParen) {
4596 return Err(ParseError {
4597 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4598 span: self.current_span(),
4599 });
4600 }
4601 self.advance(); if self.check_word("and") || self.check_preposition() || self.check(&TokenType::From) {
4606 self.advance();
4607 }
4608 }
4609
4610 let return_type = if self.check(&TokenType::Arrow) {
4612 self.advance(); let ret_type_expr = self.parse_type_expression()?;
4614 Some(self.ctx.alloc_type_expr(ret_type_expr))
4615 } else {
4616 None
4617 };
4618
4619 let mut native_path: Option<Symbol> = None;
4621 let mut is_exported = false;
4622 let mut export_target: Option<Symbol> = None;
4623
4624 if self.check_word("is") {
4625 self.advance(); if self.check(&TokenType::Native) {
4627 self.advance(); is_native = true;
4630 if let TokenType::StringLiteral(sym) = self.peek().kind {
4631 native_path = Some(sym);
4632 self.advance(); } else {
4634 return Err(ParseError {
4635 kind: ParseErrorKind::Custom(
4636 "Expected a string literal for native function path (e.g., is native \"reqwest::blocking::get\")".to_string()
4637 ),
4638 span: self.current_span(),
4639 });
4640 }
4641 } else if self.check_word("exported") {
4642 self.advance(); is_exported = true;
4645 if self.check_word("for") {
4646 self.advance(); let target_sym = self.expect_identifier()?;
4648 let target_str = self.interner.resolve(target_sym);
4649 if !target_str.eq_ignore_ascii_case("c") && !target_str.eq_ignore_ascii_case("wasm") {
4650 return Err(ParseError {
4651 kind: ParseErrorKind::Custom(
4652 format!("Unsupported export target \"{}\". Supported targets are \"c\" and \"wasm\".", target_str)
4653 ),
4654 span: self.current_span(),
4655 });
4656 }
4657 export_target = Some(target_sym);
4658 }
4659 }
4660 }
4661
4662 if is_native {
4664 if self.check(&TokenType::Period) {
4666 self.advance();
4667 }
4668 if self.check(&TokenType::Newline) {
4669 self.advance();
4670 }
4671
4672 let empty_body = self.ctx.stmts.expect("imperative arenas not initialized")
4674 .alloc_slice(std::iter::empty());
4675
4676 return Ok(Stmt::FunctionDef {
4677 name,
4678 params,
4679 body: empty_body,
4680 return_type,
4681 is_native: true,
4682 native_path,
4683 is_exported: false,
4684 export_target: None,
4685 });
4686 }
4687
4688 if !self.check(&TokenType::Colon) {
4690 return Err(ParseError {
4691 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4692 span: self.current_span(),
4693 });
4694 }
4695 self.advance(); if !self.check(&TokenType::Indent) {
4699 return Err(ParseError {
4700 kind: ParseErrorKind::ExpectedStatement,
4701 span: self.current_span(),
4702 });
4703 }
4704 self.advance(); let mut body_stmts = Vec::new();
4708 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4709 if self.check(&TokenType::Newline) {
4711 self.advance();
4712 continue;
4713 }
4714 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
4716 break;
4717 }
4718 let stmt = self.parse_statement()?;
4719 body_stmts.push(stmt);
4720 if self.check(&TokenType::Period) {
4721 self.advance();
4722 }
4723 }
4724
4725 if self.check(&TokenType::Dedent) {
4727 self.advance();
4728 }
4729
4730 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4732 .alloc_slice(body_stmts.into_iter());
4733
4734 Ok(Stmt::FunctionDef {
4735 name,
4736 params,
4737 body,
4738 return_type,
4739 is_native: false,
4740 native_path: None,
4741 is_exported,
4742 export_target,
4743 })
4744 }
4745
4746 fn parse_primary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
4748 use crate::ast::{Expr, Literal};
4749
4750 let token = self.peek().clone();
4751 match &token.kind {
4752 TokenType::New => {
4756 self.advance(); let base_type_name = self.expect_identifier()?;
4758
4759 let type_name = if self.check(&TokenType::From) {
4761 self.advance(); let module_name = self.expect_identifier()?;
4763 let module_str = self.interner.resolve(module_name);
4764 let base_str = self.interner.resolve(base_type_name);
4765 let qualified = format!("{}::{}", module_str, base_str);
4766 self.interner.intern(&qualified)
4767 } else {
4768 base_type_name
4769 };
4770
4771 if let Some(enum_name) = self.find_variant(type_name) {
4773 let fields = if self.check_word("with") {
4775 self.parse_variant_constructor_fields()?
4776 } else {
4777 vec![]
4778 };
4779 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
4780 enum_name,
4781 variant: type_name,
4782 fields,
4783 });
4784 return self.parse_field_access_chain(base);
4785 }
4786
4787 let type_args = self.parse_generic_type_args(type_name)?;
4789
4790 let init_fields = if self.check_word("with") {
4792 self.parse_struct_init_fields()?
4793 } else {
4794 vec![]
4795 };
4796
4797 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
4798 return self.parse_field_access_chain(base);
4799 }
4800
4801 TokenType::Article(_) => {
4805 if let Some(next) = self.tokens.get(self.current + 1) {
4808 if matches!(next.kind, TokenType::Manifest) {
4809 self.advance(); return self.parse_primary_expr();
4812 }
4813 if matches!(next.kind, TokenType::Chunk) {
4814 self.advance(); return self.parse_primary_expr();
4817 }
4818 }
4819 if let Some(next) = self.tokens.get(self.current + 1) {
4821 if matches!(next.kind, TokenType::New) {
4822 self.advance(); self.advance(); let base_type_name = self.expect_identifier()?;
4825
4826 let type_name = if self.check(&TokenType::From) {
4828 self.advance(); let module_name = self.expect_identifier()?;
4830 let module_str = self.interner.resolve(module_name);
4831 let base_str = self.interner.resolve(base_type_name);
4832 let qualified = format!("{}::{}", module_str, base_str);
4833 self.interner.intern(&qualified)
4834 } else {
4835 base_type_name
4836 };
4837
4838 if let Some(enum_name) = self.find_variant(type_name) {
4840 let fields = if self.check_word("with") {
4842 self.parse_variant_constructor_fields()?
4843 } else {
4844 vec![]
4845 };
4846 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
4847 enum_name,
4848 variant: type_name,
4849 fields,
4850 });
4851 return self.parse_field_access_chain(base);
4852 }
4853
4854 let type_args = self.parse_generic_type_args(type_name)?;
4856
4857 let init_fields = if self.check_word("with") {
4859 self.parse_struct_init_fields()?
4860 } else {
4861 vec![]
4862 };
4863
4864 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
4865 return self.parse_field_access_chain(base);
4866 }
4867 }
4868 let sym = token.lexeme;
4870 self.advance();
4871 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
4872 return self.parse_field_access_chain(base);
4873 }
4874
4875 TokenType::Item => {
4877 self.advance(); let index = if let TokenType::Number(sym) = &self.peek().kind {
4881 let sym = *sym;
4883 self.advance();
4884 let num_str = self.interner.resolve(sym);
4885 let index_val = num_str.parse::<i64>().unwrap_or(0);
4886
4887 if index_val == 0 {
4889 return Err(ParseError {
4890 kind: ParseErrorKind::ZeroIndex,
4891 span: self.current_span(),
4892 });
4893 }
4894
4895 self.ctx.alloc_imperative_expr(
4896 Expr::Literal(crate::ast::Literal::Number(index_val))
4897 )
4898 } else if self.check(&TokenType::LParen) {
4899 self.advance(); let inner = self.parse_imperative_expr()?;
4902 if !self.check(&TokenType::RParen) {
4903 return Err(ParseError {
4904 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4905 span: self.current_span(),
4906 });
4907 }
4908 self.advance(); inner
4910 } else if let TokenType::StringLiteral(sym) = self.peek().kind {
4911 let sym = sym;
4913 self.advance();
4914 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Text(sym)))
4915 } else if !self.check_preposition_is("of") {
4916 let sym = self.peek().lexeme;
4918 self.advance();
4919 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
4920 } else {
4921 return Err(ParseError {
4922 kind: ParseErrorKind::ExpectedExpression,
4923 span: self.current_span(),
4924 });
4925 };
4926
4927 if !self.check_preposition_is("of") {
4929 return Err(ParseError {
4930 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
4931 span: self.current_span(),
4932 });
4933 }
4934 self.advance(); let collection = self.parse_primary_expr()?;
4939
4940 Ok(self.ctx.alloc_imperative_expr(Expr::Index {
4941 collection,
4942 index,
4943 }))
4944 }
4945
4946 TokenType::Items => {
4949 let is_slice_syntax = if let Some(next) = self.tokens.get(self.current + 1) {
4953 matches!(next.kind, TokenType::Number(_) | TokenType::LParen)
4954 } else {
4955 false
4956 };
4957
4958 if !is_slice_syntax {
4959 let sym = token.lexeme;
4961 self.advance();
4962 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
4963 return self.parse_field_access_chain(base);
4964 }
4965
4966 self.advance(); let start = if let TokenType::Number(sym) = &self.peek().kind {
4970 let sym = *sym;
4972 self.advance();
4973 let num_str = self.interner.resolve(sym);
4974 let start_val = num_str.parse::<i64>().unwrap_or(0);
4975
4976 if start_val == 0 {
4978 return Err(ParseError {
4979 kind: ParseErrorKind::ZeroIndex,
4980 span: self.current_span(),
4981 });
4982 }
4983
4984 self.ctx.alloc_imperative_expr(
4985 Expr::Literal(crate::ast::Literal::Number(start_val))
4986 )
4987 } else if self.check(&TokenType::LParen) {
4988 self.advance(); let inner = self.parse_imperative_expr()?;
4991 if !self.check(&TokenType::RParen) {
4992 return Err(ParseError {
4993 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4994 span: self.current_span(),
4995 });
4996 }
4997 self.advance(); inner
4999 } else if !self.check_preposition_is("through") {
5000 let sym = self.peek().lexeme;
5002 self.advance();
5003 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5004 } else {
5005 return Err(ParseError {
5006 kind: ParseErrorKind::ExpectedExpression,
5007 span: self.current_span(),
5008 });
5009 };
5010
5011 if !self.check_preposition_is("through") {
5013 return Err(ParseError {
5014 kind: ParseErrorKind::ExpectedKeyword { keyword: "through".to_string() },
5015 span: self.current_span(),
5016 });
5017 }
5018 self.advance(); let end = if let TokenType::Number(sym) = &self.peek().kind {
5022 let sym = *sym;
5024 self.advance();
5025 let num_str = self.interner.resolve(sym);
5026 let end_val = num_str.parse::<i64>().unwrap_or(0);
5027
5028 if end_val == 0 {
5030 return Err(ParseError {
5031 kind: ParseErrorKind::ZeroIndex,
5032 span: self.current_span(),
5033 });
5034 }
5035
5036 self.ctx.alloc_imperative_expr(
5037 Expr::Literal(crate::ast::Literal::Number(end_val))
5038 )
5039 } else if self.check(&TokenType::LParen) {
5040 self.advance(); let inner = self.parse_imperative_expr()?;
5043 if !self.check(&TokenType::RParen) {
5044 return Err(ParseError {
5045 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5046 span: self.current_span(),
5047 });
5048 }
5049 self.advance(); inner
5051 } else if !self.check_preposition_is("of") {
5052 let sym = self.peek().lexeme;
5054 self.advance();
5055 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5056 } else {
5057 return Err(ParseError {
5058 kind: ParseErrorKind::ExpectedExpression,
5059 span: self.current_span(),
5060 });
5061 };
5062
5063 let collection = if self.check_preposition_is("of") {
5066 self.advance(); self.parse_imperative_expr()?
5068 } else {
5069 let items_sym = self.interner.intern("items");
5072 self.ctx.alloc_imperative_expr(Expr::Identifier(items_sym))
5073 };
5074
5075 Ok(self.ctx.alloc_imperative_expr(Expr::Slice {
5076 collection,
5077 start,
5078 end,
5079 }))
5080 }
5081
5082 TokenType::LBracket => {
5084 self.advance(); let mut items = Vec::new();
5087 if !self.check(&TokenType::RBracket) {
5088 loop {
5089 items.push(self.parse_imperative_expr()?);
5090 if !self.check(&TokenType::Comma) {
5091 break;
5092 }
5093 self.advance(); }
5095 }
5096
5097 if !self.check(&TokenType::RBracket) {
5098 return Err(ParseError {
5099 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
5100 span: self.current_span(),
5101 });
5102 }
5103 self.advance(); if items.is_empty() && self.check_word("of") {
5107 self.advance(); let type_name = self.expect_identifier()?;
5109 let seq_sym = self.interner.intern("Seq");
5111 return Ok(self.ctx.alloc_imperative_expr(Expr::New {
5112 type_name: seq_sym,
5113 type_args: vec![TypeExpr::Named(type_name)],
5114 init_fields: vec![],
5115 }));
5116 }
5117
5118 Ok(self.ctx.alloc_imperative_expr(Expr::List(items)))
5119 }
5120
5121 TokenType::Number(sym) => {
5122 let num_str = self.interner.resolve(*sym).to_string();
5123 self.advance();
5124
5125 if let TokenType::CalendarUnit(unit) = self.peek().kind {
5127 return self.parse_span_literal_from_num(&num_str);
5128 }
5129
5130 if num_str.contains('.') {
5132 let num = num_str.parse::<f64>().unwrap_or(0.0);
5133 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Float(num))))
5134 } else {
5135 let num = num_str.parse::<i64>().unwrap_or(0);
5136 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(num))))
5137 }
5138 }
5139
5140 TokenType::StringLiteral(sym) => {
5142 self.advance();
5143 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Text(*sym))))
5144 }
5145
5146 TokenType::CharLiteral(sym) => {
5148 let char_str = self.interner.resolve(*sym);
5149 let ch = char_str.chars().next().unwrap_or('\0');
5150 self.advance();
5151 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Char(ch))))
5152 }
5153
5154 TokenType::DurationLiteral { nanos, .. } => {
5156 let nanos = *nanos;
5157 self.advance();
5158 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Duration(nanos))))
5159 }
5160
5161 TokenType::DateLiteral { days } => {
5164 let days = *days;
5165 self.advance();
5166
5167 if self.check(&TokenType::At) {
5169 self.advance(); if let TokenType::TimeLiteral { nanos_from_midnight } = self.peek().kind {
5173 let time_nanos = nanos_from_midnight;
5174 self.advance(); let moment_nanos = (days as i64) * 86_400_000_000_000 + time_nanos;
5178 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Moment(moment_nanos))));
5179 } else {
5180 return Err(ParseError {
5181 kind: ParseErrorKind::ExpectedExpression,
5182 span: self.current_span(),
5183 });
5184 }
5185 }
5186
5187 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Date(days))))
5188 }
5189
5190 TokenType::TimeLiteral { nanos_from_midnight } => {
5192 let nanos = *nanos_from_midnight;
5193 self.advance();
5194 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Time(nanos))))
5195 }
5196
5197 TokenType::Nothing => {
5199 self.advance();
5200 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)))
5201 }
5202
5203 TokenType::Some => {
5205 self.advance(); let value = self.parse_imperative_expr()?;
5207 Ok(self.ctx.alloc_imperative_expr(Expr::OptionSome { value }))
5208 }
5209
5210 TokenType::Length => {
5212 let func_name = self.peek().lexeme;
5213
5214 if self.tokens.get(self.current + 1)
5216 .map(|t| matches!(t.kind, TokenType::LParen))
5217 .unwrap_or(false)
5218 {
5219 self.advance(); return self.parse_call_expr(func_name);
5221 }
5222
5223 self.advance(); if !self.check_preposition_is("of") {
5227 return Err(ParseError {
5228 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5229 span: self.current_span(),
5230 });
5231 }
5232 self.advance(); let collection = self.parse_imperative_expr()?;
5235 Ok(self.ctx.alloc_imperative_expr(Expr::Length { collection }))
5236 }
5237
5238 TokenType::Copy => {
5240 let func_name = self.peek().lexeme;
5241
5242 if self.tokens.get(self.current + 1)
5244 .map(|t| matches!(t.kind, TokenType::LParen))
5245 .unwrap_or(false)
5246 {
5247 self.advance(); return self.parse_call_expr(func_name);
5249 }
5250
5251 self.advance(); if !self.check_preposition_is("of") {
5255 return Err(ParseError {
5256 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5257 span: self.current_span(),
5258 });
5259 }
5260 self.advance(); let expr = self.parse_imperative_expr()?;
5263 Ok(self.ctx.alloc_imperative_expr(Expr::Copy { expr }))
5264 }
5265
5266 TokenType::Manifest => {
5268 self.advance(); if !self.check_preposition_is("of") {
5272 return Err(ParseError {
5273 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5274 span: self.current_span(),
5275 });
5276 }
5277 self.advance(); let zone = self.parse_imperative_expr()?;
5280 Ok(self.ctx.alloc_imperative_expr(Expr::ManifestOf { zone }))
5281 }
5282
5283 TokenType::Chunk => {
5285 self.advance(); if !self.check(&TokenType::At) {
5289 return Err(ParseError {
5290 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
5291 span: self.current_span(),
5292 });
5293 }
5294 self.advance(); let index = self.parse_imperative_expr()?;
5297
5298 if !self.check_preposition_is("in") && !self.check(&TokenType::In) {
5300 return Err(ParseError {
5301 kind: ParseErrorKind::ExpectedKeyword { keyword: "in".to_string() },
5302 span: self.current_span(),
5303 });
5304 }
5305 self.advance(); let zone = self.parse_imperative_expr()?;
5308 Ok(self.ctx.alloc_imperative_expr(Expr::ChunkAt { index, zone }))
5309 }
5310
5311 TokenType::Verb { lemma, .. } => {
5315 let word = self.interner.resolve(*lemma).to_lowercase();
5316 if word == "empty" {
5317 self.advance();
5318 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5319 }
5320 let sym = token.lexeme;
5322 self.advance();
5323 if self.check(&TokenType::LParen) {
5324 return self.parse_call_expr(sym);
5325 }
5326 self.verify_identifier_access(sym)?;
5328 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5329 self.parse_field_access_chain(base)
5330 }
5331
5332 TokenType::TemporalAdverb(_) | TokenType::ScopalAdverb(_) | TokenType::Adverb(_) => {
5334 let sym = token.lexeme;
5335 self.advance();
5336 if self.check(&TokenType::LParen) {
5337 return self.parse_call_expr(sym);
5338 }
5339 self.verify_identifier_access(sym)?;
5341 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5342 self.parse_field_access_chain(base)
5343 }
5344
5345 TokenType::Read | TokenType::Write | TokenType::File | TokenType::Console |
5348 TokenType::Add | TokenType::Remove => {
5349 let sym = token.lexeme;
5350 self.advance();
5351 if self.check(&TokenType::LParen) {
5352 return self.parse_call_expr(sym);
5353 }
5354 self.verify_identifier_access(sym)?;
5356 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5357 self.parse_field_access_chain(base)
5358 }
5359
5360 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
5363 let sym = *sym;
5364 let word = self.interner.resolve(sym);
5365
5366 if word == "true" {
5368 self.advance();
5369 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(true))));
5370 }
5371 if word == "false" {
5372 self.advance();
5373 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(false))));
5374 }
5375
5376 if word == "empty" {
5378 self.advance();
5379 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5380 }
5381
5382 if word == "none" {
5384 self.advance();
5385 return Ok(self.ctx.alloc_imperative_expr(Expr::OptionNone));
5386 }
5387
5388 self.advance();
5390
5391 if self.check(&TokenType::LParen) {
5393 return self.parse_call_expr(sym);
5394 }
5395
5396 if let Some(enum_name) = self.find_variant(sym) {
5398 let fields = if self.check_word("with") {
5399 self.parse_variant_constructor_fields()?
5400 } else {
5401 vec![]
5402 };
5403 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
5404 enum_name,
5405 variant: sym,
5406 fields,
5407 });
5408 return self.parse_field_access_chain(base);
5409 }
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)
5416 }
5417
5418 TokenType::Pronoun { .. } => {
5420 let sym = token.lexeme;
5421 self.advance();
5422 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5423 self.parse_field_access_chain(base)
5425 }
5426
5427 TokenType::Merge | TokenType::Increase => {
5429 let sym = token.lexeme;
5430 self.advance();
5431
5432 if self.check(&TokenType::LParen) {
5434 return self.parse_call_expr(sym);
5435 }
5436
5437 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5438 self.parse_field_access_chain(base)
5439 }
5440
5441 TokenType::Escape => {
5445 if self.tokens.get(self.current + 1).map_or(false, |t|
5446 matches!(t.kind, TokenType::To) || {
5447 if let TokenType::Preposition(sym) = t.kind {
5448 sym.is(self.interner, "to")
5449 } else {
5450 false
5451 }
5452 }
5453 ) {
5454 return self.parse_escape_expr();
5455 }
5456 let sym = token.lexeme;
5458 self.advance();
5459 if self.check(&TokenType::LParen) {
5460 return self.parse_call_expr(sym);
5461 }
5462 self.verify_identifier_access(sym)?;
5463 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5464 self.parse_field_access_chain(base)
5465 }
5466
5467 TokenType::Values | TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared => { let sym = token.lexeme;
5476 self.advance();
5477
5478 if self.check(&TokenType::LParen) {
5480 return self.parse_call_expr(sym);
5481 }
5482
5483 self.verify_identifier_access(sym)?;
5484 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5485 self.parse_field_access_chain(base)
5486 }
5487
5488 TokenType::Ambiguous { primary, alternatives } => {
5490 let sym = token.lexeme;
5493
5494 let is_identifier_token = match &**primary {
5496 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5497 TokenType::Verb { .. } => true,
5498 _ => alternatives.iter().any(|t| matches!(t,
5499 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5500 TokenType::Verb { .. }
5501 ))
5502 };
5503
5504 if is_identifier_token {
5505 self.advance();
5506
5507 if self.check(&TokenType::LParen) {
5509 return self.parse_call_expr(sym);
5510 }
5511
5512 self.verify_identifier_access(sym)?;
5513 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5514 self.parse_field_access_chain(base)
5516 } else {
5517 Err(ParseError {
5518 kind: ParseErrorKind::ExpectedExpression,
5519 span: self.current_span(),
5520 })
5521 }
5522 }
5523
5524 TokenType::LParen => {
5526 self.advance(); let first = self.parse_imperative_expr()?;
5528
5529 if self.check(&TokenType::Comma) {
5531 let mut items = vec![first];
5533 while self.check(&TokenType::Comma) {
5534 self.advance(); items.push(self.parse_imperative_expr()?);
5536 }
5537
5538 if !self.check(&TokenType::RParen) {
5539 return Err(ParseError {
5540 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5541 span: self.current_span(),
5542 });
5543 }
5544 self.advance(); let base = self.ctx.alloc_imperative_expr(Expr::Tuple(items));
5547 self.parse_field_access_chain(base)
5548 } else {
5549 if !self.check(&TokenType::RParen) {
5551 return Err(ParseError {
5552 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5553 span: self.current_span(),
5554 });
5555 }
5556 self.advance(); Ok(first)
5558 }
5559 }
5560
5561 TokenType::Call => {
5563 self.advance(); let function = match &self.peek().kind {
5565 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
5566 let s = *sym;
5567 self.advance();
5568 s
5569 }
5570 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
5571 let s = self.peek().lexeme;
5572 self.advance();
5573 s
5574 }
5575 _ => {
5576 return Err(ParseError {
5577 kind: ParseErrorKind::ExpectedIdentifier,
5578 span: self.current_span(),
5579 });
5580 }
5581 };
5582 let args = if self.check_preposition_is("with") {
5583 self.advance(); self.parse_call_arguments()?
5585 } else {
5586 Vec::new()
5587 };
5588 Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
5589 }
5590
5591 _ => {
5592 Err(ParseError {
5593 kind: ParseErrorKind::ExpectedExpression,
5594 span: self.current_span(),
5595 })
5596 }
5597 }
5598 }
5599
5600 fn parse_imperative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5603 self.parse_additive_expr()
5604 }
5605
5606 fn parse_additive_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5608 let mut left = self.parse_multiplicative_expr()?;
5609
5610 loop {
5611 match &self.peek().kind {
5612 TokenType::Plus => {
5613 self.advance();
5614 let right = self.parse_multiplicative_expr()?;
5615 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5616 op: BinaryOpKind::Add,
5617 left,
5618 right,
5619 });
5620 }
5621 TokenType::Minus => {
5622 self.advance();
5623 let right = self.parse_multiplicative_expr()?;
5624 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5625 op: BinaryOpKind::Subtract,
5626 left,
5627 right,
5628 });
5629 }
5630 TokenType::Combined => {
5632 self.advance(); if !self.check_preposition_is("with") {
5635 return Err(ParseError {
5636 kind: ParseErrorKind::ExpectedKeyword { keyword: "with".to_string() },
5637 span: self.current_span(),
5638 });
5639 }
5640 self.advance(); let right = self.parse_multiplicative_expr()?;
5642 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5643 op: BinaryOpKind::Concat,
5644 left,
5645 right,
5646 });
5647 }
5648 TokenType::Union => {
5650 self.advance(); let right = self.parse_multiplicative_expr()?;
5652 left = self.ctx.alloc_imperative_expr(Expr::Union {
5653 left,
5654 right,
5655 });
5656 }
5657 TokenType::Intersection => {
5658 self.advance(); let right = self.parse_multiplicative_expr()?;
5660 left = self.ctx.alloc_imperative_expr(Expr::Intersection {
5661 left,
5662 right,
5663 });
5664 }
5665 TokenType::Contains => {
5667 self.advance(); let value = self.parse_multiplicative_expr()?;
5669 left = self.ctx.alloc_imperative_expr(Expr::Contains {
5670 collection: left,
5671 value,
5672 });
5673 }
5674 _ => break,
5675 }
5676 }
5677
5678 Ok(left)
5679 }
5680
5681 fn parse_unary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5683 use crate::ast::{Expr, Literal};
5684
5685 if self.check(&TokenType::Minus) {
5686 self.advance(); let operand = self.parse_unary_expr()?; return Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5690 op: BinaryOpKind::Subtract,
5691 left: self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(0))),
5692 right: operand,
5693 }));
5694 }
5695 self.parse_primary_expr()
5696 }
5697
5698 fn parse_multiplicative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5700 let mut left = self.parse_unary_expr()?;
5701
5702 loop {
5703 let op = match &self.peek().kind {
5704 TokenType::Star => {
5705 self.advance();
5706 BinaryOpKind::Multiply
5707 }
5708 TokenType::Slash => {
5709 self.advance();
5710 BinaryOpKind::Divide
5711 }
5712 TokenType::Percent => {
5713 self.advance();
5714 BinaryOpKind::Modulo
5715 }
5716 _ => break,
5717 };
5718 let right = self.parse_unary_expr()?;
5719 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5720 op,
5721 left,
5722 right,
5723 });
5724 }
5725
5726 Ok(left)
5727 }
5728
5729 fn try_parse_binary_op(&mut self) -> Option<BinaryOpKind> {
5731 match &self.peek().kind {
5732 TokenType::Plus => {
5733 self.advance();
5734 Some(BinaryOpKind::Add)
5735 }
5736 TokenType::Minus => {
5737 self.advance();
5738 Some(BinaryOpKind::Subtract)
5739 }
5740 TokenType::Star => {
5741 self.advance();
5742 Some(BinaryOpKind::Multiply)
5743 }
5744 TokenType::Slash => {
5745 self.advance();
5746 Some(BinaryOpKind::Divide)
5747 }
5748 _ => None,
5749 }
5750 }
5751
5752 fn parse_span_literal_from_num(&mut self, first_num_str: &str) -> ParseResult<&'a Expr<'a>> {
5755 use crate::ast::Literal;
5756 use crate::token::CalendarUnit;
5757
5758 let first_num = first_num_str.parse::<i32>().unwrap_or(0);
5759
5760 let unit = match self.peek().kind {
5762 TokenType::CalendarUnit(u) => u,
5763 _ => {
5764 return Err(ParseError {
5765 kind: ParseErrorKind::ExpectedKeyword { keyword: "calendar unit (day, week, month, year)".to_string() },
5766 span: self.current_span(),
5767 });
5768 }
5769 };
5770 self.advance(); let mut total_months: i32 = 0;
5774 let mut total_days: i32 = 0;
5775
5776 match unit {
5778 CalendarUnit::Day => total_days += first_num,
5779 CalendarUnit::Week => total_days += first_num * 7,
5780 CalendarUnit::Month => total_months += first_num,
5781 CalendarUnit::Year => total_months += first_num * 12,
5782 }
5783
5784 while self.check(&TokenType::And) {
5786 self.advance(); let next_num = match &self.peek().kind {
5790 TokenType::Number(sym) => {
5791 let num_str = self.interner.resolve(*sym).to_string();
5792 self.advance();
5793 num_str.parse::<i32>().unwrap_or(0)
5794 }
5795 _ => break, };
5797
5798 let next_unit = match self.peek().kind {
5800 TokenType::CalendarUnit(u) => {
5801 self.advance();
5802 u
5803 }
5804 _ => break, };
5806
5807 match next_unit {
5809 CalendarUnit::Day => total_days += next_num,
5810 CalendarUnit::Week => total_days += next_num * 7,
5811 CalendarUnit::Month => total_months += next_num,
5812 CalendarUnit::Year => total_months += next_num * 12,
5813 }
5814 }
5815
5816 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Span {
5817 months: total_months,
5818 days: total_days,
5819 })))
5820 }
5821
5822 fn parse_call_expr(&mut self, function: Symbol) -> ParseResult<&'a Expr<'a>> {
5824 use crate::ast::Expr;
5825
5826 self.advance(); let mut args = Vec::new();
5829 if !self.check(&TokenType::RParen) {
5830 loop {
5831 args.push(self.parse_imperative_expr()?);
5832 if !self.check(&TokenType::Comma) {
5833 break;
5834 }
5835 self.advance(); }
5837 }
5838
5839 if !self.check(&TokenType::RParen) {
5840 return Err(ParseError {
5841 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5842 span: self.current_span(),
5843 });
5844 }
5845 self.advance(); Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
5848 }
5849
5850 fn parse_field_access_chain(&mut self, base: &'a Expr<'a>) -> ParseResult<&'a Expr<'a>> {
5853 use crate::ast::Expr;
5854
5855 let mut result = base;
5856
5857 loop {
5859 if self.check(&TokenType::Possessive) {
5860 self.advance(); let field = self.expect_identifier()?;
5863 result = self.ctx.alloc_imperative_expr(Expr::FieldAccess {
5864 object: result,
5865 field,
5866 });
5867 } else if self.check(&TokenType::LBracket) {
5868 self.advance(); let index = self.parse_imperative_expr()?;
5871
5872 if !self.check(&TokenType::RBracket) {
5873 return Err(ParseError {
5874 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
5875 span: self.current_span(),
5876 });
5877 }
5878 self.advance(); result = self.ctx.alloc_imperative_expr(Expr::Index {
5881 collection: result,
5882 index,
5883 });
5884 } else {
5885 break;
5886 }
5887 }
5888
5889 Ok(result)
5890 }
5891
5892 fn verify_identifier_access(&self, sym: Symbol) -> ParseResult<()> {
5895 if self.mode != ParserMode::Imperative {
5896 return Ok(());
5897 }
5898
5899 if let Some(crate::drs::OwnershipState::Moved) = self.world_state.get_ownership_by_var(sym) {
5901 return Err(ParseError {
5902 kind: ParseErrorKind::UseAfterMove {
5903 name: self.interner.resolve(sym).to_string()
5904 },
5905 span: self.current_span(),
5906 });
5907 }
5908
5909 Ok(())
5910 }
5911
5912 fn expect_identifier(&mut self) -> ParseResult<Symbol> {
5913 let token = self.peek().clone();
5914 match &token.kind {
5915 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
5917 self.advance();
5918 Ok(*sym)
5919 }
5920 TokenType::Verb { .. } => {
5923 let sym = token.lexeme;
5924 self.advance();
5925 Ok(sym)
5926 }
5927 TokenType::Article(_) => {
5929 let sym = token.lexeme;
5930 self.advance();
5931 Ok(sym)
5932 }
5933 TokenType::Pronoun { .. } | TokenType::Items | TokenType::Values | TokenType::Item | TokenType::Nothing | TokenType::TemporalAdverb(_) |
5941 TokenType::ScopalAdverb(_) |
5942 TokenType::Adverb(_) |
5943 TokenType::Read |
5945 TokenType::Write |
5946 TokenType::File |
5947 TokenType::Console |
5948 TokenType::Merge |
5950 TokenType::Increase |
5951 TokenType::Decrease |
5952 TokenType::Tally |
5954 TokenType::SharedSet |
5955 TokenType::SharedSequence |
5956 TokenType::CollaborativeSequence |
5957 TokenType::Add |
5960 TokenType::Remove |
5961 TokenType::First |
5962 TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared | TokenType::CalendarUnit(_) |
5969 TokenType::Focus(_) |
5971 TokenType::Escape => {
5973 let sym = token.lexeme;
5975 self.advance();
5976 Ok(sym)
5977 }
5978 TokenType::Ambiguous { .. } => {
5979 let sym = token.lexeme;
5982 self.advance();
5983 Ok(sym)
5984 }
5985 _ => Err(ParseError {
5986 kind: ParseErrorKind::ExpectedIdentifier,
5987 span: self.current_span(),
5988 }),
5989 }
5990 }
5991
5992 fn consume_content_word_for_relative(&mut self) -> ParseResult<Symbol> {
5993 let t = self.advance().clone();
5994 match t.kind {
5995 TokenType::Noun(s) | TokenType::Adjective(s) => Ok(s),
5996 TokenType::ProperName(s) => Ok(s),
5997 TokenType::Verb { lemma, .. } => Ok(lemma),
5998 other => Err(ParseError {
5999 kind: ParseErrorKind::ExpectedContentWord { found: other },
6000 span: self.current_span(),
6001 }),
6002 }
6003 }
6004
6005 fn check_modal(&self) -> bool {
6006 matches!(
6007 self.peek().kind,
6008 TokenType::Must
6009 | TokenType::Shall
6010 | TokenType::Should
6011 | TokenType::Can
6012 | TokenType::May
6013 | TokenType::Cannot
6014 | TokenType::Could
6015 | TokenType::Would
6016 | TokenType::Might
6017 )
6018 }
6019
6020 fn check_pronoun(&self) -> bool {
6021 match &self.peek().kind {
6022 TokenType::Pronoun { case, .. } => {
6023 if self.noun_priority_mode && matches!(case, Case::Possessive) {
6025 return false;
6026 }
6027 true
6028 }
6029 TokenType::Ambiguous { primary, alternatives } => {
6030 if self.noun_priority_mode {
6032 let has_possessive = matches!(**primary, TokenType::Pronoun { case: Case::Possessive, .. })
6033 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { case: Case::Possessive, .. }));
6034 if has_possessive {
6035 return false;
6036 }
6037 }
6038 matches!(**primary, TokenType::Pronoun { .. })
6039 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { .. }))
6040 }
6041 _ => false,
6042 }
6043 }
6044
6045 fn parse_atom(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
6046 if self.check_focus() {
6048 return self.parse_focus();
6049 }
6050
6051 if self.check_measure() {
6053 return self.parse_measure();
6054 }
6055
6056 if self.check_quantifier() {
6057 self.advance();
6058 return self.parse_quantified();
6059 }
6060
6061 if self.check_npi_quantifier() {
6062 return self.parse_npi_quantified();
6063 }
6064
6065 if self.check_temporal_npi() {
6066 return self.parse_temporal_npi();
6067 }
6068
6069 if self.match_token(&[TokenType::LParen]) {
6070 let expr = self.parse_sentence()?;
6071 self.consume(TokenType::RParen)?;
6072 return Ok(expr);
6073 }
6074
6075 if self.check_pronoun() {
6077 let token = self.advance().clone();
6078 let (gender, number) = match &token.kind {
6079 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
6080 TokenType::Ambiguous { primary, alternatives } => {
6081 if let TokenType::Pronoun { gender, number, .. } = **primary {
6082 (gender, number)
6083 } else {
6084 alternatives.iter().find_map(|t| {
6085 if let TokenType::Pronoun { gender, number, .. } = t {
6086 Some((*gender, *number))
6087 } else {
6088 None
6089 }
6090 }).unwrap_or((Gender::Unknown, Number::Singular))
6091 }
6092 }
6093 _ => (Gender::Unknown, Number::Singular),
6094 };
6095
6096 let token_text = self.interner.resolve(token.lexeme);
6097
6098 if token_text.eq_ignore_ascii_case("it") && self.check_verb() {
6101 if let TokenType::Verb { lemma, time, .. } = &self.peek().kind {
6102 let lemma_str = self.interner.resolve(*lemma);
6103 if Lexer::is_weather_verb(lemma_str) {
6104 let verb = *lemma;
6105 let verb_time = *time;
6106 self.advance(); let event_var = self.get_event_var();
6109 let suppress_existential = self.drs.in_conditional_antecedent();
6110 if suppress_existential {
6111 let event_class = self.interner.intern("Event");
6112 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
6113 }
6114 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6115 event_var,
6116 verb,
6117 roles: self.ctx.roles.alloc_slice(vec![]), modifiers: self.ctx.syms.alloc_slice(vec![]),
6119 suppress_existential,
6120 world: None,
6121 })));
6122
6123 return Ok(match verb_time {
6124 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
6125 operator: TemporalOperator::Past,
6126 body: neo_event,
6127 }),
6128 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
6129 operator: TemporalOperator::Future,
6130 body: neo_event,
6131 }),
6132 _ => neo_event,
6133 });
6134 }
6135 }
6136 }
6137
6138 let resolved = if token_text.eq_ignore_ascii_case("i") {
6140 ResolvedPronoun::Constant(self.interner.intern("Speaker"))
6141 } else if token_text.eq_ignore_ascii_case("you") {
6142 ResolvedPronoun::Constant(self.interner.intern("Addressee"))
6143 } else {
6144 self.resolve_pronoun(gender, number)?
6146 };
6147
6148 if self.check_performative() {
6150 if let TokenType::Performative(act) = self.advance().kind.clone() {
6151 let sym = match resolved {
6152 ResolvedPronoun::Variable(s) | ResolvedPronoun::Constant(s) => s,
6153 };
6154 if self.check(&TokenType::To) {
6156 self.advance(); if self.check_verb() {
6159 let infinitive_verb = self.consume_verb();
6160
6161 let content = self.ctx.exprs.alloc(LogicExpr::Predicate {
6162 name: infinitive_verb,
6163 args: self.ctx.terms.alloc_slice([Term::Constant(sym)]),
6164 world: None,
6165 });
6166
6167 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6168 performer: sym,
6169 act_type: act,
6170 content,
6171 }));
6172 }
6173 }
6174
6175 if self.check(&TokenType::That) {
6177 self.advance();
6178 }
6179 let content = self.parse_sentence()?;
6180 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6181 performer: sym,
6182 act_type: act,
6183 content,
6184 }));
6185 }
6186 }
6187
6188 return match resolved {
6191 ResolvedPronoun::Variable(sym) => self.parse_predicate_with_subject_as_var(sym),
6192 ResolvedPronoun::Constant(sym) => self.parse_predicate_with_subject(sym),
6193 };
6194 }
6195
6196 let _had_both = self.match_token(&[TokenType::Both]);
6199
6200 let subject = self.parse_noun_phrase(true)?;
6201
6202 if subject.definiteness == Some(Definiteness::Indefinite)
6208 || subject.definiteness == Some(Definiteness::Distal) {
6209 let gender = Self::infer_noun_gender(self.interner.resolve(subject.noun));
6210 let number = if Self::is_plural_noun(self.interner.resolve(subject.noun)) {
6211 Number::Plural
6212 } else {
6213 Number::Singular
6214 };
6215 self.drs.introduce_referent(subject.noun, subject.noun, gender, number);
6217 }
6218
6219 if self.check(&TokenType::And) {
6221 match self.try_parse_plural_subject(&subject) {
6222 Ok(Some(result)) => return Ok(result),
6223 Ok(None) => {} Err(e) => return Err(e), }
6226 }
6227
6228 if self.check_scopal_adverb() {
6230 return self.parse_scopal_adverb(&subject);
6231 }
6232
6233 if self.check(&TokenType::Comma) {
6235 let saved_pos = self.current;
6236 self.advance(); if self.check_pronoun() {
6240 let topic_attempt = self.try_parse(|p| {
6241 let token = p.peek().clone();
6242 let pronoun_features = match &token.kind {
6243 TokenType::Pronoun { gender, number, .. } => Some((*gender, *number)),
6244 TokenType::Ambiguous { primary, alternatives } => {
6245 if let TokenType::Pronoun { gender, number, .. } = **primary {
6246 Some((gender, number))
6247 } else {
6248 alternatives.iter().find_map(|t| {
6249 if let TokenType::Pronoun { gender, number, .. } = t {
6250 Some((*gender, *number))
6251 } else {
6252 None
6253 }
6254 })
6255 }
6256 }
6257 _ => None,
6258 };
6259
6260 if let Some((gender, number)) = pronoun_features {
6261 p.advance(); let resolved = p.resolve_pronoun(gender, number)?;
6263 let resolved_term = match resolved {
6264 ResolvedPronoun::Variable(s) => Term::Variable(s),
6265 ResolvedPronoun::Constant(s) => Term::Constant(s),
6266 };
6267
6268 if p.check_verb() {
6269 let verb = p.consume_verb();
6270 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6271 name: verb,
6272 args: p.ctx.terms.alloc_slice([
6273 resolved_term,
6274 Term::Constant(subject.noun),
6275 ]),
6276 world: None,
6277 });
6278 p.wrap_with_definiteness_full(&subject, predicate)
6279 } else {
6280 Err(ParseError {
6281 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6282 span: p.current_span(),
6283 })
6284 }
6285 } else {
6286 Err(ParseError {
6287 kind: ParseErrorKind::ExpectedContentWord { found: token.kind },
6288 span: p.current_span(),
6289 })
6290 }
6291 });
6292
6293 if let Some(result) = topic_attempt {
6294 return Ok(result);
6295 }
6296 }
6297
6298 if self.check_content_word() {
6300 let topic_attempt = self.try_parse(|p| {
6301 let real_subject = p.parse_noun_phrase(true)?;
6302 if p.check_verb() {
6303 let verb = p.consume_verb();
6304 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6305 name: verb,
6306 args: p.ctx.terms.alloc_slice([
6307 Term::Constant(real_subject.noun),
6308 Term::Constant(subject.noun),
6309 ]),
6310 world: None,
6311 });
6312 p.wrap_with_definiteness_full(&subject, predicate)
6313 } else {
6314 Err(ParseError {
6315 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6316 span: p.current_span(),
6317 })
6318 }
6319 });
6320
6321 if let Some(result) = topic_attempt {
6322 return Ok(result);
6323 }
6324 }
6325
6326 self.current = saved_pos;
6328 }
6329
6330 let mut relative_clause: Option<(Symbol, &'a LogicExpr<'a>)> = None;
6332 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
6333 self.advance();
6334 let var_name = self.next_var_name();
6335 let rel_pred = self.parse_relative_clause(var_name)?;
6336 relative_clause = Some((var_name, rel_pred));
6337 } else if matches!(self.peek().kind, TokenType::Article(_)) && self.is_contact_clause_pattern() {
6338 let var_name = self.next_var_name();
6341 let rel_pred = self.parse_relative_clause(var_name)?;
6342 relative_clause = Some((var_name, rel_pred));
6343 }
6344
6345 if let Some((var_name, rel_clause)) = relative_clause {
6347 if self.check_verb() {
6348 let (verb, verb_time, _, _) = self.consume_verb_with_metadata();
6349 let var_term = Term::Variable(var_name);
6350
6351 let event_var = self.get_event_var();
6352 let suppress_existential = self.drs.in_conditional_antecedent();
6353 let mut modifiers = vec![];
6354 if verb_time == Time::Past {
6355 modifiers.push(self.interner.intern("Past"));
6356 }
6357 let main_pred = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6358 event_var,
6359 verb,
6360 roles: self.ctx.roles.alloc_slice(vec![
6361 (ThematicRole::Agent, var_term),
6362 ]),
6363 modifiers: self.ctx.syms.alloc_slice(modifiers),
6364 suppress_existential,
6365 world: None,
6366 })));
6367
6368 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6369 name: subject.noun,
6370 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6371 world: None,
6372 });
6373
6374 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6375 left: type_pred,
6376 op: TokenType::And,
6377 right: rel_clause,
6378 });
6379
6380 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6381 left: inner,
6382 op: TokenType::And,
6383 right: main_pred,
6384 });
6385
6386 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6387 kind: QuantifierKind::Existential,
6388 variable: var_name,
6389 body,
6390 island_id: self.current_island,
6391 }));
6392 }
6393
6394 if self.is_at_end() || self.check(&TokenType::Period) || self.check(&TokenType::Comma) {
6397 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6398 name: subject.noun,
6399 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6400 world: None,
6401 });
6402
6403 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6404 left: type_pred,
6405 op: TokenType::And,
6406 right: rel_clause,
6407 });
6408
6409 let uniqueness_body = if subject.definiteness == Some(Definiteness::Definite) {
6411 let y_var = self.next_var_name();
6412 let type_pred_y = self.ctx.exprs.alloc(LogicExpr::Predicate {
6413 name: subject.noun,
6414 args: self.ctx.terms.alloc_slice([Term::Variable(y_var)]),
6415 world: None,
6416 });
6417 let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
6418 left: self.ctx.terms.alloc(Term::Variable(y_var)),
6419 right: self.ctx.terms.alloc(Term::Variable(var_name)),
6420 });
6421 let uniqueness_cond = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6422 left: type_pred_y,
6423 op: TokenType::If,
6424 right: identity,
6425 });
6426 let uniqueness = self.ctx.exprs.alloc(LogicExpr::Quantifier {
6427 kind: QuantifierKind::Universal,
6428 variable: y_var,
6429 body: uniqueness_cond,
6430 island_id: self.current_island,
6431 });
6432 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6433 left: body,
6434 op: TokenType::And,
6435 right: uniqueness,
6436 })
6437 } else {
6438 body
6439 };
6440
6441 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6442 kind: QuantifierKind::Existential,
6443 variable: var_name,
6444 body: uniqueness_body,
6445 island_id: self.current_island,
6446 }));
6447 }
6448
6449 relative_clause = Some((var_name, rel_clause));
6451 }
6452
6453 if self.check(&TokenType::Identity) {
6455 self.advance();
6456 let right = self.consume_content_word()?;
6457 return Ok(self.ctx.exprs.alloc(LogicExpr::Identity {
6458 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6459 right: self.ctx.terms.alloc(Term::Constant(right)),
6460 }));
6461 }
6462
6463 if self.check_modal() {
6464 if let Some((var_name, rel_clause)) = relative_clause {
6465 let modal_pred = self.parse_aspect_chain_with_term(Term::Variable(var_name))?;
6466
6467 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6468 name: subject.noun,
6469 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6470 world: None,
6471 });
6472
6473 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6474 left: type_pred,
6475 op: TokenType::And,
6476 right: rel_clause,
6477 });
6478
6479 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6480 left: inner,
6481 op: TokenType::And,
6482 right: modal_pred,
6483 });
6484
6485 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6486 kind: QuantifierKind::Existential,
6487 variable: var_name,
6488 body,
6489 island_id: self.current_island,
6490 }));
6491 }
6492
6493 let modal_pred = self.parse_aspect_chain(subject.noun)?;
6494 return self.wrap_with_definiteness_full(&subject, modal_pred);
6495 }
6496
6497 if self.check(&TokenType::Is) || self.check(&TokenType::Are)
6498 || self.check(&TokenType::Was) || self.check(&TokenType::Were)
6499 {
6500 let copula_time = if self.check(&TokenType::Was) || self.check(&TokenType::Were) {
6501 Time::Past
6502 } else {
6503 Time::Present
6504 };
6505 self.advance();
6506
6507 let is_negated = self.check(&TokenType::Not);
6509 if is_negated {
6510 self.advance(); }
6512
6513 if self.check_number() {
6516 let measure = self.parse_measure_phrase()?;
6517
6518 if self.check_comparative() {
6520 return self.parse_comparative(&subject, copula_time, Some(measure));
6521 }
6522
6523 if self.check_content_word() {
6525 let adj = self.consume_content_word()?;
6526 let result = self.ctx.exprs.alloc(LogicExpr::Predicate {
6527 name: adj,
6528 args: self.ctx.terms.alloc_slice([
6529 Term::Constant(subject.noun),
6530 *measure,
6531 ]),
6532 world: None,
6533 });
6534 return self.wrap_with_definiteness_full(&subject, result);
6535 }
6536
6537 if self.check(&TokenType::Period) || self.is_at_end() {
6540 if self.mode == ParserMode::Imperative {
6542 let variable = self.interner.resolve(subject.noun).to_string();
6543 let value = if let Term::Value { kind, .. } = measure {
6544 format!("{:?}", kind)
6545 } else {
6546 "value".to_string()
6547 };
6548 return Err(ParseError {
6549 kind: ParseErrorKind::IsValueEquality { variable, value },
6550 span: self.current_span(),
6551 });
6552 }
6553 let result = self.ctx.exprs.alloc(LogicExpr::Identity {
6554 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6555 right: measure,
6556 });
6557 return self.wrap_with_definiteness_full(&subject, result);
6558 }
6559 }
6560
6561 if self.check_comparative() {
6563 return self.parse_comparative(&subject, copula_time, None);
6564 }
6565
6566 if self.check(&TokenType::Period) || self.is_at_end() {
6568 let var = self.next_var_name();
6569 let body = self.ctx.exprs.alloc(LogicExpr::Identity {
6570 left: self.ctx.terms.alloc(Term::Variable(var)),
6571 right: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6572 });
6573 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6574 kind: QuantifierKind::Existential,
6575 variable: var,
6576 body,
6577 island_id: self.current_island,
6578 }));
6579 }
6580
6581 if self.check(&TokenType::Article(Definiteness::Definite)) {
6583 let saved_pos = self.current;
6584 self.advance();
6585 if self.check_superlative() {
6586 return self.parse_superlative(&subject);
6587 }
6588 self.current = saved_pos;
6589 }
6590
6591 if self.check_article() {
6593 let predicate_np = self.parse_noun_phrase(true)?;
6594 let predicate_noun = predicate_np.noun;
6595
6596 if self.event_reading_mode {
6599 let noun_str = self.interner.resolve(predicate_noun);
6600 if let Some(base_verb) = lexicon::lookup_agentive_noun(noun_str) {
6601 let event_adj = predicate_np.adjectives.iter().find(|adj| {
6603 lexicon::is_event_modifier_adjective(self.interner.resolve(**adj))
6604 });
6605
6606 if let Some(&adj_sym) = event_adj {
6607 let verb_sym = self.interner.intern(base_verb);
6609 let event_var = self.get_event_var();
6610
6611 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6612 name: verb_sym,
6613 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
6614 world: None,
6615 });
6616
6617 let agent_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6618 name: self.interner.intern("Agent"),
6619 args: self.ctx.terms.alloc_slice([
6620 Term::Variable(event_var),
6621 Term::Constant(subject.noun),
6622 ]),
6623 world: None,
6624 });
6625
6626 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6627 name: adj_sym,
6628 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
6629 world: None,
6630 });
6631
6632 let verb_agent = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6634 left: verb_pred,
6635 op: TokenType::And,
6636 right: agent_pred,
6637 });
6638
6639 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6641 left: verb_agent,
6642 op: TokenType::And,
6643 right: adj_pred,
6644 });
6645
6646 let event_reading = self.ctx.exprs.alloc(LogicExpr::Quantifier {
6648 kind: QuantifierKind::Existential,
6649 variable: event_var,
6650 body,
6651 island_id: self.current_island,
6652 });
6653
6654 return self.wrap_with_definiteness(subject.definiteness, subject.noun, event_reading);
6655 }
6656 }
6657 }
6658
6659 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
6660 let predicate_sort = lexicon::lookup_sort(self.interner.resolve(predicate_noun));
6661
6662 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
6663 if !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
6664 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
6665 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6666 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_noun)),
6667 });
6668 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
6669 }
6670 }
6671
6672 let mut predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
6675
6676 for &adj_sym in predicate_np.adjectives {
6678 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6679 name: adj_sym,
6680 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
6681 world: None,
6682 });
6683 predicates.push(adj_pred);
6684 }
6685
6686 let noun_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6688 name: predicate_noun,
6689 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
6690 world: None,
6691 });
6692 predicates.push(noun_pred);
6693
6694 let result = if predicates.len() == 1 {
6696 predicates[0]
6697 } else {
6698 let mut combined = predicates[0];
6699 for pred in &predicates[1..] {
6700 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6701 left: combined,
6702 op: TokenType::And,
6703 right: *pred,
6704 });
6705 }
6706 combined
6707 };
6708
6709 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
6710 }
6711
6712 let prefer_adjective = if let TokenType::Ambiguous { primary, alternatives } = &self.peek().kind {
6715 let is_simple_verb = if let TokenType::Verb { aspect, .. } = **primary {
6716 aspect == Aspect::Simple
6717 } else {
6718 false
6719 };
6720 let has_adj_alt = alternatives.iter().any(|t| matches!(t, TokenType::Adjective(_)));
6721 is_simple_verb && has_adj_alt
6722 } else {
6723 false
6724 };
6725
6726 if !prefer_adjective && self.check_verb() {
6727 let (verb, _verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
6728
6729 if verb_class.is_stative() && verb_aspect == Aspect::Progressive {
6731 return Err(ParseError {
6732 kind: ParseErrorKind::StativeProgressiveConflict,
6733 span: self.current_span(),
6734 });
6735 }
6736
6737 let mut goal_args: Vec<Term<'a>> = Vec::new();
6740 while self.check_to_preposition() {
6741 self.advance(); let goal = self.parse_noun_phrase(true)?;
6743 goal_args.push(self.noun_phrase_to_term(&goal));
6744 }
6745
6746 if self.check_by_preposition() {
6748 self.advance(); let agent = self.parse_noun_phrase(true)?;
6750
6751 let mut args = vec![
6753 self.noun_phrase_to_term(&agent),
6754 self.noun_phrase_to_term(&subject),
6755 ];
6756 args.extend(goal_args);
6757
6758 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
6759 name: verb,
6760 args: self.ctx.terms.alloc_slice(args),
6761 world: None,
6762 });
6763
6764 let with_time = if copula_time == Time::Past {
6765 self.ctx.exprs.alloc(LogicExpr::Temporal {
6766 operator: TemporalOperator::Past,
6767 body: predicate,
6768 })
6769 } else {
6770 predicate
6771 };
6772
6773 return self.wrap_with_definiteness(subject.definiteness, subject.noun, with_time);
6774 }
6775
6776 if copula_time == Time::Past && verb_aspect == Aspect::Simple
6781 && subject.definiteness != Some(Definiteness::Definite) {
6782 let var_name = self.next_var_name();
6784 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
6785 name: verb,
6786 args: self.ctx.terms.alloc_slice([
6787 Term::Variable(var_name),
6788 Term::Constant(subject.noun),
6789 ]),
6790 world: None,
6791 });
6792
6793 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6794 name: subject.noun,
6795 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6796 world: None,
6797 });
6798
6799 let temporal = self.ctx.exprs.alloc(LogicExpr::Temporal {
6800 operator: TemporalOperator::Past,
6801 body: predicate,
6802 });
6803
6804 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6805 left: type_pred,
6806 op: TokenType::And,
6807 right: temporal,
6808 });
6809
6810 let result = self.ctx.exprs.alloc(LogicExpr::Quantifier {
6811 kind: QuantifierKind::Existential,
6812 variable: var_name,
6813 body,
6814 island_id: self.current_island,
6815 });
6816
6817 if is_negated {
6819 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
6820 op: TokenType::Not,
6821 operand: result,
6822 }));
6823 }
6824 return Ok(result);
6825 }
6826
6827 let verb_str = self.interner.resolve(verb).to_lowercase();
6830 let subject_term = if lexicon::is_intensional_predicate(&verb_str) {
6831 Term::Intension(subject.noun)
6832 } else {
6833 Term::Constant(subject.noun)
6834 };
6835
6836 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
6837 name: verb,
6838 args: self.ctx.terms.alloc_slice([subject_term]),
6839 world: None,
6840 });
6841
6842 let with_aspect = if verb_aspect == Aspect::Progressive {
6843 let operator = if verb_class == VerbClass::Semelfactive {
6845 AspectOperator::Iterative
6846 } else {
6847 AspectOperator::Progressive
6848 };
6849 self.ctx.exprs.alloc(LogicExpr::Aspectual {
6850 operator,
6851 body: predicate,
6852 })
6853 } else {
6854 predicate
6855 };
6856
6857 let with_time = if copula_time == Time::Past {
6858 self.ctx.exprs.alloc(LogicExpr::Temporal {
6859 operator: TemporalOperator::Past,
6860 body: with_aspect,
6861 })
6862 } else {
6863 with_aspect
6864 };
6865
6866 let final_expr = if is_negated {
6867 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
6868 op: TokenType::Not,
6869 operand: with_time,
6870 })
6871 } else {
6872 with_time
6873 };
6874
6875 if subject.definiteness == Some(Definiteness::Definite) {
6879 return Ok(final_expr);
6880 }
6881
6882 return self.wrap_with_definiteness(subject.definiteness, subject.noun, final_expr);
6883 }
6884
6885 if let Some((var_name, rel_clause)) = relative_clause {
6887 let var_term = Term::Variable(var_name);
6888 let pred_word = self.consume_content_word()?;
6889
6890 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6891 name: pred_word,
6892 args: self.ctx.terms.alloc_slice([var_term]),
6893 world: None,
6894 });
6895
6896 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6897 name: subject.noun,
6898 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6899 world: None,
6900 });
6901
6902 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6903 left: type_pred,
6904 op: TokenType::And,
6905 right: rel_clause,
6906 });
6907
6908 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6909 left: inner,
6910 op: TokenType::And,
6911 right: main_pred,
6912 });
6913
6914 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6915 kind: QuantifierKind::Existential,
6916 variable: var_name,
6917 body,
6918 island_id: self.current_island,
6919 }));
6920 }
6921
6922 if let TokenType::ProperName(predicate_name) = self.peek().kind {
6927 self.advance(); let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
6929 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6930 right: self.ctx.terms.alloc(Term::Constant(predicate_name)),
6931 });
6932 let result = if is_negated {
6933 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
6934 op: TokenType::Not,
6935 operand: identity,
6936 })
6937 } else {
6938 identity
6939 };
6940 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
6941 }
6942
6943 let predicate_name = self.consume_content_word()?;
6946
6947 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
6949 let predicate_str = self.interner.resolve(predicate_name);
6950
6951 if let Some(s_sort) = subject_sort {
6953 if !crate::ontology::check_sort_compatibility(predicate_str, s_sort) {
6954 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
6955 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6956 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
6957 });
6958 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
6959 }
6960 }
6961
6962 let predicate_sort = lexicon::lookup_sort(predicate_str);
6964 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
6965 if s_sort != p_sort && !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
6966 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
6967 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6968 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
6969 });
6970 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
6971 }
6972 }
6973
6974 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
6975 name: predicate_name,
6976 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
6977 world: None,
6978 });
6979
6980 let result = if is_negated {
6982 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
6983 op: TokenType::Not,
6984 operand: predicate,
6985 })
6986 } else {
6987 predicate
6988 };
6989 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
6990 }
6991
6992 if self.check_auxiliary() && self.is_true_auxiliary_usage() {
6996 let aux_time = if let TokenType::Auxiliary(time) = self.advance().kind {
6997 time
6998 } else {
6999 Time::None
7000 };
7001 self.pending_time = Some(aux_time);
7002
7003 if self.match_token(&[TokenType::Not]) {
7005 self.negative_depth += 1;
7006
7007 if self.check(&TokenType::Ever) {
7009 self.advance();
7010 }
7011
7012 if self.check_verb() || self.check(&TokenType::Do) {
7014 let verb = if self.check(&TokenType::Do) {
7015 self.advance(); self.interner.intern("Do")
7017 } else {
7018 self.consume_verb()
7019 };
7020 let subject_term = self.noun_phrase_to_term(&subject);
7021
7022 if self.check_npi_object() {
7024 let npi_token = self.advance().kind.clone();
7025 let obj_var = self.next_var_name();
7026
7027 let restriction_name = match npi_token {
7028 TokenType::Anything => "Thing",
7029 TokenType::Anyone => "Person",
7030 _ => "Thing",
7031 };
7032
7033 let restriction_sym = self.interner.intern(restriction_name);
7034 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7035 name: restriction_sym,
7036 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7037 world: None,
7038 });
7039
7040 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7041 name: verb,
7042 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7043 world: None,
7044 });
7045
7046 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7047 left: obj_restriction,
7048 op: TokenType::And,
7049 right: verb_pred,
7050 });
7051
7052 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7053 kind: QuantifierKind::Existential,
7054 variable: obj_var,
7055 body,
7056 island_id: self.current_island,
7057 });
7058
7059 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7060 let with_time = match effective_time {
7061 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7062 operator: TemporalOperator::Past,
7063 body: quantified,
7064 }),
7065 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7066 operator: TemporalOperator::Future,
7067 body: quantified,
7068 }),
7069 _ => quantified,
7070 };
7071
7072 self.negative_depth -= 1;
7073 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7074 op: TokenType::Not,
7075 operand: with_time,
7076 }));
7077 }
7078
7079 if self.check_quantifier() {
7081 let quantifier_token = self.advance().kind.clone();
7082 let object_np = self.parse_noun_phrase(false)?;
7083 let obj_var = self.next_var_name();
7084
7085 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7086 name: object_np.noun,
7087 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7088 world: None,
7089 });
7090
7091 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7092 name: verb,
7093 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7094 world: None,
7095 });
7096
7097 let (kind, body) = match quantifier_token {
7098 TokenType::Any => {
7099 if self.is_negative_context() {
7100 (
7101 QuantifierKind::Existential,
7102 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7103 left: obj_restriction,
7104 op: TokenType::And,
7105 right: verb_pred,
7106 }),
7107 )
7108 } else {
7109 (
7110 QuantifierKind::Universal,
7111 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7112 left: obj_restriction,
7113 op: TokenType::If,
7114 right: verb_pred,
7115 }),
7116 )
7117 }
7118 }
7119 TokenType::Some => (
7120 QuantifierKind::Existential,
7121 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7122 left: obj_restriction,
7123 op: TokenType::And,
7124 right: verb_pred,
7125 }),
7126 ),
7127 TokenType::All => (
7128 QuantifierKind::Universal,
7129 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7130 left: obj_restriction,
7131 op: TokenType::If,
7132 right: verb_pred,
7133 }),
7134 ),
7135 _ => (
7136 QuantifierKind::Existential,
7137 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7138 left: obj_restriction,
7139 op: TokenType::And,
7140 right: verb_pred,
7141 }),
7142 ),
7143 };
7144
7145 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7146 kind,
7147 variable: obj_var,
7148 body,
7149 island_id: self.current_island,
7150 });
7151
7152 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7153 let with_time = match effective_time {
7154 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7155 operator: TemporalOperator::Past,
7156 body: quantified,
7157 }),
7158 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7159 operator: TemporalOperator::Future,
7160 body: quantified,
7161 }),
7162 _ => quantified,
7163 };
7164
7165 self.negative_depth -= 1;
7166 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7167 op: TokenType::Not,
7168 operand: with_time,
7169 }));
7170 }
7171
7172 let mut roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
7173
7174 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7176 let mut modifiers: Vec<Symbol> = vec![];
7177 match effective_time {
7178 Time::Past => modifiers.push(self.interner.intern("Past")),
7179 Time::Future => modifiers.push(self.interner.intern("Future")),
7180 _ => {}
7181 }
7182
7183 if self.check_content_word() || self.check_article() || self.check_pronoun() {
7185 if self.check_pronoun() {
7186 let pronoun_token = self.advance();
7188 let pronoun_sym = pronoun_token.lexeme;
7189 roles.push((ThematicRole::Theme, Term::Constant(pronoun_sym)));
7190 } else {
7191 let object = self.parse_noun_phrase(false)?;
7192 let object_term = self.noun_phrase_to_term(&object);
7193 roles.push((ThematicRole::Theme, object_term));
7194 }
7195 }
7196
7197 let event_var = self.get_event_var();
7198 let suppress_existential = self.drs.in_conditional_antecedent();
7199 if suppress_existential {
7200 let event_class = self.interner.intern("Event");
7201 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7202 }
7203 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7204 event_var,
7205 verb,
7206 roles: self.ctx.roles.alloc_slice(roles),
7207 modifiers: self.ctx.syms.alloc_slice(modifiers),
7208 suppress_existential,
7209 world: None,
7210 })));
7211
7212 self.negative_depth -= 1;
7213 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7214 op: TokenType::Not,
7215 operand: neo_event,
7216 }));
7217 }
7218
7219 self.negative_depth -= 1;
7220 }
7221 }
7223
7224 if self.check_presup_trigger() && !self.is_followed_by_np_object() && self.is_followed_by_gerund() {
7230 let presup_kind = match self.advance().kind {
7231 TokenType::PresupTrigger(kind) => kind,
7232 TokenType::Verb { lemma, .. } => {
7233 let s = self.interner.resolve(lemma).to_lowercase();
7234 crate::lexicon::lookup_presup_trigger(&s)
7235 .expect("Lexicon mismatch: Verb flagged as trigger but lookup failed")
7236 }
7237 _ => panic!("Expected presupposition trigger"),
7238 };
7239 return self.parse_presupposition(&subject, presup_kind);
7240 }
7241
7242 let noun_str = self.interner.resolve(subject.noun);
7244 let is_bare_plural = subject.definiteness.is_none()
7245 && subject.possessor.is_none()
7246 && Self::is_plural_noun(noun_str)
7247 && self.check_verb();
7248
7249 if is_bare_plural {
7250 let var_name = self.next_var_name();
7251 let (verb, verb_time, verb_aspect, _) = self.consume_verb_with_metadata();
7252
7253 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7254 name: subject.noun,
7255 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7256 world: None,
7257 });
7258
7259 let mut args = vec![Term::Variable(var_name)];
7260 if self.check_content_word() {
7261 let object = self.parse_noun_phrase(false)?;
7262 args.push(self.noun_phrase_to_term(&object));
7263 }
7264
7265 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7266 name: verb,
7267 args: self.ctx.terms.alloc_slice(args),
7268 world: None,
7269 });
7270
7271 let effective_time = self.pending_time.take().unwrap_or(verb_time);
7272 let with_time = match effective_time {
7273 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7274 operator: TemporalOperator::Past,
7275 body: verb_pred,
7276 }),
7277 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7278 operator: TemporalOperator::Future,
7279 body: verb_pred,
7280 }),
7281 _ => verb_pred,
7282 };
7283
7284 let with_aspect = if verb_aspect == Aspect::Progressive {
7285 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7286 operator: AspectOperator::Progressive,
7287 body: with_time,
7288 })
7289 } else {
7290 with_time
7291 };
7292
7293 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7294 left: type_pred,
7295 op: TokenType::If,
7296 right: with_aspect,
7297 });
7298
7299 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7300 kind: QuantifierKind::Generic,
7301 variable: var_name,
7302 body,
7303 island_id: self.current_island,
7304 }));
7305 }
7306
7307 if self.check(&TokenType::Does) || self.check(&TokenType::Do) {
7309 self.advance(); let is_negated = self.match_token(&[TokenType::Not]);
7311
7312 if self.check_verb() {
7313 let verb = self.consume_verb();
7314 let verb_lemma = self.interner.resolve(verb).to_lowercase();
7315
7316 if self.check_wh_word() {
7318 let wh_token = self.advance().kind.clone();
7319 let is_who = matches!(wh_token, TokenType::Who);
7320 let is_what = matches!(wh_token, TokenType::What);
7321
7322 let is_sluicing = self.is_at_end() ||
7323 self.check(&TokenType::Period) ||
7324 self.check(&TokenType::Comma);
7325
7326 if is_sluicing {
7327 if let Some(template) = self.last_event_template.clone() {
7328 let wh_var = self.next_var_name();
7329 let subject_term = self.noun_phrase_to_term(&subject);
7330
7331 let roles: Vec<_> = if is_who {
7332 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7333 .chain(template.non_agent_roles.iter().cloned())
7334 .collect()
7335 } else if is_what {
7336 vec![
7337 (ThematicRole::Agent, subject_term.clone()),
7338 (ThematicRole::Theme, Term::Variable(wh_var)),
7339 ]
7340 } else {
7341 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7342 .chain(template.non_agent_roles.iter().cloned())
7343 .collect()
7344 };
7345
7346 let event_var = self.get_event_var();
7347 let suppress_existential = self.drs.in_conditional_antecedent();
7348 if suppress_existential {
7349 let event_class = self.interner.intern("Event");
7350 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7351 }
7352 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7353 event_var,
7354 verb: template.verb,
7355 roles: self.ctx.roles.alloc_slice(roles),
7356 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
7357 suppress_existential,
7358 world: None,
7359 })));
7360
7361 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7362 wh_variable: wh_var,
7363 body: reconstructed,
7364 });
7365
7366 let know_event_var = self.get_event_var();
7367 let suppress_existential2 = self.drs.in_conditional_antecedent();
7368 if suppress_existential2 {
7369 let event_class = self.interner.intern("Event");
7370 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
7371 }
7372 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7373 event_var: know_event_var,
7374 verb,
7375 roles: self.ctx.roles.alloc_slice(vec![
7376 (ThematicRole::Agent, subject_term),
7377 (ThematicRole::Theme, Term::Proposition(question)),
7378 ]),
7379 modifiers: self.ctx.syms.alloc_slice(vec![]),
7380 suppress_existential: suppress_existential2,
7381 world: None,
7382 })));
7383
7384 let result = if is_negated {
7385 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7386 op: TokenType::Not,
7387 operand: know_event,
7388 })
7389 } else {
7390 know_event
7391 };
7392
7393 return self.wrap_with_definiteness_full(&subject, result);
7394 }
7395 }
7396 }
7397
7398 if verb_lemma == "exist" && is_negated {
7400 let var_name = self.next_var_name();
7402 let restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7403 name: subject.noun,
7404 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7405 world: None,
7406 });
7407 let exists = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7408 kind: QuantifierKind::Existential,
7409 variable: var_name,
7410 body: restriction,
7411 island_id: self.current_island,
7412 });
7413 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7414 op: TokenType::Not,
7415 operand: exists,
7416 }));
7417 }
7418
7419 let subject_term = self.noun_phrase_to_term(&subject);
7422 let modifiers: Vec<Symbol> = vec![];
7423
7424 if self.check(&TokenType::Reflexive) {
7426 self.advance();
7427 let roles = vec![
7428 (ThematicRole::Agent, subject_term.clone()),
7429 (ThematicRole::Theme, subject_term),
7430 ];
7431 let event_var = self.get_event_var();
7432 let suppress_existential = self.drs.in_conditional_antecedent();
7433 if suppress_existential {
7434 let event_class = self.interner.intern("Event");
7435 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7436 }
7437 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7438 event_var,
7439 verb,
7440 roles: self.ctx.roles.alloc_slice(roles),
7441 modifiers: self.ctx.syms.alloc_slice(modifiers),
7442 suppress_existential,
7443 world: None,
7444 })));
7445
7446 let result = if is_negated {
7447 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7448 op: TokenType::Not,
7449 operand: neo_event,
7450 })
7451 } else {
7452 neo_event
7453 };
7454 return self.wrap_with_definiteness_full(&subject, result);
7455 }
7456
7457 if self.check_npi_quantifier() || self.check_quantifier() || self.check_article() {
7459 let (obj_quantifier, was_definite_article) = if self.check_npi_quantifier() {
7460 let tok = self.advance().kind.clone();
7462 (Some(tok), false)
7463 } else if self.check_quantifier() {
7464 (Some(self.advance().kind.clone()), false)
7465 } else {
7466 let art = self.advance().kind.clone();
7467 if let TokenType::Article(def) = art {
7468 if def == Definiteness::Indefinite {
7469 (Some(TokenType::Some), false)
7470 } else {
7471 (None, true)
7472 }
7473 } else {
7474 (None, false)
7475 }
7476 };
7477
7478 let object_np = self.parse_noun_phrase(false)?;
7479 let obj_var = self.next_var_name();
7480
7481 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7482 name: object_np.noun,
7483 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7484 world: None,
7485 });
7486
7487 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
7489 self.advance();
7490 let rel_clause = self.parse_relative_clause(obj_var)?;
7491 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7492 left: type_pred,
7493 op: TokenType::And,
7494 right: rel_clause,
7495 })
7496 } else {
7497 type_pred
7498 };
7499
7500 let event_var = self.get_event_var();
7501 let suppress_existential = self.drs.in_conditional_antecedent();
7502 if suppress_existential {
7503 let event_class = self.interner.intern("Event");
7504 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7505 }
7506
7507 let roles = vec![
7508 (ThematicRole::Agent, subject_term),
7509 (ThematicRole::Theme, Term::Variable(obj_var)),
7510 ];
7511
7512 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7513 event_var,
7514 verb,
7515 roles: self.ctx.roles.alloc_slice(roles),
7516 modifiers: self.ctx.syms.alloc_slice(modifiers),
7517 suppress_existential,
7518 world: None,
7519 })));
7520
7521 let quantifier_kind = match &obj_quantifier {
7525 Some(TokenType::Any) if is_negated => QuantifierKind::Existential,
7526 Some(TokenType::All) => QuantifierKind::Universal,
7527 Some(TokenType::No) => QuantifierKind::Universal,
7528 _ => QuantifierKind::Existential,
7529 };
7530
7531 let obj_body = match &obj_quantifier {
7532 Some(TokenType::All) => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7533 left: obj_restriction,
7534 op: TokenType::If,
7535 right: neo_event,
7536 }),
7537 Some(TokenType::No) => {
7538 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7539 op: TokenType::Not,
7540 operand: neo_event,
7541 });
7542 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7543 left: obj_restriction,
7544 op: TokenType::If,
7545 right: neg,
7546 })
7547 }
7548 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7549 left: obj_restriction,
7550 op: TokenType::And,
7551 right: neo_event,
7552 }),
7553 };
7554
7555 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7556 kind: quantifier_kind,
7557 variable: obj_var,
7558 body: obj_body,
7559 island_id: self.current_island,
7560 });
7561
7562 let result = if is_negated && matches!(obj_quantifier, Some(TokenType::Any)) {
7564 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7565 op: TokenType::Not,
7566 operand: obj_quantified,
7567 })
7568 } else if is_negated {
7569 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7571 op: TokenType::Not,
7572 operand: obj_quantified,
7573 })
7574 } else {
7575 obj_quantified
7576 };
7577
7578 return self.wrap_with_definiteness_full(&subject, result);
7579 }
7580
7581 let roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
7583 let event_var = self.get_event_var();
7584 let suppress_existential = self.drs.in_conditional_antecedent();
7585 if suppress_existential {
7586 let event_class = self.interner.intern("Event");
7587 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7588 }
7589
7590 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7591 event_var,
7592 verb,
7593 roles: self.ctx.roles.alloc_slice(roles),
7594 modifiers: self.ctx.syms.alloc_slice(modifiers),
7595 suppress_existential,
7596 world: None,
7597 })));
7598
7599 if is_negated {
7600 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7601 op: TokenType::Not,
7602 operand: neo_event,
7603 }));
7604 }
7605 return Ok(neo_event);
7606 }
7607 }
7608
7609 let is_perfect_aux = if self.check_verb() {
7615 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
7616 word == "has" || word == "have" || word == "had"
7617 } else {
7618 false
7619 };
7620 if subject.definiteness == Some(Definiteness::Definite) && self.check_verb() && self.pending_time.is_none() && !is_perfect_aux {
7621 let saved_pos = self.current;
7622
7623 if let Some(garden_path_result) = self.try_parse(|p| {
7625 let (modifier_verb, _modifier_time, _, _) = p.consume_verb_with_metadata();
7626
7627 let mut pp_mods: Vec<&'a LogicExpr<'a>> = Vec::new();
7629 while p.check_preposition() {
7630 let prep = if let TokenType::Preposition(prep) = p.advance().kind {
7631 prep
7632 } else {
7633 break;
7634 };
7635 if p.check_article() || p.check_content_word() {
7636 let pp_obj = p.parse_noun_phrase(false)?;
7637 let pp_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7638 name: prep,
7639 args: p.ctx.terms.alloc_slice([Term::Variable(p.interner.intern("x")), Term::Constant(pp_obj.noun)]),
7640 world: None,
7641 });
7642 pp_mods.push(pp_pred);
7643 }
7644 }
7645
7646 if !p.check_verb() {
7648 return Err(ParseError {
7649 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
7650 span: p.current_span(),
7651 });
7652 }
7653
7654 let (main_verb, main_time, _, _) = p.consume_verb_with_metadata();
7655
7656 let var = p.interner.intern("x");
7658
7659 let type_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7661 name: subject.noun,
7662 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
7663 world: None,
7664 });
7665
7666 let mod_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7668 name: modifier_verb,
7669 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
7670 world: None,
7671 });
7672
7673 let main_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7675 name: main_verb,
7676 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
7677 world: None,
7678 });
7679
7680 let mut body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
7682 left: type_pred,
7683 op: TokenType::And,
7684 right: mod_pred,
7685 });
7686
7687 for pp in pp_mods {
7689 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
7690 left: body,
7691 op: TokenType::And,
7692 right: pp,
7693 });
7694 }
7695
7696 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
7698 left: body,
7699 op: TokenType::And,
7700 right: main_pred,
7701 });
7702
7703 let with_time = match main_time {
7705 Time::Past => p.ctx.exprs.alloc(LogicExpr::Temporal {
7706 operator: TemporalOperator::Past,
7707 body,
7708 }),
7709 Time::Future => p.ctx.exprs.alloc(LogicExpr::Temporal {
7710 operator: TemporalOperator::Future,
7711 body,
7712 }),
7713 _ => body,
7714 };
7715
7716 Ok(p.ctx.exprs.alloc(LogicExpr::Quantifier {
7718 kind: QuantifierKind::Existential,
7719 variable: var,
7720 body: with_time,
7721 island_id: p.current_island,
7722 }))
7723 }) {
7724 return Ok(garden_path_result);
7725 }
7726
7727 self.current = saved_pos;
7729 }
7730
7731 if self.check_modal() {
7732 return self.parse_aspect_chain(subject.noun);
7733 }
7734
7735 if self.check_content_word() {
7737 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
7738 if word == "has" || word == "have" || word == "had" {
7739 let is_perfect_aspect = if self.current + 1 < self.tokens.len() {
7741 let next_token = &self.tokens[self.current + 1].kind;
7742 matches!(
7743 next_token,
7744 TokenType::Verb { .. } | TokenType::Not
7745 ) && !matches!(next_token, TokenType::Number(_))
7746 } else {
7747 false
7748 };
7749 if is_perfect_aspect {
7750 return self.parse_aspect_chain(subject.noun);
7751 }
7752 }
7754 }
7755
7756 if self.check(&TokenType::Had) {
7758 return self.parse_aspect_chain(subject.noun);
7759 }
7760
7761 if self.check(&TokenType::Never) {
7763 self.advance();
7764 let verb = self.consume_verb();
7765 let subject_term = self.noun_phrase_to_term(&subject);
7766 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7767 name: verb,
7768 args: self.ctx.terms.alloc_slice([subject_term]),
7769 world: None,
7770 });
7771 let result = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7772 op: TokenType::Not,
7773 operand: verb_pred,
7774 });
7775 return self.wrap_with_definiteness_full(&subject, result);
7776 }
7777
7778 if self.check_verb() {
7779 let (mut verb, verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
7780
7781 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7783 let verb_str = self.interner.resolve(verb);
7784 if let Some(s_sort) = subject_sort {
7785 if !crate::ontology::check_sort_compatibility(verb_str, s_sort) {
7786 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7787 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7788 vehicle: self.ctx.terms.alloc(Term::Constant(verb)),
7789 });
7790 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7791 }
7792 }
7793
7794 if self.is_control_verb(verb) {
7796 return self.parse_control_structure(&subject, verb, verb_time);
7797 }
7798
7799 if let Some((var_name, rel_clause)) = relative_clause {
7801 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7802 name: verb,
7803 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7804 world: None,
7805 });
7806
7807 let effective_time = self.pending_time.take().unwrap_or(verb_time);
7808 let with_time = match effective_time {
7809 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7810 operator: TemporalOperator::Past,
7811 body: main_pred,
7812 }),
7813 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7814 operator: TemporalOperator::Future,
7815 body: main_pred,
7816 }),
7817 _ => main_pred,
7818 };
7819
7820 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7822 name: subject.noun,
7823 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7824 world: None,
7825 });
7826
7827 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7828 left: type_pred,
7829 op: TokenType::And,
7830 right: rel_clause,
7831 });
7832
7833 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7834 left: inner,
7835 op: TokenType::And,
7836 right: with_time,
7837 });
7838
7839 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7840 kind: QuantifierKind::Existential,
7841 variable: var_name,
7842 body,
7843 island_id: self.current_island,
7844 }));
7845 }
7846
7847 let subject_term = self.noun_phrase_to_term(&subject);
7848 let mut args = vec![subject_term.clone()];
7849
7850 let unknown = self.interner.intern("?");
7851
7852 if self.check_wh_word() {
7854 let wh_token = self.advance().kind.clone();
7855
7856 let is_who = matches!(wh_token, TokenType::Who);
7858 let is_what = matches!(wh_token, TokenType::What);
7859
7860 let is_sluicing = self.is_at_end() ||
7862 self.check(&TokenType::Period) ||
7863 self.check(&TokenType::Comma);
7864
7865 if is_sluicing {
7866 if let Some(template) = self.last_event_template.clone() {
7868 let wh_var = self.next_var_name();
7869
7870 let roles: Vec<_> = if is_who {
7872 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7874 .chain(template.non_agent_roles.iter().cloned())
7875 .collect()
7876 } else if is_what {
7877 vec![
7879 (ThematicRole::Agent, subject_term.clone()),
7880 (ThematicRole::Theme, Term::Variable(wh_var)),
7881 ]
7882 } else {
7883 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7885 .chain(template.non_agent_roles.iter().cloned())
7886 .collect()
7887 };
7888
7889 let event_var = self.get_event_var();
7890 let suppress_existential = self.drs.in_conditional_antecedent();
7891 if suppress_existential {
7892 let event_class = self.interner.intern("Event");
7893 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7894 }
7895 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7896 event_var,
7897 verb: template.verb,
7898 roles: self.ctx.roles.alloc_slice(roles),
7899 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
7900 suppress_existential,
7901 world: None,
7902 })));
7903
7904 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7905 wh_variable: wh_var,
7906 body: reconstructed,
7907 });
7908
7909 let know_event_var = self.get_event_var();
7911 let suppress_existential2 = self.drs.in_conditional_antecedent();
7912 if suppress_existential2 {
7913 let event_class = self.interner.intern("Event");
7914 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
7915 }
7916 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7917 event_var: know_event_var,
7918 verb,
7919 roles: self.ctx.roles.alloc_slice(vec![
7920 (ThematicRole::Agent, subject_term),
7921 (ThematicRole::Theme, Term::Proposition(question)),
7922 ]),
7923 modifiers: self.ctx.syms.alloc_slice(vec![]),
7924 suppress_existential: suppress_existential2,
7925 world: None,
7926 })));
7927
7928 return self.wrap_with_definiteness_full(&subject, know_event);
7929 }
7930 }
7931
7932 let embedded = self.parse_embedded_wh_clause()?;
7934 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7935 wh_variable: self.interner.intern("x"),
7936 body: embedded,
7937 });
7938
7939 let know_event_var = self.get_event_var();
7941 let suppress_existential = self.drs.in_conditional_antecedent();
7942 if suppress_existential {
7943 let event_class = self.interner.intern("Event");
7944 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
7945 }
7946 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7947 event_var: know_event_var,
7948 verb,
7949 roles: self.ctx.roles.alloc_slice(vec![
7950 (ThematicRole::Agent, subject_term),
7951 (ThematicRole::Theme, Term::Proposition(question)),
7952 ]),
7953 modifiers: self.ctx.syms.alloc_slice(vec![]),
7954 suppress_existential,
7955 world: None,
7956 })));
7957
7958 return self.wrap_with_definiteness_full(&subject, know_event);
7959 }
7960
7961 let mut object_term: Option<Term<'a>> = None;
7962 let mut second_object_term: Option<Term<'a>> = None;
7963 let mut object_superlative: Option<(Symbol, Symbol)> = None; if self.check(&TokenType::Reflexive) {
7965 self.advance();
7966 let term = self.noun_phrase_to_term(&subject);
7967 object_term = Some(term.clone());
7968 args.push(term);
7969
7970 if let TokenType::Particle(particle_sym) = self.peek().kind {
7972 let verb_str = self.interner.resolve(verb).to_lowercase();
7973 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
7974 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
7975 self.advance();
7976 verb = self.interner.intern(phrasal_lemma);
7977 }
7978 }
7979 } else if self.check_pronoun() {
7980 let token = self.advance().clone();
7981 if let TokenType::Pronoun { gender, number, .. } = token.kind {
7982 let resolved = self.resolve_pronoun(gender, number)?;
7983 let term = match resolved {
7984 ResolvedPronoun::Variable(s) => Term::Variable(s),
7985 ResolvedPronoun::Constant(s) => Term::Constant(s),
7986 };
7987 object_term = Some(term.clone());
7988 args.push(term);
7989
7990 if let TokenType::Particle(particle_sym) = self.peek().kind {
7992 let verb_str = self.interner.resolve(verb).to_lowercase();
7993 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
7994 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
7995 self.advance();
7996 verb = self.interner.intern(phrasal_lemma);
7997 }
7998 }
7999 }
8000 } else if self.check_quantifier() || self.check_article() {
8001 let (obj_quantifier, was_definite_article) = if self.check_quantifier() {
8003 (Some(self.advance().kind.clone()), false)
8004 } else {
8005 let art = self.advance().kind.clone();
8006 if let TokenType::Article(def) = art {
8007 if def == Definiteness::Indefinite {
8008 (Some(TokenType::Some), false)
8009 } else {
8010 (None, true) }
8012 } else {
8013 (None, false)
8014 }
8015 };
8016
8017 let object_np = self.parse_noun_phrase(false)?;
8018
8019 if let Some(adj) = object_np.superlative {
8021 object_superlative = Some((adj, object_np.noun));
8022 }
8023
8024 if let TokenType::Particle(particle_sym) = self.peek().kind {
8026 let verb_str = self.interner.resolve(verb).to_lowercase();
8027 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8028 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8029 self.advance(); verb = self.interner.intern(phrasal_lemma);
8031 }
8032 }
8033
8034 if let Some(obj_q) = obj_quantifier {
8035 let verb_str = self.interner.resolve(verb).to_lowercase();
8039 let is_opaque = lexicon::lookup_verb_db(&verb_str)
8040 .map(|meta| meta.features.contains(&lexicon::Feature::Opaque))
8041 .unwrap_or(false);
8042
8043 if is_opaque && matches!(obj_q, TokenType::Some) {
8044 let intension_term = Term::Intension(object_np.noun);
8046
8047 let event_var = self.get_event_var();
8049 let mut modifiers = self.collect_adverbs();
8050 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8051 match effective_time {
8052 Time::Past => modifiers.push(self.interner.intern("Past")),
8053 Time::Future => modifiers.push(self.interner.intern("Future")),
8054 _ => {}
8055 }
8056
8057 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8058 let roles = vec![
8059 (ThematicRole::Agent, subject_term_for_event),
8060 (ThematicRole::Theme, intension_term),
8061 ];
8062
8063 let suppress_existential = self.drs.in_conditional_antecedent();
8064 if suppress_existential {
8065 let event_class = self.interner.intern("Event");
8066 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8067 }
8068 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8069 event_var,
8070 verb,
8071 roles: self.ctx.roles.alloc_slice(roles),
8072 modifiers: self.ctx.syms.alloc_slice(modifiers),
8073 suppress_existential,
8074 world: None,
8075 })));
8076
8077 return self.wrap_with_definiteness_full(&subject, neo_event);
8078 }
8079
8080 let obj_var = self.next_var_name();
8081
8082 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8084 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8085 Number::Plural
8086 } else {
8087 Number::Singular
8088 };
8089 if object_np.definiteness == Some(Definiteness::Definite) {
8091 self.drs.introduce_referent_with_source(obj_var, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8092 } else {
8093 self.drs.introduce_referent(obj_var, object_np.noun, obj_gender, obj_number);
8094 }
8095
8096 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8097 name: object_np.noun,
8098 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8099 world: None,
8100 });
8101
8102 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8103 self.advance();
8104 let rel_clause = self.parse_relative_clause(obj_var)?;
8105 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8106 left: type_pred,
8107 op: TokenType::And,
8108 right: rel_clause,
8109 })
8110 } else {
8111 type_pred
8112 };
8113
8114 let event_var = self.get_event_var();
8115 let mut modifiers = self.collect_adverbs();
8116 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8117 match effective_time {
8118 Time::Past => modifiers.push(self.interner.intern("Past")),
8119 Time::Future => modifiers.push(self.interner.intern("Future")),
8120 _ => {}
8121 }
8122
8123 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8124 let roles = vec![
8125 (ThematicRole::Agent, subject_term_for_event),
8126 (ThematicRole::Theme, Term::Variable(obj_var)),
8127 ];
8128
8129 let template_roles = vec![
8132 (ThematicRole::Agent, subject_term_for_event),
8133 (ThematicRole::Theme, Term::Constant(object_np.noun)),
8134 ];
8135 self.capture_event_template(verb, &template_roles, &modifiers);
8136
8137 let suppress_existential = self.drs.in_conditional_antecedent();
8138 if suppress_existential {
8139 let event_class = self.interner.intern("Event");
8140 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8141 }
8142 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8143 event_var,
8144 verb,
8145 roles: self.ctx.roles.alloc_slice(roles),
8146 modifiers: self.ctx.syms.alloc_slice(modifiers),
8147 suppress_existential,
8148 world: None,
8149 })));
8150
8151 let obj_kind = match obj_q {
8152 TokenType::All => QuantifierKind::Universal,
8153 TokenType::Some => QuantifierKind::Existential,
8154 TokenType::No => QuantifierKind::Universal,
8155 TokenType::Most => QuantifierKind::Most,
8156 TokenType::Few => QuantifierKind::Few,
8157 TokenType::Many => QuantifierKind::Many,
8158 TokenType::Cardinal(n) => QuantifierKind::Cardinal(n),
8159 TokenType::AtLeast(n) => QuantifierKind::AtLeast(n),
8160 TokenType::AtMost(n) => QuantifierKind::AtMost(n),
8161 _ => QuantifierKind::Existential,
8162 };
8163
8164 let obj_body = match obj_q {
8165 TokenType::All => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8166 left: obj_restriction,
8167 op: TokenType::If,
8168 right: neo_event,
8169 }),
8170 TokenType::No => {
8171 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8172 op: TokenType::Not,
8173 operand: neo_event,
8174 });
8175 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8176 left: obj_restriction,
8177 op: TokenType::If,
8178 right: neg,
8179 })
8180 }
8181 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8182 left: obj_restriction,
8183 op: TokenType::And,
8184 right: neo_event,
8185 }),
8186 };
8187
8188 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8190 kind: obj_kind,
8191 variable: obj_var,
8192 body: obj_body,
8193 island_id: self.current_island,
8194 });
8195
8196 return self.wrap_with_definiteness_full(&subject, obj_quantified);
8198 } else {
8199 if was_definite_article {
8204 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8205 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8206 Number::Plural
8207 } else {
8208 Number::Singular
8209 };
8210 self.drs.introduce_referent_with_source(object_np.noun, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8212 }
8213
8214 let term = self.noun_phrase_to_term(&object_np);
8215 object_term = Some(term.clone());
8216 args.push(term);
8217 }
8218 } else if self.check_focus() {
8219 let focus_kind = if let TokenType::Focus(k) = self.advance().kind {
8220 k
8221 } else {
8222 FocusKind::Only
8223 };
8224
8225 let event_var = self.get_event_var();
8226 let mut modifiers = self.collect_adverbs();
8227 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8228 match effective_time {
8229 Time::Past => modifiers.push(self.interner.intern("Past")),
8230 Time::Future => modifiers.push(self.interner.intern("Future")),
8231 _ => {}
8232 }
8233
8234 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8235
8236 if self.check_preposition() {
8237 let prep_token = self.advance().clone();
8238 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8239 sym
8240 } else {
8241 self.interner.intern("to")
8242 };
8243 let pp_obj = self.parse_noun_phrase(false)?;
8244 let pp_obj_term = Term::Constant(pp_obj.noun);
8245
8246 let roles = vec![(ThematicRole::Agent, subject_term_for_event)];
8247 let suppress_existential = self.drs.in_conditional_antecedent();
8248 if suppress_existential {
8249 let event_class = self.interner.intern("Event");
8250 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8251 }
8252 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8253 event_var,
8254 verb,
8255 roles: self.ctx.roles.alloc_slice(roles),
8256 modifiers: self.ctx.syms.alloc_slice(modifiers),
8257 suppress_existential,
8258 world: None,
8259 })));
8260
8261 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8262 name: prep_name,
8263 args: self.ctx.terms.alloc_slice([Term::Variable(event_var), pp_obj_term]),
8264 world: None,
8265 });
8266
8267 let with_pp = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8268 left: neo_event,
8269 op: TokenType::And,
8270 right: pp_pred,
8271 });
8272
8273 let focused_ref = self.ctx.terms.alloc(pp_obj_term);
8274 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8275 kind: focus_kind,
8276 focused: focused_ref,
8277 scope: with_pp,
8278 }));
8279 }
8280
8281 let focused_np = self.parse_noun_phrase(false)?;
8282 let focused_term = self.noun_phrase_to_term(&focused_np);
8283 args.push(focused_term.clone());
8284
8285 let roles = vec![
8286 (ThematicRole::Agent, subject_term_for_event),
8287 (ThematicRole::Theme, focused_term.clone()),
8288 ];
8289
8290 let suppress_existential = self.drs.in_conditional_antecedent();
8291 if suppress_existential {
8292 let event_class = self.interner.intern("Event");
8293 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8294 }
8295 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8296 event_var,
8297 verb,
8298 roles: self.ctx.roles.alloc_slice(roles),
8299 modifiers: self.ctx.syms.alloc_slice(modifiers),
8300 suppress_existential,
8301 world: None,
8302 })));
8303
8304 let focused_ref = self.ctx.terms.alloc(focused_term);
8305 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8306 kind: focus_kind,
8307 focused: focused_ref,
8308 scope: neo_event,
8309 }));
8310 } else if self.check_number() {
8311 let measure = self.parse_measure_phrase()?;
8313
8314 if self.check_content_word() {
8316 let noun_sym = self.consume_content_word()?;
8317 let count_term = *measure;
8319 object_term = Some(count_term.clone());
8320 args.push(count_term);
8321 second_object_term = Some(Term::Constant(noun_sym));
8322 args.push(Term::Constant(noun_sym));
8323 } else {
8324 object_term = Some(*measure);
8326 args.push(*measure);
8327 }
8328 } else if self.check_content_word() || self.check_article() {
8329 let object = self.parse_noun_phrase(false)?;
8330 if let Some(adj) = object.superlative {
8331 object_superlative = Some((adj, object.noun));
8332 }
8333
8334 let mut all_objects: Vec<Symbol> = vec![object.noun];
8336
8337 while self.check(&TokenType::And) {
8339 let saved = self.current;
8340 self.advance(); if self.check_content_word() || self.check_article() {
8342 let next_obj = match self.parse_noun_phrase(false) {
8343 Ok(np) => np,
8344 Err(_) => {
8345 self.current = saved;
8346 break;
8347 }
8348 };
8349 all_objects.push(next_obj.noun);
8350 } else {
8351 self.current = saved;
8352 break;
8353 }
8354 }
8355
8356 if self.check(&TokenType::Respectively) {
8358 let respectively_span = self.peek().span;
8359 if all_objects.len() > 1 {
8361 return Err(ParseError {
8362 kind: ParseErrorKind::RespectivelyLengthMismatch {
8363 subject_count: 1,
8364 object_count: all_objects.len(),
8365 },
8366 span: respectively_span,
8367 });
8368 }
8369 self.advance(); }
8372
8373 let term = self.noun_phrase_to_term(&object);
8375 object_term = Some(term.clone());
8376 args.push(term.clone());
8377
8378 if all_objects.len() > 1 {
8380 let obj_members: Vec<Term<'a>> = all_objects.iter()
8381 .map(|o| Term::Constant(*o))
8382 .collect();
8383 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
8384 args.pop();
8386 args.push(obj_group);
8387 }
8388
8389 if let TokenType::Particle(particle_sym) = self.peek().kind {
8391 let verb_str = self.interner.resolve(verb).to_lowercase();
8392 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8393 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8394 self.advance(); verb = self.interner.intern(phrasal_lemma);
8396 }
8397 }
8398
8399 if self.check_number() {
8401 let measure = self.parse_measure_phrase()?;
8402 second_object_term = Some(*measure);
8403 args.push(*measure);
8404 }
8405 else {
8407 let verb_str = self.interner.resolve(verb);
8408 if Lexer::is_ditransitive_verb(verb_str) && (self.check_content_word() || self.check_article()) {
8409 let second_np = self.parse_noun_phrase(false)?;
8410 let second_term = self.noun_phrase_to_term(&second_np);
8411 second_object_term = Some(second_term.clone());
8412 args.push(second_term);
8413 }
8414 }
8415 }
8416
8417 let mut pp_predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
8418 while self.check_preposition() || self.check_to() {
8419 let prep_token = self.advance().clone();
8420 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8421 sym
8422 } else if matches!(prep_token.kind, TokenType::To) {
8423 self.interner.intern("To")
8424 } else {
8425 continue;
8426 };
8427
8428 let pp_obj_term = if self.check(&TokenType::Reflexive) {
8429 self.advance();
8430 self.noun_phrase_to_term(&subject)
8431 } else if self.check_pronoun() {
8432 let token = self.advance().clone();
8433 if let TokenType::Pronoun { gender, number, .. } = token.kind {
8434 let resolved = self.resolve_pronoun(gender, number)?;
8435 match resolved {
8436 ResolvedPronoun::Variable(s) => Term::Variable(s),
8437 ResolvedPronoun::Constant(s) => Term::Constant(s),
8438 }
8439 } else {
8440 continue;
8441 }
8442 } else if self.check_content_word() || self.check_article() {
8443 let prep_obj = self.parse_noun_phrase(false)?;
8444 self.noun_phrase_to_term(&prep_obj)
8445 } else {
8446 continue;
8447 };
8448
8449 if self.pp_attach_to_noun {
8450 if let Some(ref obj) = object_term {
8451 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8453 name: prep_name,
8454 args: self.ctx.terms.alloc_slice([obj.clone(), pp_obj_term]),
8455 world: None,
8456 });
8457 pp_predicates.push(pp_pred);
8458 } else {
8459 args.push(pp_obj_term);
8460 }
8461 } else {
8462 let event_sym = self.get_event_var();
8464 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8465 name: prep_name,
8466 args: self.ctx.terms.alloc_slice([Term::Variable(event_sym), pp_obj_term]),
8467 world: None,
8468 });
8469 pp_predicates.push(pp_pred);
8470 }
8471 }
8472
8473 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8475 self.advance();
8476 let rel_var = self.next_var_name();
8477 let rel_pred = self.parse_relative_clause(rel_var)?;
8478 pp_predicates.push(rel_pred);
8479 }
8480
8481 let mut modifiers = self.collect_adverbs();
8483
8484 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8486 match effective_time {
8487 Time::Past => modifiers.push(self.interner.intern("Past")),
8488 Time::Future => modifiers.push(self.interner.intern("Future")),
8489 _ => {}
8490 }
8491
8492 if verb_aspect == Aspect::Progressive {
8494 modifiers.push(self.interner.intern("Progressive"));
8495 } else if verb_aspect == Aspect::Perfect {
8496 modifiers.push(self.interner.intern("Perfect"));
8497 }
8498
8499 let mut roles: Vec<(ThematicRole, Term<'a>)> = Vec::new();
8501
8502 let verb_str_for_check = self.interner.resolve(verb).to_lowercase();
8504 let is_unaccusative = crate::lexicon::lookup_verb_db(&verb_str_for_check)
8505 .map(|meta| meta.features.contains(&crate::lexicon::Feature::Unaccusative))
8506 .unwrap_or(false);
8507
8508 let has_object = object_term.is_some() || second_object_term.is_some();
8510 let subject_role = if is_unaccusative && !has_object {
8511 ThematicRole::Theme
8512 } else {
8513 ThematicRole::Agent
8514 };
8515
8516 roles.push((subject_role, subject_term));
8517 if let Some(second_obj) = second_object_term {
8518 if let Some(first_obj) = object_term {
8520 roles.push((ThematicRole::Recipient, first_obj));
8521 }
8522 roles.push((ThematicRole::Theme, second_obj));
8523 } else if let Some(obj) = object_term {
8524 roles.push((ThematicRole::Theme, obj));
8526 }
8527
8528 let event_var = self.get_event_var();
8530
8531 self.capture_event_template(verb, &roles, &modifiers);
8533
8534 let suppress_existential = self.drs.in_conditional_antecedent();
8536 if suppress_existential {
8537 let event_class = self.interner.intern("Event");
8538 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8539 }
8540 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8541 event_var,
8542 verb,
8543 roles: self.ctx.roles.alloc_slice(roles),
8544 modifiers: self.ctx.syms.alloc_slice(modifiers),
8545 suppress_existential,
8546 world: None,
8547 })));
8548
8549 let with_pps = if pp_predicates.is_empty() {
8551 neo_event
8552 } else {
8553 let mut combined = neo_event;
8554 for pp in pp_predicates {
8555 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8556 left: combined,
8557 op: TokenType::And,
8558 right: pp,
8559 });
8560 }
8561 combined
8562 };
8563
8564 let with_aspect = if verb_aspect == Aspect::Progressive {
8566 if verb_class == crate::lexicon::VerbClass::Semelfactive {
8568 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8569 operator: AspectOperator::Iterative,
8570 body: with_pps,
8571 })
8572 } else {
8573 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8575 operator: AspectOperator::Progressive,
8576 body: with_pps,
8577 })
8578 }
8579 } else if verb_aspect == Aspect::Perfect {
8580 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8581 operator: AspectOperator::Perfect,
8582 body: with_pps,
8583 })
8584 } else if effective_time == Time::Present && verb_aspect == Aspect::Simple {
8585 if !verb_class.is_stative() {
8587 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8588 operator: AspectOperator::Habitual,
8589 body: with_pps,
8590 })
8591 } else {
8592 with_pps
8594 }
8595 } else {
8596 with_pps
8597 };
8598
8599 let with_adverbs = with_aspect;
8600
8601 let with_temporal = if self.check_temporal_adverb() {
8603 let anchor = if let TokenType::TemporalAdverb(adv) = self.advance().kind.clone() {
8604 adv
8605 } else {
8606 panic!("Expected temporal adverb");
8607 };
8608 self.ctx.exprs.alloc(LogicExpr::TemporalAnchor {
8609 anchor,
8610 body: with_adverbs,
8611 })
8612 } else {
8613 with_adverbs
8614 };
8615
8616 let wrapped = self.wrap_with_definiteness_full(&subject, with_temporal)?;
8617
8618 if let Some((adj, noun)) = object_superlative {
8620 let superlative_expr = self.ctx.exprs.alloc(LogicExpr::Superlative {
8621 adjective: adj,
8622 subject: self.ctx.terms.alloc(Term::Constant(noun)),
8623 domain: noun,
8624 });
8625 return Ok(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8626 left: wrapped,
8627 op: TokenType::And,
8628 right: superlative_expr,
8629 }));
8630 }
8631
8632 return Ok(wrapped);
8633 }
8634
8635 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(subject.noun)))
8636 }
8637
8638 fn check_preposition(&self) -> bool {
8639 matches!(self.peek().kind, TokenType::Preposition(_))
8640 }
8641
8642 fn check_by_preposition(&self) -> bool {
8643 if let TokenType::Preposition(p) = self.peek().kind {
8644 p.is(self.interner, "by")
8645 } else {
8646 false
8647 }
8648 }
8649
8650 fn check_preposition_is(&self, word: &str) -> bool {
8651 if let TokenType::Preposition(p) = self.peek().kind {
8652 p.is(self.interner, word)
8653 } else {
8654 false
8655 }
8656 }
8657
8658 fn check_word(&self, word: &str) -> bool {
8660 let token = self.peek();
8661 let lexeme = self.interner.resolve(token.lexeme);
8662 lexeme.eq_ignore_ascii_case(word)
8663 }
8664
8665 fn check_to_preposition(&self) -> bool {
8666 match self.peek().kind {
8667 TokenType::To => true,
8668 TokenType::Preposition(p) => p.is(self.interner, "to"),
8669 _ => false,
8670 }
8671 }
8672
8673 fn check_content_word(&self) -> bool {
8674 match &self.peek().kind {
8675 TokenType::Noun(_)
8676 | TokenType::Adjective(_)
8677 | TokenType::NonIntersectiveAdjective(_)
8678 | TokenType::Verb { .. }
8679 | TokenType::ProperName(_)
8680 | TokenType::Article(_) => true,
8681 TokenType::Ambiguous { primary, alternatives } => {
8682 Self::is_content_word_type(primary)
8683 || alternatives.iter().any(Self::is_content_word_type)
8684 }
8685 _ => false,
8686 }
8687 }
8688
8689 fn is_content_word_type(t: &TokenType) -> bool {
8690 matches!(
8691 t,
8692 TokenType::Noun(_)
8693 | TokenType::Adjective(_)
8694 | TokenType::NonIntersectiveAdjective(_)
8695 | TokenType::Verb { .. }
8696 | TokenType::ProperName(_)
8697 | TokenType::Article(_)
8698 )
8699 }
8700
8701 fn check_verb(&self) -> bool {
8702 match &self.peek().kind {
8703 TokenType::Verb { .. } => true,
8704 TokenType::Ambiguous { primary, alternatives } => {
8705 if self.noun_priority_mode {
8706 return false;
8707 }
8708 matches!(**primary, TokenType::Verb { .. })
8709 || alternatives.iter().any(|t| matches!(t, TokenType::Verb { .. }))
8710 }
8711 _ => false,
8712 }
8713 }
8714
8715 fn check_adverb(&self) -> bool {
8716 matches!(self.peek().kind, TokenType::Adverb(_))
8717 }
8718
8719 fn check_performative(&self) -> bool {
8720 matches!(self.peek().kind, TokenType::Performative(_))
8721 }
8722
8723 fn collect_adverbs(&mut self) -> Vec<Symbol> {
8724 let mut adverbs = Vec::new();
8725 while self.check_adverb() {
8726 if let TokenType::Adverb(adv) = self.advance().kind.clone() {
8727 adverbs.push(adv);
8728 }
8729 if self.check(&TokenType::And) {
8731 self.advance();
8732 }
8733 }
8734 adverbs
8735 }
8736
8737 fn check_auxiliary(&self) -> bool {
8738 matches!(self.peek().kind, TokenType::Auxiliary(_))
8739 }
8740
8741 fn is_true_auxiliary_usage(&self) -> bool {
8748 if self.current + 1 >= self.tokens.len() {
8749 return false;
8750 }
8751
8752 let next_token = &self.tokens[self.current + 1].kind;
8753
8754 if matches!(next_token, TokenType::Not) {
8756 return true;
8757 }
8758
8759 if matches!(next_token, TokenType::Verb { .. }) {
8761 return true;
8762 }
8763
8764 if matches!(
8766 next_token,
8767 TokenType::Pronoun { .. }
8768 | TokenType::Article(_)
8769 | TokenType::Noun(_)
8770 | TokenType::ProperName(_)
8771 ) {
8772 return false;
8773 }
8774
8775 true
8777 }
8778
8779 fn check_auxiliary_as_main_verb(&self) -> bool {
8782 if let TokenType::Auxiliary(Time::Past) = self.peek().kind {
8783 if self.current + 1 < self.tokens.len() {
8785 let next = &self.tokens[self.current + 1].kind;
8786 matches!(
8787 next,
8788 TokenType::Pronoun { .. }
8789 | TokenType::Article(_)
8790 | TokenType::Noun(_)
8791 | TokenType::ProperName(_)
8792 )
8793 } else {
8794 false
8795 }
8796 } else {
8797 false
8798 }
8799 }
8800
8801 fn parse_do_as_main_verb(&mut self, subject_term: Term<'a>) -> ParseResult<&'a LogicExpr<'a>> {
8804 let aux_token = self.advance();
8806 let verb_time = if let TokenType::Auxiliary(time) = aux_token.kind {
8807 time
8808 } else {
8809 Time::Past
8810 };
8811
8812 let verb = self.interner.intern("Do");
8814
8815 let object_term = if let TokenType::Pronoun { .. } = self.peek().kind {
8817 self.advance();
8819 let it_sym = self.interner.intern("it");
8822 Term::Constant(it_sym)
8823 } else {
8824 let object = self.parse_noun_phrase(false)?;
8825 self.noun_phrase_to_term(&object)
8826 };
8827
8828 let event_var = self.get_event_var();
8830 let suppress_existential = self.drs.in_conditional_antecedent();
8831
8832 let mut modifiers = Vec::new();
8833 if verb_time == Time::Past {
8834 modifiers.push(self.interner.intern("Past"));
8835 } else if verb_time == Time::Future {
8836 modifiers.push(self.interner.intern("Future"));
8837 }
8838
8839 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8840 event_var,
8841 verb,
8842 roles: self.ctx.roles.alloc_slice(vec![
8843 (ThematicRole::Agent, subject_term),
8844 (ThematicRole::Theme, object_term),
8845 ]),
8846 modifiers: self.ctx.syms.alloc_slice(modifiers),
8847 suppress_existential,
8848 world: None,
8849 })));
8850
8851 Ok(neo_event)
8852 }
8853
8854 fn check_to(&self) -> bool {
8855 matches!(self.peek().kind, TokenType::To)
8856 }
8857
8858 fn has_modal_subordination_ahead(&self) -> bool {
8862 for i in self.current..self.tokens.len() {
8865 match &self.tokens[i].kind {
8866 TokenType::Would | TokenType::Could | TokenType::Should | TokenType::Might => {
8867 return true;
8868 }
8869 TokenType::Period | TokenType::EOF => break,
8871 _ => {}
8872 }
8873 }
8874 false
8875 }
8876
8877 fn consume_verb(&mut self) -> Symbol {
8878 let t = self.advance().clone();
8879 match t.kind {
8880 TokenType::Verb { lemma, .. } => lemma,
8881 TokenType::Ambiguous { primary, .. } => match *primary {
8882 TokenType::Verb { lemma, .. } => lemma,
8883 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
8884 },
8885 _ => panic!("Expected verb, got {:?}", t.kind),
8886 }
8887 }
8888
8889 fn consume_verb_with_metadata(&mut self) -> (Symbol, Time, Aspect, VerbClass) {
8890 let t = self.advance().clone();
8891 match t.kind {
8892 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
8893 TokenType::Ambiguous { primary, .. } => match *primary {
8894 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
8895 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
8896 },
8897 _ => panic!("Expected verb, got {:?}", t.kind),
8898 }
8899 }
8900
8901 fn match_token(&mut self, types: &[TokenType]) -> bool {
8902 for t in types {
8903 if self.check(t) {
8904 self.advance();
8905 return true;
8906 }
8907 }
8908 false
8909 }
8910
8911 fn check_quantifier(&self) -> bool {
8912 matches!(
8913 self.peek().kind,
8914 TokenType::All
8915 | TokenType::No
8916 | TokenType::Some
8917 | TokenType::Any
8918 | TokenType::Most
8919 | TokenType::Few
8920 | TokenType::Many
8921 | TokenType::Cardinal(_)
8922 | TokenType::AtLeast(_)
8923 | TokenType::AtMost(_)
8924 )
8925 }
8926
8927 fn check_npi_quantifier(&self) -> bool {
8928 matches!(
8929 self.peek().kind,
8930 TokenType::Nobody | TokenType::Nothing | TokenType::NoOne
8931 )
8932 }
8933
8934 fn check_npi_object(&self) -> bool {
8935 matches!(
8936 self.peek().kind,
8937 TokenType::Anything | TokenType::Anyone
8938 )
8939 }
8940
8941 fn check_temporal_npi(&self) -> bool {
8942 matches!(
8943 self.peek().kind,
8944 TokenType::Ever | TokenType::Never
8945 )
8946 }
8947
8948 fn parse_npi_quantified(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
8949 let npi_token = self.advance().kind.clone();
8950 let var_name = self.next_var_name();
8951
8952 let (restriction_name, is_person) = match npi_token {
8953 TokenType::Nobody | TokenType::NoOne => ("Person", true),
8954 TokenType::Nothing => ("Thing", false),
8955 _ => ("Thing", false),
8956 };
8957
8958 let restriction_sym = self.interner.intern(restriction_name);
8959 let subject_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8960 name: restriction_sym,
8961 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8962 world: None,
8963 });
8964
8965 self.negative_depth += 1;
8966
8967 let verb = self.consume_verb();
8968
8969 if self.check_npi_object() {
8970 let obj_npi_token = self.advance().kind.clone();
8971 let obj_var = self.next_var_name();
8972
8973 let obj_restriction_name = match obj_npi_token {
8974 TokenType::Anything => "Thing",
8975 TokenType::Anyone => "Person",
8976 _ => "Thing",
8977 };
8978
8979 let obj_restriction_sym = self.interner.intern(obj_restriction_name);
8980 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
8981 name: obj_restriction_sym,
8982 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8983 world: None,
8984 });
8985
8986 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8987 name: verb,
8988 args: self.ctx.terms.alloc_slice([Term::Variable(var_name), Term::Variable(obj_var)]),
8989 world: None,
8990 });
8991
8992 let verb_and_obj = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8993 left: obj_restriction,
8994 op: TokenType::And,
8995 right: verb_pred,
8996 });
8997
8998 let inner_existential = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8999 kind: crate::ast::QuantifierKind::Existential,
9000 variable: obj_var,
9001 body: verb_and_obj,
9002 island_id: self.current_island,
9003 });
9004
9005 self.negative_depth -= 1;
9006
9007 let negated = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9008 op: TokenType::Not,
9009 operand: inner_existential,
9010 });
9011
9012 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9013 left: subject_pred,
9014 op: TokenType::If,
9015 right: negated,
9016 });
9017
9018 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9019 kind: crate::ast::QuantifierKind::Universal,
9020 variable: var_name,
9021 body,
9022 island_id: self.current_island,
9023 }));
9024 }
9025
9026 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9027 name: verb,
9028 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9029 world: None,
9030 });
9031
9032 self.negative_depth -= 1;
9033
9034 let negated_verb = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9035 op: TokenType::Not,
9036 operand: verb_pred,
9037 });
9038
9039 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9040 left: subject_pred,
9041 op: TokenType::If,
9042 right: negated_verb,
9043 });
9044
9045 Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9046 kind: crate::ast::QuantifierKind::Universal,
9047 variable: var_name,
9048 body,
9049 island_id: self.current_island,
9050 }))
9051 }
9052
9053 fn parse_temporal_npi(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9054 let npi_token = self.advance().kind.clone();
9055 let is_never = matches!(npi_token, TokenType::Never);
9056
9057 let subject = self.parse_noun_phrase(true)?;
9058
9059 if is_never {
9060 self.negative_depth += 1;
9061 }
9062
9063 let verb = self.consume_verb();
9064 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9065 name: verb,
9066 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
9067 world: None,
9068 });
9069
9070 if is_never {
9071 self.negative_depth -= 1;
9072 Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9073 op: TokenType::Not,
9074 operand: verb_pred,
9075 }))
9076 } else {
9077 Ok(verb_pred)
9078 }
9079 }
9080
9081 fn check(&self, kind: &TokenType) -> bool {
9082 if self.is_at_end() {
9083 return false;
9084 }
9085 std::mem::discriminant(&self.peek().kind) == std::mem::discriminant(kind)
9086 }
9087
9088 fn check_any(&self, kinds: &[TokenType]) -> bool {
9089 if self.is_at_end() {
9090 return false;
9091 }
9092 let current = std::mem::discriminant(&self.peek().kind);
9093 kinds.iter().any(|k| std::mem::discriminant(k) == current)
9094 }
9095
9096 fn check_article(&self) -> bool {
9097 matches!(self.peek().kind, TokenType::Article(_))
9098 }
9099
9100 fn advance(&mut self) -> &Token {
9101 if !self.is_at_end() {
9102 self.current += 1;
9103 }
9104 self.previous()
9105 }
9106
9107 fn is_at_end(&self) -> bool {
9108 self.peek().kind == TokenType::EOF
9109 }
9110
9111 fn peek(&self) -> &Token {
9112 &self.tokens[self.current]
9113 }
9114
9115 fn peek_next_is_string_literal(&self) -> bool {
9118 self.tokens.get(self.current + 1)
9119 .map(|t| matches!(t.kind, TokenType::StringLiteral(_)))
9120 .unwrap_or(false)
9121 }
9122
9123 fn previous(&self) -> &Token {
9124 &self.tokens[self.current - 1]
9125 }
9126
9127 fn current_span(&self) -> crate::token::Span {
9128 self.peek().span
9129 }
9130
9131 fn consume(&mut self, kind: TokenType) -> ParseResult<&Token> {
9132 if self.check(&kind) {
9133 Ok(self.advance())
9134 } else {
9135 Err(ParseError {
9136 kind: ParseErrorKind::UnexpectedToken {
9137 expected: kind,
9138 found: self.peek().kind.clone(),
9139 },
9140 span: self.current_span(),
9141 })
9142 }
9143 }
9144
9145 fn consume_content_word(&mut self) -> ParseResult<Symbol> {
9146 let t = self.advance().clone();
9147 match t.kind {
9148 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9149 TokenType::Article(_) => Ok(t.lexeme),
9151 TokenType::Number(s) => Ok(s),
9153 TokenType::ProperName(s) => {
9154 if self.mode == ParserMode::Imperative {
9156 if !self.drs.has_referent_by_variable(s) {
9157 return Err(ParseError {
9158 kind: ParseErrorKind::UndefinedVariable {
9159 name: self.interner.resolve(s).to_string()
9160 },
9161 span: t.span,
9162 });
9163 }
9164 return Ok(s);
9165 }
9166
9167 let s_str = self.interner.resolve(s);
9169 let gender = Self::infer_gender(s_str);
9170
9171 self.drs.introduce_proper_name(s, s, gender);
9173
9174 Ok(s)
9175 }
9176 TokenType::Verb { lemma, .. } => Ok(lemma),
9177 TokenType::Ambiguous { primary, .. } => {
9178 match *primary {
9179 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9180 TokenType::Verb { lemma, .. } => Ok(lemma),
9181 TokenType::ProperName(s) => {
9182 if self.mode == ParserMode::Imperative {
9184 if !self.drs.has_referent_by_variable(s) {
9185 return Err(ParseError {
9186 kind: ParseErrorKind::UndefinedVariable {
9187 name: self.interner.resolve(s).to_string()
9188 },
9189 span: t.span,
9190 });
9191 }
9192 return Ok(s);
9193 }
9194 let s_str = self.interner.resolve(s);
9196 let gender = Self::infer_gender(s_str);
9197 self.drs.introduce_proper_name(s, s, gender);
9198 Ok(s)
9199 }
9200 _ => Err(ParseError {
9201 kind: ParseErrorKind::ExpectedContentWord { found: *primary },
9202 span: self.current_span(),
9203 }),
9204 }
9205 }
9206 other => Err(ParseError {
9207 kind: ParseErrorKind::ExpectedContentWord { found: other },
9208 span: self.current_span(),
9209 }),
9210 }
9211 }
9212
9213 fn consume_copula(&mut self) -> ParseResult<()> {
9214 if self.match_token(&[TokenType::Is, TokenType::Are, TokenType::Was, TokenType::Were]) {
9215 Ok(())
9216 } else {
9217 Err(ParseError {
9218 kind: ParseErrorKind::ExpectedCopula,
9219 span: self.current_span(),
9220 })
9221 }
9222 }
9223
9224 fn check_comparative(&self) -> bool {
9225 matches!(self.peek().kind, TokenType::Comparative(_))
9226 }
9227
9228 fn is_contact_clause_pattern(&self) -> bool {
9229 let mut pos = self.current;
9232
9233 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Article(_)) {
9235 pos += 1;
9236 } else {
9237 return false;
9238 }
9239
9240 while pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Adjective(_)) {
9242 pos += 1;
9243 }
9244
9245 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Adjective(_)) {
9247 pos += 1;
9248 } else {
9249 return false;
9250 }
9251
9252 pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Verb { .. } | TokenType::Article(_))
9254 }
9255
9256 fn check_superlative(&self) -> bool {
9257 matches!(self.peek().kind, TokenType::Superlative(_))
9258 }
9259
9260 fn check_scopal_adverb(&self) -> bool {
9261 matches!(self.peek().kind, TokenType::ScopalAdverb(_))
9262 }
9263
9264 fn check_temporal_adverb(&self) -> bool {
9265 matches!(self.peek().kind, TokenType::TemporalAdverb(_))
9266 }
9267
9268 fn check_non_intersective_adjective(&self) -> bool {
9269 matches!(self.peek().kind, TokenType::NonIntersectiveAdjective(_))
9270 }
9271
9272 fn check_focus(&self) -> bool {
9273 matches!(self.peek().kind, TokenType::Focus(_))
9274 }
9275
9276 fn check_measure(&self) -> bool {
9277 matches!(self.peek().kind, TokenType::Measure(_))
9278 }
9279
9280 fn check_presup_trigger(&self) -> bool {
9281 match &self.peek().kind {
9282 TokenType::PresupTrigger(_) => true,
9283 TokenType::Verb { lemma, .. } => {
9284 let s = self.interner.resolve(*lemma).to_lowercase();
9285 crate::lexicon::lookup_presup_trigger(&s).is_some()
9286 }
9287 _ => false,
9288 }
9289 }
9290
9291 fn is_followed_by_np_object(&self) -> bool {
9292 if self.current + 1 >= self.tokens.len() {
9293 return false;
9294 }
9295 let next = &self.tokens[self.current + 1].kind;
9296 matches!(next,
9297 TokenType::ProperName(_) |
9298 TokenType::Article(_) |
9299 TokenType::Noun(_) |
9300 TokenType::Pronoun { .. } |
9301 TokenType::Reflexive |
9302 TokenType::Who |
9303 TokenType::What |
9304 TokenType::Where |
9305 TokenType::When |
9306 TokenType::Why
9307 )
9308 }
9309
9310 fn is_followed_by_gerund(&self) -> bool {
9311 if self.current + 1 >= self.tokens.len() {
9312 return false;
9313 }
9314 matches!(self.tokens[self.current + 1].kind, TokenType::Verb { .. })
9315 }
9316
9317 fn parse_spawn_statement(&mut self) -> ParseResult<Stmt<'a>> {
9323 self.advance(); if !self.check_article() {
9327 return Err(ParseError {
9328 kind: ParseErrorKind::ExpectedKeyword { keyword: "a/an".to_string() },
9329 span: self.current_span(),
9330 });
9331 }
9332 self.advance(); let agent_type = match &self.tokens[self.current].kind {
9336 TokenType::Noun(sym) | TokenType::ProperName(sym) => {
9337 let s = *sym;
9338 self.advance();
9339 s
9340 }
9341 _ => {
9342 return Err(ParseError {
9343 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent type".to_string() },
9344 span: self.current_span(),
9345 });
9346 }
9347 };
9348
9349 if !self.check(&TokenType::Called) {
9351 return Err(ParseError {
9352 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
9353 span: self.current_span(),
9354 });
9355 }
9356 self.advance(); let name = if let TokenType::StringLiteral(sym) = &self.tokens[self.current].kind {
9360 let s = *sym;
9361 self.advance();
9362 s
9363 } else {
9364 return Err(ParseError {
9365 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent name".to_string() },
9366 span: self.current_span(),
9367 });
9368 };
9369
9370 Ok(Stmt::Spawn { agent_type, name })
9371 }
9372
9373 fn parse_send_statement(&mut self) -> ParseResult<Stmt<'a>> {
9375 self.advance(); let message = self.parse_imperative_expr()?;
9379
9380 if !self.check_preposition_is("to") {
9382 return Err(ParseError {
9383 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9384 span: self.current_span(),
9385 });
9386 }
9387 self.advance(); let destination = self.parse_imperative_expr()?;
9391
9392 Ok(Stmt::SendMessage { message, destination })
9393 }
9394
9395 fn parse_await_statement(&mut self) -> ParseResult<Stmt<'a>> {
9397 self.advance(); if self.check_word("response") {
9401 self.advance();
9402 }
9403
9404 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
9406 return Err(ParseError {
9407 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
9408 span: self.current_span(),
9409 });
9410 }
9411 self.advance(); let source = self.parse_imperative_expr()?;
9415
9416 if !self.check_word("into") {
9418 return Err(ParseError {
9419 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
9420 span: self.current_span(),
9421 });
9422 }
9423 self.advance(); let into = match &self.tokens[self.current].kind {
9427 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
9428 let s = *sym;
9429 self.advance();
9430 s
9431 }
9432 _ if self.check_content_word() => {
9434 let sym = self.tokens[self.current].lexeme;
9435 self.advance();
9436 sym
9437 }
9438 _ => {
9439 return Err(ParseError {
9440 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
9441 span: self.current_span(),
9442 });
9443 }
9444 };
9445
9446 Ok(Stmt::AwaitMessage { source, into })
9447 }
9448
9449 fn parse_merge_statement(&mut self) -> ParseResult<Stmt<'a>> {
9455 self.advance(); let source = self.parse_imperative_expr()?;
9459
9460 if !self.check_word("into") {
9462 return Err(ParseError {
9463 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
9464 span: self.current_span(),
9465 });
9466 }
9467 self.advance(); let target = self.parse_imperative_expr()?;
9471
9472 Ok(Stmt::MergeCrdt { source, target })
9473 }
9474
9475 fn parse_increase_statement(&mut self) -> ParseResult<Stmt<'a>> {
9477 self.advance(); let expr = self.parse_imperative_expr()?;
9481
9482 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
9484 (object, field)
9485 } else {
9486 return Err(ParseError {
9487 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
9488 span: self.current_span(),
9489 });
9490 };
9491
9492 if !self.check_preposition_is("by") {
9494 return Err(ParseError {
9495 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
9496 span: self.current_span(),
9497 });
9498 }
9499 self.advance(); let amount = self.parse_imperative_expr()?;
9503
9504 Ok(Stmt::IncreaseCrdt { object, field: *field, amount })
9505 }
9506
9507 fn parse_decrease_statement(&mut self) -> ParseResult<Stmt<'a>> {
9509 self.advance(); let expr = self.parse_imperative_expr()?;
9513
9514 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
9516 (object, field)
9517 } else {
9518 return Err(ParseError {
9519 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
9520 span: self.current_span(),
9521 });
9522 };
9523
9524 if !self.check_preposition_is("by") {
9526 return Err(ParseError {
9527 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
9528 span: self.current_span(),
9529 });
9530 }
9531 self.advance(); let amount = self.parse_imperative_expr()?;
9535
9536 Ok(Stmt::DecreaseCrdt { object, field: *field, amount })
9537 }
9538
9539 fn parse_append_statement(&mut self) -> ParseResult<Stmt<'a>> {
9541 self.advance(); let value = self.parse_imperative_expr()?;
9545
9546 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
9548 return Err(ParseError {
9549 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9550 span: self.current_span(),
9551 });
9552 }
9553 self.advance(); let sequence = self.parse_imperative_expr()?;
9557
9558 Ok(Stmt::AppendToSequence { sequence, value })
9559 }
9560
9561 fn parse_resolve_statement(&mut self) -> ParseResult<Stmt<'a>> {
9563 self.advance(); let expr = self.parse_imperative_expr()?;
9567
9568 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
9570 (object, field)
9571 } else {
9572 return Err(ParseError {
9573 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's title')".to_string() },
9574 span: self.current_span(),
9575 });
9576 };
9577
9578 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
9580 return Err(ParseError {
9581 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9582 span: self.current_span(),
9583 });
9584 }
9585 self.advance(); let value = self.parse_imperative_expr()?;
9589
9590 Ok(Stmt::ResolveConflict { object, field: *field, value })
9591 }
9592
9593}
9594