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>> {
434 use noun::NounParsing;
435
436 if self.check_word("fn") {
438 if let Some(next) = self.tokens.get(self.current + 1) {
439 if matches!(next.kind, TokenType::LParen) {
440 self.advance(); self.advance(); let mut inputs = Vec::new();
445 if !self.check(&TokenType::RParen) {
446 inputs.push(self.parse_type_expression()?);
447 while self.check(&TokenType::Comma) {
448 self.advance(); inputs.push(self.parse_type_expression()?);
450 }
451 }
452
453 if !self.check(&TokenType::RParen) {
454 return Err(ParseError {
455 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
456 span: self.current_span(),
457 });
458 }
459 self.advance(); if !self.check(&TokenType::Arrow) {
463 return Err(ParseError {
464 kind: ParseErrorKind::ExpectedKeyword { keyword: "->".to_string() },
465 span: self.current_span(),
466 });
467 }
468 self.advance(); let output = self.parse_type_expression()?;
471 let output_ref = self.ctx.alloc_type_expr(output);
472 let inputs_ref = self.ctx.alloc_type_exprs(inputs);
473 return Ok(TypeExpr::Function { inputs: inputs_ref, output: output_ref });
474 }
475 }
476 }
477
478 if self.check(&TokenType::LParen) {
480 self.advance(); let inner = self.parse_type_expression()?;
482 if !self.check(&TokenType::RParen) {
483 return Err(ParseError {
484 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
485 span: self.current_span(),
486 });
487 }
488 self.advance(); return Ok(inner);
490 }
491
492 if self.check(&TokenType::Persistent) {
494 self.advance(); let inner = self.parse_type_expression()?;
496 let inner_ref = self.ctx.alloc_type_expr(inner);
497 return Ok(TypeExpr::Persistent { inner: inner_ref });
498 }
499
500 let mut base = self.consume_type_name()?;
502
503 let base_name = self.interner.resolve(base);
505 if base_name == "SharedSet" || base_name == "ORSet" {
506 if self.check(&TokenType::LParen) {
507 self.advance(); if self.check(&TokenType::RemoveWins) {
509 self.advance(); base = self.interner.intern("SharedSet_RemoveWins");
511 } else if self.check(&TokenType::AddWins) {
512 self.advance(); base = self.interner.intern("SharedSet_AddWins");
515 }
516 if !self.check(&TokenType::RParen) {
517 return Err(ParseError {
518 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
519 span: self.current_span(),
520 });
521 }
522 self.advance(); }
524 }
525
526 let base_name = self.interner.resolve(base);
528 if base_name == "SharedSequence" || base_name == "RGA" {
529 if self.check(&TokenType::LParen) {
530 self.advance(); if self.check(&TokenType::YATA) {
532 self.advance(); base = self.interner.intern("SharedSequence_YATA");
534 }
535 if !self.check(&TokenType::RParen) {
536 return Err(ParseError {
537 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
538 span: self.current_span(),
539 });
540 }
541 self.advance(); }
543 }
544
545 let base_type = if self.check(&TokenType::From) {
547 self.advance(); let module_name = self.consume_type_name()?;
549 let module_str = self.interner.resolve(module_name);
550 let base_str = self.interner.resolve(base);
551 let qualified = format!("{}::{}", module_str, base_str);
552 let qualified_sym = self.interner.intern(&qualified);
553 TypeExpr::Named(qualified_sym)
554 } else {
555 let base_name = self.interner.resolve(base);
557 let param_count = self.get_generic_param_count(base)
558 .or_else(|| match base_name {
559 "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),
569 "SharedSequence" | "RGA" | "SharedSequence_YATA" | "CollaborativeSequence" => Some(1),
570 "SharedMap" | "ORMap" => Some(2), "Divergent" | "MVRegister" => Some(1), _ => None,
573 });
574
575 if let Some(count) = param_count {
577 if self.check_of_preposition() || self.check_preposition_is("from") {
578 self.advance(); let mut params = Vec::new();
581 for i in 0..count {
582 if i > 0 {
583 if self.check(&TokenType::And) || self.check_to_preposition() || self.check(&TokenType::Comma) {
585 self.advance();
586 }
587 }
588 let param = self.parse_type_expression()?;
589 params.push(param);
590 }
591
592 let params_slice = self.ctx.alloc_type_exprs(params);
593 TypeExpr::Generic { base, params: params_slice }
594 } else {
595 let is_primitive = self.type_registry.as_ref().map(|r| r.is_type(base)).unwrap_or(false)
597 || matches!(base_name, "Int" | "Nat" | "Text" | "Bool" | "Boolean" | "Real" | "Unit");
598 if is_primitive {
599 TypeExpr::Primitive(base)
600 } else {
601 TypeExpr::Named(base)
602 }
603 }
604 } else {
605 let is_primitive = self.type_registry.as_ref().map(|r| r.is_type(base)).unwrap_or(false)
607 || matches!(base_name, "Int" | "Nat" | "Text" | "Bool" | "Boolean" | "Real" | "Unit");
608 if is_primitive {
609 TypeExpr::Primitive(base)
610 } else {
611 TypeExpr::Named(base)
613 }
614 }
615 };
616
617 if self.check(&TokenType::Where) {
619 self.advance(); let predicate_expr = self.parse_condition()?;
623
624 let bound_var = self.extract_bound_var(&predicate_expr)
626 .unwrap_or_else(|| self.interner.intern("it"));
627
628 let predicate = self.expr_to_logic_predicate(&predicate_expr, bound_var)
630 .ok_or_else(|| ParseError {
631 kind: ParseErrorKind::InvalidRefinementPredicate,
632 span: self.peek().span,
633 })?;
634
635 let base_alloc = self.ctx.alloc_type_expr(base_type);
637
638 return Ok(TypeExpr::Refinement { base: base_alloc, var: bound_var, predicate });
639 }
640
641 Ok(base_type)
642 }
643
644 fn extract_bound_var(&self, expr: &Expr<'a>) -> Option<Symbol> {
646 match expr {
647 Expr::Identifier(sym) => Some(*sym),
648 Expr::BinaryOp { left, .. } => self.extract_bound_var(left),
649 _ => None,
650 }
651 }
652
653 fn expr_to_logic_predicate(&mut self, expr: &Expr<'a>, bound_var: Symbol) -> Option<&'a LogicExpr<'a>> {
656 match expr {
657 Expr::BinaryOp { op, left, right } => {
658 let pred_name = match op {
660 BinaryOpKind::Gt => "Greater",
661 BinaryOpKind::Lt => "Less",
662 BinaryOpKind::GtEq => "GreaterEqual",
663 BinaryOpKind::LtEq => "LessEqual",
664 BinaryOpKind::Eq => "Equal",
665 BinaryOpKind::NotEq => "NotEqual",
666 BinaryOpKind::And => {
667 let left_logic = self.expr_to_logic_predicate(left, bound_var)?;
669 let right_logic = self.expr_to_logic_predicate(right, bound_var)?;
670 return Some(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
671 left: left_logic,
672 op: TokenType::And,
673 right: right_logic,
674 }));
675 }
676 BinaryOpKind::Or => {
677 let left_logic = self.expr_to_logic_predicate(left, bound_var)?;
678 let right_logic = self.expr_to_logic_predicate(right, bound_var)?;
679 return Some(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
680 left: left_logic,
681 op: TokenType::Or,
682 right: right_logic,
683 }));
684 }
685 _ => return None, };
687 let pred_sym = self.interner.intern(pred_name);
688
689 let left_term = self.expr_to_term(left)?;
691 let right_term = self.expr_to_term(right)?;
692
693 let args = self.ctx.terms.alloc_slice([left_term, right_term]);
694 Some(self.ctx.exprs.alloc(LogicExpr::Predicate { name: pred_sym, args, world: None }))
695 }
696 _ => None,
697 }
698 }
699
700 fn expr_to_term(&mut self, expr: &Expr<'a>) -> Option<Term<'a>> {
702 match expr {
703 Expr::Identifier(sym) => Some(Term::Variable(*sym)),
704 Expr::Literal(lit) => {
705 match lit {
706 Literal::Number(n) => Some(Term::Value {
707 kind: NumberKind::Integer(*n),
708 unit: None,
709 dimension: None,
710 }),
711 Literal::Boolean(b) => {
712 let sym = self.interner.intern(if *b { "true" } else { "false" });
713 Some(Term::Constant(sym))
714 }
715 _ => None, }
717 }
718 _ => None,
719 }
720 }
721
722 pub fn process_block_headers(&mut self) {
723 use crate::token::BlockType;
724
725 while self.current < self.tokens.len() {
726 if let TokenType::BlockHeader { block_type } = &self.tokens[self.current].kind {
727 self.mode = match block_type {
728 BlockType::Main | BlockType::Function => ParserMode::Imperative,
729 BlockType::Theorem | BlockType::Definition | BlockType::Proof |
730 BlockType::Example | BlockType::Logic | BlockType::Note | BlockType::TypeDef |
731 BlockType::Policy | BlockType::Requires => ParserMode::Declarative,
732 };
733 self.current += 1;
734 } else {
735 break;
736 }
737 }
738 }
739
740 pub fn get_event_var(&mut self) -> Symbol {
741 self.discourse_event_var.unwrap_or_else(|| self.interner.intern("e"))
742 }
743
744 pub fn capture_event_template(&mut self, verb: Symbol, roles: &[(ThematicRole, Term<'a>)], modifiers: &[Symbol]) {
745 let non_agent_roles: Vec<_> = roles.iter()
746 .filter(|(role, _)| *role != ThematicRole::Agent)
747 .cloned()
748 .collect();
749 self.last_event_template = Some(EventTemplate {
750 verb,
751 non_agent_roles,
752 modifiers: modifiers.to_vec(),
753 });
754 }
755
756 fn parse_embedded_wh_clause(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
757 let var_name = self.interner.intern("x");
759 let var_term = Term::Variable(var_name);
760
761 if self.check_verb() {
762 let verb = self.consume_verb();
764 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
765 name: verb,
766 args: self.ctx.terms.alloc_slice([var_term]),
767 world: None,
768 });
769 return Ok(body);
770 }
771
772 if self.check_content_word() || self.check_article() {
773 let subject = self.parse_noun_phrase(true)?;
775 if self.check_verb() {
776 let verb = self.consume_verb();
777 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
778 name: verb,
779 args: self.ctx.terms.alloc_slice([
780 Term::Constant(subject.noun),
781 var_term,
782 ]),
783 world: None,
784 });
785 return Ok(body);
786 }
787 }
788
789 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(var_name)))
791 }
792
793 pub fn set_pp_attachment_mode(&mut self, attach_to_noun: bool) {
794 self.pp_attach_to_noun = attach_to_noun;
795 }
796
797 pub fn set_noun_priority_mode(&mut self, mode: bool) {
798 self.noun_priority_mode = mode;
799 }
800
801 pub fn set_collective_mode(&mut self, mode: bool) {
802 self.collective_mode = mode;
803 }
804
805 pub fn set_event_reading_mode(&mut self, mode: bool) {
806 self.event_reading_mode = mode;
807 }
808
809 pub fn set_negative_scope_mode(&mut self, mode: NegativeScopeMode) {
810 self.negative_scope_mode = mode;
811 }
812
813 pub fn set_modal_preference(&mut self, pref: ModalPreference) {
814 self.modal_preference = pref;
815 }
816
817 fn checkpoint(&self) -> ParserCheckpoint {
818 ParserCheckpoint {
819 pos: self.current,
820 var_counter: self.var_counter,
821 bindings_len: self.donkey_bindings.len(),
822 island: self.current_island,
823 time: self.pending_time,
824 negative_depth: self.negative_depth,
825 }
826 }
827
828 fn restore(&mut self, cp: ParserCheckpoint) {
829 self.current = cp.pos;
830 self.var_counter = cp.var_counter;
831 self.donkey_bindings.truncate(cp.bindings_len);
832 self.current_island = cp.island;
833 self.pending_time = cp.time;
834 self.negative_depth = cp.negative_depth;
835 }
836
837 fn is_negative_context(&self) -> bool {
838 self.negative_depth % 2 == 1
839 }
840
841 pub fn guard(&mut self) -> ParserGuard<'_, 'a, 'ctx, 'int> {
842 ParserGuard {
843 checkpoint: self.checkpoint(),
844 parser: self,
845 committed: false,
846 }
847 }
848
849 pub(super) fn try_parse<F, T>(&mut self, op: F) -> Option<T>
850 where
851 F: FnOnce(&mut Self) -> ParseResult<T>,
852 {
853 let cp = self.checkpoint();
854 match op(self) {
855 Ok(res) => Some(res),
856 Err(_) => {
857 self.restore(cp);
858 None
859 }
860 }
861 }
862
863 fn resolve_pronoun(&mut self, gender: Gender, number: Number) -> ParseResult<ResolvedPronoun> {
864 if self.world_state.in_discourse_mode() && self.world_state.has_prior_modal_context() {
869 if let Some(candidate) = self.world_state.resolve_via_telescope(gender) {
872 return Ok(ResolvedPronoun::Variable(candidate.variable));
873 }
874 let blocked_candidates: Vec<_> = self.world_state.telescope_candidates()
878 .iter()
879 .filter(|c| c.in_modal_scope)
880 .collect();
881 if !blocked_candidates.is_empty() {
882 let has_upcoming_modal = self.has_modal_subordination_ahead();
885 if has_upcoming_modal {
886 if let Some(candidate) = blocked_candidates.into_iter().find(|c| {
888 c.gender == gender || gender == Gender::Unknown || c.gender == Gender::Unknown
889 }) {
890 return Ok(ResolvedPronoun::Variable(candidate.variable));
891 }
892 }
893 return Err(ParseError {
895 kind: ParseErrorKind::ScopeViolation(
896 "Cannot access hypothetical entity from reality. Use modal subordination (e.g., 'would') to continue a hypothetical context.".to_string()
897 ),
898 span: self.current_span(),
899 });
900 }
901 }
903
904 let current_box = self.drs.current_box_index();
906 match self.drs.resolve_pronoun(current_box, gender, number) {
907 Ok(sym) => return Ok(ResolvedPronoun::Variable(sym)),
908 Err(crate::drs::ScopeError::InaccessibleReferent { gender: g, reason, .. }) => {
909 if self.world_state.in_discourse_mode() {
913 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
914 return Ok(ResolvedPronoun::Variable(candidate.variable));
915 }
916 }
917 return Err(ParseError {
919 kind: ParseErrorKind::ScopeViolation(reason),
920 span: self.current_span(),
921 });
922 }
923 Err(crate::drs::ScopeError::NoMatchingReferent { gender: g, number: n }) => {
924 if !self.world_state.has_prior_modal_context() {
926 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
927 return Ok(ResolvedPronoun::Variable(candidate.variable));
928 }
929 }
930
931 if self.world_state.in_discourse_mode() {
933 return Err(ParseError {
934 kind: ParseErrorKind::UnresolvedPronoun {
935 gender: g,
936 number: n,
937 },
938 span: self.current_span(),
939 });
940 }
941
942 let deictic_name = match (g, n) {
945 (Gender::Male, Number::Singular) => "Him",
946 (Gender::Female, Number::Singular) => "Her",
947 (Gender::Neuter, Number::Singular) => "It",
948 (Gender::Male, Number::Plural) | (Gender::Female, Number::Plural) => "Them",
949 (Gender::Neuter, Number::Plural) => "Them",
950 (Gender::Unknown, _) => "Someone",
951 };
952 let sym = self.interner.intern(deictic_name);
953 self.drs.introduce_referent(sym, sym, g, n);
955 return Ok(ResolvedPronoun::Constant(sym));
956 }
957 }
958 }
959
960 fn resolve_donkey_pronoun(&mut self, gender: Gender) -> Option<Symbol> {
961 for (noun_class, var_name, used, _wide_neg) in self.donkey_bindings.iter_mut().rev() {
962 let noun_str = self.interner.resolve(*noun_class);
963 let noun_gender = Self::infer_noun_gender(noun_str);
964 if noun_gender == gender || gender == Gender::Neuter || noun_gender == Gender::Unknown {
965 *used = true; return Some(*var_name);
967 }
968 }
969 None
970 }
971
972 fn infer_noun_gender(noun: &str) -> Gender {
973 let lower = noun.to_lowercase();
974 if lexicon::is_female_noun(&lower) {
975 Gender::Female
976 } else if lexicon::is_male_noun(&lower) {
977 Gender::Male
978 } else if lexicon::is_neuter_noun(&lower) {
979 Gender::Neuter
980 } else {
981 Gender::Unknown
982 }
983 }
984
985 fn is_plural_noun(noun: &str) -> bool {
986 let lower = noun.to_lowercase();
987 if lexicon::is_proper_name(&lower) {
989 return false;
990 }
991 if lexicon::is_irregular_plural(&lower) {
992 return true;
993 }
994 lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2
995 }
996
997 fn singularize_noun(noun: &str) -> String {
998 let lower = noun.to_lowercase();
999 if let Some(singular) = lexicon::singularize(&lower) {
1000 return singular.to_string();
1001 }
1002 if lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2 {
1003 let base = &lower[..lower.len() - 1];
1004 let mut chars: Vec<char> = base.chars().collect();
1005 if !chars.is_empty() {
1006 chars[0] = chars[0].to_uppercase().next().unwrap();
1007 }
1008 return chars.into_iter().collect();
1009 }
1010 let mut chars: Vec<char> = lower.chars().collect();
1011 if !chars.is_empty() {
1012 chars[0] = chars[0].to_uppercase().next().unwrap();
1013 }
1014 chars.into_iter().collect()
1015 }
1016
1017 fn infer_gender(name: &str) -> Gender {
1018 let lower = name.to_lowercase();
1019 if lexicon::is_male_name(&lower) {
1020 Gender::Male
1021 } else if lexicon::is_female_name(&lower) {
1022 Gender::Female
1023 } else {
1024 Gender::Unknown
1025 }
1026 }
1027
1028
1029 fn next_var_name(&mut self) -> Symbol {
1030 const VARS: &[&str] = &["x", "y", "z", "w", "v", "u"];
1031 let idx = self.var_counter;
1032 self.var_counter += 1;
1033 if idx < VARS.len() {
1034 self.interner.intern(VARS[idx])
1035 } else {
1036 let name = format!("x{}", idx - VARS.len() + 1);
1037 self.interner.intern(&name)
1038 }
1039 }
1040
1041 pub fn parse(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
1058 let mut result = self.parse_sentence()?;
1059
1060 while self.check(&TokenType::Period) || self.check(&TokenType::Exclamation) {
1063 self.advance(); if !self.is_at_end() {
1065 let next = self.parse_sentence()?;
1066 result = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1067 left: result,
1068 op: TokenType::And,
1069 right: next,
1070 });
1071 }
1072 }
1073
1074 Ok(result)
1075 }
1076
1077 pub fn parse_program(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
1095 let mut statements = Vec::new();
1096 let mut in_definition_block = false;
1097
1098 if self.mode == ParserMode::Declarative {
1100 }
1104
1105 while !self.is_at_end() {
1106 if let Some(Token { kind: TokenType::BlockHeader { block_type }, .. }) = self.tokens.get(self.current) {
1108 match block_type {
1109 BlockType::Definition => {
1110 in_definition_block = true;
1111 self.mode = ParserMode::Declarative;
1112 self.advance();
1113 continue;
1114 }
1115 BlockType::Main => {
1116 in_definition_block = false;
1117 self.mode = ParserMode::Imperative;
1118 self.advance();
1119 continue;
1120 }
1121 BlockType::Function => {
1122 in_definition_block = false;
1123 self.mode = ParserMode::Imperative;
1124 self.advance();
1125 let func_def = self.parse_function_def()?;
1127 statements.push(func_def);
1128 continue;
1129 }
1130 BlockType::TypeDef => {
1131 self.advance();
1134 self.skip_type_def_content();
1135 continue;
1136 }
1137 BlockType::Policy => {
1138 in_definition_block = true; self.mode = ParserMode::Declarative;
1142 self.advance();
1143 continue;
1144 }
1145 BlockType::Theorem => {
1146 in_definition_block = false;
1148 self.mode = ParserMode::Declarative;
1149 self.advance();
1150 let theorem = self.parse_theorem_block()?;
1151 statements.push(theorem);
1152 continue;
1153 }
1154 BlockType::Requires => {
1155 in_definition_block = false;
1156 self.mode = ParserMode::Declarative;
1157 self.advance();
1158 let deps = self.parse_requires_block()?;
1159 statements.extend(deps);
1160 continue;
1161 }
1162 _ => {
1163 in_definition_block = false;
1165 self.mode = ParserMode::Declarative;
1166 self.advance();
1167 continue;
1168 }
1169 }
1170 }
1171
1172 if in_definition_block {
1174 self.advance();
1175 continue;
1176 }
1177
1178 if self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) || self.check(&TokenType::Newline) {
1180 self.advance();
1181 continue;
1182 }
1183
1184 if self.mode == ParserMode::Imperative {
1186 let stmt = self.parse_statement()?;
1187 statements.push(stmt);
1188
1189 if self.check(&TokenType::Period) {
1190 self.advance();
1191 }
1192 } else {
1193 self.advance();
1195 }
1196 }
1197
1198 Ok(statements)
1199 }
1200
1201 fn parse_statement(&mut self) -> ParseResult<Stmt<'a>> {
1202 if self.check(&TokenType::To) || self.check_preposition_is("to") {
1205 return self.parse_function_def();
1206 }
1207 if self.check(&TokenType::Let) {
1208 return self.parse_let_statement();
1209 }
1210 if self.check(&TokenType::Mut) {
1213 return self.parse_equals_assignment(true);
1214 }
1215 if self.peek_equals_assignment() {
1218 return self.parse_equals_assignment(false);
1219 }
1220 if self.check(&TokenType::Set) {
1221 return self.parse_set_statement();
1222 }
1223 if self.check(&TokenType::Return) {
1224 return self.parse_return_statement();
1225 }
1226 if self.check(&TokenType::If) {
1227 return self.parse_if_statement();
1228 }
1229 if self.check(&TokenType::Assert) {
1230 return self.parse_assert_statement();
1231 }
1232 if self.check(&TokenType::Trust) {
1234 return self.parse_trust_statement();
1235 }
1236 if self.check(&TokenType::Check) {
1238 return self.parse_check_statement();
1239 }
1240 if self.check(&TokenType::Listen) {
1242 return self.parse_listen_statement();
1243 }
1244 if self.check(&TokenType::NetConnect) {
1245 return self.parse_connect_statement();
1246 }
1247 if self.check(&TokenType::Sleep) {
1248 return self.parse_sleep_statement();
1249 }
1250 if self.check(&TokenType::Sync) {
1252 return self.parse_sync_statement();
1253 }
1254 if self.check(&TokenType::Mount) {
1256 return self.parse_mount_statement();
1257 }
1258 if self.check(&TokenType::While) {
1259 return self.parse_while_statement();
1260 }
1261 if self.check(&TokenType::Repeat) {
1262 return self.parse_repeat_statement();
1263 }
1264 if self.check(&TokenType::For) {
1266 return self.parse_for_statement();
1267 }
1268 if self.check(&TokenType::Call) {
1269 return self.parse_call_statement();
1270 }
1271 if self.check(&TokenType::Give) {
1272 return self.parse_give_statement();
1273 }
1274 if self.check(&TokenType::Show) {
1275 return self.parse_show_statement();
1276 }
1277 if self.check(&TokenType::Inspect) {
1279 return self.parse_inspect_statement();
1280 }
1281
1282 if self.check(&TokenType::Push) {
1284 return self.parse_push_statement();
1285 }
1286 if self.check(&TokenType::Pop) {
1287 return self.parse_pop_statement();
1288 }
1289 if self.check(&TokenType::Add) {
1291 return self.parse_add_statement();
1292 }
1293 if self.check(&TokenType::Remove) {
1294 return self.parse_remove_statement();
1295 }
1296
1297 if self.check(&TokenType::Inside) {
1299 return self.parse_zone_statement();
1300 }
1301
1302 if self.check(&TokenType::Attempt) {
1304 return self.parse_concurrent_block();
1305 }
1306 if self.check(&TokenType::Simultaneously) {
1307 return self.parse_parallel_block();
1308 }
1309
1310 if self.check(&TokenType::Read) {
1312 return self.parse_read_statement();
1313 }
1314 if self.check(&TokenType::Write) {
1315 return self.parse_write_statement();
1316 }
1317
1318 if self.check(&TokenType::Spawn) {
1320 return self.parse_spawn_statement();
1321 }
1322 if self.check(&TokenType::Send) {
1323 if self.lookahead_contains_into() {
1325 return self.parse_send_pipe_statement();
1326 }
1327 return self.parse_send_statement();
1328 }
1329 if self.check(&TokenType::Await) {
1330 if self.lookahead_is_first_of() {
1332 return self.parse_select_statement();
1333 }
1334 return self.parse_await_statement();
1335 }
1336
1337 if self.check(&TokenType::Merge) {
1339 return self.parse_merge_statement();
1340 }
1341 if self.check(&TokenType::Increase) {
1342 return self.parse_increase_statement();
1343 }
1344 if self.check(&TokenType::Decrease) {
1346 return self.parse_decrease_statement();
1347 }
1348 if self.check(&TokenType::Append) {
1349 return self.parse_append_statement();
1350 }
1351 if self.check(&TokenType::Resolve) {
1352 return self.parse_resolve_statement();
1353 }
1354
1355 if self.check(&TokenType::Launch) {
1357 return self.parse_launch_statement();
1358 }
1359 if self.check(&TokenType::Stop) {
1360 return self.parse_stop_statement();
1361 }
1362 if self.check(&TokenType::Try) {
1363 return self.parse_try_statement();
1364 }
1365 if self.check(&TokenType::Receive) {
1366 return self.parse_receive_pipe_statement();
1367 }
1368
1369 if self.check(&TokenType::Escape) {
1371 return self.parse_escape_statement();
1372 }
1373
1374 if self.tokens.get(self.current + 1)
1378 .map(|t| matches!(t.kind, TokenType::LParen))
1379 .unwrap_or(false)
1380 {
1381 let function = self.peek().lexeme;
1383 self.advance(); let expr = self.parse_call_expr(function)?;
1387 if let Expr::Call { function, args } = expr {
1388 return Ok(Stmt::Call { function: *function, args: args.clone() });
1389 }
1390 }
1391
1392 Err(ParseError {
1393 kind: ParseErrorKind::ExpectedStatement,
1394 span: self.current_span(),
1395 })
1396 }
1397
1398 fn parse_if_statement(&mut self) -> ParseResult<Stmt<'a>> {
1399 self.advance(); let cond = self.parse_condition()?;
1403
1404 if self.check(&TokenType::Then) {
1406 self.advance();
1407 }
1408
1409 if !self.check(&TokenType::Colon) {
1411 return Err(ParseError {
1412 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1413 span: self.current_span(),
1414 });
1415 }
1416 self.advance(); if !self.check(&TokenType::Indent) {
1420 return Err(ParseError {
1421 kind: ParseErrorKind::ExpectedStatement,
1422 span: self.current_span(),
1423 });
1424 }
1425 self.advance(); let mut then_stmts = Vec::new();
1429 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1430 let stmt = self.parse_statement()?;
1431 then_stmts.push(stmt);
1432 if self.check(&TokenType::Period) {
1433 self.advance();
1434 }
1435 }
1436
1437 if self.check(&TokenType::Dedent) {
1439 self.advance();
1440 }
1441
1442 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1444 .alloc_slice(then_stmts.into_iter());
1445
1446 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1448 self.advance(); if self.check(&TokenType::If) {
1452 let nested_if = self.parse_if_statement()?;
1454 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1455 .alloc_slice(std::iter::once(nested_if));
1456 Some(nested_slice)
1457 } else {
1458 if !self.check(&TokenType::Colon) {
1460 return Err(ParseError {
1461 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1462 span: self.current_span(),
1463 });
1464 }
1465 self.advance(); if !self.check(&TokenType::Indent) {
1468 return Err(ParseError {
1469 kind: ParseErrorKind::ExpectedStatement,
1470 span: self.current_span(),
1471 });
1472 }
1473 self.advance(); let mut else_stmts = Vec::new();
1476 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1477 let stmt = self.parse_statement()?;
1478 else_stmts.push(stmt);
1479 if self.check(&TokenType::Period) {
1480 self.advance();
1481 }
1482 }
1483
1484 if self.check(&TokenType::Dedent) {
1485 self.advance();
1486 }
1487
1488 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1489 .alloc_slice(else_stmts.into_iter()))
1490 }
1491 } else if self.check(&TokenType::Elif) {
1492 self.advance(); let nested_if = self.parse_elif_as_if()?;
1496 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1497 .alloc_slice(std::iter::once(nested_if));
1498 Some(nested_slice)
1499 } else {
1500 None
1501 };
1502
1503 Ok(Stmt::If {
1504 cond,
1505 then_block,
1506 else_block,
1507 })
1508 }
1509
1510 fn parse_elif_as_if(&mut self) -> ParseResult<Stmt<'a>> {
1513 let cond = self.parse_condition()?;
1515
1516 if !self.check(&TokenType::Colon) {
1518 return Err(ParseError {
1519 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1520 span: self.current_span(),
1521 });
1522 }
1523 self.advance(); if !self.check(&TokenType::Indent) {
1527 return Err(ParseError {
1528 kind: ParseErrorKind::ExpectedStatement,
1529 span: self.current_span(),
1530 });
1531 }
1532 self.advance(); let mut then_stmts = Vec::new();
1536 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1537 let stmt = self.parse_statement()?;
1538 then_stmts.push(stmt);
1539 if self.check(&TokenType::Period) {
1540 self.advance();
1541 }
1542 }
1543
1544 if self.check(&TokenType::Dedent) {
1546 self.advance();
1547 }
1548
1549 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1551 .alloc_slice(then_stmts.into_iter());
1552
1553 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1555 self.advance(); if self.check(&TokenType::If) {
1559 let nested_if = self.parse_if_statement()?;
1560 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1561 .alloc_slice(std::iter::once(nested_if));
1562 Some(nested_slice)
1563 } else {
1564 if !self.check(&TokenType::Colon) {
1566 return Err(ParseError {
1567 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1568 span: self.current_span(),
1569 });
1570 }
1571 self.advance(); if !self.check(&TokenType::Indent) {
1574 return Err(ParseError {
1575 kind: ParseErrorKind::ExpectedStatement,
1576 span: self.current_span(),
1577 });
1578 }
1579 self.advance(); let mut else_stmts = Vec::new();
1582 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1583 let stmt = self.parse_statement()?;
1584 else_stmts.push(stmt);
1585 if self.check(&TokenType::Period) {
1586 self.advance();
1587 }
1588 }
1589
1590 if self.check(&TokenType::Dedent) {
1591 self.advance();
1592 }
1593
1594 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1595 .alloc_slice(else_stmts.into_iter()))
1596 }
1597 } else if self.check(&TokenType::Elif) {
1598 self.advance(); let nested_if = self.parse_elif_as_if()?;
1600 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1601 .alloc_slice(std::iter::once(nested_if));
1602 Some(nested_slice)
1603 } else {
1604 None
1605 };
1606
1607 Ok(Stmt::If {
1608 cond,
1609 then_block,
1610 else_block,
1611 })
1612 }
1613
1614 fn parse_while_statement(&mut self) -> ParseResult<Stmt<'a>> {
1615 self.advance(); let cond = self.parse_condition()?;
1618
1619 let decreasing = if self.check(&TokenType::LParen) {
1621 self.advance(); if !self.check_word("decreasing") {
1625 return Err(ParseError {
1626 kind: ParseErrorKind::ExpectedKeyword { keyword: "decreasing".to_string() },
1627 span: self.current_span(),
1628 });
1629 }
1630 self.advance(); let variant = self.parse_imperative_expr()?;
1633
1634 if !self.check(&TokenType::RParen) {
1635 return Err(ParseError {
1636 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1637 span: self.current_span(),
1638 });
1639 }
1640 self.advance(); Some(variant)
1643 } else {
1644 None
1645 };
1646
1647 if !self.check(&TokenType::Colon) {
1648 return Err(ParseError {
1649 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1650 span: self.current_span(),
1651 });
1652 }
1653 self.advance(); if !self.check(&TokenType::Indent) {
1656 return Err(ParseError {
1657 kind: ParseErrorKind::ExpectedStatement,
1658 span: self.current_span(),
1659 });
1660 }
1661 self.advance(); let mut body_stmts = Vec::new();
1664 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1665 let stmt = self.parse_statement()?;
1666 body_stmts.push(stmt);
1667 if self.check(&TokenType::Period) {
1668 self.advance();
1669 }
1670 }
1671
1672 if self.check(&TokenType::Dedent) {
1673 self.advance();
1674 }
1675
1676 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1677 .alloc_slice(body_stmts.into_iter());
1678
1679 Ok(Stmt::While { cond, body, decreasing })
1680 }
1681
1682 fn parse_loop_pattern(&mut self) -> ParseResult<Pattern> {
1685 use crate::ast::stmt::Pattern;
1686
1687 if self.check(&TokenType::LParen) {
1689 self.advance(); let mut identifiers = Vec::new();
1692 loop {
1693 let id = self.expect_identifier()?;
1694 identifiers.push(id);
1695
1696 if self.check(&TokenType::Comma) {
1698 self.advance(); continue;
1700 }
1701 break;
1702 }
1703
1704 if !self.check(&TokenType::RParen) {
1706 return Err(ParseError {
1707 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1708 span: self.current_span(),
1709 });
1710 }
1711 self.advance(); Ok(Pattern::Tuple(identifiers))
1714 } else {
1715 let id = self.expect_identifier()?;
1717 Ok(Pattern::Identifier(id))
1718 }
1719 }
1720
1721 fn parse_repeat_statement(&mut self) -> ParseResult<Stmt<'a>> {
1722 self.advance(); if self.check(&TokenType::For) {
1726 self.advance();
1727 }
1728
1729 let pattern = self.parse_loop_pattern()?;
1731
1732 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1734 self.advance(); let start = self.parse_imperative_expr()?;
1736
1737 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1739 return Err(ParseError {
1740 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1741 span: self.current_span(),
1742 });
1743 }
1744 self.advance();
1745
1746 let end = self.parse_imperative_expr()?;
1747 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1748 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1749 self.advance(); self.parse_imperative_expr()?
1751 } else {
1752 return Err(ParseError {
1753 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1754 span: self.current_span(),
1755 });
1756 };
1757
1758 if !self.check(&TokenType::Colon) {
1760 return Err(ParseError {
1761 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1762 span: self.current_span(),
1763 });
1764 }
1765 self.advance();
1766
1767 if !self.check(&TokenType::Indent) {
1769 return Err(ParseError {
1770 kind: ParseErrorKind::ExpectedStatement,
1771 span: self.current_span(),
1772 });
1773 }
1774 self.advance();
1775
1776 let mut body_stmts = Vec::new();
1778 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1779 let stmt = self.parse_statement()?;
1780 body_stmts.push(stmt);
1781 if self.check(&TokenType::Period) {
1782 self.advance();
1783 }
1784 }
1785
1786 if self.check(&TokenType::Dedent) {
1787 self.advance();
1788 }
1789
1790 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1791 .alloc_slice(body_stmts.into_iter());
1792
1793 Ok(Stmt::Repeat { pattern, iterable, body })
1794 }
1795
1796 fn parse_for_statement(&mut self) -> ParseResult<Stmt<'a>> {
1799 self.advance(); let pattern = self.parse_loop_pattern()?;
1803
1804 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1806 self.advance(); let start = self.parse_imperative_expr()?;
1808
1809 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1811 return Err(ParseError {
1812 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1813 span: self.current_span(),
1814 });
1815 }
1816 self.advance();
1817
1818 let end = self.parse_imperative_expr()?;
1819 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1820 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1821 self.advance(); self.parse_imperative_expr()?
1823 } else {
1824 return Err(ParseError {
1825 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1826 span: self.current_span(),
1827 });
1828 };
1829
1830 if !self.check(&TokenType::Colon) {
1832 return Err(ParseError {
1833 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1834 span: self.current_span(),
1835 });
1836 }
1837 self.advance();
1838
1839 if !self.check(&TokenType::Indent) {
1841 return Err(ParseError {
1842 kind: ParseErrorKind::ExpectedStatement,
1843 span: self.current_span(),
1844 });
1845 }
1846 self.advance();
1847
1848 let mut body_stmts = Vec::new();
1850 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1851 let stmt = self.parse_statement()?;
1852 body_stmts.push(stmt);
1853 if self.check(&TokenType::Period) {
1854 self.advance();
1855 }
1856 }
1857
1858 if self.check(&TokenType::Dedent) {
1859 self.advance();
1860 }
1861
1862 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1863 .alloc_slice(body_stmts.into_iter());
1864
1865 Ok(Stmt::Repeat { pattern, iterable, body })
1866 }
1867
1868 fn parse_call_statement(&mut self) -> ParseResult<Stmt<'a>> {
1869 self.advance(); let function = match &self.peek().kind {
1875 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
1876 let s = *sym;
1877 self.advance();
1878 s
1879 }
1880 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
1881 let s = self.peek().lexeme;
1883 self.advance();
1884 s
1885 }
1886 _ => {
1887 return Err(ParseError {
1888 kind: ParseErrorKind::ExpectedIdentifier,
1889 span: self.current_span(),
1890 });
1891 }
1892 };
1893
1894 let args = if self.check_preposition_is("with") {
1896 self.advance(); self.parse_call_arguments()?
1898 } else {
1899 Vec::new()
1900 };
1901
1902 Ok(Stmt::Call { function, args })
1903 }
1904
1905 fn parse_call_arguments(&mut self) -> ParseResult<Vec<&'a Expr<'a>>> {
1906 let mut args = Vec::new();
1907
1908 let arg = self.parse_call_arg()?;
1910 args.push(arg);
1911
1912 while self.check(&TokenType::And) || self.check(&TokenType::Comma) {
1914 self.advance(); let arg = self.parse_call_arg()?;
1916 args.push(arg);
1917 }
1918
1919 Ok(args)
1920 }
1921
1922 fn parse_call_arg(&mut self) -> ParseResult<&'a Expr<'a>> {
1923 if self.check(&TokenType::Give) {
1925 self.advance(); let value = self.parse_imperative_expr()?;
1927 return Ok(self.ctx.alloc_imperative_expr(Expr::Give { value }));
1928 }
1929
1930 self.parse_imperative_expr()
1932 }
1933
1934 fn parse_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1935 self.parse_or_condition()
1938 }
1939
1940 fn parse_or_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1942 let mut left = self.parse_and_condition()?;
1943
1944 while self.check(&TokenType::Or) || self.check_word("or") {
1945 self.advance();
1946 let right = self.parse_and_condition()?;
1947 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
1948 op: BinaryOpKind::Or,
1949 left,
1950 right,
1951 });
1952 }
1953
1954 Ok(left)
1955 }
1956
1957 fn parse_and_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1959 let mut left = self.parse_comparison()?;
1960
1961 while self.check(&TokenType::And) || self.check_word("and") {
1962 self.advance();
1963 let right = self.parse_comparison()?;
1964 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
1965 op: BinaryOpKind::And,
1966 left,
1967 right,
1968 });
1969 }
1970
1971 Ok(left)
1972 }
1973
1974 fn parse_comparison(&mut self) -> ParseResult<&'a Expr<'a>> {
1976 if self.check(&TokenType::Not) || self.check_word("not") {
1978 self.advance(); let operand = self.parse_comparison()?; return Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp {
1982 op: BinaryOpKind::Eq,
1983 left: operand,
1984 right: self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(false))),
1985 }));
1986 }
1987
1988 let left = self.parse_imperative_expr()?;
1989
1990 let op = if self.check(&TokenType::Equals) {
1992 self.advance();
1993 Some(BinaryOpKind::Eq)
1994 } else if self.check(&TokenType::Identity) {
1995 self.advance();
1997 Some(BinaryOpKind::Eq)
1998 } else if self.check_word("is") {
1999 let saved_pos = self.current;
2001 self.advance(); if self.check_word("greater") {
2004 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
2006 self.advance(); Some(BinaryOpKind::Gt)
2008 } else {
2009 self.current = saved_pos;
2010 None
2011 }
2012 } else if self.check_word("less") {
2013 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
2015 self.advance(); Some(BinaryOpKind::Lt)
2017 } else {
2018 self.current = saved_pos;
2019 None
2020 }
2021 } else if self.check_word("at") {
2022 self.advance(); if self.check_word("least") {
2024 self.advance(); Some(BinaryOpKind::GtEq)
2026 } else if self.check_word("most") {
2027 self.advance(); Some(BinaryOpKind::LtEq)
2029 } else {
2030 self.current = saved_pos;
2031 None
2032 }
2033 } else if self.check_word("not") || self.check(&TokenType::Not) {
2034 self.advance(); Some(BinaryOpKind::NotEq)
2037 } else if self.check_word("equal") {
2038 self.advance(); if self.check_preposition_is("to") {
2041 self.advance(); Some(BinaryOpKind::Eq)
2043 } else {
2044 self.current = saved_pos;
2045 None
2046 }
2047 } else {
2048 self.current = saved_pos;
2049 None
2050 }
2051 } else if self.check(&TokenType::Lt) {
2052 self.advance();
2053 Some(BinaryOpKind::Lt)
2054 } else if self.check(&TokenType::Gt) {
2055 self.advance();
2056 Some(BinaryOpKind::Gt)
2057 } else if self.check(&TokenType::LtEq) {
2058 self.advance();
2059 Some(BinaryOpKind::LtEq)
2060 } else if self.check(&TokenType::GtEq) {
2061 self.advance();
2062 Some(BinaryOpKind::GtEq)
2063 } else if self.check(&TokenType::EqEq) || self.check(&TokenType::Assign) {
2064 self.advance();
2065 Some(BinaryOpKind::Eq)
2066 } else if self.check(&TokenType::NotEq) {
2067 self.advance();
2068 Some(BinaryOpKind::NotEq)
2069 } else {
2070 None
2071 };
2072
2073 if let Some(op) = op {
2074 let right = self.parse_imperative_expr()?;
2075 Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp { op, left, right }))
2076 } else {
2077 Ok(left)
2078 }
2079 }
2080
2081 fn parse_let_statement(&mut self) -> ParseResult<Stmt<'a>> {
2082 self.advance(); let mutable = if self.check_mutable_keyword() {
2086 self.advance();
2087 true
2088 } else {
2089 false
2090 };
2091
2092 let var = self.expect_identifier()?;
2094
2095 let ty = if self.check(&TokenType::Colon) {
2097 self.advance(); let type_expr = self.parse_type_expression()?;
2099 Some(self.ctx.alloc_type_expr(type_expr))
2100 } else {
2101 None
2102 };
2103
2104 if !self.check(&TokenType::Be) && !self.check(&TokenType::Assign) {
2106 return Err(ParseError {
2107 kind: ParseErrorKind::ExpectedKeyword { keyword: "be or =".to_string() },
2108 span: self.current_span(),
2109 });
2110 }
2111 self.advance(); if self.check_word("mounted") {
2115 self.advance(); if !self.check(&TokenType::At) && !self.check_preposition_is("at") {
2117 return Err(ParseError {
2118 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2119 span: self.current_span(),
2120 });
2121 }
2122 self.advance(); let path = self.parse_imperative_expr()?;
2124 return Ok(Stmt::Mount { var, path });
2125 }
2126
2127 if self.check_article() {
2129 let saved_pos = self.current;
2130 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = self.peek().kind {
2134 let word = self.interner.resolve(sym).to_lowercase();
2135 if word == "peeragent" {
2136 self.advance(); if self.check(&TokenType::At) || self.check_preposition_is("at") {
2140 self.advance(); let address = self.parse_imperative_expr()?;
2144
2145 return Ok(Stmt::LetPeerAgent { var, address });
2146 }
2147 }
2148 }
2149 self.current = saved_pos;
2151 }
2152
2153 if self.check_article() {
2155 let saved_pos = self.current;
2156 self.advance(); if self.check(&TokenType::Pipe) {
2159 self.advance(); if !self.check_word("of") {
2163 return Err(ParseError {
2164 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
2165 span: self.current_span(),
2166 });
2167 }
2168 self.advance(); let element_type = self.expect_identifier()?;
2172
2173 return Ok(Stmt::CreatePipe { var, element_type, capacity: None });
2176 }
2177 self.current = saved_pos;
2179 }
2180
2181 if self.check(&TokenType::Launch) {
2183 self.advance(); if !self.check_article() {
2187 return Err(ParseError {
2188 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2189 span: self.current_span(),
2190 });
2191 }
2192 self.advance();
2193
2194 if !self.check(&TokenType::Task) {
2196 return Err(ParseError {
2197 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2198 span: self.current_span(),
2199 });
2200 }
2201 self.advance();
2202
2203 if !self.check(&TokenType::To) && !self.check_word("to") {
2205 return Err(ParseError {
2206 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2207 span: self.current_span(),
2208 });
2209 }
2210 self.advance();
2211
2212 let function = self.expect_identifier()?;
2214
2215 let args = if self.check_word("with") {
2217 self.advance();
2218 self.parse_call_arguments()?
2219 } else {
2220 vec![]
2221 };
2222
2223 return Ok(Stmt::LaunchTaskWithHandle { handle: var, function, args });
2224 }
2225
2226 let value = self.parse_imperative_expr()?;
2228
2229 if let Some(declared_ty) = &ty {
2231 if let Some(inferred) = self.infer_literal_type(value) {
2232 if !self.check_type_compatibility(declared_ty, inferred) {
2233 let expected = match declared_ty {
2234 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2235 self.interner.resolve(*sym).to_string()
2236 }
2237 _ => "unknown".to_string(),
2238 };
2239 return Err(ParseError {
2240 kind: ParseErrorKind::TypeMismatch {
2241 expected,
2242 found: inferred.to_string(),
2243 },
2244 span: self.current_span(),
2245 });
2246 }
2247 }
2248 }
2249
2250 let value = if self.check_word("with") {
2252 let saved = self.current;
2253 self.advance(); if self.check_word("capacity") {
2255 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2257 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2258 } else {
2259 self.current = saved; value
2261 }
2262 } else {
2263 value
2264 };
2265
2266 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2268
2269 Ok(Stmt::Let { var, ty, value, mutable })
2270 }
2271
2272 fn check_mutable_keyword(&self) -> bool {
2273 if matches!(self.peek().kind, TokenType::Mut) {
2275 return true;
2276 }
2277 if let TokenType::Noun(sym) | TokenType::Adjective(sym) = self.peek().kind {
2279 let word = self.interner.resolve(sym).to_lowercase();
2280 word == "mutable" || word == "mut"
2281 } else {
2282 false
2283 }
2284 }
2285
2286 fn infer_literal_type(&self, expr: &Expr<'_>) -> Option<&'static str> {
2288 match expr {
2289 Expr::Literal(lit) => match lit {
2290 crate::ast::Literal::Number(_) => Some("Int"),
2291 crate::ast::Literal::Float(_) => Some("Real"),
2292 crate::ast::Literal::Text(_) => Some("Text"),
2293 crate::ast::Literal::Boolean(_) => Some("Bool"),
2294 crate::ast::Literal::Nothing => Some("Unit"),
2295 crate::ast::Literal::Char(_) => Some("Char"),
2296 crate::ast::Literal::Duration(_) => Some("Duration"),
2297 crate::ast::Literal::Date(_) => Some("Date"),
2298 crate::ast::Literal::Moment(_) => Some("Moment"),
2299 crate::ast::Literal::Span { .. } => Some("Span"),
2300 crate::ast::Literal::Time(_) => Some("Time"),
2301 },
2302 _ => None, }
2304 }
2305
2306 fn check_type_compatibility(&self, declared: &TypeExpr<'_>, inferred: &str) -> bool {
2308 match declared {
2309 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2310 let declared_name = self.interner.resolve(*sym);
2311 declared_name.eq_ignore_ascii_case(inferred)
2313 || (declared_name.eq_ignore_ascii_case("Nat") && inferred == "Int")
2314 || (declared_name.eq_ignore_ascii_case("Byte") && inferred == "Int")
2315 }
2316 _ => true, }
2318 }
2319
2320 fn peek_equals_assignment(&self) -> bool {
2327 let is_identifier = matches!(
2331 self.peek().kind,
2332 TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Identifier
2333 | TokenType::Adjective(_) | TokenType::Verb { .. }
2334 | TokenType::Particle(_) | TokenType::Ambiguous { .. }
2335 | TokenType::Pronoun { .. }
2336 );
2337 if !is_identifier {
2338 return false;
2339 }
2340
2341 if self.current + 1 >= self.tokens.len() {
2343 return false;
2344 }
2345
2346 let next = &self.tokens[self.current + 1].kind;
2347
2348 if matches!(next, TokenType::Assign) {
2350 return true;
2351 }
2352
2353 if matches!(next, TokenType::Colon) {
2356 let mut offset = 2;
2357 while self.current + offset < self.tokens.len() {
2358 let tok = &self.tokens[self.current + offset].kind;
2359 if matches!(tok, TokenType::Assign) {
2360 return true;
2361 }
2362 if matches!(tok, TokenType::Period | TokenType::Newline | TokenType::EOF) {
2363 return false;
2364 }
2365 offset += 1;
2366 }
2367 }
2368
2369 false
2370 }
2371
2372 fn parse_equals_assignment(&mut self, explicit_mutable: bool) -> ParseResult<Stmt<'a>> {
2374 if explicit_mutable {
2376 self.advance(); }
2378
2379 let var = self.expect_identifier()?;
2381
2382 let ty = if self.check(&TokenType::Colon) {
2384 self.advance(); let type_expr = self.parse_type_expression()?;
2386 Some(self.ctx.alloc_type_expr(type_expr))
2387 } else {
2388 None
2389 };
2390
2391 if !self.check(&TokenType::Assign) {
2393 return Err(ParseError {
2394 kind: ParseErrorKind::ExpectedKeyword { keyword: "=".to_string() },
2395 span: self.current_span(),
2396 });
2397 }
2398 self.advance(); let value = self.parse_imperative_expr()?;
2402
2403 let value = if self.check_word("with") {
2405 let saved = self.current;
2406 self.advance(); if self.check_word("capacity") {
2408 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2410 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2411 } else {
2412 self.current = saved; value
2414 }
2415 } else {
2416 value
2417 };
2418
2419 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2421
2422 Ok(Stmt::Let { var, ty, value, mutable: explicit_mutable })
2423 }
2424
2425 fn parse_set_statement(&mut self) -> ParseResult<Stmt<'a>> {
2426 use crate::ast::Expr;
2427 self.advance(); let target_expr = self.parse_imperative_expr()?;
2431
2432 let target_expr = if self.check(&TokenType::At) {
2434 self.advance(); let key = self.parse_imperative_expr()?;
2436 self.ctx.alloc_imperative_expr(Expr::Index { collection: target_expr, index: key })
2437 } else {
2438 target_expr
2439 };
2440
2441 let is_to = self.check(&TokenType::To) || matches!(
2443 &self.peek().kind,
2444 TokenType::Preposition(sym) if self.interner.resolve(*sym) == "to"
2445 );
2446 if !is_to {
2447 return Err(ParseError {
2448 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2449 span: self.current_span(),
2450 });
2451 }
2452 self.advance(); let value = self.parse_imperative_expr()?;
2456
2457 match target_expr {
2460 Expr::FieldAccess { object, field } => {
2461 Ok(Stmt::SetField { object: *object, field: *field, value })
2462 }
2463 Expr::Identifier(target) => {
2464 Ok(Stmt::Set { target: *target, value })
2465 }
2466 Expr::Index { collection, index } => {
2467 Ok(Stmt::SetIndex { collection: *collection, index: *index, value })
2468 }
2469 _ => Err(ParseError {
2470 kind: ParseErrorKind::ExpectedIdentifier,
2471 span: self.current_span(),
2472 })
2473 }
2474 }
2475
2476 fn parse_return_statement(&mut self) -> ParseResult<Stmt<'a>> {
2477 self.advance(); if self.check(&TokenType::Period) || self.is_at_end() {
2481 return Ok(Stmt::Return { value: None });
2482 }
2483
2484 let value = self.parse_comparison()?;
2486 Ok(Stmt::Return { value: Some(value) })
2487 }
2488
2489 fn parse_assert_statement(&mut self) -> ParseResult<Stmt<'a>> {
2490 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2494 self.advance();
2495 }
2496
2497 let condition = self.parse_condition()?;
2500
2501 Ok(Stmt::RuntimeAssert { condition })
2502 }
2503
2504 fn parse_trust_statement(&mut self) -> ParseResult<Stmt<'a>> {
2507 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2511 self.advance();
2512 }
2513
2514 let saved_mode = self.mode;
2516 self.mode = ParserMode::Declarative;
2517
2518 let proposition = self.parse()?;
2520
2521 self.mode = saved_mode;
2523
2524 if !self.check(&TokenType::Because) {
2526 return Err(ParseError {
2527 kind: ParseErrorKind::UnexpectedToken {
2528 expected: TokenType::Because,
2529 found: self.peek().kind.clone(),
2530 },
2531 span: self.current_span(),
2532 });
2533 }
2534 self.advance(); let justification = match &self.peek().kind {
2538 TokenType::StringLiteral(sym) => {
2539 let s = *sym;
2540 self.advance();
2541 s
2542 }
2543 _ => {
2544 return Err(ParseError {
2545 kind: ParseErrorKind::UnexpectedToken {
2546 expected: TokenType::StringLiteral(self.interner.intern("")),
2547 found: self.peek().kind.clone(),
2548 },
2549 span: self.current_span(),
2550 });
2551 }
2552 };
2553
2554 Ok(Stmt::Trust { proposition, justification })
2555 }
2556
2557 fn parse_check_statement(&mut self) -> ParseResult<Stmt<'a>> {
2561 let start_span = self.current_span();
2562 self.advance(); if self.check(&TokenType::That) {
2566 self.advance();
2567 }
2568
2569 if matches!(self.peek().kind, TokenType::Article(_)) {
2571 self.advance();
2572 }
2573
2574 let subject = match &self.peek().kind {
2576 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2577 let s = *sym;
2578 self.advance();
2579 s
2580 }
2581 _ => {
2582 let tok = self.peek();
2584 let s = tok.lexeme;
2585 self.advance();
2586 s
2587 }
2588 };
2589
2590 let is_capability;
2592 let predicate;
2593 let object;
2594
2595 if self.check(&TokenType::Is) || self.check(&TokenType::Are) {
2596 is_capability = false;
2598 self.advance(); predicate = match &self.peek().kind {
2602 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2603 let s = *sym;
2604 self.advance();
2605 s
2606 }
2607 _ => {
2608 let tok = self.peek();
2609 let s = tok.lexeme;
2610 self.advance();
2611 s
2612 }
2613 };
2614 object = None;
2615 } else if self.check(&TokenType::Can) {
2616 is_capability = true;
2618 self.advance(); predicate = match &self.peek().kind {
2622 TokenType::Verb { lemma, .. } => {
2623 let s = *lemma;
2624 self.advance();
2625 s
2626 }
2627 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2628 let s = *sym;
2629 self.advance();
2630 s
2631 }
2632 _ => {
2633 let tok = self.peek();
2634 let s = tok.lexeme;
2635 self.advance();
2636 s
2637 }
2638 };
2639
2640 if matches!(self.peek().kind, TokenType::Article(_)) {
2642 self.advance();
2643 }
2644
2645 let obj = match &self.peek().kind {
2647 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2648 let s = *sym;
2649 self.advance();
2650 s
2651 }
2652 _ => {
2653 let tok = self.peek();
2654 let s = tok.lexeme;
2655 self.advance();
2656 s
2657 }
2658 };
2659 object = Some(obj);
2660 } else {
2661 return Err(ParseError {
2662 kind: ParseErrorKind::ExpectedKeyword { keyword: "is/can".to_string() },
2663 span: self.current_span(),
2664 });
2665 }
2666
2667 let source_text = if is_capability {
2669 let obj_name = self.interner.resolve(object.unwrap());
2670 let pred_name = self.interner.resolve(predicate);
2671 let subj_name = self.interner.resolve(subject);
2672 format!("{} can {} the {}", subj_name, pred_name, obj_name)
2673 } else {
2674 let pred_name = self.interner.resolve(predicate);
2675 let subj_name = self.interner.resolve(subject);
2676 format!("{} is {}", subj_name, pred_name)
2677 };
2678
2679 Ok(Stmt::Check {
2680 subject,
2681 predicate,
2682 is_capability,
2683 object,
2684 source_text,
2685 span: start_span,
2686 })
2687 }
2688
2689 fn parse_listen_statement(&mut self) -> ParseResult<Stmt<'a>> {
2692 self.advance(); if !self.check_preposition_is("on") {
2696 return Err(ParseError {
2697 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2698 span: self.current_span(),
2699 });
2700 }
2701 self.advance(); let address = self.parse_imperative_expr()?;
2705
2706 Ok(Stmt::Listen { address })
2707 }
2708
2709 fn parse_connect_statement(&mut self) -> ParseResult<Stmt<'a>> {
2712 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2716 return Err(ParseError {
2717 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2718 span: self.current_span(),
2719 });
2720 }
2721 self.advance(); let address = self.parse_imperative_expr()?;
2725
2726 Ok(Stmt::ConnectTo { address })
2727 }
2728
2729 fn parse_sleep_statement(&mut self) -> ParseResult<Stmt<'a>> {
2732 self.advance(); let milliseconds = self.parse_imperative_expr()?;
2736
2737 Ok(Stmt::Sleep { milliseconds })
2738 }
2739
2740 fn parse_sync_statement(&mut self) -> ParseResult<Stmt<'a>> {
2743 self.advance(); let var = match &self.tokens[self.current].kind {
2748 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2749 let s = *sym;
2750 self.advance();
2751 s
2752 }
2753 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2754 let s = self.tokens[self.current].lexeme;
2755 self.advance();
2756 s
2757 }
2758 _ => {
2759 return Err(ParseError {
2760 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2761 span: self.current_span(),
2762 });
2763 }
2764 };
2765
2766 if !self.check_preposition_is("on") {
2768 return Err(ParseError {
2769 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2770 span: self.current_span(),
2771 });
2772 }
2773 self.advance(); let topic = self.parse_imperative_expr()?;
2777
2778 Ok(Stmt::Sync { var, topic })
2779 }
2780
2781 fn parse_mount_statement(&mut self) -> ParseResult<Stmt<'a>> {
2785 self.advance(); let var = match &self.tokens[self.current].kind {
2790 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2791 let s = *sym;
2792 self.advance();
2793 s
2794 }
2795 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2796 let s = self.tokens[self.current].lexeme;
2797 self.advance();
2798 s
2799 }
2800 _ => {
2801 return Err(ParseError {
2802 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2803 span: self.current_span(),
2804 });
2805 }
2806 };
2807
2808 if !self.check(&TokenType::At) {
2810 return Err(ParseError {
2811 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2812 span: self.current_span(),
2813 });
2814 }
2815 self.advance(); let path = self.parse_imperative_expr()?;
2819
2820 Ok(Stmt::Mount { var, path })
2821 }
2822
2823 fn lookahead_contains_into(&self) -> bool {
2829 for i in self.current..std::cmp::min(self.current + 5, self.tokens.len()) {
2830 if matches!(self.tokens[i].kind, TokenType::Into) {
2831 return true;
2832 }
2833 }
2834 false
2835 }
2836
2837 fn lookahead_is_first_of(&self) -> bool {
2839 self.current + 3 < self.tokens.len()
2841 && matches!(self.tokens.get(self.current + 1), Some(t) if matches!(t.kind, TokenType::Article(_)))
2842 && self.tokens.get(self.current + 2)
2843 .map(|t| self.interner.resolve(t.lexeme).to_lowercase() == "first")
2844 .unwrap_or(false)
2845 }
2846
2847 fn parse_launch_statement(&mut self) -> ParseResult<Stmt<'a>> {
2850 self.advance(); if !self.check_article() {
2854 return Err(ParseError {
2855 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2856 span: self.current_span(),
2857 });
2858 }
2859 self.advance();
2860
2861 if !self.check(&TokenType::Task) {
2863 return Err(ParseError {
2864 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2865 span: self.current_span(),
2866 });
2867 }
2868 self.advance();
2869
2870 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2872 return Err(ParseError {
2873 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2874 span: self.current_span(),
2875 });
2876 }
2877 self.advance();
2878
2879 let function = match &self.tokens[self.current].kind {
2882 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2883 let s = *sym;
2884 self.advance();
2885 s
2886 }
2887 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2888 let s = self.tokens[self.current].lexeme;
2889 self.advance();
2890 s
2891 }
2892 _ => {
2893 return Err(ParseError {
2894 kind: ParseErrorKind::ExpectedKeyword { keyword: "function name".to_string() },
2895 span: self.current_span(),
2896 });
2897 }
2898 };
2899
2900 let args = if self.check(&TokenType::LParen) {
2902 self.parse_call_arguments()?
2903 } else if self.check_word("with") {
2904 self.advance(); let mut args = Vec::new();
2906 let arg = self.parse_imperative_expr()?;
2907 args.push(arg);
2908 while self.check(&TokenType::And) {
2910 self.advance();
2911 let arg = self.parse_imperative_expr()?;
2912 args.push(arg);
2913 }
2914 args
2915 } else {
2916 Vec::new()
2917 };
2918
2919 Ok(Stmt::LaunchTask { function, args })
2920 }
2921
2922 fn parse_send_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2925 self.advance(); let value = self.parse_imperative_expr()?;
2929
2930 if !self.check(&TokenType::Into) {
2932 return Err(ParseError {
2933 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
2934 span: self.current_span(),
2935 });
2936 }
2937 self.advance();
2938
2939 let pipe = self.parse_imperative_expr()?;
2941
2942 Ok(Stmt::SendPipe { value, pipe })
2943 }
2944
2945 fn parse_receive_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2948 self.advance(); let var = self.expect_identifier()?;
2952
2953 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
2955 return Err(ParseError {
2956 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
2957 span: self.current_span(),
2958 });
2959 }
2960 self.advance();
2961
2962 let pipe = self.parse_imperative_expr()?;
2964
2965 Ok(Stmt::ReceivePipe { var, pipe })
2966 }
2967
2968 fn parse_try_statement(&mut self) -> ParseResult<Stmt<'a>> {
2971 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2975 return Err(ParseError {
2976 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2977 span: self.current_span(),
2978 });
2979 }
2980 self.advance();
2981
2982 if self.check(&TokenType::Send) {
2984 self.advance(); let value = self.parse_imperative_expr()?;
2986
2987 if !self.check(&TokenType::Into) {
2988 return Err(ParseError {
2989 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
2990 span: self.current_span(),
2991 });
2992 }
2993 self.advance();
2994
2995 let pipe = self.parse_imperative_expr()?;
2996 Ok(Stmt::TrySendPipe { value, pipe, result: None })
2997 } else if self.check(&TokenType::Receive) {
2998 self.advance(); let var = self.expect_identifier()?;
3001
3002 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3003 return Err(ParseError {
3004 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3005 span: self.current_span(),
3006 });
3007 }
3008 self.advance();
3009
3010 let pipe = self.parse_imperative_expr()?;
3011 Ok(Stmt::TryReceivePipe { var, pipe })
3012 } else {
3013 Err(ParseError {
3014 kind: ParseErrorKind::ExpectedKeyword { keyword: "send or receive".to_string() },
3015 span: self.current_span(),
3016 })
3017 }
3018 }
3019
3020 fn parse_escape_body(&mut self) -> ParseResult<(crate::intern::Symbol, crate::intern::Symbol, crate::token::Span)> {
3023 let start_span = self.current_span();
3024 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3028 return Err(ParseError {
3029 kind: ParseErrorKind::Custom(
3030 "Expected 'to' after 'Escape'. Syntax: Escape to Rust:".to_string()
3031 ),
3032 span: self.current_span(),
3033 });
3034 }
3035 self.advance(); let language = match &self.peek().kind {
3039 TokenType::ProperName(sym) => {
3040 let s = *sym;
3041 self.advance();
3042 s
3043 }
3044 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3045 let s = *sym;
3046 self.advance();
3047 s
3048 }
3049 _ => {
3050 return Err(ParseError {
3051 kind: ParseErrorKind::Custom(
3052 "Expected language name after 'Escape to'. Currently only 'Rust' is supported.".to_string()
3053 ),
3054 span: self.current_span(),
3055 });
3056 }
3057 };
3058
3059 if !language.is(self.interner, "Rust") {
3061 let lang_str = self.interner.resolve(language);
3062 return Err(ParseError {
3063 kind: ParseErrorKind::Custom(
3064 format!("Unsupported escape target '{}'. Only 'Rust' is supported.", lang_str)
3065 ),
3066 span: self.current_span(),
3067 });
3068 }
3069
3070 if !self.check(&TokenType::Colon) {
3072 return Err(ParseError {
3073 kind: ParseErrorKind::Custom(
3074 "Expected ':' after 'Escape to Rust'. Syntax: Escape to Rust:".to_string()
3075 ),
3076 span: self.current_span(),
3077 });
3078 }
3079 self.advance(); if !self.check(&TokenType::Indent) {
3083 return Err(ParseError {
3084 kind: ParseErrorKind::Custom(
3085 "Expected indented block after 'Escape to Rust:'.".to_string()
3086 ),
3087 span: self.current_span(),
3088 });
3089 }
3090 self.advance(); let code = match &self.peek().kind {
3094 TokenType::EscapeBlock(sym) => {
3095 let s = *sym;
3096 self.advance();
3097 s
3098 }
3099 _ => {
3100 return Err(ParseError {
3101 kind: ParseErrorKind::Custom(
3102 "Escape block body is empty or malformed.".to_string()
3103 ),
3104 span: self.current_span(),
3105 });
3106 }
3107 };
3108
3109 if self.check(&TokenType::Dedent) {
3111 self.advance();
3112 }
3113
3114 let end_span = self.previous().span;
3115 Ok((language, code, crate::token::Span::new(start_span.start, end_span.end)))
3116 }
3117
3118 fn parse_escape_statement(&mut self) -> ParseResult<Stmt<'a>> {
3120 let (language, code, span) = self.parse_escape_body()?;
3121 Ok(Stmt::Escape { language, code, span })
3122 }
3123
3124 fn parse_escape_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
3127 let (language, code, _span) = self.parse_escape_body()?;
3128 Ok(self.ctx.alloc_imperative_expr(Expr::Escape { language, code }))
3129 }
3130
3131 fn parse_requires_block(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
3134 let mut deps = Vec::new();
3135
3136 loop {
3137 if self.is_at_end() {
3139 break;
3140 }
3141 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
3142 break;
3143 }
3144
3145 if self.check(&TokenType::Indent)
3147 || self.check(&TokenType::Dedent)
3148 || self.check(&TokenType::Newline)
3149 {
3150 self.advance();
3151 continue;
3152 }
3153
3154 if matches!(self.peek().kind, TokenType::Article(_)) {
3156 let dep = self.parse_require_line()?;
3157 deps.push(dep);
3158 continue;
3159 }
3160
3161 self.advance();
3163 }
3164
3165 Ok(deps)
3166 }
3167
3168 fn parse_require_line(&mut self) -> ParseResult<Stmt<'a>> {
3171 let start_span = self.current_span();
3172
3173 if !matches!(self.peek().kind, TokenType::Article(_)) {
3175 return Err(crate::error::ParseError {
3176 kind: crate::error::ParseErrorKind::Custom(
3177 "Expected 'The' to begin a dependency declaration.".to_string(),
3178 ),
3179 span: self.current_span(),
3180 });
3181 }
3182 self.advance(); let crate_name = if let TokenType::StringLiteral(sym) = self.peek().kind {
3186 let s = sym;
3187 self.advance();
3188 s
3189 } else {
3190 return Err(crate::error::ParseError {
3191 kind: crate::error::ParseErrorKind::Custom(
3192 "Expected a string literal for the crate name, e.g. \"serde\".".to_string(),
3193 ),
3194 span: self.current_span(),
3195 });
3196 };
3197
3198 if !self.check_word("crate") {
3200 return Err(crate::error::ParseError {
3201 kind: crate::error::ParseErrorKind::Custom(
3202 "Expected the word 'crate' after the crate name.".to_string(),
3203 ),
3204 span: self.current_span(),
3205 });
3206 }
3207 self.advance(); if !self.check_word("version") {
3211 return Err(crate::error::ParseError {
3212 kind: crate::error::ParseErrorKind::Custom(
3213 "Expected 'version' after 'crate'.".to_string(),
3214 ),
3215 span: self.current_span(),
3216 });
3217 }
3218 self.advance(); let version = if let TokenType::StringLiteral(sym) = self.peek().kind {
3222 let s = sym;
3223 self.advance();
3224 s
3225 } else {
3226 return Err(crate::error::ParseError {
3227 kind: crate::error::ParseErrorKind::Custom(
3228 "Expected a string literal for the version, e.g. \"1.0\".".to_string(),
3229 ),
3230 span: self.current_span(),
3231 });
3232 };
3233
3234 let mut features = Vec::new();
3236 if self.check_preposition_is("with") {
3237 self.advance(); if !self.check_word("features") {
3241 return Err(crate::error::ParseError {
3242 kind: crate::error::ParseErrorKind::Custom(
3243 "Expected 'features' after 'with'.".to_string(),
3244 ),
3245 span: self.current_span(),
3246 });
3247 }
3248 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3252 features.push(sym);
3253 self.advance();
3254 } else {
3255 return Err(crate::error::ParseError {
3256 kind: crate::error::ParseErrorKind::Custom(
3257 "Expected a string literal for a feature name.".to_string(),
3258 ),
3259 span: self.current_span(),
3260 });
3261 }
3262
3263 while self.check(&TokenType::And) {
3265 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3267 features.push(sym);
3268 self.advance();
3269 } else {
3270 return Err(crate::error::ParseError {
3271 kind: crate::error::ParseErrorKind::Custom(
3272 "Expected a string literal for a feature name after 'and'.".to_string(),
3273 ),
3274 span: self.current_span(),
3275 });
3276 }
3277 }
3278 }
3279
3280 if self.check(&TokenType::For) {
3282 self.advance(); while !self.check(&TokenType::Period) && !self.check(&TokenType::EOF)
3284 && !self.check(&TokenType::Newline)
3285 && !matches!(self.peek().kind, TokenType::BlockHeader { .. })
3286 {
3287 self.advance();
3288 }
3289 }
3290
3291 if self.check(&TokenType::Period) {
3293 self.advance();
3294 }
3295
3296 let end_span = self.previous().span;
3297
3298 Ok(Stmt::Require {
3299 crate_name,
3300 version,
3301 features,
3302 span: crate::token::Span::new(start_span.start, end_span.end),
3303 })
3304 }
3305
3306 fn parse_stop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3309 self.advance(); let handle = self.parse_imperative_expr()?;
3312
3313 Ok(Stmt::StopTask { handle })
3314 }
3315
3316 fn parse_select_statement(&mut self) -> ParseResult<Stmt<'a>> {
3324 use crate::ast::stmt::SelectBranch;
3325
3326 self.advance(); if !self.check_article() {
3330 return Err(ParseError {
3331 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
3332 span: self.current_span(),
3333 });
3334 }
3335 self.advance();
3336
3337 if !self.check_word("first") {
3339 return Err(ParseError {
3340 kind: ParseErrorKind::ExpectedKeyword { keyword: "first".to_string() },
3341 span: self.current_span(),
3342 });
3343 }
3344 self.advance();
3345
3346 if !self.check_preposition_is("of") {
3348 return Err(ParseError {
3349 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3350 span: self.current_span(),
3351 });
3352 }
3353 self.advance();
3354
3355 if !self.check(&TokenType::Colon) {
3357 return Err(ParseError {
3358 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3359 span: self.current_span(),
3360 });
3361 }
3362 self.advance();
3363
3364 if !self.check(&TokenType::Indent) {
3366 return Err(ParseError {
3367 kind: ParseErrorKind::ExpectedStatement,
3368 span: self.current_span(),
3369 });
3370 }
3371 self.advance();
3372
3373 let mut branches = Vec::new();
3375 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3376 let branch = self.parse_select_branch()?;
3377 branches.push(branch);
3378 }
3379
3380 if self.check(&TokenType::Dedent) {
3382 self.advance();
3383 }
3384
3385 Ok(Stmt::Select { branches })
3386 }
3387
3388 fn parse_select_branch(&mut self) -> ParseResult<crate::ast::stmt::SelectBranch<'a>> {
3390 use crate::ast::stmt::SelectBranch;
3391
3392 if self.check(&TokenType::Receive) {
3393 self.advance(); let var = match &self.tokens[self.current].kind {
3396 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3397 let s = *sym;
3398 self.advance();
3399 s
3400 }
3401 _ => {
3402 return Err(ParseError {
3403 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
3404 span: self.current_span(),
3405 });
3406 }
3407 };
3408
3409 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3410 return Err(ParseError {
3411 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3412 span: self.current_span(),
3413 });
3414 }
3415 self.advance();
3416
3417 let pipe = self.parse_imperative_expr()?;
3418
3419 if !self.check(&TokenType::Colon) {
3421 return Err(ParseError {
3422 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3423 span: self.current_span(),
3424 });
3425 }
3426 self.advance();
3427
3428 let body = self.parse_indented_block()?;
3430
3431 Ok(SelectBranch::Receive { var, pipe, body })
3432 } else if self.check_word("after") {
3433 self.advance(); let milliseconds = self.parse_imperative_expr()?;
3436
3437 if self.check_word("seconds") || self.check_word("milliseconds") {
3439 self.advance();
3440 }
3441
3442 if !self.check(&TokenType::Colon) {
3444 return Err(ParseError {
3445 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3446 span: self.current_span(),
3447 });
3448 }
3449 self.advance();
3450
3451 let body = self.parse_indented_block()?;
3453
3454 Ok(SelectBranch::Timeout { milliseconds, body })
3455 } else {
3456 Err(ParseError {
3457 kind: ParseErrorKind::ExpectedKeyword { keyword: "Receive or After".to_string() },
3458 span: self.current_span(),
3459 })
3460 }
3461 }
3462
3463 fn parse_indented_block(&mut self) -> ParseResult<crate::ast::stmt::Block<'a>> {
3465 if !self.check(&TokenType::Indent) {
3467 return Err(ParseError {
3468 kind: ParseErrorKind::ExpectedStatement,
3469 span: self.current_span(),
3470 });
3471 }
3472 self.advance();
3473
3474 let mut stmts = Vec::new();
3475 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3476 let stmt = self.parse_statement()?;
3477 stmts.push(stmt);
3478 if self.check(&TokenType::Period) {
3479 self.advance();
3480 }
3481 }
3482
3483 if self.check(&TokenType::Dedent) {
3485 self.advance();
3486 }
3487
3488 let block = self.ctx.stmts.expect("imperative arenas not initialized")
3489 .alloc_slice(stmts.into_iter());
3490
3491 Ok(block)
3492 }
3493
3494 fn parse_give_statement(&mut self) -> ParseResult<Stmt<'a>> {
3495 self.advance(); let object = self.parse_imperative_expr()?;
3499
3500 if !self.check_to_preposition() {
3502 return Err(ParseError {
3503 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3504 span: self.current_span(),
3505 });
3506 }
3507 self.advance(); let recipient = self.parse_imperative_expr()?;
3511
3512 if let Expr::Identifier(sym) = object {
3514 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Moved);
3515 }
3516
3517 Ok(Stmt::Give { object, recipient })
3518 }
3519
3520 fn parse_show_statement(&mut self) -> ParseResult<Stmt<'a>> {
3521 self.advance(); let object = self.parse_condition()?;
3526
3527 let recipient = if self.check_to_preposition() {
3531 self.advance(); if self.check_article() {
3536 self.advance(); }
3538 if self.check(&TokenType::Console) {
3539 self.advance(); let show_sym = self.interner.intern("show");
3541 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3542 } else {
3543 self.parse_imperative_expr()?
3545 }
3546 } else {
3547 let show_sym = self.interner.intern("show");
3549 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3550 };
3551
3552 if let Expr::Identifier(sym) = object {
3554 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Borrowed);
3555 }
3556
3557 Ok(Stmt::Show { object, recipient })
3558 }
3559
3560 fn parse_push_statement(&mut self) -> ParseResult<Stmt<'a>> {
3563 self.advance(); let value = self.parse_imperative_expr()?;
3567
3568 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3570 return Err(ParseError {
3571 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3572 span: self.current_span(),
3573 });
3574 }
3575 self.advance(); let collection = self.parse_imperative_expr()?;
3579
3580 Ok(Stmt::Push { value, collection })
3581 }
3582
3583 fn parse_pop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3586 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3590 return Err(ParseError {
3591 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3592 span: self.current_span(),
3593 });
3594 }
3595 self.advance(); let collection = self.parse_imperative_expr()?;
3599
3600 let into = if self.check(&TokenType::Into) || self.check_preposition_is("into") {
3602 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = &self.peek().kind {
3606 let sym = *sym;
3607 self.advance();
3608 Some(sym)
3609 } else if let Some(token) = self.tokens.get(self.current) {
3610 let sym = token.lexeme;
3612 self.advance();
3613 Some(sym)
3614 } else {
3615 return Err(ParseError {
3616 kind: ParseErrorKind::ExpectedIdentifier,
3617 span: self.current_span(),
3618 });
3619 }
3620 } else {
3621 None
3622 };
3623
3624 Ok(Stmt::Pop { collection, into })
3625 }
3626
3627 fn parse_add_statement(&mut self) -> ParseResult<Stmt<'a>> {
3630 self.advance(); let value = self.parse_imperative_expr()?;
3634
3635 if !self.check_preposition_is("to") && !self.check(&TokenType::To) {
3637 return Err(ParseError {
3638 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3639 span: self.current_span(),
3640 });
3641 }
3642 self.advance(); let collection = self.parse_imperative_expr()?;
3646
3647 Ok(Stmt::Add { value, collection })
3648 }
3649
3650 fn parse_remove_statement(&mut self) -> ParseResult<Stmt<'a>> {
3653 self.advance(); let value = self.parse_imperative_expr()?;
3657
3658 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3660 return Err(ParseError {
3661 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3662 span: self.current_span(),
3663 });
3664 }
3665 self.advance(); let collection = self.parse_imperative_expr()?;
3669
3670 Ok(Stmt::Remove { value, collection })
3671 }
3672
3673 fn parse_read_statement(&mut self) -> ParseResult<Stmt<'a>> {
3677 self.advance(); let var = self.expect_identifier()?;
3681
3682 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3684 return Err(ParseError {
3685 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3686 span: self.current_span(),
3687 });
3688 }
3689 self.advance(); if self.check_article() {
3693 self.advance();
3694 }
3695
3696 let source = if self.check(&TokenType::Console) {
3698 self.advance(); ReadSource::Console
3700 } else if self.check(&TokenType::File) {
3701 self.advance(); let path = self.parse_imperative_expr()?;
3703 ReadSource::File(path)
3704 } else {
3705 return Err(ParseError {
3706 kind: ParseErrorKind::ExpectedKeyword { keyword: "console or file".to_string() },
3707 span: self.current_span(),
3708 });
3709 };
3710
3711 Ok(Stmt::ReadFrom { var, source })
3712 }
3713
3714 fn parse_write_statement(&mut self) -> ParseResult<Stmt<'a>> {
3717 self.advance(); let content = self.parse_imperative_expr()?;
3721
3722 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3724 return Err(ParseError {
3725 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3726 span: self.current_span(),
3727 });
3728 }
3729 self.advance(); if !self.check(&TokenType::File) {
3733 return Err(ParseError {
3734 kind: ParseErrorKind::ExpectedKeyword { keyword: "file".to_string() },
3735 span: self.current_span(),
3736 });
3737 }
3738 self.advance(); let path = self.parse_imperative_expr()?;
3742
3743 Ok(Stmt::WriteFile { content, path })
3744 }
3745
3746 fn parse_zone_statement(&mut self) -> ParseResult<Stmt<'a>> {
3752 self.advance(); if self.check_article() {
3756 self.advance();
3757 }
3758
3759 if self.check(&TokenType::New) {
3761 self.advance();
3762 }
3763
3764 if !self.check(&TokenType::Zone) {
3766 return Err(ParseError {
3767 kind: ParseErrorKind::ExpectedKeyword { keyword: "zone".to_string() },
3768 span: self.current_span(),
3769 });
3770 }
3771 self.advance(); if !self.check(&TokenType::Called) {
3775 return Err(ParseError {
3776 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
3777 span: self.current_span(),
3778 });
3779 }
3780 self.advance(); let name = match &self.peek().kind {
3784 TokenType::StringLiteral(sym) => {
3785 let s = *sym;
3786 self.advance();
3787 s
3788 }
3789 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3790 let s = *sym;
3791 self.advance();
3792 s
3793 }
3794 _ => {
3795 let token = self.peek().clone();
3797 self.advance();
3798 token.lexeme
3799 }
3800 };
3801
3802 let mut capacity = None;
3803 let mut source_file = None;
3804
3805 if self.check(&TokenType::Mapped) {
3807 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3811 return Err(ParseError {
3812 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3813 span: self.current_span(),
3814 });
3815 }
3816 self.advance(); if let TokenType::StringLiteral(path) = &self.peek().kind {
3820 source_file = Some(*path);
3821 self.advance();
3822 } else {
3823 return Err(ParseError {
3824 kind: ParseErrorKind::ExpectedKeyword { keyword: "file path string".to_string() },
3825 span: self.current_span(),
3826 });
3827 }
3828 }
3829 else if self.check_of_preposition() {
3831 self.advance(); if !self.check(&TokenType::Size) {
3835 return Err(ParseError {
3836 kind: ParseErrorKind::ExpectedKeyword { keyword: "size".to_string() },
3837 span: self.current_span(),
3838 });
3839 }
3840 self.advance(); let size_value = match &self.peek().kind {
3844 TokenType::Number(sym) => {
3845 let num_str = self.interner.resolve(*sym);
3846 let val = num_str.replace('_', "").parse::<usize>().unwrap_or(0);
3847 self.advance();
3848 val
3849 }
3850 TokenType::Cardinal(n) => {
3851 let val = *n as usize;
3852 self.advance();
3853 val
3854 }
3855 _ => {
3856 return Err(ParseError {
3857 kind: ParseErrorKind::ExpectedNumber,
3858 span: self.current_span(),
3859 });
3860 }
3861 };
3862
3863 let unit_multiplier = self.parse_size_unit()?;
3865 capacity = Some(size_value * unit_multiplier);
3866 }
3867
3868 if !self.check(&TokenType::Colon) {
3870 return Err(ParseError {
3871 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3872 span: self.current_span(),
3873 });
3874 }
3875 self.advance(); if !self.check(&TokenType::Indent) {
3879 return Err(ParseError {
3880 kind: ParseErrorKind::ExpectedStatement,
3881 span: self.current_span(),
3882 });
3883 }
3884 self.advance(); let mut body_stmts = Vec::new();
3888 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3889 let stmt = self.parse_statement()?;
3890 body_stmts.push(stmt);
3891 if self.check(&TokenType::Period) {
3892 self.advance();
3893 }
3894 }
3895
3896 if self.check(&TokenType::Dedent) {
3898 self.advance();
3899 }
3900
3901 let body = self.ctx.stmts.expect("imperative arenas not initialized")
3902 .alloc_slice(body_stmts.into_iter());
3903
3904 Ok(Stmt::Zone { name, capacity, source_file, body })
3905 }
3906
3907 fn parse_size_unit(&mut self) -> ParseResult<usize> {
3909 let token = self.peek().clone();
3910 let unit_str = self.interner.resolve(token.lexeme).to_uppercase();
3911 self.advance();
3912
3913 match unit_str.as_str() {
3914 "B" | "BYTES" | "BYTE" => Ok(1),
3915 "KB" | "KILOBYTE" | "KILOBYTES" => Ok(1024),
3916 "MB" | "MEGABYTE" | "MEGABYTES" => Ok(1024 * 1024),
3917 "GB" | "GIGABYTE" | "GIGABYTES" => Ok(1024 * 1024 * 1024),
3918 _ => Err(ParseError {
3919 kind: ParseErrorKind::ExpectedKeyword {
3920 keyword: "size unit (B, KB, MB, GB)".to_string(),
3921 },
3922 span: token.span,
3923 }),
3924 }
3925 }
3926
3927 fn parse_concurrent_block(&mut self) -> ParseResult<Stmt<'a>> {
3936 self.advance(); if !self.check(&TokenType::All) {
3940 return Err(ParseError {
3941 kind: ParseErrorKind::ExpectedKeyword { keyword: "all".to_string() },
3942 span: self.current_span(),
3943 });
3944 }
3945 self.advance(); if !self.check_of_preposition() {
3949 return Err(ParseError {
3950 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3951 span: self.current_span(),
3952 });
3953 }
3954 self.advance(); if !self.check_article() {
3958 return Err(ParseError {
3959 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
3960 span: self.current_span(),
3961 });
3962 }
3963 self.advance(); if !self.check(&TokenType::Following) {
3967 return Err(ParseError {
3968 kind: ParseErrorKind::ExpectedKeyword { keyword: "following".to_string() },
3969 span: self.current_span(),
3970 });
3971 }
3972 self.advance(); if !self.check(&TokenType::Colon) {
3976 return Err(ParseError {
3977 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3978 span: self.current_span(),
3979 });
3980 }
3981 self.advance(); if !self.check(&TokenType::Indent) {
3985 return Err(ParseError {
3986 kind: ParseErrorKind::ExpectedStatement,
3987 span: self.current_span(),
3988 });
3989 }
3990 self.advance(); let mut task_stmts = Vec::new();
3994 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3995 let stmt = self.parse_statement()?;
3996 task_stmts.push(stmt);
3997 if self.check(&TokenType::Period) {
3998 self.advance();
3999 }
4000 }
4001
4002 if self.check(&TokenType::Dedent) {
4004 self.advance();
4005 }
4006
4007 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
4008 .alloc_slice(task_stmts.into_iter());
4009
4010 Ok(Stmt::Concurrent { tasks })
4011 }
4012
4013 fn parse_parallel_block(&mut self) -> ParseResult<Stmt<'a>> {
4022 self.advance(); if !self.check(&TokenType::Colon) {
4026 return Err(ParseError {
4027 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4028 span: self.current_span(),
4029 });
4030 }
4031 self.advance(); if !self.check(&TokenType::Indent) {
4035 return Err(ParseError {
4036 kind: ParseErrorKind::ExpectedStatement,
4037 span: self.current_span(),
4038 });
4039 }
4040 self.advance(); let mut task_stmts = Vec::new();
4044 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4045 let stmt = self.parse_statement()?;
4046 task_stmts.push(stmt);
4047 if self.check(&TokenType::Period) {
4048 self.advance();
4049 }
4050 }
4051
4052 if self.check(&TokenType::Dedent) {
4054 self.advance();
4055 }
4056
4057 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
4058 .alloc_slice(task_stmts.into_iter());
4059
4060 Ok(Stmt::Parallel { tasks })
4061 }
4062
4063 fn parse_inspect_statement(&mut self) -> ParseResult<Stmt<'a>> {
4070 self.advance(); let target = self.parse_imperative_expr()?;
4074
4075 if !self.check(&TokenType::Colon) {
4077 return Err(ParseError {
4078 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4079 span: self.current_span(),
4080 });
4081 }
4082 self.advance(); if !self.check(&TokenType::Indent) {
4086 return Err(ParseError {
4087 kind: ParseErrorKind::ExpectedStatement,
4088 span: self.current_span(),
4089 });
4090 }
4091 self.advance(); let mut arms = Vec::new();
4094 let mut has_otherwise = false;
4095
4096 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4098 if self.check(&TokenType::Otherwise) {
4099 self.advance(); if !self.check(&TokenType::Colon) {
4103 return Err(ParseError {
4104 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4105 span: self.current_span(),
4106 });
4107 }
4108 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4112 self.advance(); let mut stmts = Vec::new();
4114 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4115 let stmt = self.parse_statement()?;
4116 stmts.push(stmt);
4117 if self.check(&TokenType::Period) {
4118 self.advance();
4119 }
4120 }
4121 if self.check(&TokenType::Dedent) {
4122 self.advance();
4123 }
4124 stmts
4125 } else {
4126 let stmt = self.parse_statement()?;
4128 if self.check(&TokenType::Period) {
4129 self.advance();
4130 }
4131 vec![stmt]
4132 };
4133
4134 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4135 .alloc_slice(body_stmts.into_iter());
4136
4137 arms.push(MatchArm { enum_name: None, variant: None, bindings: vec![], body });
4138 has_otherwise = true;
4139 break;
4140 }
4141
4142 if self.check(&TokenType::If) {
4143 let arm = self.parse_match_arm()?;
4145 arms.push(arm);
4146 } else if self.check(&TokenType::When) || self.check_word("When") {
4147 let arm = self.parse_when_arm()?;
4149 arms.push(arm);
4150 } else if self.check(&TokenType::Newline) {
4151 self.advance();
4153 } else {
4154 self.advance();
4156 }
4157 }
4158
4159 if self.check(&TokenType::Dedent) {
4161 self.advance();
4162 }
4163
4164 Ok(Stmt::Inspect { target, arms, has_otherwise })
4165 }
4166
4167 fn parse_match_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4169 self.advance(); if !self.check_word("it") {
4173 return Err(ParseError {
4174 kind: ParseErrorKind::ExpectedKeyword { keyword: "it".to_string() },
4175 span: self.current_span(),
4176 });
4177 }
4178 self.advance(); if !self.check(&TokenType::Is) {
4182 return Err(ParseError {
4183 kind: ParseErrorKind::ExpectedKeyword { keyword: "is".to_string() },
4184 span: self.current_span(),
4185 });
4186 }
4187 self.advance(); if self.check_article() {
4191 self.advance();
4192 }
4193
4194 let variant = self.expect_identifier()?;
4196
4197 let enum_name = self.find_variant(variant);
4199
4200 let bindings = if self.check(&TokenType::LParen) {
4202 self.parse_pattern_bindings()?
4203 } else {
4204 vec![]
4205 };
4206
4207 if !self.check(&TokenType::Colon) {
4209 return Err(ParseError {
4210 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4211 span: self.current_span(),
4212 });
4213 }
4214 self.advance(); if !self.check(&TokenType::Indent) {
4218 return Err(ParseError {
4219 kind: ParseErrorKind::ExpectedStatement,
4220 span: self.current_span(),
4221 });
4222 }
4223 self.advance(); let mut body_stmts = Vec::new();
4227 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4228 let stmt = self.parse_statement()?;
4229 body_stmts.push(stmt);
4230 if self.check(&TokenType::Period) {
4231 self.advance();
4232 }
4233 }
4234
4235 if self.check(&TokenType::Dedent) {
4237 self.advance();
4238 }
4239
4240 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4241 .alloc_slice(body_stmts.into_iter());
4242
4243 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4244 }
4245
4246 fn parse_when_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4248 self.advance(); let variant = self.expect_identifier()?;
4252
4253 let (enum_name, variant_fields) = self.type_registry
4255 .as_ref()
4256 .and_then(|r| r.find_variant(variant).map(|(enum_name, vdef)| {
4257 let fields: Vec<_> = vdef.fields.iter().map(|f| f.name).collect();
4258 (Some(enum_name), fields)
4259 }))
4260 .unwrap_or((None, vec![]));
4261
4262 let bindings = if self.check(&TokenType::LParen) {
4264 let raw_bindings = self.parse_when_bindings()?;
4265 raw_bindings.into_iter().enumerate().map(|(i, binding)| {
4267 let field = variant_fields.get(i).copied().unwrap_or(binding);
4268 (field, binding)
4269 }).collect()
4270 } else {
4271 vec![]
4272 };
4273
4274 if !self.check(&TokenType::Colon) {
4276 return Err(ParseError {
4277 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4278 span: self.current_span(),
4279 });
4280 }
4281 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4285 self.advance(); let mut stmts = Vec::new();
4287 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4288 let stmt = self.parse_statement()?;
4289 stmts.push(stmt);
4290 if self.check(&TokenType::Period) {
4291 self.advance();
4292 }
4293 }
4294 if self.check(&TokenType::Dedent) {
4295 self.advance();
4296 }
4297 stmts
4298 } else {
4299 let stmt = self.parse_statement()?;
4301 if self.check(&TokenType::Period) {
4302 self.advance();
4303 }
4304 vec![stmt]
4305 };
4306
4307 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4308 .alloc_slice(body_stmts.into_iter());
4309
4310 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4311 }
4312
4313 fn parse_when_bindings(&mut self) -> ParseResult<Vec<Symbol>> {
4315 self.advance(); let mut bindings = Vec::new();
4317
4318 loop {
4319 let binding = self.expect_identifier()?;
4320 bindings.push(binding);
4321
4322 if !self.check(&TokenType::Comma) {
4323 break;
4324 }
4325 self.advance(); }
4327
4328 if !self.check(&TokenType::RParen) {
4329 return Err(ParseError {
4330 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4331 span: self.current_span(),
4332 });
4333 }
4334 self.advance(); Ok(bindings)
4337 }
4338
4339 fn parse_pattern_bindings(&mut self) -> ParseResult<Vec<(Symbol, Symbol)>> {
4341 self.advance(); let mut bindings = Vec::new();
4343
4344 loop {
4345 let field = self.expect_identifier()?;
4346 let binding = if self.check(&TokenType::Colon) {
4347 self.advance(); self.expect_identifier()?
4349 } else {
4350 field };
4352 bindings.push((field, binding));
4353
4354 if !self.check(&TokenType::Comma) {
4355 break;
4356 }
4357 self.advance(); }
4359
4360 if !self.check(&TokenType::RParen) {
4361 return Err(ParseError {
4362 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4363 span: self.current_span(),
4364 });
4365 }
4366 self.advance(); Ok(bindings)
4369 }
4370
4371 fn parse_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4375 use crate::ast::Expr;
4376 let mut fields = Vec::new();
4377
4378 self.advance();
4380
4381 loop {
4382 let field_name = self.expect_identifier()?;
4384
4385 let value = self.parse_imperative_expr()?;
4387
4388 fields.push((field_name, value));
4389
4390 if self.check(&TokenType::And) {
4392 self.advance(); continue;
4394 }
4395 break;
4396 }
4397
4398 Ok(fields)
4399 }
4400
4401 fn parse_variant_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4403 self.parse_constructor_fields()
4404 }
4405
4406 fn parse_struct_init_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4408 self.parse_constructor_fields()
4409 }
4410
4411 fn parse_generic_type_args(&mut self, type_name: Symbol) -> ParseResult<Vec<TypeExpr<'a>>> {
4415 if !self.is_generic_type(type_name) {
4417 return Ok(vec![]);
4418 }
4419
4420 if !self.check_preposition_is("of") {
4422 return Ok(vec![]); }
4424 self.advance(); let mut type_args = Vec::new();
4427 loop {
4428 let type_arg = self.parse_type_expression()?;
4430 type_args.push(type_arg);
4431
4432 if self.check(&TokenType::And) || self.check_to_preposition() {
4434 self.advance(); continue;
4436 }
4437 break;
4438 }
4439
4440 Ok(type_args)
4441 }
4442
4443 fn skip_type_def_content(&mut self) {
4447 while !self.is_at_end() {
4448 if matches!(
4450 self.tokens.get(self.current),
4451 Some(Token { kind: TokenType::BlockHeader { .. }, .. })
4452 ) {
4453 break;
4454 }
4455 self.advance();
4456 }
4457 }
4458
4459 fn parse_theorem_block(&mut self) -> ParseResult<Stmt<'a>> {
4467 use crate::ast::theorem::{TheoremBlock, ProofStrategy};
4468
4469 self.skip_whitespace_tokens();
4471
4472 if self.check(&TokenType::Colon) {
4477 self.advance();
4478 }
4479
4480 self.skip_whitespace_tokens();
4482
4483 let name = if let Some(token) = self.tokens.get(self.current) {
4485 match &token.kind {
4486 TokenType::Noun(_)
4487 | TokenType::ProperName(_)
4488 | TokenType::Verb { .. }
4489 | TokenType::Adjective(_) => {
4490 let name = self.interner.resolve(token.lexeme).to_string();
4491 self.advance();
4492 name
4493 }
4494 _ => {
4495 let lexeme = self.interner.resolve(token.lexeme);
4497 if !lexeme.is_empty() && lexeme.chars().next().map(|c| c.is_alphanumeric()).unwrap_or(false) {
4498 let name = lexeme.to_string();
4499 self.advance();
4500 name
4501 } else {
4502 "Anonymous".to_string()
4503 }
4504 }
4505 }
4506 } else {
4507 "Anonymous".to_string()
4508 };
4509
4510 self.skip_whitespace_tokens();
4511
4512 if self.check(&TokenType::Period) {
4514 self.advance();
4515 }
4516
4517 self.skip_whitespace_tokens();
4518
4519 let mut premises = Vec::new();
4522 while self.check(&TokenType::Given) {
4523 self.advance(); if self.check(&TokenType::Colon) {
4527 self.advance();
4528 }
4529
4530 self.skip_whitespace_tokens();
4531
4532 let premise_expr = self.parse_sentence()?;
4534 premises.push(premise_expr);
4535
4536 self.world_state.end_sentence();
4539
4540 if self.check(&TokenType::Period) {
4542 self.advance();
4543 }
4544
4545 self.skip_whitespace_tokens();
4546 }
4547
4548 let goal = if self.check(&TokenType::Prove) {
4550 self.advance(); if self.check(&TokenType::Colon) {
4553 self.advance();
4554 }
4555
4556 self.skip_whitespace_tokens();
4557
4558 let goal_expr = self.parse_sentence()?;
4559
4560 if self.check(&TokenType::Period) {
4561 self.advance();
4562 }
4563
4564 goal_expr
4565 } else {
4566 return Err(ParseError {
4567 kind: ParseErrorKind::ExpectedKeyword { keyword: "Prove".to_string() },
4568 span: self.current_span(),
4569 });
4570 };
4571
4572 self.skip_whitespace_tokens();
4573
4574 let strategy = if self.check(&TokenType::BlockHeader { block_type: crate::token::BlockType::Proof }) {
4576 self.advance();
4577 self.skip_whitespace_tokens();
4578
4579 if self.check(&TokenType::Colon) {
4580 self.advance();
4581 }
4582
4583 self.skip_whitespace_tokens();
4584
4585 if self.check(&TokenType::Auto) {
4586 self.advance();
4587 ProofStrategy::Auto
4588 } else {
4589 ProofStrategy::Auto
4591 }
4592 } else {
4593 ProofStrategy::Auto
4595 };
4596
4597 if self.check(&TokenType::Period) {
4599 self.advance();
4600 }
4601
4602 let theorem = TheoremBlock {
4603 name,
4604 premises,
4605 goal,
4606 strategy,
4607 };
4608
4609 Ok(Stmt::Theorem(theorem))
4610 }
4611
4612 fn skip_whitespace_tokens(&mut self) {
4614 while self.check(&TokenType::Newline) || self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) {
4615 self.advance();
4616 }
4617 }
4618
4619 fn parse_function_def(&mut self) -> ParseResult<Stmt<'a>> {
4624 if self.check(&TokenType::To) || self.check_preposition_is("to") {
4626 self.advance();
4627 }
4628
4629 let mut is_native = if self.check(&TokenType::Native) {
4631 self.advance(); true
4633 } else {
4634 false
4635 };
4636
4637 let name = self.expect_identifier()?;
4639
4640 let mut params = Vec::new();
4642 while self.check(&TokenType::LParen) {
4643 self.advance(); if self.check(&TokenType::RParen) {
4647 self.advance(); break;
4649 }
4650
4651 loop {
4653 let param_name = self.expect_identifier()?;
4654
4655 if !self.check(&TokenType::Colon) {
4657 return Err(ParseError {
4658 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4659 span: self.current_span(),
4660 });
4661 }
4662 self.advance(); let param_type_expr = self.parse_type_expression()?;
4666 let param_type = self.ctx.alloc_type_expr(param_type_expr);
4667
4668 params.push((param_name, param_type));
4669
4670 if self.check(&TokenType::Comma) {
4672 self.advance(); continue;
4674 }
4675 break;
4676 }
4677
4678 if !self.check(&TokenType::RParen) {
4680 return Err(ParseError {
4681 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4682 span: self.current_span(),
4683 });
4684 }
4685 self.advance(); if self.check_word("and") || self.check_preposition() || self.check(&TokenType::From) {
4690 self.advance();
4691 }
4692 }
4693
4694 let return_type = if self.check(&TokenType::Arrow) {
4696 self.advance(); let ret_type_expr = self.parse_type_expression()?;
4698 Some(self.ctx.alloc_type_expr(ret_type_expr))
4699 } else {
4700 None
4701 };
4702
4703 let mut native_path: Option<Symbol> = None;
4705 let mut is_exported = false;
4706 let mut export_target: Option<Symbol> = None;
4707
4708 if self.check_word("is") {
4709 self.advance(); if self.check(&TokenType::Native) {
4711 self.advance(); is_native = true;
4714 if let TokenType::StringLiteral(sym) = self.peek().kind {
4715 native_path = Some(sym);
4716 self.advance(); } else {
4718 return Err(ParseError {
4719 kind: ParseErrorKind::Custom(
4720 "Expected a string literal for native function path (e.g., is native \"reqwest::blocking::get\")".to_string()
4721 ),
4722 span: self.current_span(),
4723 });
4724 }
4725 } else if self.check_word("exported") {
4726 self.advance(); is_exported = true;
4729 if self.check_word("for") {
4730 self.advance(); let target_sym = self.expect_identifier()?;
4732 let target_str = self.interner.resolve(target_sym);
4733 if !target_str.eq_ignore_ascii_case("c") && !target_str.eq_ignore_ascii_case("wasm") {
4734 return Err(ParseError {
4735 kind: ParseErrorKind::Custom(
4736 format!("Unsupported export target \"{}\". Supported targets are \"c\" and \"wasm\".", target_str)
4737 ),
4738 span: self.current_span(),
4739 });
4740 }
4741 export_target = Some(target_sym);
4742 }
4743 }
4744 }
4745
4746 if is_native {
4748 if self.check(&TokenType::Period) {
4750 self.advance();
4751 }
4752 if self.check(&TokenType::Newline) {
4753 self.advance();
4754 }
4755
4756 let empty_body = self.ctx.stmts.expect("imperative arenas not initialized")
4758 .alloc_slice(std::iter::empty());
4759
4760 return Ok(Stmt::FunctionDef {
4761 name,
4762 params,
4763 body: empty_body,
4764 return_type,
4765 is_native: true,
4766 native_path,
4767 is_exported: false,
4768 export_target: None,
4769 });
4770 }
4771
4772 if !self.check(&TokenType::Colon) {
4774 return Err(ParseError {
4775 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4776 span: self.current_span(),
4777 });
4778 }
4779 self.advance(); if !self.check(&TokenType::Indent) {
4783 return Err(ParseError {
4784 kind: ParseErrorKind::ExpectedStatement,
4785 span: self.current_span(),
4786 });
4787 }
4788 self.advance(); let mut body_stmts = Vec::new();
4792 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4793 if self.check(&TokenType::Newline) {
4795 self.advance();
4796 continue;
4797 }
4798 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
4800 break;
4801 }
4802 let stmt = self.parse_statement()?;
4803 body_stmts.push(stmt);
4804 if self.check(&TokenType::Period) {
4805 self.advance();
4806 }
4807 }
4808
4809 if self.check(&TokenType::Dedent) {
4811 self.advance();
4812 }
4813
4814 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4816 .alloc_slice(body_stmts.into_iter());
4817
4818 Ok(Stmt::FunctionDef {
4819 name,
4820 params,
4821 body,
4822 return_type,
4823 is_native: false,
4824 native_path: None,
4825 is_exported,
4826 export_target,
4827 })
4828 }
4829
4830 fn parse_primary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
4832 use crate::ast::{Expr, Literal};
4833
4834 let token = self.peek().clone();
4835 match &token.kind {
4836 TokenType::New => {
4840 self.advance(); let base_type_name = self.expect_identifier()?;
4842
4843 let type_name = if self.check(&TokenType::From) {
4845 self.advance(); let module_name = self.expect_identifier()?;
4847 let module_str = self.interner.resolve(module_name);
4848 let base_str = self.interner.resolve(base_type_name);
4849 let qualified = format!("{}::{}", module_str, base_str);
4850 self.interner.intern(&qualified)
4851 } else {
4852 base_type_name
4853 };
4854
4855 if let Some(enum_name) = self.find_variant(type_name) {
4857 let fields = if self.check_word("with") {
4859 self.parse_variant_constructor_fields()?
4860 } else {
4861 vec![]
4862 };
4863 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
4864 enum_name,
4865 variant: type_name,
4866 fields,
4867 });
4868 return self.parse_field_access_chain(base);
4869 }
4870
4871 let type_args = self.parse_generic_type_args(type_name)?;
4873
4874 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
4877 self.parse_struct_init_fields()?
4878 } else {
4879 vec![]
4880 };
4881
4882 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
4883 return self.parse_field_access_chain(base);
4884 }
4885
4886 TokenType::Article(_) => {
4890 if let Some(next) = self.tokens.get(self.current + 1) {
4893 if matches!(next.kind, TokenType::Manifest) {
4894 self.advance(); return self.parse_primary_expr();
4897 }
4898 if matches!(next.kind, TokenType::Chunk) {
4899 self.advance(); return self.parse_primary_expr();
4902 }
4903 if matches!(next.kind, TokenType::Length) {
4904 self.advance(); return self.parse_primary_expr();
4906 }
4907 }
4908 if let Some(next) = self.tokens.get(self.current + 1) {
4910 if matches!(next.kind, TokenType::New) {
4911 self.advance(); self.advance(); let base_type_name = self.expect_identifier()?;
4914
4915 let type_name = if self.check(&TokenType::From) {
4917 self.advance(); let module_name = self.expect_identifier()?;
4919 let module_str = self.interner.resolve(module_name);
4920 let base_str = self.interner.resolve(base_type_name);
4921 let qualified = format!("{}::{}", module_str, base_str);
4922 self.interner.intern(&qualified)
4923 } else {
4924 base_type_name
4925 };
4926
4927 if let Some(enum_name) = self.find_variant(type_name) {
4929 let fields = if self.check_word("with") {
4931 self.parse_variant_constructor_fields()?
4932 } else {
4933 vec![]
4934 };
4935 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
4936 enum_name,
4937 variant: type_name,
4938 fields,
4939 });
4940 return self.parse_field_access_chain(base);
4941 }
4942
4943 let type_args = self.parse_generic_type_args(type_name)?;
4945
4946 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
4949 self.parse_struct_init_fields()?
4950 } else {
4951 vec![]
4952 };
4953
4954 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
4955 return self.parse_field_access_chain(base);
4956 }
4957 }
4958 let sym = token.lexeme;
4960 self.advance();
4961 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
4962 return self.parse_field_access_chain(base);
4963 }
4964
4965 TokenType::Item => {
4967 self.advance(); let index = if let TokenType::Number(sym) = &self.peek().kind {
4971 let sym = *sym;
4973 self.advance();
4974 let num_str = self.interner.resolve(sym);
4975 let index_val = num_str.parse::<i64>().unwrap_or(0);
4976
4977 if index_val == 0 {
4979 return Err(ParseError {
4980 kind: ParseErrorKind::ZeroIndex,
4981 span: self.current_span(),
4982 });
4983 }
4984
4985 self.ctx.alloc_imperative_expr(
4986 Expr::Literal(crate::ast::Literal::Number(index_val))
4987 )
4988 } else if self.check(&TokenType::LParen) {
4989 self.advance(); let inner = self.parse_imperative_expr()?;
4992 if !self.check(&TokenType::RParen) {
4993 return Err(ParseError {
4994 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4995 span: self.current_span(),
4996 });
4997 }
4998 self.advance(); inner
5000 } else if let TokenType::StringLiteral(sym) = self.peek().kind {
5001 let sym = sym;
5003 self.advance();
5004 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Text(sym)))
5005 } else if !self.check_preposition_is("of") {
5006 let word = self.interner.resolve(self.peek().lexeme);
5008 if word == "true" {
5009 self.advance();
5010 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(true)))
5011 } else if word == "false" {
5012 self.advance();
5013 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(false)))
5014 } else {
5015 let sym = self.peek().lexeme;
5017 self.advance();
5018 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5019 }
5020 } else {
5021 return Err(ParseError {
5022 kind: ParseErrorKind::ExpectedExpression,
5023 span: self.current_span(),
5024 });
5025 };
5026
5027 if !self.check_preposition_is("of") {
5029 return Err(ParseError {
5030 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5031 span: self.current_span(),
5032 });
5033 }
5034 self.advance(); let collection = self.parse_primary_expr()?;
5039
5040 Ok(self.ctx.alloc_imperative_expr(Expr::Index {
5041 collection,
5042 index,
5043 }))
5044 }
5045
5046 TokenType::Items => {
5049 let is_slice_syntax = if let Some(next) = self.tokens.get(self.current + 1) {
5053 matches!(next.kind, TokenType::Number(_) | TokenType::LParen)
5054 } else {
5055 false
5056 };
5057
5058 if !is_slice_syntax {
5059 let sym = token.lexeme;
5061 self.advance();
5062 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5063 return self.parse_field_access_chain(base);
5064 }
5065
5066 self.advance(); let start = if let TokenType::Number(sym) = &self.peek().kind {
5070 let sym = *sym;
5072 self.advance();
5073 let num_str = self.interner.resolve(sym);
5074 let start_val = num_str.parse::<i64>().unwrap_or(0);
5075
5076 if start_val == 0 {
5078 return Err(ParseError {
5079 kind: ParseErrorKind::ZeroIndex,
5080 span: self.current_span(),
5081 });
5082 }
5083
5084 self.ctx.alloc_imperative_expr(
5085 Expr::Literal(crate::ast::Literal::Number(start_val))
5086 )
5087 } else if self.check(&TokenType::LParen) {
5088 self.advance(); let inner = self.parse_imperative_expr()?;
5091 if !self.check(&TokenType::RParen) {
5092 return Err(ParseError {
5093 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5094 span: self.current_span(),
5095 });
5096 }
5097 self.advance(); inner
5099 } else if !self.check_preposition_is("through") {
5100 let sym = self.peek().lexeme;
5102 self.advance();
5103 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5104 } else {
5105 return Err(ParseError {
5106 kind: ParseErrorKind::ExpectedExpression,
5107 span: self.current_span(),
5108 });
5109 };
5110
5111 if !self.check_preposition_is("through") {
5113 return Err(ParseError {
5114 kind: ParseErrorKind::ExpectedKeyword { keyword: "through".to_string() },
5115 span: self.current_span(),
5116 });
5117 }
5118 self.advance(); let end = if let TokenType::Number(sym) = &self.peek().kind {
5122 let sym = *sym;
5124 self.advance();
5125 let num_str = self.interner.resolve(sym);
5126 let end_val = num_str.parse::<i64>().unwrap_or(0);
5127
5128 if end_val == 0 {
5130 return Err(ParseError {
5131 kind: ParseErrorKind::ZeroIndex,
5132 span: self.current_span(),
5133 });
5134 }
5135
5136 self.ctx.alloc_imperative_expr(
5137 Expr::Literal(crate::ast::Literal::Number(end_val))
5138 )
5139 } else if self.check(&TokenType::LParen) {
5140 self.advance(); let inner = self.parse_imperative_expr()?;
5143 if !self.check(&TokenType::RParen) {
5144 return Err(ParseError {
5145 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5146 span: self.current_span(),
5147 });
5148 }
5149 self.advance(); inner
5151 } else if !self.check_preposition_is("of") {
5152 let sym = self.peek().lexeme;
5154 self.advance();
5155 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5156 } else {
5157 return Err(ParseError {
5158 kind: ParseErrorKind::ExpectedExpression,
5159 span: self.current_span(),
5160 });
5161 };
5162
5163 let collection = if self.check_preposition_is("of") {
5166 self.advance(); self.parse_imperative_expr()?
5168 } else {
5169 let items_sym = self.interner.intern("items");
5172 self.ctx.alloc_imperative_expr(Expr::Identifier(items_sym))
5173 };
5174
5175 Ok(self.ctx.alloc_imperative_expr(Expr::Slice {
5176 collection,
5177 start,
5178 end,
5179 }))
5180 }
5181
5182 TokenType::LBracket => {
5184 self.advance(); let mut items = Vec::new();
5187 if !self.check(&TokenType::RBracket) {
5188 loop {
5189 items.push(self.parse_imperative_expr()?);
5190 if !self.check(&TokenType::Comma) {
5191 break;
5192 }
5193 self.advance(); }
5195 }
5196
5197 if !self.check(&TokenType::RBracket) {
5198 return Err(ParseError {
5199 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
5200 span: self.current_span(),
5201 });
5202 }
5203 self.advance(); if items.is_empty() && self.check_word("of") {
5207 self.advance(); let type_name = self.expect_identifier()?;
5209 let seq_sym = self.interner.intern("Seq");
5211 return Ok(self.ctx.alloc_imperative_expr(Expr::New {
5212 type_name: seq_sym,
5213 type_args: vec![TypeExpr::Named(type_name)],
5214 init_fields: vec![],
5215 }));
5216 }
5217
5218 Ok(self.ctx.alloc_imperative_expr(Expr::List(items)))
5219 }
5220
5221 TokenType::Number(sym) => {
5222 let num_str = self.interner.resolve(*sym).to_string();
5223 self.advance();
5224
5225 if let TokenType::CalendarUnit(unit) = self.peek().kind {
5227 return self.parse_span_literal_from_num(&num_str);
5228 }
5229
5230 if num_str.contains('.') {
5232 let num = num_str.parse::<f64>().unwrap_or(0.0);
5233 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Float(num))))
5234 } else {
5235 let num = num_str.parse::<i64>().unwrap_or(0);
5236 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(num))))
5237 }
5238 }
5239
5240 TokenType::StringLiteral(sym) => {
5242 self.advance();
5243 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Text(*sym))))
5244 }
5245
5246 TokenType::CharLiteral(sym) => {
5248 let char_str = self.interner.resolve(*sym);
5249 let ch = char_str.chars().next().unwrap_or('\0');
5250 self.advance();
5251 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Char(ch))))
5252 }
5253
5254 TokenType::DurationLiteral { nanos, .. } => {
5256 let nanos = *nanos;
5257 self.advance();
5258 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Duration(nanos))))
5259 }
5260
5261 TokenType::DateLiteral { days } => {
5264 let days = *days;
5265 self.advance();
5266
5267 if self.check(&TokenType::At) {
5269 self.advance(); if let TokenType::TimeLiteral { nanos_from_midnight } = self.peek().kind {
5273 let time_nanos = nanos_from_midnight;
5274 self.advance(); let moment_nanos = (days as i64) * 86_400_000_000_000 + time_nanos;
5278 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Moment(moment_nanos))));
5279 } else {
5280 return Err(ParseError {
5281 kind: ParseErrorKind::ExpectedExpression,
5282 span: self.current_span(),
5283 });
5284 }
5285 }
5286
5287 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Date(days))))
5288 }
5289
5290 TokenType::TimeLiteral { nanos_from_midnight } => {
5292 let nanos = *nanos_from_midnight;
5293 self.advance();
5294 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Time(nanos))))
5295 }
5296
5297 TokenType::Nothing => {
5299 self.advance();
5300 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)))
5301 }
5302
5303 TokenType::Some => {
5305 self.advance(); let value = self.parse_imperative_expr()?;
5307 Ok(self.ctx.alloc_imperative_expr(Expr::OptionSome { value }))
5308 }
5309
5310 TokenType::Length => {
5312 let func_name = self.peek().lexeme;
5313
5314 if self.tokens.get(self.current + 1)
5316 .map(|t| matches!(t.kind, TokenType::LParen))
5317 .unwrap_or(false)
5318 {
5319 self.advance(); return self.parse_call_expr(func_name);
5321 }
5322
5323 self.advance(); if !self.check_preposition_is("of") {
5327 return Err(ParseError {
5328 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5329 span: self.current_span(),
5330 });
5331 }
5332 self.advance(); let collection = self.parse_imperative_expr()?;
5335 Ok(self.ctx.alloc_imperative_expr(Expr::Length { collection }))
5336 }
5337
5338 TokenType::Copy => {
5340 let func_name = self.peek().lexeme;
5341
5342 if self.tokens.get(self.current + 1)
5344 .map(|t| matches!(t.kind, TokenType::LParen))
5345 .unwrap_or(false)
5346 {
5347 self.advance(); return self.parse_call_expr(func_name);
5349 }
5350
5351 self.advance(); if !self.check_preposition_is("of") {
5355 return Err(ParseError {
5356 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5357 span: self.current_span(),
5358 });
5359 }
5360 self.advance(); let expr = self.parse_imperative_expr()?;
5363 Ok(self.ctx.alloc_imperative_expr(Expr::Copy { expr }))
5364 }
5365
5366 TokenType::Manifest => {
5368 self.advance(); if !self.check_preposition_is("of") {
5372 return Err(ParseError {
5373 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5374 span: self.current_span(),
5375 });
5376 }
5377 self.advance(); let zone = self.parse_imperative_expr()?;
5380 Ok(self.ctx.alloc_imperative_expr(Expr::ManifestOf { zone }))
5381 }
5382
5383 TokenType::Chunk => {
5385 self.advance(); if !self.check(&TokenType::At) {
5389 return Err(ParseError {
5390 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
5391 span: self.current_span(),
5392 });
5393 }
5394 self.advance(); let index = self.parse_imperative_expr()?;
5397
5398 if !self.check_preposition_is("in") && !self.check(&TokenType::In) {
5400 return Err(ParseError {
5401 kind: ParseErrorKind::ExpectedKeyword { keyword: "in".to_string() },
5402 span: self.current_span(),
5403 });
5404 }
5405 self.advance(); let zone = self.parse_imperative_expr()?;
5408 Ok(self.ctx.alloc_imperative_expr(Expr::ChunkAt { index, zone }))
5409 }
5410
5411 TokenType::Verb { lemma, .. } => {
5415 let word = self.interner.resolve(*lemma).to_lowercase();
5416 if word == "empty" {
5417 self.advance();
5418 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5419 }
5420 let sym = token.lexeme;
5422 self.advance();
5423 if self.check(&TokenType::LParen) {
5424 return self.parse_call_expr(sym);
5425 }
5426 self.verify_identifier_access(sym)?;
5428 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5429 self.parse_field_access_chain(base)
5430 }
5431
5432 TokenType::TemporalAdverb(_) | TokenType::ScopalAdverb(_) | TokenType::Adverb(_) => {
5434 let sym = token.lexeme;
5435 self.advance();
5436 if self.check(&TokenType::LParen) {
5437 return self.parse_call_expr(sym);
5438 }
5439 self.verify_identifier_access(sym)?;
5441 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5442 self.parse_field_access_chain(base)
5443 }
5444
5445 TokenType::Read | TokenType::Write | TokenType::File | TokenType::Console |
5448 TokenType::Add | TokenType::Remove => {
5449 let sym = token.lexeme;
5450 self.advance();
5451 if self.check(&TokenType::LParen) {
5452 return self.parse_call_expr(sym);
5453 }
5454 self.verify_identifier_access(sym)?;
5456 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5457 self.parse_field_access_chain(base)
5458 }
5459
5460 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
5463 let sym = *sym;
5464 let word = self.interner.resolve(sym);
5465
5466 if word == "true" {
5468 self.advance();
5469 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(true))));
5470 }
5471 if word == "false" {
5472 self.advance();
5473 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(false))));
5474 }
5475
5476 if word == "empty" {
5478 self.advance();
5479 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5480 }
5481
5482 if word == "none" {
5484 self.advance();
5485 return Ok(self.ctx.alloc_imperative_expr(Expr::OptionNone));
5486 }
5487
5488 self.advance();
5490
5491 if self.check(&TokenType::LParen) {
5493 return self.parse_call_expr(sym);
5494 }
5495
5496 if let Some(enum_name) = self.find_variant(sym) {
5498 let fields = if self.check_word("with") {
5499 self.parse_variant_constructor_fields()?
5500 } else {
5501 vec![]
5502 };
5503 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
5504 enum_name,
5505 variant: sym,
5506 fields,
5507 });
5508 return self.parse_field_access_chain(base);
5509 }
5510
5511 self.verify_identifier_access(sym)?;
5513 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5514 self.parse_field_access_chain(base)
5516 }
5517
5518 TokenType::Pronoun { .. } => {
5520 let sym = token.lexeme;
5521 self.advance();
5522 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5523 self.parse_field_access_chain(base)
5525 }
5526
5527 TokenType::Merge | TokenType::Increase => {
5529 let sym = token.lexeme;
5530 self.advance();
5531
5532 if self.check(&TokenType::LParen) {
5534 return self.parse_call_expr(sym);
5535 }
5536
5537 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5538 self.parse_field_access_chain(base)
5539 }
5540
5541 TokenType::Escape => {
5545 if self.tokens.get(self.current + 1).map_or(false, |t|
5546 matches!(t.kind, TokenType::To) || {
5547 if let TokenType::Preposition(sym) = t.kind {
5548 sym.is(self.interner, "to")
5549 } else {
5550 false
5551 }
5552 }
5553 ) {
5554 return self.parse_escape_expr();
5555 }
5556 let sym = token.lexeme;
5558 self.advance();
5559 if self.check(&TokenType::LParen) {
5560 return self.parse_call_expr(sym);
5561 }
5562 self.verify_identifier_access(sym)?;
5563 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5564 self.parse_field_access_chain(base)
5565 }
5566
5567 TokenType::Values | TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared => { let sym = token.lexeme;
5576 self.advance();
5577
5578 if self.check(&TokenType::LParen) {
5580 return self.parse_call_expr(sym);
5581 }
5582
5583 self.verify_identifier_access(sym)?;
5584 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5585 self.parse_field_access_chain(base)
5586 }
5587
5588 TokenType::Ambiguous { primary, alternatives } => {
5590 let sym = token.lexeme;
5593
5594 let is_identifier_token = match &**primary {
5596 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5597 TokenType::Verb { .. } => true,
5598 _ => alternatives.iter().any(|t| matches!(t,
5599 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5600 TokenType::Verb { .. }
5601 ))
5602 };
5603
5604 if is_identifier_token {
5605 self.advance();
5606
5607 if self.check(&TokenType::LParen) {
5609 return self.parse_call_expr(sym);
5610 }
5611
5612 self.verify_identifier_access(sym)?;
5613 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5614 self.parse_field_access_chain(base)
5616 } else {
5617 Err(ParseError {
5618 kind: ParseErrorKind::ExpectedExpression,
5619 span: self.current_span(),
5620 })
5621 }
5622 }
5623
5624 TokenType::LParen => {
5626 if let Some(closure) = self.try_parse(|p| p.parse_closure_expr()) {
5629 return Ok(closure);
5630 }
5631
5632 self.advance(); let first = self.parse_imperative_expr()?;
5635
5636 if self.check(&TokenType::Comma) {
5638 let mut items = vec![first];
5640 while self.check(&TokenType::Comma) {
5641 self.advance(); items.push(self.parse_imperative_expr()?);
5643 }
5644
5645 if !self.check(&TokenType::RParen) {
5646 return Err(ParseError {
5647 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5648 span: self.current_span(),
5649 });
5650 }
5651 self.advance(); let base = self.ctx.alloc_imperative_expr(Expr::Tuple(items));
5654 self.parse_field_access_chain(base)
5655 } else {
5656 if !self.check(&TokenType::RParen) {
5658 return Err(ParseError {
5659 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5660 span: self.current_span(),
5661 });
5662 }
5663 self.advance(); Ok(first)
5665 }
5666 }
5667
5668 TokenType::Call => {
5670 self.advance(); let function = match &self.peek().kind {
5672 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
5673 let s = *sym;
5674 self.advance();
5675 s
5676 }
5677 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
5678 let s = self.peek().lexeme;
5679 self.advance();
5680 s
5681 }
5682 _ => {
5683 return Err(ParseError {
5684 kind: ParseErrorKind::ExpectedIdentifier,
5685 span: self.current_span(),
5686 });
5687 }
5688 };
5689 let args = if self.check_preposition_is("with") {
5690 self.advance(); self.parse_call_arguments()?
5692 } else {
5693 Vec::new()
5694 };
5695 Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
5696 }
5697
5698 _ => {
5699 Err(ParseError {
5700 kind: ParseErrorKind::ExpectedExpression,
5701 span: self.current_span(),
5702 })
5703 }
5704 }
5705 }
5706
5707 fn parse_closure_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5710 use crate::ast::stmt::ClosureBody;
5711
5712 if !self.check(&TokenType::LParen) {
5714 return Err(ParseError {
5715 kind: ParseErrorKind::ExpectedExpression,
5716 span: self.current_span(),
5717 });
5718 }
5719 self.advance(); let mut params = Vec::new();
5723 if !self.check(&TokenType::RParen) {
5724 let name = self.expect_identifier()?;
5726 if !self.check(&TokenType::Colon) {
5727 return Err(ParseError {
5728 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
5729 span: self.current_span(),
5730 });
5731 }
5732 self.advance(); let ty = self.parse_type_expression()?;
5734 let ty_ref = self.ctx.alloc_type_expr(ty);
5735 params.push((name, ty_ref));
5736
5737 while self.check(&TokenType::Comma) {
5739 self.advance(); let name = self.expect_identifier()?;
5741 if !self.check(&TokenType::Colon) {
5742 return Err(ParseError {
5743 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
5744 span: self.current_span(),
5745 });
5746 }
5747 self.advance(); let ty = self.parse_type_expression()?;
5749 let ty_ref = self.ctx.alloc_type_expr(ty);
5750 params.push((name, ty_ref));
5751 }
5752 }
5753
5754 if !self.check(&TokenType::RParen) {
5756 return Err(ParseError {
5757 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5758 span: self.current_span(),
5759 });
5760 }
5761 self.advance(); if !self.check(&TokenType::Arrow) {
5765 return Err(ParseError {
5766 kind: ParseErrorKind::ExpectedKeyword { keyword: "->".to_string() },
5767 span: self.current_span(),
5768 });
5769 }
5770 self.advance(); let body = if self.check(&TokenType::Colon) {
5774 self.advance(); if !self.check(&TokenType::Indent) {
5777 return Err(ParseError {
5778 kind: ParseErrorKind::ExpectedStatement,
5779 span: self.current_span(),
5780 });
5781 }
5782 self.advance(); let mut block_stmts = Vec::new();
5785 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
5786 let stmt = self.parse_statement()?;
5787 block_stmts.push(stmt);
5788 if self.check(&TokenType::Period) {
5789 self.advance();
5790 }
5791 }
5792 if self.check(&TokenType::Dedent) {
5793 self.advance(); }
5795
5796 let block = self.ctx.stmts.expect("imperative arenas not initialized")
5797 .alloc_slice(block_stmts.into_iter());
5798 ClosureBody::Block(block)
5799 } else {
5800 let expr = self.parse_condition()?;
5802 ClosureBody::Expression(expr)
5803 };
5804
5805 Ok(self.ctx.alloc_imperative_expr(Expr::Closure {
5806 params,
5807 body,
5808 return_type: None,
5809 }))
5810 }
5811
5812 fn parse_imperative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5815 self.parse_additive_expr()
5816 }
5817
5818 fn parse_additive_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5820 let mut left = self.parse_multiplicative_expr()?;
5821
5822 loop {
5823 match &self.peek().kind {
5824 TokenType::Plus => {
5825 self.advance();
5826 let right = self.parse_multiplicative_expr()?;
5827 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5828 op: BinaryOpKind::Add,
5829 left,
5830 right,
5831 });
5832 }
5833 TokenType::Minus => {
5834 self.advance();
5835 let right = self.parse_multiplicative_expr()?;
5836 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5837 op: BinaryOpKind::Subtract,
5838 left,
5839 right,
5840 });
5841 }
5842 TokenType::Combined => {
5844 self.advance(); if !self.check_preposition_is("with") {
5847 return Err(ParseError {
5848 kind: ParseErrorKind::ExpectedKeyword { keyword: "with".to_string() },
5849 span: self.current_span(),
5850 });
5851 }
5852 self.advance(); let right = self.parse_multiplicative_expr()?;
5854 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5855 op: BinaryOpKind::Concat,
5856 left,
5857 right,
5858 });
5859 }
5860 TokenType::Union => {
5862 self.advance(); let right = self.parse_multiplicative_expr()?;
5864 left = self.ctx.alloc_imperative_expr(Expr::Union {
5865 left,
5866 right,
5867 });
5868 }
5869 TokenType::Intersection => {
5870 self.advance(); let right = self.parse_multiplicative_expr()?;
5872 left = self.ctx.alloc_imperative_expr(Expr::Intersection {
5873 left,
5874 right,
5875 });
5876 }
5877 TokenType::Contains => {
5879 self.advance(); let value = self.parse_multiplicative_expr()?;
5881 left = self.ctx.alloc_imperative_expr(Expr::Contains {
5882 collection: left,
5883 value,
5884 });
5885 }
5886 _ => break,
5887 }
5888 }
5889
5890 Ok(left)
5891 }
5892
5893 fn parse_unary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5895 use crate::ast::{Expr, Literal};
5896
5897 if self.check(&TokenType::Minus) {
5898 self.advance(); let operand = self.parse_unary_expr()?; return Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5902 op: BinaryOpKind::Subtract,
5903 left: self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(0))),
5904 right: operand,
5905 }));
5906 }
5907 self.parse_primary_expr()
5908 }
5909
5910 fn parse_multiplicative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5912 let mut left = self.parse_unary_expr()?;
5913
5914 loop {
5915 let op = match &self.peek().kind {
5916 TokenType::Star => {
5917 self.advance();
5918 BinaryOpKind::Multiply
5919 }
5920 TokenType::Slash => {
5921 self.advance();
5922 BinaryOpKind::Divide
5923 }
5924 TokenType::Percent => {
5925 self.advance();
5926 BinaryOpKind::Modulo
5927 }
5928 _ => break,
5929 };
5930 let right = self.parse_unary_expr()?;
5931 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5932 op,
5933 left,
5934 right,
5935 });
5936 }
5937
5938 Ok(left)
5939 }
5940
5941 fn try_parse_binary_op(&mut self) -> Option<BinaryOpKind> {
5943 match &self.peek().kind {
5944 TokenType::Plus => {
5945 self.advance();
5946 Some(BinaryOpKind::Add)
5947 }
5948 TokenType::Minus => {
5949 self.advance();
5950 Some(BinaryOpKind::Subtract)
5951 }
5952 TokenType::Star => {
5953 self.advance();
5954 Some(BinaryOpKind::Multiply)
5955 }
5956 TokenType::Slash => {
5957 self.advance();
5958 Some(BinaryOpKind::Divide)
5959 }
5960 _ => None,
5961 }
5962 }
5963
5964 fn parse_span_literal_from_num(&mut self, first_num_str: &str) -> ParseResult<&'a Expr<'a>> {
5967 use crate::ast::Literal;
5968 use crate::token::CalendarUnit;
5969
5970 let first_num = first_num_str.parse::<i32>().unwrap_or(0);
5971
5972 let unit = match self.peek().kind {
5974 TokenType::CalendarUnit(u) => u,
5975 _ => {
5976 return Err(ParseError {
5977 kind: ParseErrorKind::ExpectedKeyword { keyword: "calendar unit (day, week, month, year)".to_string() },
5978 span: self.current_span(),
5979 });
5980 }
5981 };
5982 self.advance(); let mut total_months: i32 = 0;
5986 let mut total_days: i32 = 0;
5987
5988 match unit {
5990 CalendarUnit::Day => total_days += first_num,
5991 CalendarUnit::Week => total_days += first_num * 7,
5992 CalendarUnit::Month => total_months += first_num,
5993 CalendarUnit::Year => total_months += first_num * 12,
5994 }
5995
5996 while self.check(&TokenType::And) {
5998 self.advance(); let next_num = match &self.peek().kind {
6002 TokenType::Number(sym) => {
6003 let num_str = self.interner.resolve(*sym).to_string();
6004 self.advance();
6005 num_str.parse::<i32>().unwrap_or(0)
6006 }
6007 _ => break, };
6009
6010 let next_unit = match self.peek().kind {
6012 TokenType::CalendarUnit(u) => {
6013 self.advance();
6014 u
6015 }
6016 _ => break, };
6018
6019 match next_unit {
6021 CalendarUnit::Day => total_days += next_num,
6022 CalendarUnit::Week => total_days += next_num * 7,
6023 CalendarUnit::Month => total_months += next_num,
6024 CalendarUnit::Year => total_months += next_num * 12,
6025 }
6026 }
6027
6028 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Span {
6029 months: total_months,
6030 days: total_days,
6031 })))
6032 }
6033
6034 fn parse_call_expr(&mut self, function: Symbol) -> ParseResult<&'a Expr<'a>> {
6036 use crate::ast::Expr;
6037
6038 self.advance(); let mut args = Vec::new();
6041 if !self.check(&TokenType::RParen) {
6042 loop {
6043 args.push(self.parse_imperative_expr()?);
6044 if !self.check(&TokenType::Comma) {
6045 break;
6046 }
6047 self.advance(); }
6049 }
6050
6051 if !self.check(&TokenType::RParen) {
6052 return Err(ParseError {
6053 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
6054 span: self.current_span(),
6055 });
6056 }
6057 self.advance(); Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
6060 }
6061
6062 fn parse_field_access_chain(&mut self, base: &'a Expr<'a>) -> ParseResult<&'a Expr<'a>> {
6065 use crate::ast::Expr;
6066
6067 let mut result = base;
6068
6069 loop {
6071 if self.check(&TokenType::Possessive) {
6072 self.advance(); let field = self.expect_identifier()?;
6075 result = self.ctx.alloc_imperative_expr(Expr::FieldAccess {
6076 object: result,
6077 field,
6078 });
6079 } else if self.check(&TokenType::LBracket) {
6080 self.advance(); let index = self.parse_imperative_expr()?;
6083
6084 if !self.check(&TokenType::RBracket) {
6085 return Err(ParseError {
6086 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
6087 span: self.current_span(),
6088 });
6089 }
6090 self.advance(); result = self.ctx.alloc_imperative_expr(Expr::Index {
6093 collection: result,
6094 index,
6095 });
6096 } else {
6097 break;
6098 }
6099 }
6100
6101 Ok(result)
6102 }
6103
6104 fn verify_identifier_access(&self, sym: Symbol) -> ParseResult<()> {
6107 if self.mode != ParserMode::Imperative {
6108 return Ok(());
6109 }
6110
6111 if let Some(crate::drs::OwnershipState::Moved) = self.world_state.get_ownership_by_var(sym) {
6113 return Err(ParseError {
6114 kind: ParseErrorKind::UseAfterMove {
6115 name: self.interner.resolve(sym).to_string()
6116 },
6117 span: self.current_span(),
6118 });
6119 }
6120
6121 Ok(())
6122 }
6123
6124 fn expect_identifier(&mut self) -> ParseResult<Symbol> {
6125 let token = self.peek().clone();
6126 match &token.kind {
6127 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
6129 self.advance();
6130 Ok(*sym)
6131 }
6132 TokenType::Verb { .. } => {
6135 let sym = token.lexeme;
6136 self.advance();
6137 Ok(sym)
6138 }
6139 TokenType::Article(_) => {
6141 let sym = token.lexeme;
6142 self.advance();
6143 Ok(sym)
6144 }
6145 TokenType::Pronoun { .. } | TokenType::Items | TokenType::Values | TokenType::Item | TokenType::Nothing | TokenType::TemporalAdverb(_) |
6153 TokenType::ScopalAdverb(_) |
6154 TokenType::Adverb(_) |
6155 TokenType::Read |
6157 TokenType::Write |
6158 TokenType::File |
6159 TokenType::Console |
6160 TokenType::Merge |
6162 TokenType::Increase |
6163 TokenType::Decrease |
6164 TokenType::Tally |
6166 TokenType::SharedSet |
6167 TokenType::SharedSequence |
6168 TokenType::CollaborativeSequence |
6169 TokenType::Add |
6172 TokenType::Remove |
6173 TokenType::First |
6174 TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared | TokenType::CalendarUnit(_) |
6181 TokenType::Focus(_) |
6183 TokenType::Escape => {
6185 let sym = token.lexeme;
6187 self.advance();
6188 Ok(sym)
6189 }
6190 TokenType::Ambiguous { .. } => {
6191 let sym = token.lexeme;
6194 self.advance();
6195 Ok(sym)
6196 }
6197 _ => Err(ParseError {
6198 kind: ParseErrorKind::ExpectedIdentifier,
6199 span: self.current_span(),
6200 }),
6201 }
6202 }
6203
6204 fn consume_content_word_for_relative(&mut self) -> ParseResult<Symbol> {
6205 let t = self.advance().clone();
6206 match t.kind {
6207 TokenType::Noun(s) | TokenType::Adjective(s) => Ok(s),
6208 TokenType::ProperName(s) => Ok(s),
6209 TokenType::Verb { lemma, .. } => Ok(lemma),
6210 other => Err(ParseError {
6211 kind: ParseErrorKind::ExpectedContentWord { found: other },
6212 span: self.current_span(),
6213 }),
6214 }
6215 }
6216
6217 fn check_modal(&self) -> bool {
6218 matches!(
6219 self.peek().kind,
6220 TokenType::Must
6221 | TokenType::Shall
6222 | TokenType::Should
6223 | TokenType::Can
6224 | TokenType::May
6225 | TokenType::Cannot
6226 | TokenType::Could
6227 | TokenType::Would
6228 | TokenType::Might
6229 )
6230 }
6231
6232 fn check_pronoun(&self) -> bool {
6233 match &self.peek().kind {
6234 TokenType::Pronoun { case, .. } => {
6235 if self.noun_priority_mode && matches!(case, Case::Possessive) {
6237 return false;
6238 }
6239 true
6240 }
6241 TokenType::Ambiguous { primary, alternatives } => {
6242 if self.noun_priority_mode {
6244 let has_possessive = matches!(**primary, TokenType::Pronoun { case: Case::Possessive, .. })
6245 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { case: Case::Possessive, .. }));
6246 if has_possessive {
6247 return false;
6248 }
6249 }
6250 matches!(**primary, TokenType::Pronoun { .. })
6251 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { .. }))
6252 }
6253 _ => false,
6254 }
6255 }
6256
6257 fn parse_atom(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
6258 if self.check_focus() {
6260 return self.parse_focus();
6261 }
6262
6263 if self.check_measure() {
6265 return self.parse_measure();
6266 }
6267
6268 if self.check_quantifier() {
6269 self.advance();
6270 return self.parse_quantified();
6271 }
6272
6273 if self.check_npi_quantifier() {
6274 return self.parse_npi_quantified();
6275 }
6276
6277 if self.check_temporal_npi() {
6278 return self.parse_temporal_npi();
6279 }
6280
6281 if self.match_token(&[TokenType::LParen]) {
6282 let expr = self.parse_sentence()?;
6283 self.consume(TokenType::RParen)?;
6284 return Ok(expr);
6285 }
6286
6287 if self.check_pronoun() {
6289 let token = self.advance().clone();
6290 let (gender, number) = match &token.kind {
6291 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
6292 TokenType::Ambiguous { primary, alternatives } => {
6293 if let TokenType::Pronoun { gender, number, .. } = **primary {
6294 (gender, number)
6295 } else {
6296 alternatives.iter().find_map(|t| {
6297 if let TokenType::Pronoun { gender, number, .. } = t {
6298 Some((*gender, *number))
6299 } else {
6300 None
6301 }
6302 }).unwrap_or((Gender::Unknown, Number::Singular))
6303 }
6304 }
6305 _ => (Gender::Unknown, Number::Singular),
6306 };
6307
6308 let token_text = self.interner.resolve(token.lexeme);
6309
6310 if token_text.eq_ignore_ascii_case("it") && self.check_verb() {
6313 if let TokenType::Verb { lemma, time, .. } = &self.peek().kind {
6314 let lemma_str = self.interner.resolve(*lemma);
6315 if Lexer::is_weather_verb(lemma_str) {
6316 let verb = *lemma;
6317 let verb_time = *time;
6318 self.advance(); let event_var = self.get_event_var();
6321 let suppress_existential = self.drs.in_conditional_antecedent();
6322 if suppress_existential {
6323 let event_class = self.interner.intern("Event");
6324 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
6325 }
6326 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6327 event_var,
6328 verb,
6329 roles: self.ctx.roles.alloc_slice(vec![]), modifiers: self.ctx.syms.alloc_slice(vec![]),
6331 suppress_existential,
6332 world: None,
6333 })));
6334
6335 return Ok(match verb_time {
6336 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
6337 operator: TemporalOperator::Past,
6338 body: neo_event,
6339 }),
6340 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
6341 operator: TemporalOperator::Future,
6342 body: neo_event,
6343 }),
6344 _ => neo_event,
6345 });
6346 }
6347 }
6348 }
6349
6350 let resolved = if token_text.eq_ignore_ascii_case("i") {
6352 ResolvedPronoun::Constant(self.interner.intern("Speaker"))
6353 } else if token_text.eq_ignore_ascii_case("you") {
6354 ResolvedPronoun::Constant(self.interner.intern("Addressee"))
6355 } else {
6356 self.resolve_pronoun(gender, number)?
6358 };
6359
6360 if self.check_performative() {
6362 if let TokenType::Performative(act) = self.advance().kind.clone() {
6363 let sym = match resolved {
6364 ResolvedPronoun::Variable(s) | ResolvedPronoun::Constant(s) => s,
6365 };
6366 if self.check(&TokenType::To) {
6368 self.advance(); if self.check_verb() {
6371 let infinitive_verb = self.consume_verb();
6372
6373 let content = self.ctx.exprs.alloc(LogicExpr::Predicate {
6374 name: infinitive_verb,
6375 args: self.ctx.terms.alloc_slice([Term::Constant(sym)]),
6376 world: None,
6377 });
6378
6379 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6380 performer: sym,
6381 act_type: act,
6382 content,
6383 }));
6384 }
6385 }
6386
6387 if self.check(&TokenType::That) {
6389 self.advance();
6390 }
6391 let content = self.parse_sentence()?;
6392 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6393 performer: sym,
6394 act_type: act,
6395 content,
6396 }));
6397 }
6398 }
6399
6400 return match resolved {
6403 ResolvedPronoun::Variable(sym) => self.parse_predicate_with_subject_as_var(sym),
6404 ResolvedPronoun::Constant(sym) => self.parse_predicate_with_subject(sym),
6405 };
6406 }
6407
6408 let _had_both = self.match_token(&[TokenType::Both]);
6411
6412 let subject = self.parse_noun_phrase(true)?;
6413
6414 if subject.definiteness == Some(Definiteness::Indefinite)
6420 || subject.definiteness == Some(Definiteness::Distal) {
6421 let gender = Self::infer_noun_gender(self.interner.resolve(subject.noun));
6422 let number = if Self::is_plural_noun(self.interner.resolve(subject.noun)) {
6423 Number::Plural
6424 } else {
6425 Number::Singular
6426 };
6427 self.drs.introduce_referent(subject.noun, subject.noun, gender, number);
6429 }
6430
6431 if self.check(&TokenType::And) {
6433 match self.try_parse_plural_subject(&subject) {
6434 Ok(Some(result)) => return Ok(result),
6435 Ok(None) => {} Err(e) => return Err(e), }
6438 }
6439
6440 if self.check_scopal_adverb() {
6442 return self.parse_scopal_adverb(&subject);
6443 }
6444
6445 if self.check(&TokenType::Comma) {
6447 let saved_pos = self.current;
6448 self.advance(); if self.check_pronoun() {
6452 let topic_attempt = self.try_parse(|p| {
6453 let token = p.peek().clone();
6454 let pronoun_features = match &token.kind {
6455 TokenType::Pronoun { gender, number, .. } => Some((*gender, *number)),
6456 TokenType::Ambiguous { primary, alternatives } => {
6457 if let TokenType::Pronoun { gender, number, .. } = **primary {
6458 Some((gender, number))
6459 } else {
6460 alternatives.iter().find_map(|t| {
6461 if let TokenType::Pronoun { gender, number, .. } = t {
6462 Some((*gender, *number))
6463 } else {
6464 None
6465 }
6466 })
6467 }
6468 }
6469 _ => None,
6470 };
6471
6472 if let Some((gender, number)) = pronoun_features {
6473 p.advance(); let resolved = p.resolve_pronoun(gender, number)?;
6475 let resolved_term = match resolved {
6476 ResolvedPronoun::Variable(s) => Term::Variable(s),
6477 ResolvedPronoun::Constant(s) => Term::Constant(s),
6478 };
6479
6480 if p.check_verb() {
6481 let verb = p.consume_verb();
6482 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6483 name: verb,
6484 args: p.ctx.terms.alloc_slice([
6485 resolved_term,
6486 Term::Constant(subject.noun),
6487 ]),
6488 world: None,
6489 });
6490 p.wrap_with_definiteness_full(&subject, predicate)
6491 } else {
6492 Err(ParseError {
6493 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6494 span: p.current_span(),
6495 })
6496 }
6497 } else {
6498 Err(ParseError {
6499 kind: ParseErrorKind::ExpectedContentWord { found: token.kind },
6500 span: p.current_span(),
6501 })
6502 }
6503 });
6504
6505 if let Some(result) = topic_attempt {
6506 return Ok(result);
6507 }
6508 }
6509
6510 if self.check_content_word() {
6512 let topic_attempt = self.try_parse(|p| {
6513 let real_subject = p.parse_noun_phrase(true)?;
6514 if p.check_verb() {
6515 let verb = p.consume_verb();
6516 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6517 name: verb,
6518 args: p.ctx.terms.alloc_slice([
6519 Term::Constant(real_subject.noun),
6520 Term::Constant(subject.noun),
6521 ]),
6522 world: None,
6523 });
6524 p.wrap_with_definiteness_full(&subject, predicate)
6525 } else {
6526 Err(ParseError {
6527 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6528 span: p.current_span(),
6529 })
6530 }
6531 });
6532
6533 if let Some(result) = topic_attempt {
6534 return Ok(result);
6535 }
6536 }
6537
6538 self.current = saved_pos;
6540 }
6541
6542 let mut relative_clause: Option<(Symbol, &'a LogicExpr<'a>)> = None;
6544 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
6545 self.advance();
6546 let var_name = self.next_var_name();
6547 let rel_pred = self.parse_relative_clause(var_name)?;
6548 relative_clause = Some((var_name, rel_pred));
6549 } else if matches!(self.peek().kind, TokenType::Article(_)) && self.is_contact_clause_pattern() {
6550 let var_name = self.next_var_name();
6553 let rel_pred = self.parse_relative_clause(var_name)?;
6554 relative_clause = Some((var_name, rel_pred));
6555 }
6556
6557 if let Some((var_name, rel_clause)) = relative_clause {
6559 if self.check_verb() {
6560 let (verb, verb_time, _, _) = self.consume_verb_with_metadata();
6561 let var_term = Term::Variable(var_name);
6562
6563 let event_var = self.get_event_var();
6564 let suppress_existential = self.drs.in_conditional_antecedent();
6565 let mut modifiers = vec![];
6566 if verb_time == Time::Past {
6567 modifiers.push(self.interner.intern("Past"));
6568 }
6569 let main_pred = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6570 event_var,
6571 verb,
6572 roles: self.ctx.roles.alloc_slice(vec![
6573 (ThematicRole::Agent, var_term),
6574 ]),
6575 modifiers: self.ctx.syms.alloc_slice(modifiers),
6576 suppress_existential,
6577 world: None,
6578 })));
6579
6580 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6581 name: subject.noun,
6582 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6583 world: None,
6584 });
6585
6586 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6587 left: type_pred,
6588 op: TokenType::And,
6589 right: rel_clause,
6590 });
6591
6592 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6593 left: inner,
6594 op: TokenType::And,
6595 right: main_pred,
6596 });
6597
6598 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6599 kind: QuantifierKind::Existential,
6600 variable: var_name,
6601 body,
6602 island_id: self.current_island,
6603 }));
6604 }
6605
6606 if self.is_at_end() || self.check(&TokenType::Period) || self.check(&TokenType::Comma) {
6609 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6610 name: subject.noun,
6611 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6612 world: None,
6613 });
6614
6615 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6616 left: type_pred,
6617 op: TokenType::And,
6618 right: rel_clause,
6619 });
6620
6621 let uniqueness_body = if subject.definiteness == Some(Definiteness::Definite) {
6623 let y_var = self.next_var_name();
6624 let type_pred_y = self.ctx.exprs.alloc(LogicExpr::Predicate {
6625 name: subject.noun,
6626 args: self.ctx.terms.alloc_slice([Term::Variable(y_var)]),
6627 world: None,
6628 });
6629 let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
6630 left: self.ctx.terms.alloc(Term::Variable(y_var)),
6631 right: self.ctx.terms.alloc(Term::Variable(var_name)),
6632 });
6633 let uniqueness_cond = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6634 left: type_pred_y,
6635 op: TokenType::If,
6636 right: identity,
6637 });
6638 let uniqueness = self.ctx.exprs.alloc(LogicExpr::Quantifier {
6639 kind: QuantifierKind::Universal,
6640 variable: y_var,
6641 body: uniqueness_cond,
6642 island_id: self.current_island,
6643 });
6644 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6645 left: body,
6646 op: TokenType::And,
6647 right: uniqueness,
6648 })
6649 } else {
6650 body
6651 };
6652
6653 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6654 kind: QuantifierKind::Existential,
6655 variable: var_name,
6656 body: uniqueness_body,
6657 island_id: self.current_island,
6658 }));
6659 }
6660
6661 relative_clause = Some((var_name, rel_clause));
6663 }
6664
6665 if self.check(&TokenType::Identity) {
6667 self.advance();
6668 let right = self.consume_content_word()?;
6669 return Ok(self.ctx.exprs.alloc(LogicExpr::Identity {
6670 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6671 right: self.ctx.terms.alloc(Term::Constant(right)),
6672 }));
6673 }
6674
6675 if self.check_modal() {
6676 if let Some((var_name, rel_clause)) = relative_clause {
6677 let modal_pred = self.parse_aspect_chain_with_term(Term::Variable(var_name))?;
6678
6679 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6680 name: subject.noun,
6681 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6682 world: None,
6683 });
6684
6685 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6686 left: type_pred,
6687 op: TokenType::And,
6688 right: rel_clause,
6689 });
6690
6691 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6692 left: inner,
6693 op: TokenType::And,
6694 right: modal_pred,
6695 });
6696
6697 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6698 kind: QuantifierKind::Existential,
6699 variable: var_name,
6700 body,
6701 island_id: self.current_island,
6702 }));
6703 }
6704
6705 let modal_pred = self.parse_aspect_chain(subject.noun)?;
6706 return self.wrap_with_definiteness_full(&subject, modal_pred);
6707 }
6708
6709 if self.check(&TokenType::Is) || self.check(&TokenType::Are)
6710 || self.check(&TokenType::Was) || self.check(&TokenType::Were)
6711 {
6712 let copula_time = if self.check(&TokenType::Was) || self.check(&TokenType::Were) {
6713 Time::Past
6714 } else {
6715 Time::Present
6716 };
6717 self.advance();
6718
6719 let is_negated = self.check(&TokenType::Not);
6721 if is_negated {
6722 self.advance(); }
6724
6725 if self.check_number() {
6728 let measure = self.parse_measure_phrase()?;
6729
6730 if self.check_comparative() {
6732 return self.parse_comparative(&subject, copula_time, Some(measure));
6733 }
6734
6735 if self.check_content_word() {
6737 let adj = self.consume_content_word()?;
6738 let result = self.ctx.exprs.alloc(LogicExpr::Predicate {
6739 name: adj,
6740 args: self.ctx.terms.alloc_slice([
6741 Term::Constant(subject.noun),
6742 *measure,
6743 ]),
6744 world: None,
6745 });
6746 return self.wrap_with_definiteness_full(&subject, result);
6747 }
6748
6749 if self.check(&TokenType::Period) || self.is_at_end() {
6752 if self.mode == ParserMode::Imperative {
6754 let variable = self.interner.resolve(subject.noun).to_string();
6755 let value = if let Term::Value { kind, .. } = measure {
6756 format!("{:?}", kind)
6757 } else {
6758 "value".to_string()
6759 };
6760 return Err(ParseError {
6761 kind: ParseErrorKind::IsValueEquality { variable, value },
6762 span: self.current_span(),
6763 });
6764 }
6765 let result = self.ctx.exprs.alloc(LogicExpr::Identity {
6766 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6767 right: measure,
6768 });
6769 return self.wrap_with_definiteness_full(&subject, result);
6770 }
6771 }
6772
6773 if self.check_comparative() {
6775 return self.parse_comparative(&subject, copula_time, None);
6776 }
6777
6778 if self.check(&TokenType::Period) || self.is_at_end() {
6780 let var = self.next_var_name();
6781 let body = self.ctx.exprs.alloc(LogicExpr::Identity {
6782 left: self.ctx.terms.alloc(Term::Variable(var)),
6783 right: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6784 });
6785 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6786 kind: QuantifierKind::Existential,
6787 variable: var,
6788 body,
6789 island_id: self.current_island,
6790 }));
6791 }
6792
6793 if self.check(&TokenType::Article(Definiteness::Definite)) {
6795 let saved_pos = self.current;
6796 self.advance();
6797 if self.check_superlative() {
6798 return self.parse_superlative(&subject);
6799 }
6800 self.current = saved_pos;
6801 }
6802
6803 if self.check_article() {
6805 let predicate_np = self.parse_noun_phrase(true)?;
6806 let predicate_noun = predicate_np.noun;
6807
6808 if self.event_reading_mode {
6811 let noun_str = self.interner.resolve(predicate_noun);
6812 if let Some(base_verb) = lexicon::lookup_agentive_noun(noun_str) {
6813 let event_adj = predicate_np.adjectives.iter().find(|adj| {
6815 lexicon::is_event_modifier_adjective(self.interner.resolve(**adj))
6816 });
6817
6818 if let Some(&adj_sym) = event_adj {
6819 let verb_sym = self.interner.intern(base_verb);
6821 let event_var = self.get_event_var();
6822
6823 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6824 name: verb_sym,
6825 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
6826 world: None,
6827 });
6828
6829 let agent_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6830 name: self.interner.intern("Agent"),
6831 args: self.ctx.terms.alloc_slice([
6832 Term::Variable(event_var),
6833 Term::Constant(subject.noun),
6834 ]),
6835 world: None,
6836 });
6837
6838 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6839 name: adj_sym,
6840 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
6841 world: None,
6842 });
6843
6844 let verb_agent = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6846 left: verb_pred,
6847 op: TokenType::And,
6848 right: agent_pred,
6849 });
6850
6851 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6853 left: verb_agent,
6854 op: TokenType::And,
6855 right: adj_pred,
6856 });
6857
6858 let event_reading = self.ctx.exprs.alloc(LogicExpr::Quantifier {
6860 kind: QuantifierKind::Existential,
6861 variable: event_var,
6862 body,
6863 island_id: self.current_island,
6864 });
6865
6866 return self.wrap_with_definiteness(subject.definiteness, subject.noun, event_reading);
6867 }
6868 }
6869 }
6870
6871 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
6872 let predicate_sort = lexicon::lookup_sort(self.interner.resolve(predicate_noun));
6873
6874 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
6875 if !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
6876 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
6877 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
6878 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_noun)),
6879 });
6880 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
6881 }
6882 }
6883
6884 let mut predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
6887
6888 for &adj_sym in predicate_np.adjectives {
6890 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6891 name: adj_sym,
6892 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
6893 world: None,
6894 });
6895 predicates.push(adj_pred);
6896 }
6897
6898 let noun_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6900 name: predicate_noun,
6901 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
6902 world: None,
6903 });
6904 predicates.push(noun_pred);
6905
6906 let result = if predicates.len() == 1 {
6908 predicates[0]
6909 } else {
6910 let mut combined = predicates[0];
6911 for pred in &predicates[1..] {
6912 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6913 left: combined,
6914 op: TokenType::And,
6915 right: *pred,
6916 });
6917 }
6918 combined
6919 };
6920
6921 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
6922 }
6923
6924 let prefer_adjective = if let TokenType::Ambiguous { primary, alternatives } = &self.peek().kind {
6927 let is_simple_verb = if let TokenType::Verb { aspect, .. } = **primary {
6928 aspect == Aspect::Simple
6929 } else {
6930 false
6931 };
6932 let has_adj_alt = alternatives.iter().any(|t| matches!(t, TokenType::Adjective(_)));
6933 is_simple_verb && has_adj_alt
6934 } else {
6935 false
6936 };
6937
6938 if !prefer_adjective && self.check_verb() {
6939 let (verb, _verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
6940
6941 if verb_class.is_stative() && verb_aspect == Aspect::Progressive {
6943 return Err(ParseError {
6944 kind: ParseErrorKind::StativeProgressiveConflict,
6945 span: self.current_span(),
6946 });
6947 }
6948
6949 let mut goal_args: Vec<Term<'a>> = Vec::new();
6952 while self.check_to_preposition() {
6953 self.advance(); let goal = self.parse_noun_phrase(true)?;
6955 goal_args.push(self.noun_phrase_to_term(&goal));
6956 }
6957
6958 if self.check_by_preposition() {
6960 self.advance(); let agent = self.parse_noun_phrase(true)?;
6962
6963 let mut args = vec![
6965 self.noun_phrase_to_term(&agent),
6966 self.noun_phrase_to_term(&subject),
6967 ];
6968 args.extend(goal_args);
6969
6970 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
6971 name: verb,
6972 args: self.ctx.terms.alloc_slice(args),
6973 world: None,
6974 });
6975
6976 let with_time = if copula_time == Time::Past {
6977 self.ctx.exprs.alloc(LogicExpr::Temporal {
6978 operator: TemporalOperator::Past,
6979 body: predicate,
6980 })
6981 } else {
6982 predicate
6983 };
6984
6985 return self.wrap_with_definiteness(subject.definiteness, subject.noun, with_time);
6986 }
6987
6988 if copula_time == Time::Past && verb_aspect == Aspect::Simple
6993 && subject.definiteness != Some(Definiteness::Definite) {
6994 let var_name = self.next_var_name();
6996 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
6997 name: verb,
6998 args: self.ctx.terms.alloc_slice([
6999 Term::Variable(var_name),
7000 Term::Constant(subject.noun),
7001 ]),
7002 world: None,
7003 });
7004
7005 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7006 name: subject.noun,
7007 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7008 world: None,
7009 });
7010
7011 let temporal = self.ctx.exprs.alloc(LogicExpr::Temporal {
7012 operator: TemporalOperator::Past,
7013 body: predicate,
7014 });
7015
7016 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7017 left: type_pred,
7018 op: TokenType::And,
7019 right: temporal,
7020 });
7021
7022 let result = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7023 kind: QuantifierKind::Existential,
7024 variable: var_name,
7025 body,
7026 island_id: self.current_island,
7027 });
7028
7029 if is_negated {
7031 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7032 op: TokenType::Not,
7033 operand: result,
7034 }));
7035 }
7036 return Ok(result);
7037 }
7038
7039 let verb_str = self.interner.resolve(verb).to_lowercase();
7042 let subject_term = if lexicon::is_intensional_predicate(&verb_str) {
7043 Term::Intension(subject.noun)
7044 } else {
7045 Term::Constant(subject.noun)
7046 };
7047
7048 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7049 name: verb,
7050 args: self.ctx.terms.alloc_slice([subject_term]),
7051 world: None,
7052 });
7053
7054 let with_aspect = if verb_aspect == Aspect::Progressive {
7055 let operator = if verb_class == VerbClass::Semelfactive {
7057 AspectOperator::Iterative
7058 } else {
7059 AspectOperator::Progressive
7060 };
7061 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7062 operator,
7063 body: predicate,
7064 })
7065 } else {
7066 predicate
7067 };
7068
7069 let with_time = if copula_time == Time::Past {
7070 self.ctx.exprs.alloc(LogicExpr::Temporal {
7071 operator: TemporalOperator::Past,
7072 body: with_aspect,
7073 })
7074 } else {
7075 with_aspect
7076 };
7077
7078 let final_expr = if is_negated {
7079 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7080 op: TokenType::Not,
7081 operand: with_time,
7082 })
7083 } else {
7084 with_time
7085 };
7086
7087 if subject.definiteness == Some(Definiteness::Definite) {
7091 return Ok(final_expr);
7092 }
7093
7094 return self.wrap_with_definiteness(subject.definiteness, subject.noun, final_expr);
7095 }
7096
7097 if let Some((var_name, rel_clause)) = relative_clause {
7099 let var_term = Term::Variable(var_name);
7100 let pred_word = self.consume_content_word()?;
7101
7102 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7103 name: pred_word,
7104 args: self.ctx.terms.alloc_slice([var_term]),
7105 world: None,
7106 });
7107
7108 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7109 name: subject.noun,
7110 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7111 world: None,
7112 });
7113
7114 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7115 left: type_pred,
7116 op: TokenType::And,
7117 right: rel_clause,
7118 });
7119
7120 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7121 left: inner,
7122 op: TokenType::And,
7123 right: main_pred,
7124 });
7125
7126 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7127 kind: QuantifierKind::Existential,
7128 variable: var_name,
7129 body,
7130 island_id: self.current_island,
7131 }));
7132 }
7133
7134 if let TokenType::ProperName(predicate_name) = self.peek().kind {
7139 self.advance(); let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
7141 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7142 right: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7143 });
7144 let result = if is_negated {
7145 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7146 op: TokenType::Not,
7147 operand: identity,
7148 })
7149 } else {
7150 identity
7151 };
7152 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7153 }
7154
7155 let predicate_name = self.consume_content_word()?;
7158
7159 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7161 let predicate_str = self.interner.resolve(predicate_name);
7162
7163 if let Some(s_sort) = subject_sort {
7165 if !crate::ontology::check_sort_compatibility(predicate_str, s_sort) {
7166 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7167 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7168 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7169 });
7170 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7171 }
7172 }
7173
7174 let predicate_sort = lexicon::lookup_sort(predicate_str);
7176 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
7177 if s_sort != p_sort && !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
7178 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7179 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7180 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7181 });
7182 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7183 }
7184 }
7185
7186 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7187 name: predicate_name,
7188 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7189 world: None,
7190 });
7191
7192 let result = if is_negated {
7194 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7195 op: TokenType::Not,
7196 operand: predicate,
7197 })
7198 } else {
7199 predicate
7200 };
7201 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7202 }
7203
7204 if self.check_auxiliary() && self.is_true_auxiliary_usage() {
7208 let aux_time = if let TokenType::Auxiliary(time) = self.advance().kind {
7209 time
7210 } else {
7211 Time::None
7212 };
7213 self.pending_time = Some(aux_time);
7214
7215 if self.match_token(&[TokenType::Not]) {
7217 self.negative_depth += 1;
7218
7219 if self.check(&TokenType::Ever) {
7221 self.advance();
7222 }
7223
7224 if self.check_verb() || self.check(&TokenType::Do) {
7226 let verb = if self.check(&TokenType::Do) {
7227 self.advance(); self.interner.intern("Do")
7229 } else {
7230 self.consume_verb()
7231 };
7232 let subject_term = self.noun_phrase_to_term(&subject);
7233
7234 if self.check_npi_object() {
7236 let npi_token = self.advance().kind.clone();
7237 let obj_var = self.next_var_name();
7238
7239 let restriction_name = match npi_token {
7240 TokenType::Anything => "Thing",
7241 TokenType::Anyone => "Person",
7242 _ => "Thing",
7243 };
7244
7245 let restriction_sym = self.interner.intern(restriction_name);
7246 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7247 name: restriction_sym,
7248 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7249 world: None,
7250 });
7251
7252 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7253 name: verb,
7254 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7255 world: None,
7256 });
7257
7258 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7259 left: obj_restriction,
7260 op: TokenType::And,
7261 right: verb_pred,
7262 });
7263
7264 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7265 kind: QuantifierKind::Existential,
7266 variable: obj_var,
7267 body,
7268 island_id: self.current_island,
7269 });
7270
7271 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7272 let with_time = match effective_time {
7273 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7274 operator: TemporalOperator::Past,
7275 body: quantified,
7276 }),
7277 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7278 operator: TemporalOperator::Future,
7279 body: quantified,
7280 }),
7281 _ => quantified,
7282 };
7283
7284 self.negative_depth -= 1;
7285 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7286 op: TokenType::Not,
7287 operand: with_time,
7288 }));
7289 }
7290
7291 if self.check_quantifier() {
7293 let quantifier_token = self.advance().kind.clone();
7294 let object_np = self.parse_noun_phrase(false)?;
7295 let obj_var = self.next_var_name();
7296
7297 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7298 name: object_np.noun,
7299 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7300 world: None,
7301 });
7302
7303 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7304 name: verb,
7305 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7306 world: None,
7307 });
7308
7309 let (kind, body) = match quantifier_token {
7310 TokenType::Any => {
7311 if self.is_negative_context() {
7312 (
7313 QuantifierKind::Existential,
7314 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7315 left: obj_restriction,
7316 op: TokenType::And,
7317 right: verb_pred,
7318 }),
7319 )
7320 } else {
7321 (
7322 QuantifierKind::Universal,
7323 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7324 left: obj_restriction,
7325 op: TokenType::If,
7326 right: verb_pred,
7327 }),
7328 )
7329 }
7330 }
7331 TokenType::Some => (
7332 QuantifierKind::Existential,
7333 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7334 left: obj_restriction,
7335 op: TokenType::And,
7336 right: verb_pred,
7337 }),
7338 ),
7339 TokenType::All => (
7340 QuantifierKind::Universal,
7341 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7342 left: obj_restriction,
7343 op: TokenType::If,
7344 right: verb_pred,
7345 }),
7346 ),
7347 _ => (
7348 QuantifierKind::Existential,
7349 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7350 left: obj_restriction,
7351 op: TokenType::And,
7352 right: verb_pred,
7353 }),
7354 ),
7355 };
7356
7357 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7358 kind,
7359 variable: obj_var,
7360 body,
7361 island_id: self.current_island,
7362 });
7363
7364 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7365 let with_time = match effective_time {
7366 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7367 operator: TemporalOperator::Past,
7368 body: quantified,
7369 }),
7370 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7371 operator: TemporalOperator::Future,
7372 body: quantified,
7373 }),
7374 _ => quantified,
7375 };
7376
7377 self.negative_depth -= 1;
7378 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7379 op: TokenType::Not,
7380 operand: with_time,
7381 }));
7382 }
7383
7384 let mut roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
7385
7386 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7388 let mut modifiers: Vec<Symbol> = vec![];
7389 match effective_time {
7390 Time::Past => modifiers.push(self.interner.intern("Past")),
7391 Time::Future => modifiers.push(self.interner.intern("Future")),
7392 _ => {}
7393 }
7394
7395 if self.check_content_word() || self.check_article() || self.check_pronoun() {
7397 if self.check_pronoun() {
7398 let pronoun_token = self.advance();
7400 let pronoun_sym = pronoun_token.lexeme;
7401 roles.push((ThematicRole::Theme, Term::Constant(pronoun_sym)));
7402 } else {
7403 let object = self.parse_noun_phrase(false)?;
7404 let object_term = self.noun_phrase_to_term(&object);
7405 roles.push((ThematicRole::Theme, object_term));
7406 }
7407 }
7408
7409 let event_var = self.get_event_var();
7410 let suppress_existential = self.drs.in_conditional_antecedent();
7411 if suppress_existential {
7412 let event_class = self.interner.intern("Event");
7413 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7414 }
7415 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7416 event_var,
7417 verb,
7418 roles: self.ctx.roles.alloc_slice(roles),
7419 modifiers: self.ctx.syms.alloc_slice(modifiers),
7420 suppress_existential,
7421 world: None,
7422 })));
7423
7424 self.negative_depth -= 1;
7425 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7426 op: TokenType::Not,
7427 operand: neo_event,
7428 }));
7429 }
7430
7431 self.negative_depth -= 1;
7432 }
7433 }
7435
7436 if self.check_presup_trigger() && !self.is_followed_by_np_object() && self.is_followed_by_gerund() {
7442 let presup_kind = match self.advance().kind {
7443 TokenType::PresupTrigger(kind) => kind,
7444 TokenType::Verb { lemma, .. } => {
7445 let s = self.interner.resolve(lemma).to_lowercase();
7446 crate::lexicon::lookup_presup_trigger(&s)
7447 .expect("Lexicon mismatch: Verb flagged as trigger but lookup failed")
7448 }
7449 _ => panic!("Expected presupposition trigger"),
7450 };
7451 return self.parse_presupposition(&subject, presup_kind);
7452 }
7453
7454 let noun_str = self.interner.resolve(subject.noun);
7456 let is_bare_plural = subject.definiteness.is_none()
7457 && subject.possessor.is_none()
7458 && Self::is_plural_noun(noun_str)
7459 && self.check_verb();
7460
7461 if is_bare_plural {
7462 let var_name = self.next_var_name();
7463 let (verb, verb_time, verb_aspect, _) = self.consume_verb_with_metadata();
7464
7465 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7466 name: subject.noun,
7467 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7468 world: None,
7469 });
7470
7471 let mut args = vec![Term::Variable(var_name)];
7472 if self.check_content_word() {
7473 let object = self.parse_noun_phrase(false)?;
7474 args.push(self.noun_phrase_to_term(&object));
7475 }
7476
7477 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7478 name: verb,
7479 args: self.ctx.terms.alloc_slice(args),
7480 world: None,
7481 });
7482
7483 let effective_time = self.pending_time.take().unwrap_or(verb_time);
7484 let with_time = match effective_time {
7485 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7486 operator: TemporalOperator::Past,
7487 body: verb_pred,
7488 }),
7489 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7490 operator: TemporalOperator::Future,
7491 body: verb_pred,
7492 }),
7493 _ => verb_pred,
7494 };
7495
7496 let with_aspect = if verb_aspect == Aspect::Progressive {
7497 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7498 operator: AspectOperator::Progressive,
7499 body: with_time,
7500 })
7501 } else {
7502 with_time
7503 };
7504
7505 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7506 left: type_pred,
7507 op: TokenType::If,
7508 right: with_aspect,
7509 });
7510
7511 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7512 kind: QuantifierKind::Generic,
7513 variable: var_name,
7514 body,
7515 island_id: self.current_island,
7516 }));
7517 }
7518
7519 if self.check(&TokenType::Does) || self.check(&TokenType::Do) {
7521 self.advance(); let is_negated = self.match_token(&[TokenType::Not]);
7523
7524 if self.check_verb() {
7525 let verb = self.consume_verb();
7526 let verb_lemma = self.interner.resolve(verb).to_lowercase();
7527
7528 if self.check_wh_word() {
7530 let wh_token = self.advance().kind.clone();
7531 let is_who = matches!(wh_token, TokenType::Who);
7532 let is_what = matches!(wh_token, TokenType::What);
7533
7534 let is_sluicing = self.is_at_end() ||
7535 self.check(&TokenType::Period) ||
7536 self.check(&TokenType::Comma);
7537
7538 if is_sluicing {
7539 if let Some(template) = self.last_event_template.clone() {
7540 let wh_var = self.next_var_name();
7541 let subject_term = self.noun_phrase_to_term(&subject);
7542
7543 let roles: Vec<_> = if is_who {
7544 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7545 .chain(template.non_agent_roles.iter().cloned())
7546 .collect()
7547 } else if is_what {
7548 vec![
7549 (ThematicRole::Agent, subject_term.clone()),
7550 (ThematicRole::Theme, Term::Variable(wh_var)),
7551 ]
7552 } else {
7553 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7554 .chain(template.non_agent_roles.iter().cloned())
7555 .collect()
7556 };
7557
7558 let event_var = self.get_event_var();
7559 let suppress_existential = self.drs.in_conditional_antecedent();
7560 if suppress_existential {
7561 let event_class = self.interner.intern("Event");
7562 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7563 }
7564 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7565 event_var,
7566 verb: template.verb,
7567 roles: self.ctx.roles.alloc_slice(roles),
7568 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
7569 suppress_existential,
7570 world: None,
7571 })));
7572
7573 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7574 wh_variable: wh_var,
7575 body: reconstructed,
7576 });
7577
7578 let know_event_var = self.get_event_var();
7579 let suppress_existential2 = self.drs.in_conditional_antecedent();
7580 if suppress_existential2 {
7581 let event_class = self.interner.intern("Event");
7582 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
7583 }
7584 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7585 event_var: know_event_var,
7586 verb,
7587 roles: self.ctx.roles.alloc_slice(vec![
7588 (ThematicRole::Agent, subject_term),
7589 (ThematicRole::Theme, Term::Proposition(question)),
7590 ]),
7591 modifiers: self.ctx.syms.alloc_slice(vec![]),
7592 suppress_existential: suppress_existential2,
7593 world: None,
7594 })));
7595
7596 let result = if is_negated {
7597 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7598 op: TokenType::Not,
7599 operand: know_event,
7600 })
7601 } else {
7602 know_event
7603 };
7604
7605 return self.wrap_with_definiteness_full(&subject, result);
7606 }
7607 }
7608 }
7609
7610 if verb_lemma == "exist" && is_negated {
7612 let var_name = self.next_var_name();
7614 let restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7615 name: subject.noun,
7616 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7617 world: None,
7618 });
7619 let exists = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7620 kind: QuantifierKind::Existential,
7621 variable: var_name,
7622 body: restriction,
7623 island_id: self.current_island,
7624 });
7625 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7626 op: TokenType::Not,
7627 operand: exists,
7628 }));
7629 }
7630
7631 let subject_term = self.noun_phrase_to_term(&subject);
7634 let modifiers: Vec<Symbol> = vec![];
7635
7636 if self.check(&TokenType::Reflexive) {
7638 self.advance();
7639 let roles = vec![
7640 (ThematicRole::Agent, subject_term.clone()),
7641 (ThematicRole::Theme, subject_term),
7642 ];
7643 let event_var = self.get_event_var();
7644 let suppress_existential = self.drs.in_conditional_antecedent();
7645 if suppress_existential {
7646 let event_class = self.interner.intern("Event");
7647 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7648 }
7649 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7650 event_var,
7651 verb,
7652 roles: self.ctx.roles.alloc_slice(roles),
7653 modifiers: self.ctx.syms.alloc_slice(modifiers),
7654 suppress_existential,
7655 world: None,
7656 })));
7657
7658 let result = if is_negated {
7659 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7660 op: TokenType::Not,
7661 operand: neo_event,
7662 })
7663 } else {
7664 neo_event
7665 };
7666 return self.wrap_with_definiteness_full(&subject, result);
7667 }
7668
7669 if self.check_npi_quantifier() || self.check_quantifier() || self.check_article() {
7671 let (obj_quantifier, was_definite_article) = if self.check_npi_quantifier() {
7672 let tok = self.advance().kind.clone();
7674 (Some(tok), false)
7675 } else if self.check_quantifier() {
7676 (Some(self.advance().kind.clone()), false)
7677 } else {
7678 let art = self.advance().kind.clone();
7679 if let TokenType::Article(def) = art {
7680 if def == Definiteness::Indefinite {
7681 (Some(TokenType::Some), false)
7682 } else {
7683 (None, true)
7684 }
7685 } else {
7686 (None, false)
7687 }
7688 };
7689
7690 let object_np = self.parse_noun_phrase(false)?;
7691 let obj_var = self.next_var_name();
7692
7693 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7694 name: object_np.noun,
7695 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7696 world: None,
7697 });
7698
7699 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
7701 self.advance();
7702 let rel_clause = self.parse_relative_clause(obj_var)?;
7703 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7704 left: type_pred,
7705 op: TokenType::And,
7706 right: rel_clause,
7707 })
7708 } else {
7709 type_pred
7710 };
7711
7712 let event_var = self.get_event_var();
7713 let suppress_existential = self.drs.in_conditional_antecedent();
7714 if suppress_existential {
7715 let event_class = self.interner.intern("Event");
7716 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7717 }
7718
7719 let roles = vec![
7720 (ThematicRole::Agent, subject_term),
7721 (ThematicRole::Theme, Term::Variable(obj_var)),
7722 ];
7723
7724 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7725 event_var,
7726 verb,
7727 roles: self.ctx.roles.alloc_slice(roles),
7728 modifiers: self.ctx.syms.alloc_slice(modifiers),
7729 suppress_existential,
7730 world: None,
7731 })));
7732
7733 let quantifier_kind = match &obj_quantifier {
7737 Some(TokenType::Any) if is_negated => QuantifierKind::Existential,
7738 Some(TokenType::All) => QuantifierKind::Universal,
7739 Some(TokenType::No) => QuantifierKind::Universal,
7740 _ => QuantifierKind::Existential,
7741 };
7742
7743 let obj_body = match &obj_quantifier {
7744 Some(TokenType::All) => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7745 left: obj_restriction,
7746 op: TokenType::If,
7747 right: neo_event,
7748 }),
7749 Some(TokenType::No) => {
7750 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7751 op: TokenType::Not,
7752 operand: neo_event,
7753 });
7754 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7755 left: obj_restriction,
7756 op: TokenType::If,
7757 right: neg,
7758 })
7759 }
7760 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7761 left: obj_restriction,
7762 op: TokenType::And,
7763 right: neo_event,
7764 }),
7765 };
7766
7767 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7768 kind: quantifier_kind,
7769 variable: obj_var,
7770 body: obj_body,
7771 island_id: self.current_island,
7772 });
7773
7774 let result = if is_negated && matches!(obj_quantifier, Some(TokenType::Any)) {
7776 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7777 op: TokenType::Not,
7778 operand: obj_quantified,
7779 })
7780 } else if is_negated {
7781 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7783 op: TokenType::Not,
7784 operand: obj_quantified,
7785 })
7786 } else {
7787 obj_quantified
7788 };
7789
7790 return self.wrap_with_definiteness_full(&subject, result);
7791 }
7792
7793 let roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
7795 let event_var = self.get_event_var();
7796 let suppress_existential = self.drs.in_conditional_antecedent();
7797 if suppress_existential {
7798 let event_class = self.interner.intern("Event");
7799 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7800 }
7801
7802 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7803 event_var,
7804 verb,
7805 roles: self.ctx.roles.alloc_slice(roles),
7806 modifiers: self.ctx.syms.alloc_slice(modifiers),
7807 suppress_existential,
7808 world: None,
7809 })));
7810
7811 if is_negated {
7812 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7813 op: TokenType::Not,
7814 operand: neo_event,
7815 }));
7816 }
7817 return Ok(neo_event);
7818 }
7819 }
7820
7821 let is_perfect_aux = if self.check_verb() {
7827 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
7828 word == "has" || word == "have" || word == "had"
7829 } else {
7830 false
7831 };
7832 if subject.definiteness == Some(Definiteness::Definite) && self.check_verb() && self.pending_time.is_none() && !is_perfect_aux {
7833 let saved_pos = self.current;
7834
7835 if let Some(garden_path_result) = self.try_parse(|p| {
7837 let (modifier_verb, _modifier_time, _, _) = p.consume_verb_with_metadata();
7838
7839 let mut pp_mods: Vec<&'a LogicExpr<'a>> = Vec::new();
7841 while p.check_preposition() {
7842 let prep = if let TokenType::Preposition(prep) = p.advance().kind {
7843 prep
7844 } else {
7845 break;
7846 };
7847 if p.check_article() || p.check_content_word() {
7848 let pp_obj = p.parse_noun_phrase(false)?;
7849 let pp_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7850 name: prep,
7851 args: p.ctx.terms.alloc_slice([Term::Variable(p.interner.intern("x")), Term::Constant(pp_obj.noun)]),
7852 world: None,
7853 });
7854 pp_mods.push(pp_pred);
7855 }
7856 }
7857
7858 if !p.check_verb() {
7860 return Err(ParseError {
7861 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
7862 span: p.current_span(),
7863 });
7864 }
7865
7866 let (main_verb, main_time, _, _) = p.consume_verb_with_metadata();
7867
7868 let var = p.interner.intern("x");
7870
7871 let type_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7873 name: subject.noun,
7874 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
7875 world: None,
7876 });
7877
7878 let mod_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7880 name: modifier_verb,
7881 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
7882 world: None,
7883 });
7884
7885 let main_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
7887 name: main_verb,
7888 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
7889 world: None,
7890 });
7891
7892 let mut body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
7894 left: type_pred,
7895 op: TokenType::And,
7896 right: mod_pred,
7897 });
7898
7899 for pp in pp_mods {
7901 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
7902 left: body,
7903 op: TokenType::And,
7904 right: pp,
7905 });
7906 }
7907
7908 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
7910 left: body,
7911 op: TokenType::And,
7912 right: main_pred,
7913 });
7914
7915 let with_time = match main_time {
7917 Time::Past => p.ctx.exprs.alloc(LogicExpr::Temporal {
7918 operator: TemporalOperator::Past,
7919 body,
7920 }),
7921 Time::Future => p.ctx.exprs.alloc(LogicExpr::Temporal {
7922 operator: TemporalOperator::Future,
7923 body,
7924 }),
7925 _ => body,
7926 };
7927
7928 Ok(p.ctx.exprs.alloc(LogicExpr::Quantifier {
7930 kind: QuantifierKind::Existential,
7931 variable: var,
7932 body: with_time,
7933 island_id: p.current_island,
7934 }))
7935 }) {
7936 return Ok(garden_path_result);
7937 }
7938
7939 self.current = saved_pos;
7941 }
7942
7943 if self.check_modal() {
7944 return self.parse_aspect_chain(subject.noun);
7945 }
7946
7947 if self.check_content_word() {
7949 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
7950 if word == "has" || word == "have" || word == "had" {
7951 let is_perfect_aspect = if self.current + 1 < self.tokens.len() {
7953 let next_token = &self.tokens[self.current + 1].kind;
7954 matches!(
7955 next_token,
7956 TokenType::Verb { .. } | TokenType::Not
7957 ) && !matches!(next_token, TokenType::Number(_))
7958 } else {
7959 false
7960 };
7961 if is_perfect_aspect {
7962 return self.parse_aspect_chain(subject.noun);
7963 }
7964 }
7966 }
7967
7968 if self.check(&TokenType::Had) {
7970 return self.parse_aspect_chain(subject.noun);
7971 }
7972
7973 if self.check(&TokenType::Never) {
7975 self.advance();
7976 let verb = self.consume_verb();
7977 let subject_term = self.noun_phrase_to_term(&subject);
7978 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7979 name: verb,
7980 args: self.ctx.terms.alloc_slice([subject_term]),
7981 world: None,
7982 });
7983 let result = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7984 op: TokenType::Not,
7985 operand: verb_pred,
7986 });
7987 return self.wrap_with_definiteness_full(&subject, result);
7988 }
7989
7990 if self.check_verb() {
7991 let (mut verb, verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
7992
7993 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7995 let verb_str = self.interner.resolve(verb);
7996 if let Some(s_sort) = subject_sort {
7997 if !crate::ontology::check_sort_compatibility(verb_str, s_sort) {
7998 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7999 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
8000 vehicle: self.ctx.terms.alloc(Term::Constant(verb)),
8001 });
8002 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
8003 }
8004 }
8005
8006 if self.is_control_verb(verb) {
8008 return self.parse_control_structure(&subject, verb, verb_time);
8009 }
8010
8011 if let Some((var_name, rel_clause)) = relative_clause {
8013 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8014 name: verb,
8015 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8016 world: None,
8017 });
8018
8019 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8020 let with_time = match effective_time {
8021 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
8022 operator: TemporalOperator::Past,
8023 body: main_pred,
8024 }),
8025 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
8026 operator: TemporalOperator::Future,
8027 body: main_pred,
8028 }),
8029 _ => main_pred,
8030 };
8031
8032 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8034 name: subject.noun,
8035 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8036 world: None,
8037 });
8038
8039 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8040 left: type_pred,
8041 op: TokenType::And,
8042 right: rel_clause,
8043 });
8044
8045 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8046 left: inner,
8047 op: TokenType::And,
8048 right: with_time,
8049 });
8050
8051 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
8052 kind: QuantifierKind::Existential,
8053 variable: var_name,
8054 body,
8055 island_id: self.current_island,
8056 }));
8057 }
8058
8059 let subject_term = self.noun_phrase_to_term(&subject);
8060 let mut args = vec![subject_term.clone()];
8061
8062 let unknown = self.interner.intern("?");
8063
8064 if self.check_wh_word() {
8066 let wh_token = self.advance().kind.clone();
8067
8068 let is_who = matches!(wh_token, TokenType::Who);
8070 let is_what = matches!(wh_token, TokenType::What);
8071
8072 let is_sluicing = self.is_at_end() ||
8074 self.check(&TokenType::Period) ||
8075 self.check(&TokenType::Comma);
8076
8077 if is_sluicing {
8078 if let Some(template) = self.last_event_template.clone() {
8080 let wh_var = self.next_var_name();
8081
8082 let roles: Vec<_> = if is_who {
8084 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
8086 .chain(template.non_agent_roles.iter().cloned())
8087 .collect()
8088 } else if is_what {
8089 vec![
8091 (ThematicRole::Agent, subject_term.clone()),
8092 (ThematicRole::Theme, Term::Variable(wh_var)),
8093 ]
8094 } else {
8095 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
8097 .chain(template.non_agent_roles.iter().cloned())
8098 .collect()
8099 };
8100
8101 let event_var = self.get_event_var();
8102 let suppress_existential = self.drs.in_conditional_antecedent();
8103 if suppress_existential {
8104 let event_class = self.interner.intern("Event");
8105 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8106 }
8107 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8108 event_var,
8109 verb: template.verb,
8110 roles: self.ctx.roles.alloc_slice(roles),
8111 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
8112 suppress_existential,
8113 world: None,
8114 })));
8115
8116 let question = self.ctx.exprs.alloc(LogicExpr::Question {
8117 wh_variable: wh_var,
8118 body: reconstructed,
8119 });
8120
8121 let know_event_var = self.get_event_var();
8123 let suppress_existential2 = self.drs.in_conditional_antecedent();
8124 if suppress_existential2 {
8125 let event_class = self.interner.intern("Event");
8126 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8127 }
8128 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8129 event_var: know_event_var,
8130 verb,
8131 roles: self.ctx.roles.alloc_slice(vec![
8132 (ThematicRole::Agent, subject_term),
8133 (ThematicRole::Theme, Term::Proposition(question)),
8134 ]),
8135 modifiers: self.ctx.syms.alloc_slice(vec![]),
8136 suppress_existential: suppress_existential2,
8137 world: None,
8138 })));
8139
8140 return self.wrap_with_definiteness_full(&subject, know_event);
8141 }
8142 }
8143
8144 let embedded = self.parse_embedded_wh_clause()?;
8146 let question = self.ctx.exprs.alloc(LogicExpr::Question {
8147 wh_variable: self.interner.intern("x"),
8148 body: embedded,
8149 });
8150
8151 let know_event_var = self.get_event_var();
8153 let suppress_existential = self.drs.in_conditional_antecedent();
8154 if suppress_existential {
8155 let event_class = self.interner.intern("Event");
8156 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8157 }
8158 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8159 event_var: know_event_var,
8160 verb,
8161 roles: self.ctx.roles.alloc_slice(vec![
8162 (ThematicRole::Agent, subject_term),
8163 (ThematicRole::Theme, Term::Proposition(question)),
8164 ]),
8165 modifiers: self.ctx.syms.alloc_slice(vec![]),
8166 suppress_existential,
8167 world: None,
8168 })));
8169
8170 return self.wrap_with_definiteness_full(&subject, know_event);
8171 }
8172
8173 let mut object_term: Option<Term<'a>> = None;
8174 let mut second_object_term: Option<Term<'a>> = None;
8175 let mut object_superlative: Option<(Symbol, Symbol)> = None; if self.check(&TokenType::Reflexive) {
8177 self.advance();
8178 let term = self.noun_phrase_to_term(&subject);
8179 object_term = Some(term.clone());
8180 args.push(term);
8181
8182 if let TokenType::Particle(particle_sym) = self.peek().kind {
8184 let verb_str = self.interner.resolve(verb).to_lowercase();
8185 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8186 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8187 self.advance();
8188 verb = self.interner.intern(phrasal_lemma);
8189 }
8190 }
8191 } else if self.check_pronoun() {
8192 let token = self.advance().clone();
8193 if let TokenType::Pronoun { gender, number, .. } = token.kind {
8194 let resolved = self.resolve_pronoun(gender, number)?;
8195 let term = match resolved {
8196 ResolvedPronoun::Variable(s) => Term::Variable(s),
8197 ResolvedPronoun::Constant(s) => Term::Constant(s),
8198 };
8199 object_term = Some(term.clone());
8200 args.push(term);
8201
8202 if let TokenType::Particle(particle_sym) = self.peek().kind {
8204 let verb_str = self.interner.resolve(verb).to_lowercase();
8205 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8206 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8207 self.advance();
8208 verb = self.interner.intern(phrasal_lemma);
8209 }
8210 }
8211 }
8212 } else if self.check_quantifier() || self.check_article() {
8213 let (obj_quantifier, was_definite_article) = if self.check_quantifier() {
8215 (Some(self.advance().kind.clone()), false)
8216 } else {
8217 let art = self.advance().kind.clone();
8218 if let TokenType::Article(def) = art {
8219 if def == Definiteness::Indefinite {
8220 (Some(TokenType::Some), false)
8221 } else {
8222 (None, true) }
8224 } else {
8225 (None, false)
8226 }
8227 };
8228
8229 let object_np = self.parse_noun_phrase(false)?;
8230
8231 if let Some(adj) = object_np.superlative {
8233 object_superlative = Some((adj, object_np.noun));
8234 }
8235
8236 if let TokenType::Particle(particle_sym) = self.peek().kind {
8238 let verb_str = self.interner.resolve(verb).to_lowercase();
8239 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8240 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8241 self.advance(); verb = self.interner.intern(phrasal_lemma);
8243 }
8244 }
8245
8246 if let Some(obj_q) = obj_quantifier {
8247 let verb_str = self.interner.resolve(verb).to_lowercase();
8251 let is_opaque = lexicon::lookup_verb_db(&verb_str)
8252 .map(|meta| meta.features.contains(&lexicon::Feature::Opaque))
8253 .unwrap_or(false);
8254
8255 if is_opaque && matches!(obj_q, TokenType::Some) {
8256 let intension_term = Term::Intension(object_np.noun);
8258
8259 let event_var = self.get_event_var();
8261 let mut modifiers = self.collect_adverbs();
8262 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8263 match effective_time {
8264 Time::Past => modifiers.push(self.interner.intern("Past")),
8265 Time::Future => modifiers.push(self.interner.intern("Future")),
8266 _ => {}
8267 }
8268
8269 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8270 let roles = vec![
8271 (ThematicRole::Agent, subject_term_for_event),
8272 (ThematicRole::Theme, intension_term),
8273 ];
8274
8275 let suppress_existential = self.drs.in_conditional_antecedent();
8276 if suppress_existential {
8277 let event_class = self.interner.intern("Event");
8278 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8279 }
8280 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8281 event_var,
8282 verb,
8283 roles: self.ctx.roles.alloc_slice(roles),
8284 modifiers: self.ctx.syms.alloc_slice(modifiers),
8285 suppress_existential,
8286 world: None,
8287 })));
8288
8289 return self.wrap_with_definiteness_full(&subject, neo_event);
8290 }
8291
8292 let obj_var = self.next_var_name();
8293
8294 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8296 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8297 Number::Plural
8298 } else {
8299 Number::Singular
8300 };
8301 if object_np.definiteness == Some(Definiteness::Definite) {
8303 self.drs.introduce_referent_with_source(obj_var, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8304 } else {
8305 self.drs.introduce_referent(obj_var, object_np.noun, obj_gender, obj_number);
8306 }
8307
8308 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8309 name: object_np.noun,
8310 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8311 world: None,
8312 });
8313
8314 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8315 self.advance();
8316 let rel_clause = self.parse_relative_clause(obj_var)?;
8317 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8318 left: type_pred,
8319 op: TokenType::And,
8320 right: rel_clause,
8321 })
8322 } else {
8323 type_pred
8324 };
8325
8326 let event_var = self.get_event_var();
8327 let mut modifiers = self.collect_adverbs();
8328 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8329 match effective_time {
8330 Time::Past => modifiers.push(self.interner.intern("Past")),
8331 Time::Future => modifiers.push(self.interner.intern("Future")),
8332 _ => {}
8333 }
8334
8335 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8336 let roles = vec![
8337 (ThematicRole::Agent, subject_term_for_event),
8338 (ThematicRole::Theme, Term::Variable(obj_var)),
8339 ];
8340
8341 let template_roles = vec![
8344 (ThematicRole::Agent, subject_term_for_event),
8345 (ThematicRole::Theme, Term::Constant(object_np.noun)),
8346 ];
8347 self.capture_event_template(verb, &template_roles, &modifiers);
8348
8349 let suppress_existential = self.drs.in_conditional_antecedent();
8350 if suppress_existential {
8351 let event_class = self.interner.intern("Event");
8352 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8353 }
8354 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8355 event_var,
8356 verb,
8357 roles: self.ctx.roles.alloc_slice(roles),
8358 modifiers: self.ctx.syms.alloc_slice(modifiers),
8359 suppress_existential,
8360 world: None,
8361 })));
8362
8363 let obj_kind = match obj_q {
8364 TokenType::All => QuantifierKind::Universal,
8365 TokenType::Some => QuantifierKind::Existential,
8366 TokenType::No => QuantifierKind::Universal,
8367 TokenType::Most => QuantifierKind::Most,
8368 TokenType::Few => QuantifierKind::Few,
8369 TokenType::Many => QuantifierKind::Many,
8370 TokenType::Cardinal(n) => QuantifierKind::Cardinal(n),
8371 TokenType::AtLeast(n) => QuantifierKind::AtLeast(n),
8372 TokenType::AtMost(n) => QuantifierKind::AtMost(n),
8373 _ => QuantifierKind::Existential,
8374 };
8375
8376 let obj_body = match obj_q {
8377 TokenType::All => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8378 left: obj_restriction,
8379 op: TokenType::If,
8380 right: neo_event,
8381 }),
8382 TokenType::No => {
8383 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8384 op: TokenType::Not,
8385 operand: neo_event,
8386 });
8387 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8388 left: obj_restriction,
8389 op: TokenType::If,
8390 right: neg,
8391 })
8392 }
8393 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8394 left: obj_restriction,
8395 op: TokenType::And,
8396 right: neo_event,
8397 }),
8398 };
8399
8400 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8402 kind: obj_kind,
8403 variable: obj_var,
8404 body: obj_body,
8405 island_id: self.current_island,
8406 });
8407
8408 return self.wrap_with_definiteness_full(&subject, obj_quantified);
8410 } else {
8411 if was_definite_article {
8416 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8417 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8418 Number::Plural
8419 } else {
8420 Number::Singular
8421 };
8422 self.drs.introduce_referent_with_source(object_np.noun, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8424 }
8425
8426 let term = self.noun_phrase_to_term(&object_np);
8427 object_term = Some(term.clone());
8428 args.push(term);
8429 }
8430 } else if self.check_focus() {
8431 let focus_kind = if let TokenType::Focus(k) = self.advance().kind {
8432 k
8433 } else {
8434 FocusKind::Only
8435 };
8436
8437 let event_var = self.get_event_var();
8438 let mut modifiers = self.collect_adverbs();
8439 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8440 match effective_time {
8441 Time::Past => modifiers.push(self.interner.intern("Past")),
8442 Time::Future => modifiers.push(self.interner.intern("Future")),
8443 _ => {}
8444 }
8445
8446 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8447
8448 if self.check_preposition() {
8449 let prep_token = self.advance().clone();
8450 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8451 sym
8452 } else {
8453 self.interner.intern("to")
8454 };
8455 let pp_obj = self.parse_noun_phrase(false)?;
8456 let pp_obj_term = Term::Constant(pp_obj.noun);
8457
8458 let roles = vec![(ThematicRole::Agent, subject_term_for_event)];
8459 let suppress_existential = self.drs.in_conditional_antecedent();
8460 if suppress_existential {
8461 let event_class = self.interner.intern("Event");
8462 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8463 }
8464 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8465 event_var,
8466 verb,
8467 roles: self.ctx.roles.alloc_slice(roles),
8468 modifiers: self.ctx.syms.alloc_slice(modifiers),
8469 suppress_existential,
8470 world: None,
8471 })));
8472
8473 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8474 name: prep_name,
8475 args: self.ctx.terms.alloc_slice([Term::Variable(event_var), pp_obj_term]),
8476 world: None,
8477 });
8478
8479 let with_pp = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8480 left: neo_event,
8481 op: TokenType::And,
8482 right: pp_pred,
8483 });
8484
8485 let focused_ref = self.ctx.terms.alloc(pp_obj_term);
8486 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8487 kind: focus_kind,
8488 focused: focused_ref,
8489 scope: with_pp,
8490 }));
8491 }
8492
8493 let focused_np = self.parse_noun_phrase(false)?;
8494 let focused_term = self.noun_phrase_to_term(&focused_np);
8495 args.push(focused_term.clone());
8496
8497 let roles = vec![
8498 (ThematicRole::Agent, subject_term_for_event),
8499 (ThematicRole::Theme, focused_term.clone()),
8500 ];
8501
8502 let suppress_existential = self.drs.in_conditional_antecedent();
8503 if suppress_existential {
8504 let event_class = self.interner.intern("Event");
8505 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8506 }
8507 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8508 event_var,
8509 verb,
8510 roles: self.ctx.roles.alloc_slice(roles),
8511 modifiers: self.ctx.syms.alloc_slice(modifiers),
8512 suppress_existential,
8513 world: None,
8514 })));
8515
8516 let focused_ref = self.ctx.terms.alloc(focused_term);
8517 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8518 kind: focus_kind,
8519 focused: focused_ref,
8520 scope: neo_event,
8521 }));
8522 } else if self.check_number() {
8523 let measure = self.parse_measure_phrase()?;
8525
8526 if self.check_content_word() {
8528 let noun_sym = self.consume_content_word()?;
8529 let count_term = *measure;
8531 object_term = Some(count_term.clone());
8532 args.push(count_term);
8533 second_object_term = Some(Term::Constant(noun_sym));
8534 args.push(Term::Constant(noun_sym));
8535 } else {
8536 object_term = Some(*measure);
8538 args.push(*measure);
8539 }
8540 } else if self.check_content_word() || self.check_article() {
8541 let object = self.parse_noun_phrase(false)?;
8542 if let Some(adj) = object.superlative {
8543 object_superlative = Some((adj, object.noun));
8544 }
8545
8546 let mut all_objects: Vec<Symbol> = vec![object.noun];
8548
8549 while self.check(&TokenType::And) {
8551 let saved = self.current;
8552 self.advance(); if self.check_content_word() || self.check_article() {
8554 let next_obj = match self.parse_noun_phrase(false) {
8555 Ok(np) => np,
8556 Err(_) => {
8557 self.current = saved;
8558 break;
8559 }
8560 };
8561 all_objects.push(next_obj.noun);
8562 } else {
8563 self.current = saved;
8564 break;
8565 }
8566 }
8567
8568 if self.check(&TokenType::Respectively) {
8570 let respectively_span = self.peek().span;
8571 if all_objects.len() > 1 {
8573 return Err(ParseError {
8574 kind: ParseErrorKind::RespectivelyLengthMismatch {
8575 subject_count: 1,
8576 object_count: all_objects.len(),
8577 },
8578 span: respectively_span,
8579 });
8580 }
8581 self.advance(); }
8584
8585 let term = self.noun_phrase_to_term(&object);
8587 object_term = Some(term.clone());
8588 args.push(term.clone());
8589
8590 if all_objects.len() > 1 {
8592 let obj_members: Vec<Term<'a>> = all_objects.iter()
8593 .map(|o| Term::Constant(*o))
8594 .collect();
8595 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
8596 args.pop();
8598 args.push(obj_group);
8599 }
8600
8601 if let TokenType::Particle(particle_sym) = self.peek().kind {
8603 let verb_str = self.interner.resolve(verb).to_lowercase();
8604 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8605 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8606 self.advance(); verb = self.interner.intern(phrasal_lemma);
8608 }
8609 }
8610
8611 if self.check_number() {
8613 let measure = self.parse_measure_phrase()?;
8614 second_object_term = Some(*measure);
8615 args.push(*measure);
8616 }
8617 else {
8619 let verb_str = self.interner.resolve(verb);
8620 if Lexer::is_ditransitive_verb(verb_str) && (self.check_content_word() || self.check_article()) {
8621 let second_np = self.parse_noun_phrase(false)?;
8622 let second_term = self.noun_phrase_to_term(&second_np);
8623 second_object_term = Some(second_term.clone());
8624 args.push(second_term);
8625 }
8626 }
8627 }
8628
8629 let mut pp_predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
8630 while self.check_preposition() || self.check_to() {
8631 let prep_token = self.advance().clone();
8632 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8633 sym
8634 } else if matches!(prep_token.kind, TokenType::To) {
8635 self.interner.intern("To")
8636 } else {
8637 continue;
8638 };
8639
8640 let pp_obj_term = if self.check(&TokenType::Reflexive) {
8641 self.advance();
8642 self.noun_phrase_to_term(&subject)
8643 } else if self.check_pronoun() {
8644 let token = self.advance().clone();
8645 if let TokenType::Pronoun { gender, number, .. } = token.kind {
8646 let resolved = self.resolve_pronoun(gender, number)?;
8647 match resolved {
8648 ResolvedPronoun::Variable(s) => Term::Variable(s),
8649 ResolvedPronoun::Constant(s) => Term::Constant(s),
8650 }
8651 } else {
8652 continue;
8653 }
8654 } else if self.check_content_word() || self.check_article() {
8655 let prep_obj = self.parse_noun_phrase(false)?;
8656 self.noun_phrase_to_term(&prep_obj)
8657 } else {
8658 continue;
8659 };
8660
8661 if self.pp_attach_to_noun {
8662 if let Some(ref obj) = object_term {
8663 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8665 name: prep_name,
8666 args: self.ctx.terms.alloc_slice([obj.clone(), pp_obj_term]),
8667 world: None,
8668 });
8669 pp_predicates.push(pp_pred);
8670 } else {
8671 args.push(pp_obj_term);
8672 }
8673 } else {
8674 let event_sym = self.get_event_var();
8676 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8677 name: prep_name,
8678 args: self.ctx.terms.alloc_slice([Term::Variable(event_sym), pp_obj_term]),
8679 world: None,
8680 });
8681 pp_predicates.push(pp_pred);
8682 }
8683 }
8684
8685 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8687 self.advance();
8688 let rel_var = self.next_var_name();
8689 let rel_pred = self.parse_relative_clause(rel_var)?;
8690 pp_predicates.push(rel_pred);
8691 }
8692
8693 let mut modifiers = self.collect_adverbs();
8695
8696 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8698 match effective_time {
8699 Time::Past => modifiers.push(self.interner.intern("Past")),
8700 Time::Future => modifiers.push(self.interner.intern("Future")),
8701 _ => {}
8702 }
8703
8704 if verb_aspect == Aspect::Progressive {
8706 modifiers.push(self.interner.intern("Progressive"));
8707 } else if verb_aspect == Aspect::Perfect {
8708 modifiers.push(self.interner.intern("Perfect"));
8709 }
8710
8711 let mut roles: Vec<(ThematicRole, Term<'a>)> = Vec::new();
8713
8714 let verb_str_for_check = self.interner.resolve(verb).to_lowercase();
8716 let is_unaccusative = crate::lexicon::lookup_verb_db(&verb_str_for_check)
8717 .map(|meta| meta.features.contains(&crate::lexicon::Feature::Unaccusative))
8718 .unwrap_or(false);
8719
8720 let has_object = object_term.is_some() || second_object_term.is_some();
8722 let subject_role = if is_unaccusative && !has_object {
8723 ThematicRole::Theme
8724 } else {
8725 ThematicRole::Agent
8726 };
8727
8728 roles.push((subject_role, subject_term));
8729 if let Some(second_obj) = second_object_term {
8730 if let Some(first_obj) = object_term {
8732 roles.push((ThematicRole::Recipient, first_obj));
8733 }
8734 roles.push((ThematicRole::Theme, second_obj));
8735 } else if let Some(obj) = object_term {
8736 roles.push((ThematicRole::Theme, obj));
8738 }
8739
8740 let event_var = self.get_event_var();
8742
8743 self.capture_event_template(verb, &roles, &modifiers);
8745
8746 let suppress_existential = self.drs.in_conditional_antecedent();
8748 if suppress_existential {
8749 let event_class = self.interner.intern("Event");
8750 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8751 }
8752 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8753 event_var,
8754 verb,
8755 roles: self.ctx.roles.alloc_slice(roles),
8756 modifiers: self.ctx.syms.alloc_slice(modifiers),
8757 suppress_existential,
8758 world: None,
8759 })));
8760
8761 let with_pps = if pp_predicates.is_empty() {
8763 neo_event
8764 } else {
8765 let mut combined = neo_event;
8766 for pp in pp_predicates {
8767 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8768 left: combined,
8769 op: TokenType::And,
8770 right: pp,
8771 });
8772 }
8773 combined
8774 };
8775
8776 let with_aspect = if verb_aspect == Aspect::Progressive {
8778 if verb_class == crate::lexicon::VerbClass::Semelfactive {
8780 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8781 operator: AspectOperator::Iterative,
8782 body: with_pps,
8783 })
8784 } else {
8785 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8787 operator: AspectOperator::Progressive,
8788 body: with_pps,
8789 })
8790 }
8791 } else if verb_aspect == Aspect::Perfect {
8792 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8793 operator: AspectOperator::Perfect,
8794 body: with_pps,
8795 })
8796 } else if effective_time == Time::Present && verb_aspect == Aspect::Simple {
8797 if !verb_class.is_stative() {
8799 self.ctx.exprs.alloc(LogicExpr::Aspectual {
8800 operator: AspectOperator::Habitual,
8801 body: with_pps,
8802 })
8803 } else {
8804 with_pps
8806 }
8807 } else {
8808 with_pps
8809 };
8810
8811 let with_adverbs = with_aspect;
8812
8813 let with_temporal = if self.check_temporal_adverb() {
8815 let anchor = if let TokenType::TemporalAdverb(adv) = self.advance().kind.clone() {
8816 adv
8817 } else {
8818 panic!("Expected temporal adverb");
8819 };
8820 self.ctx.exprs.alloc(LogicExpr::TemporalAnchor {
8821 anchor,
8822 body: with_adverbs,
8823 })
8824 } else {
8825 with_adverbs
8826 };
8827
8828 let wrapped = self.wrap_with_definiteness_full(&subject, with_temporal)?;
8829
8830 if let Some((adj, noun)) = object_superlative {
8832 let superlative_expr = self.ctx.exprs.alloc(LogicExpr::Superlative {
8833 adjective: adj,
8834 subject: self.ctx.terms.alloc(Term::Constant(noun)),
8835 domain: noun,
8836 });
8837 return Ok(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8838 left: wrapped,
8839 op: TokenType::And,
8840 right: superlative_expr,
8841 }));
8842 }
8843
8844 return Ok(wrapped);
8845 }
8846
8847 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(subject.noun)))
8848 }
8849
8850 fn check_preposition(&self) -> bool {
8851 matches!(self.peek().kind, TokenType::Preposition(_))
8852 }
8853
8854 fn check_by_preposition(&self) -> bool {
8855 if let TokenType::Preposition(p) = self.peek().kind {
8856 p.is(self.interner, "by")
8857 } else {
8858 false
8859 }
8860 }
8861
8862 fn check_preposition_is(&self, word: &str) -> bool {
8863 if let TokenType::Preposition(p) = self.peek().kind {
8864 p.is(self.interner, word)
8865 } else {
8866 false
8867 }
8868 }
8869
8870 fn check_word(&self, word: &str) -> bool {
8872 let token = self.peek();
8873 let lexeme = self.interner.resolve(token.lexeme);
8874 lexeme.eq_ignore_ascii_case(word)
8875 }
8876
8877 fn peek_word_at(&self, offset: usize, word: &str) -> bool {
8878 if self.current + offset >= self.tokens.len() {
8879 return false;
8880 }
8881 let token = &self.tokens[self.current + offset];
8882 let lexeme = self.interner.resolve(token.lexeme);
8883 lexeme.eq_ignore_ascii_case(word)
8884 }
8885
8886 fn check_to_preposition(&self) -> bool {
8887 match self.peek().kind {
8888 TokenType::To => true,
8889 TokenType::Preposition(p) => p.is(self.interner, "to"),
8890 _ => false,
8891 }
8892 }
8893
8894 fn check_content_word(&self) -> bool {
8895 match &self.peek().kind {
8896 TokenType::Noun(_)
8897 | TokenType::Adjective(_)
8898 | TokenType::NonIntersectiveAdjective(_)
8899 | TokenType::Verb { .. }
8900 | TokenType::ProperName(_)
8901 | TokenType::Article(_) => true,
8902 TokenType::Ambiguous { primary, alternatives } => {
8903 Self::is_content_word_type(primary)
8904 || alternatives.iter().any(Self::is_content_word_type)
8905 }
8906 _ => false,
8907 }
8908 }
8909
8910 fn is_content_word_type(t: &TokenType) -> bool {
8911 matches!(
8912 t,
8913 TokenType::Noun(_)
8914 | TokenType::Adjective(_)
8915 | TokenType::NonIntersectiveAdjective(_)
8916 | TokenType::Verb { .. }
8917 | TokenType::ProperName(_)
8918 | TokenType::Article(_)
8919 )
8920 }
8921
8922 fn check_verb(&self) -> bool {
8923 match &self.peek().kind {
8924 TokenType::Verb { .. } => true,
8925 TokenType::Ambiguous { primary, alternatives } => {
8926 if self.noun_priority_mode {
8927 return false;
8928 }
8929 matches!(**primary, TokenType::Verb { .. })
8930 || alternatives.iter().any(|t| matches!(t, TokenType::Verb { .. }))
8931 }
8932 _ => false,
8933 }
8934 }
8935
8936 fn check_adverb(&self) -> bool {
8937 matches!(self.peek().kind, TokenType::Adverb(_))
8938 }
8939
8940 fn check_performative(&self) -> bool {
8941 matches!(self.peek().kind, TokenType::Performative(_))
8942 }
8943
8944 fn collect_adverbs(&mut self) -> Vec<Symbol> {
8945 let mut adverbs = Vec::new();
8946 while self.check_adverb() {
8947 if let TokenType::Adverb(adv) = self.advance().kind.clone() {
8948 adverbs.push(adv);
8949 }
8950 if self.check(&TokenType::And) {
8952 self.advance();
8953 }
8954 }
8955 adverbs
8956 }
8957
8958 fn check_auxiliary(&self) -> bool {
8959 matches!(self.peek().kind, TokenType::Auxiliary(_))
8960 }
8961
8962 fn is_true_auxiliary_usage(&self) -> bool {
8969 if self.current + 1 >= self.tokens.len() {
8970 return false;
8971 }
8972
8973 let next_token = &self.tokens[self.current + 1].kind;
8974
8975 if matches!(next_token, TokenType::Not) {
8977 return true;
8978 }
8979
8980 if matches!(next_token, TokenType::Verb { .. }) {
8982 return true;
8983 }
8984
8985 if matches!(
8987 next_token,
8988 TokenType::Pronoun { .. }
8989 | TokenType::Article(_)
8990 | TokenType::Noun(_)
8991 | TokenType::ProperName(_)
8992 ) {
8993 return false;
8994 }
8995
8996 true
8998 }
8999
9000 fn check_auxiliary_as_main_verb(&self) -> bool {
9003 if let TokenType::Auxiliary(Time::Past) = self.peek().kind {
9004 if self.current + 1 < self.tokens.len() {
9006 let next = &self.tokens[self.current + 1].kind;
9007 matches!(
9008 next,
9009 TokenType::Pronoun { .. }
9010 | TokenType::Article(_)
9011 | TokenType::Noun(_)
9012 | TokenType::ProperName(_)
9013 )
9014 } else {
9015 false
9016 }
9017 } else {
9018 false
9019 }
9020 }
9021
9022 fn parse_do_as_main_verb(&mut self, subject_term: Term<'a>) -> ParseResult<&'a LogicExpr<'a>> {
9025 let aux_token = self.advance();
9027 let verb_time = if let TokenType::Auxiliary(time) = aux_token.kind {
9028 time
9029 } else {
9030 Time::Past
9031 };
9032
9033 let verb = self.interner.intern("Do");
9035
9036 let object_term = if let TokenType::Pronoun { .. } = self.peek().kind {
9038 self.advance();
9040 let it_sym = self.interner.intern("it");
9043 Term::Constant(it_sym)
9044 } else {
9045 let object = self.parse_noun_phrase(false)?;
9046 self.noun_phrase_to_term(&object)
9047 };
9048
9049 let event_var = self.get_event_var();
9051 let suppress_existential = self.drs.in_conditional_antecedent();
9052
9053 let mut modifiers = Vec::new();
9054 if verb_time == Time::Past {
9055 modifiers.push(self.interner.intern("Past"));
9056 } else if verb_time == Time::Future {
9057 modifiers.push(self.interner.intern("Future"));
9058 }
9059
9060 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
9061 event_var,
9062 verb,
9063 roles: self.ctx.roles.alloc_slice(vec![
9064 (ThematicRole::Agent, subject_term),
9065 (ThematicRole::Theme, object_term),
9066 ]),
9067 modifiers: self.ctx.syms.alloc_slice(modifiers),
9068 suppress_existential,
9069 world: None,
9070 })));
9071
9072 Ok(neo_event)
9073 }
9074
9075 fn check_to(&self) -> bool {
9076 matches!(self.peek().kind, TokenType::To)
9077 }
9078
9079 fn has_modal_subordination_ahead(&self) -> bool {
9083 for i in self.current..self.tokens.len() {
9086 match &self.tokens[i].kind {
9087 TokenType::Would | TokenType::Could | TokenType::Should | TokenType::Might => {
9088 return true;
9089 }
9090 TokenType::Period | TokenType::EOF => break,
9092 _ => {}
9093 }
9094 }
9095 false
9096 }
9097
9098 fn consume_verb(&mut self) -> Symbol {
9099 let t = self.advance().clone();
9100 match t.kind {
9101 TokenType::Verb { lemma, .. } => lemma,
9102 TokenType::Ambiguous { primary, .. } => match *primary {
9103 TokenType::Verb { lemma, .. } => lemma,
9104 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
9105 },
9106 _ => panic!("Expected verb, got {:?}", t.kind),
9107 }
9108 }
9109
9110 fn consume_verb_with_metadata(&mut self) -> (Symbol, Time, Aspect, VerbClass) {
9111 let t = self.advance().clone();
9112 match t.kind {
9113 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
9114 TokenType::Ambiguous { primary, .. } => match *primary {
9115 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
9116 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
9117 },
9118 _ => panic!("Expected verb, got {:?}", t.kind),
9119 }
9120 }
9121
9122 fn match_token(&mut self, types: &[TokenType]) -> bool {
9123 for t in types {
9124 if self.check(t) {
9125 self.advance();
9126 return true;
9127 }
9128 }
9129 false
9130 }
9131
9132 fn check_quantifier(&self) -> bool {
9133 matches!(
9134 self.peek().kind,
9135 TokenType::All
9136 | TokenType::No
9137 | TokenType::Some
9138 | TokenType::Any
9139 | TokenType::Most
9140 | TokenType::Few
9141 | TokenType::Many
9142 | TokenType::Cardinal(_)
9143 | TokenType::AtLeast(_)
9144 | TokenType::AtMost(_)
9145 )
9146 }
9147
9148 fn check_npi_quantifier(&self) -> bool {
9149 matches!(
9150 self.peek().kind,
9151 TokenType::Nobody | TokenType::Nothing | TokenType::NoOne
9152 )
9153 }
9154
9155 fn check_npi_object(&self) -> bool {
9156 matches!(
9157 self.peek().kind,
9158 TokenType::Anything | TokenType::Anyone
9159 )
9160 }
9161
9162 fn check_temporal_npi(&self) -> bool {
9163 matches!(
9164 self.peek().kind,
9165 TokenType::Ever | TokenType::Never
9166 )
9167 }
9168
9169 fn parse_npi_quantified(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9170 let npi_token = self.advance().kind.clone();
9171 let var_name = self.next_var_name();
9172
9173 let (restriction_name, is_person) = match npi_token {
9174 TokenType::Nobody | TokenType::NoOne => ("Person", true),
9175 TokenType::Nothing => ("Thing", false),
9176 _ => ("Thing", false),
9177 };
9178
9179 let restriction_sym = self.interner.intern(restriction_name);
9180 let subject_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9181 name: restriction_sym,
9182 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9183 world: None,
9184 });
9185
9186 self.negative_depth += 1;
9187
9188 let verb = self.consume_verb();
9189
9190 if self.check_npi_object() {
9191 let obj_npi_token = self.advance().kind.clone();
9192 let obj_var = self.next_var_name();
9193
9194 let obj_restriction_name = match obj_npi_token {
9195 TokenType::Anything => "Thing",
9196 TokenType::Anyone => "Person",
9197 _ => "Thing",
9198 };
9199
9200 let obj_restriction_sym = self.interner.intern(obj_restriction_name);
9201 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
9202 name: obj_restriction_sym,
9203 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
9204 world: None,
9205 });
9206
9207 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9208 name: verb,
9209 args: self.ctx.terms.alloc_slice([Term::Variable(var_name), Term::Variable(obj_var)]),
9210 world: None,
9211 });
9212
9213 let verb_and_obj = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9214 left: obj_restriction,
9215 op: TokenType::And,
9216 right: verb_pred,
9217 });
9218
9219 let inner_existential = self.ctx.exprs.alloc(LogicExpr::Quantifier {
9220 kind: crate::ast::QuantifierKind::Existential,
9221 variable: obj_var,
9222 body: verb_and_obj,
9223 island_id: self.current_island,
9224 });
9225
9226 self.negative_depth -= 1;
9227
9228 let negated = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9229 op: TokenType::Not,
9230 operand: inner_existential,
9231 });
9232
9233 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9234 left: subject_pred,
9235 op: TokenType::If,
9236 right: negated,
9237 });
9238
9239 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9240 kind: crate::ast::QuantifierKind::Universal,
9241 variable: var_name,
9242 body,
9243 island_id: self.current_island,
9244 }));
9245 }
9246
9247 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9248 name: verb,
9249 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9250 world: None,
9251 });
9252
9253 self.negative_depth -= 1;
9254
9255 let negated_verb = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9256 op: TokenType::Not,
9257 operand: verb_pred,
9258 });
9259
9260 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9261 left: subject_pred,
9262 op: TokenType::If,
9263 right: negated_verb,
9264 });
9265
9266 Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9267 kind: crate::ast::QuantifierKind::Universal,
9268 variable: var_name,
9269 body,
9270 island_id: self.current_island,
9271 }))
9272 }
9273
9274 fn parse_temporal_npi(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9275 let npi_token = self.advance().kind.clone();
9276 let is_never = matches!(npi_token, TokenType::Never);
9277
9278 let subject = self.parse_noun_phrase(true)?;
9279
9280 if is_never {
9281 self.negative_depth += 1;
9282 }
9283
9284 let verb = self.consume_verb();
9285 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9286 name: verb,
9287 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
9288 world: None,
9289 });
9290
9291 if is_never {
9292 self.negative_depth -= 1;
9293 Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9294 op: TokenType::Not,
9295 operand: verb_pred,
9296 }))
9297 } else {
9298 Ok(verb_pred)
9299 }
9300 }
9301
9302 fn check(&self, kind: &TokenType) -> bool {
9303 if self.is_at_end() {
9304 return false;
9305 }
9306 std::mem::discriminant(&self.peek().kind) == std::mem::discriminant(kind)
9307 }
9308
9309 fn check_any(&self, kinds: &[TokenType]) -> bool {
9310 if self.is_at_end() {
9311 return false;
9312 }
9313 let current = std::mem::discriminant(&self.peek().kind);
9314 kinds.iter().any(|k| std::mem::discriminant(k) == current)
9315 }
9316
9317 fn check_article(&self) -> bool {
9318 matches!(self.peek().kind, TokenType::Article(_))
9319 }
9320
9321 fn advance(&mut self) -> &Token {
9322 if !self.is_at_end() {
9323 self.current += 1;
9324 }
9325 self.previous()
9326 }
9327
9328 fn is_at_end(&self) -> bool {
9329 self.peek().kind == TokenType::EOF
9330 }
9331
9332 fn peek(&self) -> &Token {
9333 &self.tokens[self.current]
9334 }
9335
9336 fn peek_next_is_string_literal(&self) -> bool {
9339 self.tokens.get(self.current + 1)
9340 .map(|t| matches!(t.kind, TokenType::StringLiteral(_)))
9341 .unwrap_or(false)
9342 }
9343
9344 fn previous(&self) -> &Token {
9345 &self.tokens[self.current - 1]
9346 }
9347
9348 fn current_span(&self) -> crate::token::Span {
9349 self.peek().span
9350 }
9351
9352 fn consume(&mut self, kind: TokenType) -> ParseResult<&Token> {
9353 if self.check(&kind) {
9354 Ok(self.advance())
9355 } else {
9356 Err(ParseError {
9357 kind: ParseErrorKind::UnexpectedToken {
9358 expected: kind,
9359 found: self.peek().kind.clone(),
9360 },
9361 span: self.current_span(),
9362 })
9363 }
9364 }
9365
9366 fn consume_content_word(&mut self) -> ParseResult<Symbol> {
9367 let t = self.advance().clone();
9368 match t.kind {
9369 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9370 TokenType::Article(_) => Ok(t.lexeme),
9372 TokenType::Number(s) => Ok(s),
9374 TokenType::ProperName(s) => {
9375 if self.mode == ParserMode::Imperative {
9377 if !self.drs.has_referent_by_variable(s) {
9378 return Err(ParseError {
9379 kind: ParseErrorKind::UndefinedVariable {
9380 name: self.interner.resolve(s).to_string()
9381 },
9382 span: t.span,
9383 });
9384 }
9385 return Ok(s);
9386 }
9387
9388 let s_str = self.interner.resolve(s);
9390 let gender = Self::infer_gender(s_str);
9391
9392 self.drs.introduce_proper_name(s, s, gender);
9394
9395 Ok(s)
9396 }
9397 TokenType::Verb { lemma, .. } => Ok(lemma),
9398 TokenType::Ambiguous { primary, .. } => {
9399 match *primary {
9400 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9401 TokenType::Verb { lemma, .. } => Ok(lemma),
9402 TokenType::ProperName(s) => {
9403 if self.mode == ParserMode::Imperative {
9405 if !self.drs.has_referent_by_variable(s) {
9406 return Err(ParseError {
9407 kind: ParseErrorKind::UndefinedVariable {
9408 name: self.interner.resolve(s).to_string()
9409 },
9410 span: t.span,
9411 });
9412 }
9413 return Ok(s);
9414 }
9415 let s_str = self.interner.resolve(s);
9417 let gender = Self::infer_gender(s_str);
9418 self.drs.introduce_proper_name(s, s, gender);
9419 Ok(s)
9420 }
9421 _ => Err(ParseError {
9422 kind: ParseErrorKind::ExpectedContentWord { found: *primary },
9423 span: self.current_span(),
9424 }),
9425 }
9426 }
9427 other => Err(ParseError {
9428 kind: ParseErrorKind::ExpectedContentWord { found: other },
9429 span: self.current_span(),
9430 }),
9431 }
9432 }
9433
9434 fn consume_copula(&mut self) -> ParseResult<()> {
9435 if self.match_token(&[TokenType::Is, TokenType::Are, TokenType::Was, TokenType::Were]) {
9436 Ok(())
9437 } else {
9438 Err(ParseError {
9439 kind: ParseErrorKind::ExpectedCopula,
9440 span: self.current_span(),
9441 })
9442 }
9443 }
9444
9445 fn check_comparative(&self) -> bool {
9446 matches!(self.peek().kind, TokenType::Comparative(_))
9447 }
9448
9449 fn is_contact_clause_pattern(&self) -> bool {
9450 let mut pos = self.current;
9453
9454 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Article(_)) {
9456 pos += 1;
9457 } else {
9458 return false;
9459 }
9460
9461 while pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Adjective(_)) {
9463 pos += 1;
9464 }
9465
9466 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Adjective(_)) {
9468 pos += 1;
9469 } else {
9470 return false;
9471 }
9472
9473 pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Verb { .. } | TokenType::Article(_))
9475 }
9476
9477 fn check_superlative(&self) -> bool {
9478 matches!(self.peek().kind, TokenType::Superlative(_))
9479 }
9480
9481 fn check_scopal_adverb(&self) -> bool {
9482 matches!(self.peek().kind, TokenType::ScopalAdverb(_))
9483 }
9484
9485 fn check_temporal_adverb(&self) -> bool {
9486 matches!(self.peek().kind, TokenType::TemporalAdverb(_))
9487 }
9488
9489 fn check_non_intersective_adjective(&self) -> bool {
9490 matches!(self.peek().kind, TokenType::NonIntersectiveAdjective(_))
9491 }
9492
9493 fn check_focus(&self) -> bool {
9494 matches!(self.peek().kind, TokenType::Focus(_))
9495 }
9496
9497 fn check_measure(&self) -> bool {
9498 matches!(self.peek().kind, TokenType::Measure(_))
9499 }
9500
9501 fn check_presup_trigger(&self) -> bool {
9502 match &self.peek().kind {
9503 TokenType::PresupTrigger(_) => true,
9504 TokenType::Verb { lemma, .. } => {
9505 let s = self.interner.resolve(*lemma).to_lowercase();
9506 crate::lexicon::lookup_presup_trigger(&s).is_some()
9507 }
9508 _ => false,
9509 }
9510 }
9511
9512 fn is_followed_by_np_object(&self) -> bool {
9513 if self.current + 1 >= self.tokens.len() {
9514 return false;
9515 }
9516 let next = &self.tokens[self.current + 1].kind;
9517 matches!(next,
9518 TokenType::ProperName(_) |
9519 TokenType::Article(_) |
9520 TokenType::Noun(_) |
9521 TokenType::Pronoun { .. } |
9522 TokenType::Reflexive |
9523 TokenType::Who |
9524 TokenType::What |
9525 TokenType::Where |
9526 TokenType::When |
9527 TokenType::Why
9528 )
9529 }
9530
9531 fn is_followed_by_gerund(&self) -> bool {
9532 if self.current + 1 >= self.tokens.len() {
9533 return false;
9534 }
9535 matches!(self.tokens[self.current + 1].kind, TokenType::Verb { .. })
9536 }
9537
9538 fn parse_spawn_statement(&mut self) -> ParseResult<Stmt<'a>> {
9544 self.advance(); if !self.check_article() {
9548 return Err(ParseError {
9549 kind: ParseErrorKind::ExpectedKeyword { keyword: "a/an".to_string() },
9550 span: self.current_span(),
9551 });
9552 }
9553 self.advance(); let agent_type = match &self.tokens[self.current].kind {
9557 TokenType::Noun(sym) | TokenType::ProperName(sym) => {
9558 let s = *sym;
9559 self.advance();
9560 s
9561 }
9562 _ => {
9563 return Err(ParseError {
9564 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent type".to_string() },
9565 span: self.current_span(),
9566 });
9567 }
9568 };
9569
9570 if !self.check(&TokenType::Called) {
9572 return Err(ParseError {
9573 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
9574 span: self.current_span(),
9575 });
9576 }
9577 self.advance(); let name = if let TokenType::StringLiteral(sym) = &self.tokens[self.current].kind {
9581 let s = *sym;
9582 self.advance();
9583 s
9584 } else {
9585 return Err(ParseError {
9586 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent name".to_string() },
9587 span: self.current_span(),
9588 });
9589 };
9590
9591 Ok(Stmt::Spawn { agent_type, name })
9592 }
9593
9594 fn parse_send_statement(&mut self) -> ParseResult<Stmt<'a>> {
9596 self.advance(); let message = self.parse_imperative_expr()?;
9600
9601 if !self.check_preposition_is("to") {
9603 return Err(ParseError {
9604 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9605 span: self.current_span(),
9606 });
9607 }
9608 self.advance(); let destination = self.parse_imperative_expr()?;
9612
9613 Ok(Stmt::SendMessage { message, destination })
9614 }
9615
9616 fn parse_await_statement(&mut self) -> ParseResult<Stmt<'a>> {
9618 self.advance(); if self.check_word("response") {
9622 self.advance();
9623 }
9624
9625 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
9627 return Err(ParseError {
9628 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
9629 span: self.current_span(),
9630 });
9631 }
9632 self.advance(); let source = self.parse_imperative_expr()?;
9636
9637 if !self.check_word("into") {
9639 return Err(ParseError {
9640 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
9641 span: self.current_span(),
9642 });
9643 }
9644 self.advance(); let into = match &self.tokens[self.current].kind {
9648 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
9649 let s = *sym;
9650 self.advance();
9651 s
9652 }
9653 _ if self.check_content_word() => {
9655 let sym = self.tokens[self.current].lexeme;
9656 self.advance();
9657 sym
9658 }
9659 _ => {
9660 return Err(ParseError {
9661 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
9662 span: self.current_span(),
9663 });
9664 }
9665 };
9666
9667 Ok(Stmt::AwaitMessage { source, into })
9668 }
9669
9670 fn parse_merge_statement(&mut self) -> ParseResult<Stmt<'a>> {
9676 self.advance(); let source = self.parse_imperative_expr()?;
9680
9681 if !self.check_word("into") {
9683 return Err(ParseError {
9684 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
9685 span: self.current_span(),
9686 });
9687 }
9688 self.advance(); let target = self.parse_imperative_expr()?;
9692
9693 Ok(Stmt::MergeCrdt { source, target })
9694 }
9695
9696 fn parse_increase_statement(&mut self) -> ParseResult<Stmt<'a>> {
9698 self.advance(); let expr = self.parse_imperative_expr()?;
9702
9703 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
9705 (object, field)
9706 } else {
9707 return Err(ParseError {
9708 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
9709 span: self.current_span(),
9710 });
9711 };
9712
9713 if !self.check_preposition_is("by") {
9715 return Err(ParseError {
9716 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
9717 span: self.current_span(),
9718 });
9719 }
9720 self.advance(); let amount = self.parse_imperative_expr()?;
9724
9725 Ok(Stmt::IncreaseCrdt { object, field: *field, amount })
9726 }
9727
9728 fn parse_decrease_statement(&mut self) -> ParseResult<Stmt<'a>> {
9730 self.advance(); let expr = self.parse_imperative_expr()?;
9734
9735 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
9737 (object, field)
9738 } else {
9739 return Err(ParseError {
9740 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
9741 span: self.current_span(),
9742 });
9743 };
9744
9745 if !self.check_preposition_is("by") {
9747 return Err(ParseError {
9748 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
9749 span: self.current_span(),
9750 });
9751 }
9752 self.advance(); let amount = self.parse_imperative_expr()?;
9756
9757 Ok(Stmt::DecreaseCrdt { object, field: *field, amount })
9758 }
9759
9760 fn parse_append_statement(&mut self) -> ParseResult<Stmt<'a>> {
9762 self.advance(); let value = self.parse_imperative_expr()?;
9766
9767 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
9769 return Err(ParseError {
9770 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9771 span: self.current_span(),
9772 });
9773 }
9774 self.advance(); let sequence = self.parse_imperative_expr()?;
9778
9779 Ok(Stmt::AppendToSequence { sequence, value })
9780 }
9781
9782 fn parse_resolve_statement(&mut self) -> ParseResult<Stmt<'a>> {
9784 self.advance(); let expr = self.parse_imperative_expr()?;
9788
9789 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
9791 (object, field)
9792 } else {
9793 return Err(ParseError {
9794 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's title')".to_string() },
9795 span: self.current_span(),
9796 });
9797 };
9798
9799 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
9801 return Err(ParseError {
9802 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
9803 span: self.current_span(),
9804 });
9805 }
9806 self.advance(); let value = self.parse_imperative_expr()?;
9810
9811 Ok(Stmt::ResolveConflict { object, field: *field, value })
9812 }
9813
9814}
9815