1mod clause;
55mod common;
56mod modal;
57mod noun;
58mod pragmatics;
59mod quantifier;
60mod question;
61mod verb;
62
63#[cfg(test)]
64mod tests;
65
66pub use clause::ClauseParsing;
67pub use modal::ModalParsing;
68pub use noun::NounParsing;
69pub use pragmatics::PragmaticsParsing;
70pub use quantifier::QuantifierParsing;
71pub use question::QuestionParsing;
72pub use verb::{LogicVerbParsing, ImperativeVerbParsing};
73
74use crate::analysis::TypeRegistry;
75use crate::arena_ctx::AstContext;
76use crate::ast::{AspectOperator, LogicExpr, NeoEventData, NumberKind, QuantifierKind, TemporalOperator, Term, ThematicRole, Stmt, Expr, Literal, TypeExpr, BinaryOpKind, MatchArm, OptFlag};
77use crate::ast::stmt::{ReadSource, Pattern};
78use std::collections::HashSet;
79use crate::drs::{Case, Gender, Number, ReferentSource};
80use crate::drs::{Drs, BoxType, WorldState};
81use crate::error::{ParseError, ParseErrorKind};
82use logicaffeine_base::{Interner, Symbol, SymbolEq};
83use crate::lexer::Lexer;
84use crate::lexicon::{self, Aspect, Definiteness, Time, VerbClass};
85use crate::token::{BlockType, FocusKind, Token, TokenType};
86
87pub(super) type ParseResult<T> = Result<T, ParseError>;
88
89use std::ops::{Deref, DerefMut};
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
93pub enum ParserMode {
94 #[default]
96 Declarative,
97 Imperative,
99}
100
101#[derive(Debug, Clone, Copy)]
103pub(super) enum CopulaTemporal {
104 Always,
105 Never,
106 Eventually,
107}
108
109#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
114pub enum NegativeScopeMode {
115 #[default]
118 Narrow,
119 Wide,
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
132pub enum ModalPreference {
133 #[default]
135 Default,
136 Epistemic,
138 Deontic,
140}
141
142#[derive(Debug, Clone, Copy)]
147pub enum ResolvedPronoun {
148 Variable(Symbol),
150 Constant(Symbol),
152}
153
154#[derive(Clone)]
155struct ParserCheckpoint {
156 pos: usize,
157 var_counter: usize,
158 bindings_len: usize,
159 island: u32,
160 time: Option<Time>,
161 negative_depth: u32,
162}
163
164pub struct ParserGuard<'p, 'a, 'ctx, 'int> {
197 parser: &'p mut Parser<'a, 'ctx, 'int>,
198 checkpoint: ParserCheckpoint,
199 committed: bool,
200}
201
202impl<'p, 'a, 'ctx, 'int> ParserGuard<'p, 'a, 'ctx, 'int> {
203 pub fn commit(mut self) {
205 self.committed = true;
206 }
207}
208
209impl<'p, 'a, 'ctx, 'int> Drop for ParserGuard<'p, 'a, 'ctx, 'int> {
210 fn drop(&mut self) {
211 if !self.committed {
212 self.parser.restore(self.checkpoint.clone());
213 }
214 }
215}
216
217impl<'p, 'a, 'ctx, 'int> Deref for ParserGuard<'p, 'a, 'ctx, 'int> {
218 type Target = Parser<'a, 'ctx, 'int>;
219 fn deref(&self) -> &Self::Target {
220 self.parser
221 }
222}
223
224impl<'p, 'a, 'ctx, 'int> DerefMut for ParserGuard<'p, 'a, 'ctx, 'int> {
225 fn deref_mut(&mut self) -> &mut Self::Target {
226 self.parser
227 }
228}
229
230#[derive(Clone, Debug)]
235pub struct EventTemplate<'a> {
236 pub verb: Symbol,
238 pub non_agent_roles: Vec<(ThematicRole, Term<'a>)>,
240 pub modifiers: Vec<Symbol>,
242}
243
244pub struct Parser<'a, 'ctx, 'int> {
261 pub(super) tokens: Vec<Token>,
263 pub(super) current: usize,
265 pub(super) var_counter: usize,
267 pub(super) pending_time: Option<Time>,
269 pub(super) donkey_bindings: Vec<(Symbol, Symbol, bool, bool)>,
271 pub(super) interner: &'int mut Interner,
273 pub(super) ctx: AstContext<'a>,
275 pub(super) current_island: u32,
277 pub(super) pp_attach_to_noun: bool,
279 pub(super) filler_gap: Option<Symbol>,
281 pub(super) negative_depth: u32,
283 pub(super) discourse_event_var: Option<Symbol>,
285 pub(super) last_event_template: Option<EventTemplate<'a>>,
287 pub(super) noun_priority_mode: bool,
289 pub(super) collective_mode: bool,
291 pub(super) pending_cardinal: Option<u32>,
293 pub(super) mode: ParserMode,
295 pub(super) type_registry: Option<TypeRegistry>,
297 pub(super) event_reading_mode: bool,
299 pub(super) drs: Drs,
301 pub(super) negative_scope_mode: NegativeScopeMode,
303 pub(super) modal_preference: ModalPreference,
305 pub(super) world_state: &'ctx mut WorldState,
307 pub(super) in_negative_quantifier: bool,
309}
310
311impl<'a, 'ctx, 'int> Parser<'a, 'ctx, 'int> {
312 pub fn new(
316 tokens: Vec<Token>,
317 world_state: &'ctx mut WorldState,
318 interner: &'int mut Interner,
319 ctx: AstContext<'a>,
320 types: TypeRegistry,
321 ) -> Self {
322 Parser {
323 tokens,
324 current: 0,
325 var_counter: 0,
326 pending_time: None,
327 donkey_bindings: Vec::new(),
328 interner,
329 ctx,
330 current_island: 0,
331 pp_attach_to_noun: false,
332 filler_gap: None,
333 negative_depth: 0,
334 discourse_event_var: None,
335 last_event_template: None,
336 noun_priority_mode: false,
337 collective_mode: false,
338 pending_cardinal: None,
339 mode: ParserMode::Declarative,
340 type_registry: Some(types),
341 event_reading_mode: false,
342 drs: Drs::new(), negative_scope_mode: NegativeScopeMode::default(),
344 modal_preference: ModalPreference::default(),
345 world_state,
346 in_negative_quantifier: false,
347 }
348 }
349
350 pub fn set_discourse_event_var(&mut self, var: Symbol) {
351 self.discourse_event_var = Some(var);
352 }
353
354 pub fn drs_mut(&mut self) -> &mut Drs {
356 &mut self.world_state.drs
357 }
358
359 pub fn drs_ref(&self) -> &Drs {
361 &self.world_state.drs
362 }
363
364 pub fn swap_drs_with_world_state(&mut self) {
368 std::mem::swap(&mut self.drs, &mut self.world_state.drs);
369 }
370
371 pub fn has_world_state(&self) -> bool {
373 true
374 }
375
376 pub fn mode(&self) -> ParserMode {
377 self.mode
378 }
379
380 pub fn is_known_type(&self, sym: Symbol) -> bool {
383 self.type_registry
384 .as_ref()
385 .map(|r| r.is_type(sym))
386 .unwrap_or(false)
387 }
388
389 pub fn is_generic_type(&self, sym: Symbol) -> bool {
392 self.type_registry
393 .as_ref()
394 .map(|r| r.is_generic(sym))
395 .unwrap_or(false)
396 }
397
398 fn get_generic_param_count(&self, sym: Symbol) -> Option<usize> {
400 use crate::analysis::TypeDef;
401 self.type_registry.as_ref().and_then(|r| {
402 match r.get(sym) {
403 Some(TypeDef::Generic { param_count }) => Some(*param_count),
404 _ => None,
405 }
406 })
407 }
408
409 fn find_variant(&self, sym: Symbol) -> Option<Symbol> {
411 self.type_registry
412 .as_ref()
413 .and_then(|r| r.find_variant(sym).map(|(enum_name, _)| enum_name))
414 }
415
416 fn consume_type_name(&mut self) -> ParseResult<Symbol> {
418 let t = self.advance().clone();
419 match t.kind {
420 TokenType::Noun(s) | TokenType::Adjective(s) => Ok(s),
421 TokenType::ProperName(s) => Ok(s),
422 TokenType::Verb { .. } => Ok(t.lexeme),
424 TokenType::Tally => Ok(self.interner.intern("Tally")),
426 TokenType::SharedSet => Ok(self.interner.intern("SharedSet")),
427 TokenType::SharedSequence => Ok(self.interner.intern("SharedSequence")),
428 TokenType::CollaborativeSequence => Ok(self.interner.intern("CollaborativeSequence")),
429 TokenType::SharedMap => Ok(self.interner.intern("SharedMap")),
430 TokenType::Divergent => Ok(self.interner.intern("Divergent")),
431 TokenType::Article(_) => Ok(t.lexeme),
433 other => Err(ParseError {
434 kind: ParseErrorKind::ExpectedContentWord { found: other },
435 span: self.current_span(),
436 }),
437 }
438 }
439
440 fn parse_type_expression(&mut self) -> ParseResult<TypeExpr<'a>> {
445 use noun::NounParsing;
446
447 if self.check_word("fn") {
449 if let Some(next) = self.tokens.get(self.current + 1) {
450 if matches!(next.kind, TokenType::LParen) {
451 self.advance(); self.advance(); let mut inputs = Vec::new();
456 if !self.check(&TokenType::RParen) {
457 inputs.push(self.parse_type_expression()?);
458 while self.check(&TokenType::Comma) {
459 self.advance(); inputs.push(self.parse_type_expression()?);
461 }
462 }
463
464 if !self.check(&TokenType::RParen) {
465 return Err(ParseError {
466 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
467 span: self.current_span(),
468 });
469 }
470 self.advance(); if !self.check(&TokenType::Arrow) {
474 return Err(ParseError {
475 kind: ParseErrorKind::ExpectedKeyword { keyword: "->".to_string() },
476 span: self.current_span(),
477 });
478 }
479 self.advance(); let output = self.parse_type_expression()?;
482 let output_ref = self.ctx.alloc_type_expr(output);
483 let inputs_ref = self.ctx.alloc_type_exprs(inputs);
484 return Ok(TypeExpr::Function { inputs: inputs_ref, output: output_ref });
485 }
486 }
487 }
488
489 if self.check(&TokenType::LParen) {
491 self.advance(); let inner = self.parse_type_expression()?;
493 if !self.check(&TokenType::RParen) {
494 return Err(ParseError {
495 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
496 span: self.current_span(),
497 });
498 }
499 self.advance(); return Ok(inner);
501 }
502
503 if self.check(&TokenType::Persistent) {
505 self.advance(); let inner = self.parse_type_expression()?;
507 let inner_ref = self.ctx.alloc_type_expr(inner);
508 return Ok(TypeExpr::Persistent { inner: inner_ref });
509 }
510
511 let mut base = self.consume_type_name()?;
513
514 let base_name = self.interner.resolve(base);
516 if base_name == "SharedSet" || base_name == "ORSet" {
517 if self.check(&TokenType::LParen) {
518 self.advance(); if self.check(&TokenType::RemoveWins) {
520 self.advance(); base = self.interner.intern("SharedSet_RemoveWins");
522 } else if self.check(&TokenType::AddWins) {
523 self.advance(); base = self.interner.intern("SharedSet_AddWins");
526 }
527 if !self.check(&TokenType::RParen) {
528 return Err(ParseError {
529 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
530 span: self.current_span(),
531 });
532 }
533 self.advance(); }
535 }
536
537 let base_name = self.interner.resolve(base);
539 if base_name == "SharedSequence" || base_name == "RGA" {
540 if self.check(&TokenType::LParen) {
541 self.advance(); if self.check(&TokenType::YATA) {
543 self.advance(); base = self.interner.intern("SharedSequence_YATA");
545 }
546 if !self.check(&TokenType::RParen) {
547 return Err(ParseError {
548 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
549 span: self.current_span(),
550 });
551 }
552 self.advance(); }
554 }
555
556 let base_type = if self.check(&TokenType::From) {
558 self.advance(); let module_name = self.consume_type_name()?;
560 let module_str = self.interner.resolve(module_name);
561 let base_str = self.interner.resolve(base);
562 let qualified = format!("{}::{}", module_str, base_str);
563 let qualified_sym = self.interner.intern(&qualified);
564 TypeExpr::Named(qualified_sym)
565 } else {
566 let base_name = self.interner.resolve(base);
568 let param_count = self.get_generic_param_count(base)
569 .or_else(|| match base_name {
570 "Result" => Some(2), "Option" | "Maybe" => Some(1), "Seq" | "List" | "Vec" => Some(1), "Set" | "HashSet" => Some(1), "Map" | "HashMap" => Some(2), "Pair" => Some(2), "Triple" => Some(3), "SharedSet" | "ORSet" | "SharedSet_AddWins" | "SharedSet_RemoveWins" => Some(1),
580 "SharedSequence" | "RGA" | "SharedSequence_YATA" | "CollaborativeSequence" => Some(1),
581 "SharedMap" | "ORMap" => Some(2), "Divergent" | "MVRegister" => Some(1), _ => None,
584 });
585
586 if let Some(count) = param_count {
588 let has_preposition = self.check_of_preposition() || self.check_preposition_is("from");
589 let maybe_direct = !has_preposition && base_name == "Maybe" && matches!(
591 self.peek().kind,
592 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) | TokenType::Verb { .. }
593 );
594 if has_preposition || maybe_direct {
595 if has_preposition {
596 self.advance(); }
598
599 let mut params = Vec::new();
600 for i in 0..count {
601 if i > 0 {
602 if self.check(&TokenType::And) || self.check_to_preposition() || self.check(&TokenType::Comma) {
604 self.advance();
605 }
606 }
607 let param = self.parse_type_expression()?;
608 params.push(param);
609 }
610
611 let params_slice = self.ctx.alloc_type_exprs(params);
612 TypeExpr::Generic { base, params: params_slice }
613 } else {
614 let is_primitive = self.type_registry.as_ref().map(|r| r.is_type(base)).unwrap_or(false)
616 || matches!(base_name, "Int" | "Nat" | "Text" | "Bool" | "Boolean" | "Real" | "Unit");
617 if is_primitive {
618 TypeExpr::Primitive(base)
619 } else {
620 TypeExpr::Named(base)
621 }
622 }
623 } else {
624 let is_primitive = self.type_registry.as_ref().map(|r| r.is_type(base)).unwrap_or(false)
626 || matches!(base_name, "Int" | "Nat" | "Text" | "Bool" | "Boolean" | "Real" | "Unit");
627 if is_primitive {
628 TypeExpr::Primitive(base)
629 } else {
630 TypeExpr::Named(base)
632 }
633 }
634 };
635
636 if self.check(&TokenType::Where) {
638 self.advance(); let predicate_expr = self.parse_condition()?;
642
643 let bound_var = self.extract_bound_var(&predicate_expr)
645 .unwrap_or_else(|| self.interner.intern("it"));
646
647 let predicate = self.expr_to_logic_predicate(&predicate_expr, bound_var)
649 .ok_or_else(|| ParseError {
650 kind: ParseErrorKind::InvalidRefinementPredicate,
651 span: self.peek().span,
652 })?;
653
654 let base_alloc = self.ctx.alloc_type_expr(base_type);
656
657 return Ok(TypeExpr::Refinement { base: base_alloc, var: bound_var, predicate });
658 }
659
660 Ok(base_type)
661 }
662
663 fn extract_bound_var(&self, expr: &Expr<'a>) -> Option<Symbol> {
665 match expr {
666 Expr::Identifier(sym) => Some(*sym),
667 Expr::BinaryOp { left, .. } => self.extract_bound_var(left),
668 _ => None,
669 }
670 }
671
672 fn expr_to_logic_predicate(&mut self, expr: &Expr<'a>, bound_var: Symbol) -> Option<&'a LogicExpr<'a>> {
675 match expr {
676 Expr::BinaryOp { op, left, right } => {
677 let pred_name = match op {
679 BinaryOpKind::Gt => "Greater",
680 BinaryOpKind::Lt => "Less",
681 BinaryOpKind::GtEq => "GreaterEqual",
682 BinaryOpKind::LtEq => "LessEqual",
683 BinaryOpKind::Eq => "Equal",
684 BinaryOpKind::NotEq => "NotEqual",
685 BinaryOpKind::And => {
686 let left_logic = self.expr_to_logic_predicate(left, bound_var)?;
688 let right_logic = self.expr_to_logic_predicate(right, bound_var)?;
689 return Some(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
690 left: left_logic,
691 op: TokenType::And,
692 right: right_logic,
693 }));
694 }
695 BinaryOpKind::Or => {
696 let left_logic = self.expr_to_logic_predicate(left, bound_var)?;
697 let right_logic = self.expr_to_logic_predicate(right, bound_var)?;
698 return Some(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
699 left: left_logic,
700 op: TokenType::Or,
701 right: right_logic,
702 }));
703 }
704 _ => return None, };
706 let pred_sym = self.interner.intern(pred_name);
707
708 let left_term = self.expr_to_term(left)?;
710 let right_term = self.expr_to_term(right)?;
711
712 let args = self.ctx.terms.alloc_slice([left_term, right_term]);
713 Some(self.ctx.exprs.alloc(LogicExpr::Predicate { name: pred_sym, args, world: None }))
714 }
715 _ => None,
716 }
717 }
718
719 fn expr_to_term(&mut self, expr: &Expr<'a>) -> Option<Term<'a>> {
721 match expr {
722 Expr::Identifier(sym) => Some(Term::Variable(*sym)),
723 Expr::Literal(lit) => {
724 match lit {
725 Literal::Number(n) => Some(Term::Value {
726 kind: NumberKind::Integer(*n),
727 unit: None,
728 dimension: None,
729 }),
730 Literal::Boolean(b) => {
731 let sym = self.interner.intern(if *b { "true" } else { "false" });
732 Some(Term::Constant(sym))
733 }
734 _ => None, }
736 }
737 _ => None,
738 }
739 }
740
741 pub fn process_block_headers(&mut self) {
742 use crate::token::BlockType;
743
744 while self.current < self.tokens.len() {
745 if let TokenType::BlockHeader { block_type } = &self.tokens[self.current].kind {
746 self.mode = match block_type {
747 BlockType::Main | BlockType::Function => ParserMode::Imperative,
748 BlockType::Theorem | BlockType::Definition | BlockType::Proof |
749 BlockType::Example | BlockType::Logic | BlockType::Note | BlockType::TypeDef |
750 BlockType::Policy | BlockType::Requires |
751 BlockType::Hardware | BlockType::Property => ParserMode::Declarative,
752 BlockType::No => self.mode, };
754 self.current += 1;
755 } else {
756 break;
757 }
758 }
759 }
760
761 pub fn get_event_var(&mut self) -> Symbol {
762 self.discourse_event_var.unwrap_or_else(|| self.interner.intern("e"))
763 }
764
765 pub fn capture_event_template(&mut self, verb: Symbol, roles: &[(ThematicRole, Term<'a>)], modifiers: &[Symbol]) {
766 let non_agent_roles: Vec<_> = roles.iter()
767 .filter(|(role, _)| *role != ThematicRole::Agent)
768 .cloned()
769 .collect();
770 self.last_event_template = Some(EventTemplate {
771 verb,
772 non_agent_roles,
773 modifiers: modifiers.to_vec(),
774 });
775 }
776
777 fn parse_embedded_wh_clause(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
778 let var_name = self.interner.intern("x");
780 let var_term = Term::Variable(var_name);
781
782 if self.check_verb() {
783 let verb = self.consume_verb();
785 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
786 name: verb,
787 args: self.ctx.terms.alloc_slice([var_term]),
788 world: None,
789 });
790 return Ok(body);
791 }
792
793 if self.check_content_word() || self.check_article() {
794 let subject = self.parse_noun_phrase(true)?;
796 if self.check_verb() {
797 let verb = self.consume_verb();
798 let body = self.ctx.exprs.alloc(LogicExpr::Predicate {
799 name: verb,
800 args: self.ctx.terms.alloc_slice([
801 Term::Constant(subject.noun),
802 var_term,
803 ]),
804 world: None,
805 });
806 return Ok(body);
807 }
808 }
809
810 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(var_name)))
812 }
813
814 pub fn set_pp_attachment_mode(&mut self, attach_to_noun: bool) {
815 self.pp_attach_to_noun = attach_to_noun;
816 }
817
818 pub fn set_noun_priority_mode(&mut self, mode: bool) {
819 self.noun_priority_mode = mode;
820 }
821
822 pub fn set_collective_mode(&mut self, mode: bool) {
823 self.collective_mode = mode;
824 }
825
826 pub fn set_event_reading_mode(&mut self, mode: bool) {
827 self.event_reading_mode = mode;
828 }
829
830 pub fn set_negative_scope_mode(&mut self, mode: NegativeScopeMode) {
831 self.negative_scope_mode = mode;
832 }
833
834 pub fn set_modal_preference(&mut self, pref: ModalPreference) {
835 self.modal_preference = pref;
836 }
837
838 fn checkpoint(&self) -> ParserCheckpoint {
839 ParserCheckpoint {
840 pos: self.current,
841 var_counter: self.var_counter,
842 bindings_len: self.donkey_bindings.len(),
843 island: self.current_island,
844 time: self.pending_time,
845 negative_depth: self.negative_depth,
846 }
847 }
848
849 fn restore(&mut self, cp: ParserCheckpoint) {
850 self.current = cp.pos;
851 self.var_counter = cp.var_counter;
852 self.donkey_bindings.truncate(cp.bindings_len);
853 self.current_island = cp.island;
854 self.pending_time = cp.time;
855 self.negative_depth = cp.negative_depth;
856 }
857
858 fn is_negative_context(&self) -> bool {
859 self.negative_depth % 2 == 1
860 }
861
862 pub fn guard(&mut self) -> ParserGuard<'_, 'a, 'ctx, 'int> {
863 ParserGuard {
864 checkpoint: self.checkpoint(),
865 parser: self,
866 committed: false,
867 }
868 }
869
870 pub(super) fn try_parse<F, T>(&mut self, op: F) -> Option<T>
871 where
872 F: FnOnce(&mut Self) -> ParseResult<T>,
873 {
874 let cp = self.checkpoint();
875 match op(self) {
876 Ok(res) => Some(res),
877 Err(_) => {
878 self.restore(cp);
879 None
880 }
881 }
882 }
883
884 fn resolve_pronoun(&mut self, gender: Gender, number: Number) -> ParseResult<ResolvedPronoun> {
885 if self.world_state.in_discourse_mode() && self.world_state.has_prior_modal_context() {
890 if let Some(candidate) = self.world_state.resolve_via_telescope(gender) {
893 return Ok(ResolvedPronoun::Variable(candidate.variable));
894 }
895 let blocked_candidates: Vec<_> = self.world_state.telescope_candidates()
899 .iter()
900 .filter(|c| c.in_modal_scope)
901 .collect();
902 if !blocked_candidates.is_empty() {
903 let has_upcoming_modal = self.has_modal_subordination_ahead();
906 if has_upcoming_modal {
907 if let Some(candidate) = blocked_candidates.into_iter().find(|c| {
909 c.gender == gender || gender == Gender::Unknown || c.gender == Gender::Unknown
910 }) {
911 return Ok(ResolvedPronoun::Variable(candidate.variable));
912 }
913 }
914 return Err(ParseError {
916 kind: ParseErrorKind::ScopeViolation(
917 "Cannot access hypothetical entity from reality. Use modal subordination (e.g., 'would') to continue a hypothetical context.".to_string()
918 ),
919 span: self.current_span(),
920 });
921 }
922 }
924
925 let current_box = self.drs.current_box_index();
927 match self.drs.resolve_pronoun(current_box, gender, number) {
928 Ok(sym) => return Ok(ResolvedPronoun::Variable(sym)),
929 Err(crate::drs::ScopeError::InaccessibleReferent { gender: g, reason, .. }) => {
930 if self.world_state.in_discourse_mode() {
934 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
935 return Ok(ResolvedPronoun::Variable(candidate.variable));
936 }
937 }
938 return Err(ParseError {
940 kind: ParseErrorKind::ScopeViolation(reason),
941 span: self.current_span(),
942 });
943 }
944 Err(crate::drs::ScopeError::NoMatchingReferent { gender: g, number: n }) => {
945 if !self.world_state.has_prior_modal_context() {
947 if let Some(candidate) = self.world_state.resolve_via_telescope(g) {
948 return Ok(ResolvedPronoun::Variable(candidate.variable));
949 }
950 }
951
952 if self.world_state.in_discourse_mode() {
954 return Err(ParseError {
955 kind: ParseErrorKind::UnresolvedPronoun {
956 gender: g,
957 number: n,
958 },
959 span: self.current_span(),
960 });
961 }
962
963 let deictic_name = match (g, n) {
966 (Gender::Male, Number::Singular) => "Him",
967 (Gender::Female, Number::Singular) => "Her",
968 (Gender::Neuter, Number::Singular) => "It",
969 (Gender::Male, Number::Plural) | (Gender::Female, Number::Plural) => "Them",
970 (Gender::Neuter, Number::Plural) => "Them",
971 (Gender::Unknown, _) => "Someone",
972 };
973 let sym = self.interner.intern(deictic_name);
974 self.drs.introduce_referent(sym, sym, g, n);
976 return Ok(ResolvedPronoun::Constant(sym));
977 }
978 }
979 }
980
981 fn resolve_donkey_pronoun(&mut self, gender: Gender) -> Option<Symbol> {
982 for (noun_class, var_name, used, _wide_neg) in self.donkey_bindings.iter_mut().rev() {
983 let noun_str = self.interner.resolve(*noun_class);
984 let noun_gender = Self::infer_noun_gender(noun_str);
985 if noun_gender == gender || gender == Gender::Neuter || noun_gender == Gender::Unknown {
986 *used = true; return Some(*var_name);
988 }
989 }
990 None
991 }
992
993 fn infer_noun_gender(noun: &str) -> Gender {
994 let lower = noun.to_lowercase();
995 if lexicon::is_female_noun(&lower) {
996 Gender::Female
997 } else if lexicon::is_male_noun(&lower) {
998 Gender::Male
999 } else if lexicon::is_neuter_noun(&lower) {
1000 Gender::Neuter
1001 } else {
1002 Gender::Unknown
1003 }
1004 }
1005
1006 fn is_plural_noun(noun: &str) -> bool {
1007 let lower = noun.to_lowercase();
1008 if lexicon::is_proper_name(&lower) {
1010 return false;
1011 }
1012 if lexicon::is_irregular_plural(&lower) {
1013 return true;
1014 }
1015 lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2
1016 }
1017
1018 fn singularize_noun(noun: &str) -> String {
1019 let lower = noun.to_lowercase();
1020 if let Some(singular) = lexicon::singularize(&lower) {
1021 return singular.to_string();
1022 }
1023 if lower.ends_with('s') && !lower.ends_with("ss") && lower.len() > 2 {
1024 let base = &lower[..lower.len() - 1];
1025 let mut chars: Vec<char> = base.chars().collect();
1026 if !chars.is_empty() {
1027 chars[0] = chars[0].to_uppercase().next().unwrap();
1028 }
1029 return chars.into_iter().collect();
1030 }
1031 let mut chars: Vec<char> = lower.chars().collect();
1032 if !chars.is_empty() {
1033 chars[0] = chars[0].to_uppercase().next().unwrap();
1034 }
1035 chars.into_iter().collect()
1036 }
1037
1038 fn infer_gender(name: &str) -> Gender {
1039 let lower = name.to_lowercase();
1040 if lexicon::is_male_name(&lower) {
1041 Gender::Male
1042 } else if lexicon::is_female_name(&lower) {
1043 Gender::Female
1044 } else {
1045 Gender::Unknown
1046 }
1047 }
1048
1049
1050 fn next_var_name(&mut self) -> Symbol {
1051 const VARS: &[&str] = &["x", "y", "z", "w", "v", "u"];
1052 let idx = self.var_counter;
1053 self.var_counter += 1;
1054 if idx < VARS.len() {
1055 self.interner.intern(VARS[idx])
1056 } else {
1057 let name = format!("x{}", idx - VARS.len() + 1);
1058 self.interner.intern(&name)
1059 }
1060 }
1061
1062 pub fn parse(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
1079 let mut result = self.parse_sentence()?;
1080
1081 while self.check(&TokenType::Period) || self.check(&TokenType::Exclamation) {
1084 self.advance(); if !self.is_at_end() {
1086 let next = self.parse_sentence()?;
1087 result = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
1088 left: result,
1089 op: TokenType::And,
1090 right: next,
1091 });
1092 }
1093 }
1094
1095 Ok(result)
1096 }
1097
1098 pub fn parse_program(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
1116 let mut statements = Vec::new();
1117 let mut in_definition_block = false;
1118 let mut pending_opt_flags: HashSet<OptFlag> = HashSet::new();
1119
1120 if self.mode == ParserMode::Declarative {
1122 }
1126
1127 while !self.is_at_end() {
1128 if let Some(Token { kind: TokenType::BlockHeader { block_type }, .. }) = self.tokens.get(self.current) {
1130 match block_type {
1131 BlockType::Definition => {
1132 in_definition_block = true;
1133 self.mode = ParserMode::Declarative;
1134 self.advance();
1135 continue;
1136 }
1137 BlockType::Main => {
1138 in_definition_block = false;
1139 self.mode = ParserMode::Imperative;
1140 self.advance();
1141 continue;
1142 }
1143 BlockType::No => {
1144 self.advance(); if let Some(token) = self.tokens.get(self.current) {
1149 let word = self.interner.resolve(token.lexeme).to_lowercase();
1150 match word.as_str() {
1151 "memo" => { pending_opt_flags.insert(OptFlag::NoMemo); }
1152 "tco" => { pending_opt_flags.insert(OptFlag::NoTCO); }
1153 "peephole" => { pending_opt_flags.insert(OptFlag::NoPeephole); }
1154 "borrow" => { pending_opt_flags.insert(OptFlag::NoBorrow); }
1155 "optimize" => {
1156 pending_opt_flags.insert(OptFlag::NoOptimize);
1157 pending_opt_flags.insert(OptFlag::NoMemo);
1158 pending_opt_flags.insert(OptFlag::NoTCO);
1159 pending_opt_flags.insert(OptFlag::NoPeephole);
1160 pending_opt_flags.insert(OptFlag::NoBorrow);
1161 }
1162 _ => {} }
1164 self.advance(); }
1166 while self.check(&TokenType::Newline) {
1168 self.advance();
1169 }
1170 continue;
1171 }
1172 BlockType::Function => {
1173 in_definition_block = false;
1174 self.mode = ParserMode::Imperative;
1175 self.advance();
1176 let flags = std::mem::take(&mut pending_opt_flags);
1178 let func_def = self.parse_function_def_with_flags(flags)?;
1179 statements.push(func_def);
1180 continue;
1181 }
1182 BlockType::TypeDef => {
1183 self.advance();
1186 self.skip_type_def_content();
1187 continue;
1188 }
1189 BlockType::Policy => {
1190 in_definition_block = true; self.mode = ParserMode::Declarative;
1194 self.advance();
1195 continue;
1196 }
1197 BlockType::Hardware | BlockType::Property => {
1198 in_definition_block = true;
1201 self.mode = ParserMode::Declarative;
1202 self.advance();
1203 continue;
1204 }
1205 BlockType::Theorem => {
1206 in_definition_block = false;
1208 self.mode = ParserMode::Declarative;
1209 self.advance();
1210 let theorem = self.parse_theorem_block()?;
1211 statements.push(theorem);
1212 continue;
1213 }
1214 BlockType::Requires => {
1215 in_definition_block = false;
1216 self.mode = ParserMode::Declarative;
1217 self.advance();
1218 let deps = self.parse_requires_block()?;
1219 statements.extend(deps);
1220 continue;
1221 }
1222 _ => {
1223 in_definition_block = false;
1225 self.mode = ParserMode::Declarative;
1226 self.advance();
1227 continue;
1228 }
1229 }
1230 }
1231
1232 if in_definition_block {
1234 self.advance();
1235 continue;
1236 }
1237
1238 if self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) || self.check(&TokenType::Newline) {
1240 self.advance();
1241 continue;
1242 }
1243
1244 if self.mode == ParserMode::Imperative {
1246 let stmt = self.parse_statement()?;
1247 statements.push(stmt);
1248
1249 if self.check(&TokenType::Period) {
1250 self.advance();
1251 }
1252 } else {
1253 self.advance();
1255 }
1256 }
1257
1258 Ok(statements)
1259 }
1260
1261 fn parse_statement(&mut self) -> ParseResult<Stmt<'a>> {
1262 if self.check(&TokenType::To) || self.check_preposition_is("to") {
1265 return self.parse_function_def();
1266 }
1267 if self.check(&TokenType::Let) {
1268 return self.parse_let_statement();
1269 }
1270 if self.check(&TokenType::Mut) {
1273 return self.parse_equals_assignment(true);
1274 }
1275 if self.peek_equals_assignment() {
1278 return self.parse_equals_assignment(false);
1279 }
1280 if self.check(&TokenType::Set) {
1281 return self.parse_set_statement();
1282 }
1283 if self.check(&TokenType::Return) {
1284 return self.parse_return_statement();
1285 }
1286 if self.check(&TokenType::Break) {
1287 return self.parse_break_statement();
1288 }
1289 if self.check(&TokenType::If) {
1290 return self.parse_if_statement();
1291 }
1292 if self.check(&TokenType::Assert) {
1293 return self.parse_assert_statement();
1294 }
1295 if self.check(&TokenType::Trust) {
1297 return self.parse_trust_statement();
1298 }
1299 if self.check(&TokenType::Check) {
1301 return self.parse_check_statement();
1302 }
1303 if self.check(&TokenType::Listen) {
1305 return self.parse_listen_statement();
1306 }
1307 if self.check(&TokenType::NetConnect) {
1308 return self.parse_connect_statement();
1309 }
1310 if self.check(&TokenType::Sleep) {
1311 return self.parse_sleep_statement();
1312 }
1313 if self.check(&TokenType::Sync) {
1315 return self.parse_sync_statement();
1316 }
1317 if self.check(&TokenType::Mount) {
1319 return self.parse_mount_statement();
1320 }
1321 if self.check(&TokenType::While) {
1322 return self.parse_while_statement();
1323 }
1324 if self.check(&TokenType::Repeat) {
1325 return self.parse_repeat_statement();
1326 }
1327 if self.check(&TokenType::For) {
1329 return self.parse_for_statement();
1330 }
1331 if self.check(&TokenType::Call) {
1332 return self.parse_call_statement();
1333 }
1334 if self.check(&TokenType::Give) {
1335 return self.parse_give_statement();
1336 }
1337 if self.check(&TokenType::Show) {
1338 return self.parse_show_statement();
1339 }
1340 if self.check(&TokenType::Inspect) {
1342 return self.parse_inspect_statement();
1343 }
1344
1345 if self.check(&TokenType::Push) {
1347 return self.parse_push_statement();
1348 }
1349 if self.check(&TokenType::Pop) {
1350 return self.parse_pop_statement();
1351 }
1352 if self.check(&TokenType::Add) {
1354 return self.parse_add_statement();
1355 }
1356 if self.check(&TokenType::Remove) {
1357 return self.parse_remove_statement();
1358 }
1359
1360 if self.check(&TokenType::Inside) {
1362 return self.parse_zone_statement();
1363 }
1364
1365 if self.check(&TokenType::Attempt) {
1367 return self.parse_concurrent_block();
1368 }
1369 if self.check(&TokenType::Simultaneously) {
1370 return self.parse_parallel_block();
1371 }
1372
1373 if self.check(&TokenType::Read) {
1375 return self.parse_read_statement();
1376 }
1377 if self.check(&TokenType::Write) {
1378 return self.parse_write_statement();
1379 }
1380
1381 if self.check(&TokenType::Spawn) {
1383 return self.parse_spawn_statement();
1384 }
1385 if self.check(&TokenType::Send) {
1386 if self.lookahead_contains_into() {
1388 return self.parse_send_pipe_statement();
1389 }
1390 return self.parse_send_statement();
1391 }
1392 if self.check(&TokenType::Await) {
1393 if self.lookahead_is_first_of() {
1395 return self.parse_select_statement();
1396 }
1397 return self.parse_await_statement();
1398 }
1399
1400 if self.check(&TokenType::Merge) {
1402 return self.parse_merge_statement();
1403 }
1404 if self.check(&TokenType::Increase) {
1405 return self.parse_increase_statement();
1406 }
1407 if self.check(&TokenType::Decrease) {
1409 return self.parse_decrease_statement();
1410 }
1411 if self.check(&TokenType::Append) {
1412 return self.parse_append_statement();
1413 }
1414 if self.check(&TokenType::Resolve) {
1415 return self.parse_resolve_statement();
1416 }
1417
1418 if self.check(&TokenType::Launch) {
1420 return self.parse_launch_statement();
1421 }
1422 if self.check(&TokenType::Stop) {
1423 return self.parse_stop_statement();
1424 }
1425 if self.check(&TokenType::Try) {
1426 return self.parse_try_statement();
1427 }
1428 if self.check(&TokenType::Receive) {
1429 return self.parse_receive_pipe_statement();
1430 }
1431
1432 if self.check(&TokenType::Escape) {
1434 return self.parse_escape_statement();
1435 }
1436
1437 if self.tokens.get(self.current + 1)
1441 .map(|t| matches!(t.kind, TokenType::LParen))
1442 .unwrap_or(false)
1443 {
1444 let function = self.peek().lexeme;
1446 self.advance(); let expr = self.parse_call_expr(function)?;
1450 if let Expr::Call { function, args } = expr {
1451 return Ok(Stmt::Call { function: *function, args: args.clone() });
1452 }
1453 }
1454
1455 Err(ParseError {
1456 kind: ParseErrorKind::ExpectedStatement,
1457 span: self.current_span(),
1458 })
1459 }
1460
1461 fn parse_if_statement(&mut self) -> ParseResult<Stmt<'a>> {
1462 self.advance(); let cond = self.parse_condition()?;
1466
1467 if self.check(&TokenType::Then) {
1469 self.advance();
1470 }
1471
1472 if !self.check(&TokenType::Colon) {
1474 return Err(ParseError {
1475 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1476 span: self.current_span(),
1477 });
1478 }
1479 self.advance(); if !self.check(&TokenType::Indent) {
1483 return Err(ParseError {
1484 kind: ParseErrorKind::ExpectedStatement,
1485 span: self.current_span(),
1486 });
1487 }
1488 self.advance(); let mut then_stmts = Vec::new();
1492 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1493 let stmt = self.parse_statement()?;
1494 then_stmts.push(stmt);
1495 if self.check(&TokenType::Period) {
1496 self.advance();
1497 }
1498 }
1499
1500 if self.check(&TokenType::Dedent) {
1502 self.advance();
1503 }
1504
1505 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1507 .alloc_slice(then_stmts.into_iter());
1508
1509 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1511 self.advance(); if self.check(&TokenType::If) {
1515 let nested_if = self.parse_if_statement()?;
1517 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1518 .alloc_slice(std::iter::once(nested_if));
1519 Some(nested_slice)
1520 } else {
1521 if !self.check(&TokenType::Colon) {
1523 return Err(ParseError {
1524 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1525 span: self.current_span(),
1526 });
1527 }
1528 self.advance(); if !self.check(&TokenType::Indent) {
1531 return Err(ParseError {
1532 kind: ParseErrorKind::ExpectedStatement,
1533 span: self.current_span(),
1534 });
1535 }
1536 self.advance(); let mut else_stmts = Vec::new();
1539 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1540 let stmt = self.parse_statement()?;
1541 else_stmts.push(stmt);
1542 if self.check(&TokenType::Period) {
1543 self.advance();
1544 }
1545 }
1546
1547 if self.check(&TokenType::Dedent) {
1548 self.advance();
1549 }
1550
1551 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1552 .alloc_slice(else_stmts.into_iter()))
1553 }
1554 } else if self.check(&TokenType::Elif) {
1555 self.advance(); let nested_if = self.parse_elif_as_if()?;
1559 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1560 .alloc_slice(std::iter::once(nested_if));
1561 Some(nested_slice)
1562 } else {
1563 None
1564 };
1565
1566 Ok(Stmt::If {
1567 cond,
1568 then_block,
1569 else_block,
1570 })
1571 }
1572
1573 fn parse_elif_as_if(&mut self) -> ParseResult<Stmt<'a>> {
1576 let cond = self.parse_condition()?;
1578
1579 if !self.check(&TokenType::Colon) {
1581 return Err(ParseError {
1582 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1583 span: self.current_span(),
1584 });
1585 }
1586 self.advance(); if !self.check(&TokenType::Indent) {
1590 return Err(ParseError {
1591 kind: ParseErrorKind::ExpectedStatement,
1592 span: self.current_span(),
1593 });
1594 }
1595 self.advance(); let mut then_stmts = Vec::new();
1599 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1600 let stmt = self.parse_statement()?;
1601 then_stmts.push(stmt);
1602 if self.check(&TokenType::Period) {
1603 self.advance();
1604 }
1605 }
1606
1607 if self.check(&TokenType::Dedent) {
1609 self.advance();
1610 }
1611
1612 let then_block = self.ctx.stmts.expect("imperative arenas not initialized")
1614 .alloc_slice(then_stmts.into_iter());
1615
1616 let else_block = if self.check(&TokenType::Otherwise) || self.check(&TokenType::Else) {
1618 self.advance(); if self.check(&TokenType::If) {
1622 let nested_if = self.parse_if_statement()?;
1623 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1624 .alloc_slice(std::iter::once(nested_if));
1625 Some(nested_slice)
1626 } else {
1627 if !self.check(&TokenType::Colon) {
1629 return Err(ParseError {
1630 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1631 span: self.current_span(),
1632 });
1633 }
1634 self.advance(); if !self.check(&TokenType::Indent) {
1637 return Err(ParseError {
1638 kind: ParseErrorKind::ExpectedStatement,
1639 span: self.current_span(),
1640 });
1641 }
1642 self.advance(); let mut else_stmts = Vec::new();
1645 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1646 let stmt = self.parse_statement()?;
1647 else_stmts.push(stmt);
1648 if self.check(&TokenType::Period) {
1649 self.advance();
1650 }
1651 }
1652
1653 if self.check(&TokenType::Dedent) {
1654 self.advance();
1655 }
1656
1657 Some(self.ctx.stmts.expect("imperative arenas not initialized")
1658 .alloc_slice(else_stmts.into_iter()))
1659 }
1660 } else if self.check(&TokenType::Elif) {
1661 self.advance(); let nested_if = self.parse_elif_as_if()?;
1663 let nested_slice = self.ctx.stmts.expect("imperative arenas not initialized")
1664 .alloc_slice(std::iter::once(nested_if));
1665 Some(nested_slice)
1666 } else {
1667 None
1668 };
1669
1670 Ok(Stmt::If {
1671 cond,
1672 then_block,
1673 else_block,
1674 })
1675 }
1676
1677 fn parse_while_statement(&mut self) -> ParseResult<Stmt<'a>> {
1678 self.advance(); let cond = self.parse_condition()?;
1681
1682 let decreasing = if self.check(&TokenType::LParen) {
1684 self.advance(); if !self.check_word("decreasing") {
1688 return Err(ParseError {
1689 kind: ParseErrorKind::ExpectedKeyword { keyword: "decreasing".to_string() },
1690 span: self.current_span(),
1691 });
1692 }
1693 self.advance(); let variant = self.parse_imperative_expr()?;
1696
1697 if !self.check(&TokenType::RParen) {
1698 return Err(ParseError {
1699 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1700 span: self.current_span(),
1701 });
1702 }
1703 self.advance(); Some(variant)
1706 } else {
1707 None
1708 };
1709
1710 if !self.check(&TokenType::Colon) {
1711 return Err(ParseError {
1712 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1713 span: self.current_span(),
1714 });
1715 }
1716 self.advance(); if !self.check(&TokenType::Indent) {
1719 return Err(ParseError {
1720 kind: ParseErrorKind::ExpectedStatement,
1721 span: self.current_span(),
1722 });
1723 }
1724 self.advance(); let mut body_stmts = Vec::new();
1727 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1728 let stmt = self.parse_statement()?;
1729 body_stmts.push(stmt);
1730 if self.check(&TokenType::Period) {
1731 self.advance();
1732 }
1733 }
1734
1735 if self.check(&TokenType::Dedent) {
1736 self.advance();
1737 }
1738
1739 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1740 .alloc_slice(body_stmts.into_iter());
1741
1742 Ok(Stmt::While { cond, body, decreasing })
1743 }
1744
1745 fn parse_loop_pattern(&mut self) -> ParseResult<Pattern> {
1748 use crate::ast::stmt::Pattern;
1749
1750 if self.check(&TokenType::LParen) {
1752 self.advance(); let mut identifiers = Vec::new();
1755 loop {
1756 let id = self.expect_identifier()?;
1757 identifiers.push(id);
1758
1759 if self.check(&TokenType::Comma) {
1761 self.advance(); continue;
1763 }
1764 break;
1765 }
1766
1767 if !self.check(&TokenType::RParen) {
1769 return Err(ParseError {
1770 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
1771 span: self.current_span(),
1772 });
1773 }
1774 self.advance(); Ok(Pattern::Tuple(identifiers))
1777 } else {
1778 let id = self.expect_identifier()?;
1780 Ok(Pattern::Identifier(id))
1781 }
1782 }
1783
1784 fn parse_repeat_statement(&mut self) -> ParseResult<Stmt<'a>> {
1785 self.advance(); if self.check(&TokenType::For) {
1789 self.advance();
1790 }
1791
1792 let pattern = self.parse_loop_pattern()?;
1794
1795 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1797 self.advance(); let start = self.parse_imperative_expr()?;
1799
1800 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1802 return Err(ParseError {
1803 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1804 span: self.current_span(),
1805 });
1806 }
1807 self.advance();
1808
1809 let end = self.parse_imperative_expr()?;
1810 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1811 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1812 self.advance(); self.parse_imperative_expr()?
1814 } else {
1815 return Err(ParseError {
1816 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1817 span: self.current_span(),
1818 });
1819 };
1820
1821 if !self.check(&TokenType::Colon) {
1823 return Err(ParseError {
1824 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1825 span: self.current_span(),
1826 });
1827 }
1828 self.advance();
1829
1830 if !self.check(&TokenType::Indent) {
1832 return Err(ParseError {
1833 kind: ParseErrorKind::ExpectedStatement,
1834 span: self.current_span(),
1835 });
1836 }
1837 self.advance();
1838
1839 let mut body_stmts = Vec::new();
1841 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1842 let stmt = self.parse_statement()?;
1843 body_stmts.push(stmt);
1844 if self.check(&TokenType::Period) {
1845 self.advance();
1846 }
1847 }
1848
1849 if self.check(&TokenType::Dedent) {
1850 self.advance();
1851 }
1852
1853 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1854 .alloc_slice(body_stmts.into_iter());
1855
1856 Ok(Stmt::Repeat { pattern, iterable, body })
1857 }
1858
1859 fn parse_for_statement(&mut self) -> ParseResult<Stmt<'a>> {
1862 self.advance(); let pattern = self.parse_loop_pattern()?;
1866
1867 let iterable = if self.check(&TokenType::From) || self.check_preposition_is("from") {
1869 self.advance(); let start = self.parse_imperative_expr()?;
1871
1872 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
1874 return Err(ParseError {
1875 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
1876 span: self.current_span(),
1877 });
1878 }
1879 self.advance();
1880
1881 let end = self.parse_imperative_expr()?;
1882 self.ctx.alloc_imperative_expr(Expr::Range { start, end })
1883 } else if self.check(&TokenType::In) || self.check_preposition_is("in") {
1884 self.advance(); self.parse_imperative_expr()?
1886 } else {
1887 return Err(ParseError {
1888 kind: ParseErrorKind::ExpectedKeyword { keyword: "in or from".to_string() },
1889 span: self.current_span(),
1890 });
1891 };
1892
1893 if !self.check(&TokenType::Colon) {
1895 return Err(ParseError {
1896 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
1897 span: self.current_span(),
1898 });
1899 }
1900 self.advance();
1901
1902 if !self.check(&TokenType::Indent) {
1904 return Err(ParseError {
1905 kind: ParseErrorKind::ExpectedStatement,
1906 span: self.current_span(),
1907 });
1908 }
1909 self.advance();
1910
1911 let mut body_stmts = Vec::new();
1913 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
1914 let stmt = self.parse_statement()?;
1915 body_stmts.push(stmt);
1916 if self.check(&TokenType::Period) {
1917 self.advance();
1918 }
1919 }
1920
1921 if self.check(&TokenType::Dedent) {
1922 self.advance();
1923 }
1924
1925 let body = self.ctx.stmts.expect("imperative arenas not initialized")
1926 .alloc_slice(body_stmts.into_iter());
1927
1928 Ok(Stmt::Repeat { pattern, iterable, body })
1929 }
1930
1931 fn parse_call_statement(&mut self) -> ParseResult<Stmt<'a>> {
1932 self.advance(); let function = match &self.peek().kind {
1938 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
1939 let s = *sym;
1940 self.advance();
1941 s
1942 }
1943 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
1944 let s = self.peek().lexeme;
1946 self.advance();
1947 s
1948 }
1949 _ => {
1950 return Err(ParseError {
1951 kind: ParseErrorKind::ExpectedIdentifier,
1952 span: self.current_span(),
1953 });
1954 }
1955 };
1956
1957 let args = if self.check_preposition_is("with") {
1959 self.advance(); self.parse_call_arguments()?
1961 } else {
1962 Vec::new()
1963 };
1964
1965 Ok(Stmt::Call { function, args })
1966 }
1967
1968 fn parse_call_arguments(&mut self) -> ParseResult<Vec<&'a Expr<'a>>> {
1969 let mut args = Vec::new();
1970
1971 let arg = self.parse_call_arg()?;
1973 args.push(arg);
1974
1975 while self.check(&TokenType::And) || self.check(&TokenType::Comma) {
1977 self.advance(); let arg = self.parse_call_arg()?;
1979 args.push(arg);
1980 }
1981
1982 Ok(args)
1983 }
1984
1985 fn parse_call_arg(&mut self) -> ParseResult<&'a Expr<'a>> {
1986 if self.check(&TokenType::Give) {
1988 self.advance(); let value = self.parse_comparison()?;
1990 return Ok(self.ctx.alloc_imperative_expr(Expr::Give { value }));
1991 }
1992
1993 self.parse_comparison()
1996 }
1997
1998 fn parse_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
1999 self.parse_or_condition()
2002 }
2003
2004 fn parse_or_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
2006 let mut left = self.parse_and_condition()?;
2007
2008 while self.check(&TokenType::Or) || self.check_word("or") {
2009 self.advance();
2010 let right = self.parse_and_condition()?;
2011 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
2012 op: BinaryOpKind::Or,
2013 left,
2014 right,
2015 });
2016 }
2017
2018 Ok(left)
2019 }
2020
2021 fn parse_and_condition(&mut self) -> ParseResult<&'a Expr<'a>> {
2023 let mut left = self.parse_comparison()?;
2024
2025 while self.check(&TokenType::And) || self.check_word("and") {
2026 self.advance();
2027 let right = self.parse_comparison()?;
2028 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
2029 op: BinaryOpKind::And,
2030 left,
2031 right,
2032 });
2033 }
2034
2035 Ok(left)
2036 }
2037
2038 fn parse_comparison(&mut self) -> ParseResult<&'a Expr<'a>> {
2040 if self.check(&TokenType::Not) || self.check_word("not") {
2042 self.advance(); let operand = self.parse_comparison()?; return Ok(self.ctx.alloc_imperative_expr(Expr::Not { operand }));
2045 }
2046
2047 let left = self.parse_xor_expr()?;
2048
2049 let op = if self.check(&TokenType::Equals) {
2051 self.advance();
2052 Some(BinaryOpKind::Eq)
2053 } else if self.check(&TokenType::Identity) {
2054 self.advance();
2056 Some(BinaryOpKind::Eq)
2057 } else if self.check_word("is") {
2058 let saved_pos = self.current;
2060 self.advance(); if self.check_word("greater") {
2063 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
2065 self.advance(); Some(BinaryOpKind::Gt)
2067 } else {
2068 self.current = saved_pos;
2069 None
2070 }
2071 } else if self.check_word("less") {
2072 self.advance(); if self.check_word("than") || self.check_preposition_is("than") {
2074 self.advance(); Some(BinaryOpKind::Lt)
2076 } else {
2077 self.current = saved_pos;
2078 None
2079 }
2080 } else if self.check_word("at") {
2081 self.advance(); if self.check_word("least") {
2083 self.advance(); Some(BinaryOpKind::GtEq)
2085 } else if self.check_word("most") {
2086 self.advance(); Some(BinaryOpKind::LtEq)
2088 } else {
2089 self.current = saved_pos;
2090 None
2091 }
2092 } else if self.check_word("not") || self.check(&TokenType::Not) {
2093 self.advance(); Some(BinaryOpKind::NotEq)
2096 } else if self.check_word("equal") {
2097 self.advance(); if self.check_preposition_is("to") {
2100 self.advance(); Some(BinaryOpKind::Eq)
2102 } else {
2103 self.current = saved_pos;
2104 None
2105 }
2106 } else {
2107 self.current = saved_pos;
2108 None
2109 }
2110 } else if self.check(&TokenType::Lt) {
2111 self.advance();
2112 Some(BinaryOpKind::Lt)
2113 } else if self.check(&TokenType::Gt) {
2114 self.advance();
2115 Some(BinaryOpKind::Gt)
2116 } else if self.check(&TokenType::LtEq) {
2117 self.advance();
2118 Some(BinaryOpKind::LtEq)
2119 } else if self.check(&TokenType::GtEq) {
2120 self.advance();
2121 Some(BinaryOpKind::GtEq)
2122 } else if self.check(&TokenType::EqEq) || self.check(&TokenType::Assign) {
2123 self.advance();
2124 Some(BinaryOpKind::Eq)
2125 } else if self.check(&TokenType::NotEq) {
2126 self.advance();
2127 Some(BinaryOpKind::NotEq)
2128 } else {
2129 None
2130 };
2131
2132 if let Some(op) = op {
2133 let right = self.parse_xor_expr()?;
2134 Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp { op, left, right }))
2135 } else {
2136 Ok(left)
2137 }
2138 }
2139
2140 fn parse_let_statement(&mut self) -> ParseResult<Stmt<'a>> {
2141 self.advance(); let mutable = if self.check_mutable_keyword() {
2145 self.advance();
2146 true
2147 } else {
2148 false
2149 };
2150
2151 let var = self.expect_identifier()?;
2153
2154 let ty = if self.check(&TokenType::Colon) {
2156 self.advance(); let type_expr = self.parse_type_expression()?;
2158 Some(self.ctx.alloc_type_expr(type_expr))
2159 } else {
2160 None
2161 };
2162
2163 if !self.check(&TokenType::Be) && !self.check(&TokenType::Assign) {
2165 return Err(ParseError {
2166 kind: ParseErrorKind::ExpectedKeyword { keyword: "be or =".to_string() },
2167 span: self.current_span(),
2168 });
2169 }
2170 self.advance(); if self.check_word("mounted") {
2174 self.advance(); if !self.check(&TokenType::At) && !self.check_preposition_is("at") {
2176 return Err(ParseError {
2177 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2178 span: self.current_span(),
2179 });
2180 }
2181 self.advance(); let path = self.parse_imperative_expr()?;
2183 return Ok(Stmt::Mount { var, path });
2184 }
2185
2186 if self.check_article() {
2188 let saved_pos = self.current;
2189 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = self.peek().kind {
2193 let word = self.interner.resolve(sym).to_lowercase();
2194 if word == "peeragent" {
2195 self.advance(); if self.check(&TokenType::At) || self.check_preposition_is("at") {
2199 self.advance(); let address = self.parse_imperative_expr()?;
2203
2204 return Ok(Stmt::LetPeerAgent { var, address });
2205 }
2206 }
2207 }
2208 self.current = saved_pos;
2210 }
2211
2212 if self.check_article() {
2214 let saved_pos = self.current;
2215 self.advance(); if self.check(&TokenType::Pipe) {
2218 self.advance(); if !self.check_word("of") {
2222 return Err(ParseError {
2223 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
2224 span: self.current_span(),
2225 });
2226 }
2227 self.advance(); let element_type = self.expect_identifier()?;
2231
2232 return Ok(Stmt::CreatePipe { var, element_type, capacity: None });
2235 }
2236 self.current = saved_pos;
2238 }
2239
2240 if self.check(&TokenType::Launch) {
2242 self.advance(); if !self.check_article() {
2246 return Err(ParseError {
2247 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2248 span: self.current_span(),
2249 });
2250 }
2251 self.advance();
2252
2253 if !self.check(&TokenType::Task) {
2255 return Err(ParseError {
2256 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2257 span: self.current_span(),
2258 });
2259 }
2260 self.advance();
2261
2262 if !self.check(&TokenType::To) && !self.check_word("to") {
2264 return Err(ParseError {
2265 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2266 span: self.current_span(),
2267 });
2268 }
2269 self.advance();
2270
2271 let function = self.expect_identifier()?;
2273
2274 let args = if self.check_word("with") {
2276 self.advance();
2277 self.parse_call_arguments()?
2278 } else {
2279 vec![]
2280 };
2281
2282 return Ok(Stmt::LaunchTaskWithHandle { handle: var, function, args });
2283 }
2284
2285 let value = self.parse_imperative_expr()?;
2287
2288 if let Some(declared_ty) = &ty {
2290 if let Some(inferred) = self.infer_literal_type(value) {
2291 if !self.check_type_compatibility(declared_ty, inferred) {
2292 let expected = match declared_ty {
2293 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2294 self.interner.resolve(*sym).to_string()
2295 }
2296 _ => "unknown".to_string(),
2297 };
2298 return Err(ParseError {
2299 kind: ParseErrorKind::TypeMismatch {
2300 expected,
2301 found: inferred.to_string(),
2302 },
2303 span: self.current_span(),
2304 });
2305 }
2306 }
2307 }
2308
2309 let value = if self.check_word("with") {
2311 let saved = self.current;
2312 self.advance(); if self.check_word("capacity") {
2314 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2316 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2317 } else {
2318 self.current = saved; value
2320 }
2321 } else {
2322 value
2323 };
2324
2325 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2327
2328 Ok(Stmt::Let { var, ty, value, mutable })
2329 }
2330
2331 fn check_mutable_keyword(&self) -> bool {
2332 if matches!(self.peek().kind, TokenType::Mut) {
2334 return true;
2335 }
2336 if let TokenType::Noun(sym) | TokenType::Adjective(sym) = self.peek().kind {
2338 let word = self.interner.resolve(sym).to_lowercase();
2339 word == "mutable" || word == "mut"
2340 } else {
2341 false
2342 }
2343 }
2344
2345 fn infer_literal_type(&self, expr: &Expr<'_>) -> Option<&'static str> {
2347 match expr {
2348 Expr::Literal(lit) => match lit {
2349 crate::ast::Literal::Number(_) => Some("Int"),
2350 crate::ast::Literal::Float(_) => Some("Real"),
2351 crate::ast::Literal::Text(_) => Some("Text"),
2352 crate::ast::Literal::Boolean(_) => Some("Bool"),
2353 crate::ast::Literal::Nothing => Some("Unit"),
2354 crate::ast::Literal::Char(_) => Some("Char"),
2355 crate::ast::Literal::Duration(_) => Some("Duration"),
2356 crate::ast::Literal::Date(_) => Some("Date"),
2357 crate::ast::Literal::Moment(_) => Some("Moment"),
2358 crate::ast::Literal::Span { .. } => Some("Span"),
2359 crate::ast::Literal::Time(_) => Some("Time"),
2360 },
2361 _ => None, }
2363 }
2364
2365 fn check_type_compatibility(&self, declared: &TypeExpr<'_>, inferred: &str) -> bool {
2367 match declared {
2368 TypeExpr::Primitive(sym) | TypeExpr::Named(sym) => {
2369 let declared_name = self.interner.resolve(*sym);
2370 declared_name.eq_ignore_ascii_case(inferred)
2372 || (declared_name.eq_ignore_ascii_case("Nat") && inferred == "Int")
2373 || (declared_name.eq_ignore_ascii_case("Byte") && inferred == "Int")
2374 }
2375 _ => true, }
2377 }
2378
2379 fn peek_equals_assignment(&self) -> bool {
2386 let is_identifier = matches!(
2390 self.peek().kind,
2391 TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Identifier
2392 | TokenType::Adjective(_) | TokenType::Verb { .. }
2393 | TokenType::Particle(_) | TokenType::Ambiguous { .. }
2394 | TokenType::Pronoun { .. }
2395 );
2396 if !is_identifier {
2397 return false;
2398 }
2399
2400 if self.current + 1 >= self.tokens.len() {
2402 return false;
2403 }
2404
2405 let next = &self.tokens[self.current + 1].kind;
2406
2407 if matches!(next, TokenType::Assign) {
2409 return true;
2410 }
2411
2412 if matches!(next, TokenType::Colon) {
2415 let mut offset = 2;
2416 while self.current + offset < self.tokens.len() {
2417 let tok = &self.tokens[self.current + offset].kind;
2418 if matches!(tok, TokenType::Assign) {
2419 return true;
2420 }
2421 if matches!(tok, TokenType::Period | TokenType::Newline | TokenType::EOF) {
2422 return false;
2423 }
2424 offset += 1;
2425 }
2426 }
2427
2428 false
2429 }
2430
2431 fn parse_equals_assignment(&mut self, explicit_mutable: bool) -> ParseResult<Stmt<'a>> {
2433 if explicit_mutable {
2435 self.advance(); }
2437
2438 let var = self.expect_identifier()?;
2440
2441 let ty = if self.check(&TokenType::Colon) {
2443 self.advance(); let type_expr = self.parse_type_expression()?;
2445 Some(self.ctx.alloc_type_expr(type_expr))
2446 } else {
2447 None
2448 };
2449
2450 if !self.check(&TokenType::Assign) {
2452 return Err(ParseError {
2453 kind: ParseErrorKind::ExpectedKeyword { keyword: "=".to_string() },
2454 span: self.current_span(),
2455 });
2456 }
2457 self.advance(); let value = self.parse_imperative_expr()?;
2461
2462 let value = if self.check_word("with") {
2464 let saved = self.current;
2465 self.advance(); if self.check_word("capacity") {
2467 self.advance(); let cap_expr = self.parse_imperative_expr()?;
2469 self.ctx.alloc_imperative_expr(Expr::WithCapacity { value, capacity: cap_expr })
2470 } else {
2471 self.current = saved; value
2473 }
2474 } else {
2475 value
2476 };
2477
2478 self.world_state.drs.introduce_referent(var, var, crate::drs::Gender::Unknown, crate::drs::Number::Singular);
2480
2481 Ok(Stmt::Let { var, ty, value, mutable: explicit_mutable })
2482 }
2483
2484 fn parse_set_statement(&mut self) -> ParseResult<Stmt<'a>> {
2485 use crate::ast::Expr;
2486 self.advance(); let target_expr = self.parse_imperative_expr()?;
2490
2491 let target_expr = if self.check(&TokenType::At) {
2493 self.advance(); let key = self.parse_imperative_expr()?;
2495 self.ctx.alloc_imperative_expr(Expr::Index { collection: target_expr, index: key })
2496 } else {
2497 target_expr
2498 };
2499
2500 let is_to = self.check(&TokenType::To) || matches!(
2502 &self.peek().kind,
2503 TokenType::Preposition(sym) if self.interner.resolve(*sym) == "to"
2504 );
2505 if !is_to {
2506 return Err(ParseError {
2507 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2508 span: self.current_span(),
2509 });
2510 }
2511 self.advance(); let value = self.parse_imperative_expr()?;
2515
2516 match target_expr {
2519 Expr::FieldAccess { object, field } => {
2520 Ok(Stmt::SetField { object: *object, field: *field, value })
2521 }
2522 Expr::Identifier(target) => {
2523 Ok(Stmt::Set { target: *target, value })
2524 }
2525 Expr::Index { collection, index } => {
2526 Ok(Stmt::SetIndex { collection: *collection, index: *index, value })
2527 }
2528 _ => Err(ParseError {
2529 kind: ParseErrorKind::ExpectedIdentifier,
2530 span: self.current_span(),
2531 })
2532 }
2533 }
2534
2535 fn parse_return_statement(&mut self) -> ParseResult<Stmt<'a>> {
2536 self.advance(); if self.check(&TokenType::Period) || self.is_at_end() {
2540 return Ok(Stmt::Return { value: None });
2541 }
2542
2543 let value = self.parse_comparison()?;
2545 Ok(Stmt::Return { value: Some(value) })
2546 }
2547
2548 fn parse_break_statement(&mut self) -> ParseResult<Stmt<'a>> {
2549 self.advance(); Ok(Stmt::Break)
2551 }
2552
2553 fn parse_assert_statement(&mut self) -> ParseResult<Stmt<'a>> {
2554 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2558 self.advance();
2559 }
2560
2561 let condition = self.parse_condition()?;
2564
2565 Ok(Stmt::RuntimeAssert { condition })
2566 }
2567
2568 fn parse_trust_statement(&mut self) -> ParseResult<Stmt<'a>> {
2571 self.advance(); if self.check(&TokenType::That) || matches!(self.peek().kind, TokenType::Article(Definiteness::Distal)) {
2575 self.advance();
2576 }
2577
2578 let saved_mode = self.mode;
2580 self.mode = ParserMode::Declarative;
2581
2582 let proposition = self.parse()?;
2584
2585 self.mode = saved_mode;
2587
2588 if !self.check(&TokenType::Because) {
2590 return Err(ParseError {
2591 kind: ParseErrorKind::UnexpectedToken {
2592 expected: TokenType::Because,
2593 found: self.peek().kind.clone(),
2594 },
2595 span: self.current_span(),
2596 });
2597 }
2598 self.advance(); let justification = match &self.peek().kind {
2602 TokenType::StringLiteral(sym) => {
2603 let s = *sym;
2604 self.advance();
2605 s
2606 }
2607 _ => {
2608 return Err(ParseError {
2609 kind: ParseErrorKind::UnexpectedToken {
2610 expected: TokenType::StringLiteral(self.interner.intern("")),
2611 found: self.peek().kind.clone(),
2612 },
2613 span: self.current_span(),
2614 });
2615 }
2616 };
2617
2618 Ok(Stmt::Trust { proposition, justification })
2619 }
2620
2621 fn parse_check_statement(&mut self) -> ParseResult<Stmt<'a>> {
2625 let start_span = self.current_span();
2626 self.advance(); if self.check(&TokenType::That) {
2630 self.advance();
2631 }
2632
2633 if matches!(self.peek().kind, TokenType::Article(_)) {
2635 self.advance();
2636 }
2637
2638 let subject = match &self.peek().kind {
2640 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2641 let s = *sym;
2642 self.advance();
2643 s
2644 }
2645 _ => {
2646 let tok = self.peek();
2648 let s = tok.lexeme;
2649 self.advance();
2650 s
2651 }
2652 };
2653
2654 let is_capability;
2656 let predicate;
2657 let object;
2658
2659 if self.check(&TokenType::Is) || self.check(&TokenType::Are) {
2660 is_capability = false;
2662 self.advance(); predicate = match &self.peek().kind {
2666 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2667 let s = *sym;
2668 self.advance();
2669 s
2670 }
2671 _ => {
2672 let tok = self.peek();
2673 let s = tok.lexeme;
2674 self.advance();
2675 s
2676 }
2677 };
2678 object = None;
2679 } else if self.check(&TokenType::Can) {
2680 is_capability = true;
2682 self.advance(); predicate = match &self.peek().kind {
2686 TokenType::Verb { lemma, .. } => {
2687 let s = *lemma;
2688 self.advance();
2689 s
2690 }
2691 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2692 let s = *sym;
2693 self.advance();
2694 s
2695 }
2696 _ => {
2697 let tok = self.peek();
2698 let s = tok.lexeme;
2699 self.advance();
2700 s
2701 }
2702 };
2703
2704 if matches!(self.peek().kind, TokenType::Article(_)) {
2706 self.advance();
2707 }
2708
2709 let obj = match &self.peek().kind {
2711 TokenType::Noun(sym) | TokenType::Adjective(sym) | TokenType::ProperName(sym) => {
2712 let s = *sym;
2713 self.advance();
2714 s
2715 }
2716 _ => {
2717 let tok = self.peek();
2718 let s = tok.lexeme;
2719 self.advance();
2720 s
2721 }
2722 };
2723 object = Some(obj);
2724 } else {
2725 return Err(ParseError {
2726 kind: ParseErrorKind::ExpectedKeyword { keyword: "is/can".to_string() },
2727 span: self.current_span(),
2728 });
2729 }
2730
2731 let source_text = if is_capability {
2733 let obj_name = self.interner.resolve(object.unwrap());
2734 let pred_name = self.interner.resolve(predicate);
2735 let subj_name = self.interner.resolve(subject);
2736 format!("{} can {} the {}", subj_name, pred_name, obj_name)
2737 } else {
2738 let pred_name = self.interner.resolve(predicate);
2739 let subj_name = self.interner.resolve(subject);
2740 format!("{} is {}", subj_name, pred_name)
2741 };
2742
2743 Ok(Stmt::Check {
2744 subject,
2745 predicate,
2746 is_capability,
2747 object,
2748 source_text,
2749 span: start_span,
2750 })
2751 }
2752
2753 fn parse_listen_statement(&mut self) -> ParseResult<Stmt<'a>> {
2756 self.advance(); if !self.check_preposition_is("on") {
2760 return Err(ParseError {
2761 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2762 span: self.current_span(),
2763 });
2764 }
2765 self.advance(); let address = self.parse_imperative_expr()?;
2769
2770 Ok(Stmt::Listen { address })
2771 }
2772
2773 fn parse_connect_statement(&mut self) -> ParseResult<Stmt<'a>> {
2776 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2780 return Err(ParseError {
2781 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2782 span: self.current_span(),
2783 });
2784 }
2785 self.advance(); let address = self.parse_imperative_expr()?;
2789
2790 Ok(Stmt::ConnectTo { address })
2791 }
2792
2793 fn parse_sleep_statement(&mut self) -> ParseResult<Stmt<'a>> {
2796 self.advance(); let milliseconds = self.parse_imperative_expr()?;
2800
2801 Ok(Stmt::Sleep { milliseconds })
2802 }
2803
2804 fn parse_sync_statement(&mut self) -> ParseResult<Stmt<'a>> {
2807 self.advance(); let var = match &self.tokens[self.current].kind {
2812 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2813 let s = *sym;
2814 self.advance();
2815 s
2816 }
2817 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2818 let s = self.tokens[self.current].lexeme;
2819 self.advance();
2820 s
2821 }
2822 _ => {
2823 return Err(ParseError {
2824 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2825 span: self.current_span(),
2826 });
2827 }
2828 };
2829
2830 if !self.check_preposition_is("on") {
2832 return Err(ParseError {
2833 kind: ParseErrorKind::ExpectedKeyword { keyword: "on".to_string() },
2834 span: self.current_span(),
2835 });
2836 }
2837 self.advance(); let topic = self.parse_imperative_expr()?;
2841
2842 Ok(Stmt::Sync { var, topic })
2843 }
2844
2845 fn parse_mount_statement(&mut self) -> ParseResult<Stmt<'a>> {
2849 self.advance(); let var = match &self.tokens[self.current].kind {
2854 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2855 let s = *sym;
2856 self.advance();
2857 s
2858 }
2859 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2860 let s = self.tokens[self.current].lexeme;
2861 self.advance();
2862 s
2863 }
2864 _ => {
2865 return Err(ParseError {
2866 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
2867 span: self.current_span(),
2868 });
2869 }
2870 };
2871
2872 if !self.check(&TokenType::At) {
2874 return Err(ParseError {
2875 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
2876 span: self.current_span(),
2877 });
2878 }
2879 self.advance(); let path = self.parse_imperative_expr()?;
2883
2884 Ok(Stmt::Mount { var, path })
2885 }
2886
2887 fn lookahead_contains_into(&self) -> bool {
2893 for i in self.current..std::cmp::min(self.current + 5, self.tokens.len()) {
2894 if matches!(self.tokens[i].kind, TokenType::Into) {
2895 return true;
2896 }
2897 }
2898 false
2899 }
2900
2901 fn lookahead_is_first_of(&self) -> bool {
2903 self.current + 3 < self.tokens.len()
2905 && matches!(self.tokens.get(self.current + 1), Some(t) if matches!(t.kind, TokenType::Article(_)))
2906 && self.tokens.get(self.current + 2)
2907 .map(|t| self.interner.resolve(t.lexeme).to_lowercase() == "first")
2908 .unwrap_or(false)
2909 }
2910
2911 fn parse_launch_statement(&mut self) -> ParseResult<Stmt<'a>> {
2914 self.advance(); if !self.check_article() {
2918 return Err(ParseError {
2919 kind: ParseErrorKind::ExpectedKeyword { keyword: "a".to_string() },
2920 span: self.current_span(),
2921 });
2922 }
2923 self.advance();
2924
2925 if !self.check(&TokenType::Task) {
2927 return Err(ParseError {
2928 kind: ParseErrorKind::ExpectedKeyword { keyword: "task".to_string() },
2929 span: self.current_span(),
2930 });
2931 }
2932 self.advance();
2933
2934 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
2936 return Err(ParseError {
2937 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
2938 span: self.current_span(),
2939 });
2940 }
2941 self.advance();
2942
2943 let function = match &self.tokens[self.current].kind {
2946 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
2947 let s = *sym;
2948 self.advance();
2949 s
2950 }
2951 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
2952 let s = self.tokens[self.current].lexeme;
2953 self.advance();
2954 s
2955 }
2956 _ => {
2957 return Err(ParseError {
2958 kind: ParseErrorKind::ExpectedKeyword { keyword: "function name".to_string() },
2959 span: self.current_span(),
2960 });
2961 }
2962 };
2963
2964 let args = if self.check(&TokenType::LParen) {
2966 self.parse_call_arguments()?
2967 } else if self.check_word("with") {
2968 self.advance(); let mut args = Vec::new();
2970 let arg = self.parse_imperative_expr()?;
2971 args.push(arg);
2972 while self.check(&TokenType::And) {
2974 self.advance();
2975 let arg = self.parse_imperative_expr()?;
2976 args.push(arg);
2977 }
2978 args
2979 } else {
2980 Vec::new()
2981 };
2982
2983 Ok(Stmt::LaunchTask { function, args })
2984 }
2985
2986 fn parse_send_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
2989 self.advance(); let value = self.parse_imperative_expr()?;
2993
2994 if !self.check(&TokenType::Into) {
2996 return Err(ParseError {
2997 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
2998 span: self.current_span(),
2999 });
3000 }
3001 self.advance();
3002
3003 let pipe = self.parse_imperative_expr()?;
3005
3006 Ok(Stmt::SendPipe { value, pipe })
3007 }
3008
3009 fn parse_receive_pipe_statement(&mut self) -> ParseResult<Stmt<'a>> {
3012 self.advance(); let var = self.expect_identifier()?;
3016
3017 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3019 return Err(ParseError {
3020 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3021 span: self.current_span(),
3022 });
3023 }
3024 self.advance();
3025
3026 let pipe = self.parse_imperative_expr()?;
3028
3029 Ok(Stmt::ReceivePipe { var, pipe })
3030 }
3031
3032 fn parse_try_statement(&mut self) -> ParseResult<Stmt<'a>> {
3035 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3039 return Err(ParseError {
3040 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3041 span: self.current_span(),
3042 });
3043 }
3044 self.advance();
3045
3046 if self.check(&TokenType::Send) {
3048 self.advance(); let value = self.parse_imperative_expr()?;
3050
3051 if !self.check(&TokenType::Into) {
3052 return Err(ParseError {
3053 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
3054 span: self.current_span(),
3055 });
3056 }
3057 self.advance();
3058
3059 let pipe = self.parse_imperative_expr()?;
3060 Ok(Stmt::TrySendPipe { value, pipe, result: None })
3061 } else if self.check(&TokenType::Receive) {
3062 self.advance(); let var = self.expect_identifier()?;
3065
3066 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3067 return Err(ParseError {
3068 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3069 span: self.current_span(),
3070 });
3071 }
3072 self.advance();
3073
3074 let pipe = self.parse_imperative_expr()?;
3075 Ok(Stmt::TryReceivePipe { var, pipe })
3076 } else {
3077 Err(ParseError {
3078 kind: ParseErrorKind::ExpectedKeyword { keyword: "send or receive".to_string() },
3079 span: self.current_span(),
3080 })
3081 }
3082 }
3083
3084 fn parse_escape_body(&mut self) -> ParseResult<(crate::intern::Symbol, crate::intern::Symbol, crate::token::Span)> {
3087 let start_span = self.current_span();
3088 self.advance(); if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3092 return Err(ParseError {
3093 kind: ParseErrorKind::Custom(
3094 "Expected 'to' after 'Escape'. Syntax: Escape to Rust:".to_string()
3095 ),
3096 span: self.current_span(),
3097 });
3098 }
3099 self.advance(); let language = match &self.peek().kind {
3103 TokenType::ProperName(sym) => {
3104 let s = *sym;
3105 self.advance();
3106 s
3107 }
3108 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3109 let s = *sym;
3110 self.advance();
3111 s
3112 }
3113 _ => {
3114 return Err(ParseError {
3115 kind: ParseErrorKind::Custom(
3116 "Expected language name after 'Escape to'. Currently only 'Rust' is supported.".to_string()
3117 ),
3118 span: self.current_span(),
3119 });
3120 }
3121 };
3122
3123 if !language.is(self.interner, "Rust") {
3125 let lang_str = self.interner.resolve(language);
3126 return Err(ParseError {
3127 kind: ParseErrorKind::Custom(
3128 format!("Unsupported escape target '{}'. Only 'Rust' is supported.", lang_str)
3129 ),
3130 span: self.current_span(),
3131 });
3132 }
3133
3134 if !self.check(&TokenType::Colon) {
3136 return Err(ParseError {
3137 kind: ParseErrorKind::Custom(
3138 "Expected ':' after 'Escape to Rust'. Syntax: Escape to Rust:".to_string()
3139 ),
3140 span: self.current_span(),
3141 });
3142 }
3143 self.advance(); if !self.check(&TokenType::Indent) {
3147 return Err(ParseError {
3148 kind: ParseErrorKind::Custom(
3149 "Expected indented block after 'Escape to Rust:'.".to_string()
3150 ),
3151 span: self.current_span(),
3152 });
3153 }
3154 self.advance(); let code = match &self.peek().kind {
3158 TokenType::EscapeBlock(sym) => {
3159 let s = *sym;
3160 self.advance();
3161 s
3162 }
3163 _ => {
3164 return Err(ParseError {
3165 kind: ParseErrorKind::Custom(
3166 "Escape block body is empty or malformed.".to_string()
3167 ),
3168 span: self.current_span(),
3169 });
3170 }
3171 };
3172
3173 if self.check(&TokenType::Dedent) {
3175 self.advance();
3176 }
3177
3178 let end_span = self.previous().span;
3179 Ok((language, code, crate::token::Span::new(start_span.start, end_span.end)))
3180 }
3181
3182 fn parse_escape_statement(&mut self) -> ParseResult<Stmt<'a>> {
3184 let (language, code, span) = self.parse_escape_body()?;
3185 Ok(Stmt::Escape { language, code, span })
3186 }
3187
3188 fn parse_escape_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
3191 let (language, code, _span) = self.parse_escape_body()?;
3192 Ok(self.ctx.alloc_imperative_expr(Expr::Escape { language, code }))
3193 }
3194
3195 fn parse_requires_block(&mut self) -> ParseResult<Vec<Stmt<'a>>> {
3198 let mut deps = Vec::new();
3199
3200 loop {
3201 if self.is_at_end() {
3203 break;
3204 }
3205 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
3206 break;
3207 }
3208
3209 if self.check(&TokenType::Indent)
3211 || self.check(&TokenType::Dedent)
3212 || self.check(&TokenType::Newline)
3213 {
3214 self.advance();
3215 continue;
3216 }
3217
3218 if matches!(self.peek().kind, TokenType::Article(_)) {
3220 let dep = self.parse_require_line()?;
3221 deps.push(dep);
3222 continue;
3223 }
3224
3225 self.advance();
3227 }
3228
3229 Ok(deps)
3230 }
3231
3232 fn parse_require_line(&mut self) -> ParseResult<Stmt<'a>> {
3235 let start_span = self.current_span();
3236
3237 if !matches!(self.peek().kind, TokenType::Article(_)) {
3239 return Err(crate::error::ParseError {
3240 kind: crate::error::ParseErrorKind::Custom(
3241 "Expected 'The' to begin a dependency declaration.".to_string(),
3242 ),
3243 span: self.current_span(),
3244 });
3245 }
3246 self.advance(); let crate_name = if let TokenType::StringLiteral(sym) = self.peek().kind {
3250 let s = sym;
3251 self.advance();
3252 s
3253 } else {
3254 return Err(crate::error::ParseError {
3255 kind: crate::error::ParseErrorKind::Custom(
3256 "Expected a string literal for the crate name, e.g. \"serde\".".to_string(),
3257 ),
3258 span: self.current_span(),
3259 });
3260 };
3261
3262 if !self.check_word("crate") {
3264 return Err(crate::error::ParseError {
3265 kind: crate::error::ParseErrorKind::Custom(
3266 "Expected the word 'crate' after the crate name.".to_string(),
3267 ),
3268 span: self.current_span(),
3269 });
3270 }
3271 self.advance(); if !self.check_word("version") {
3275 return Err(crate::error::ParseError {
3276 kind: crate::error::ParseErrorKind::Custom(
3277 "Expected 'version' after 'crate'.".to_string(),
3278 ),
3279 span: self.current_span(),
3280 });
3281 }
3282 self.advance(); let version = if let TokenType::StringLiteral(sym) = self.peek().kind {
3286 let s = sym;
3287 self.advance();
3288 s
3289 } else {
3290 return Err(crate::error::ParseError {
3291 kind: crate::error::ParseErrorKind::Custom(
3292 "Expected a string literal for the version, e.g. \"1.0\".".to_string(),
3293 ),
3294 span: self.current_span(),
3295 });
3296 };
3297
3298 let mut features = Vec::new();
3300 if self.check_preposition_is("with") {
3301 self.advance(); if !self.check_word("features") {
3305 return Err(crate::error::ParseError {
3306 kind: crate::error::ParseErrorKind::Custom(
3307 "Expected 'features' after 'with'.".to_string(),
3308 ),
3309 span: self.current_span(),
3310 });
3311 }
3312 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3316 features.push(sym);
3317 self.advance();
3318 } else {
3319 return Err(crate::error::ParseError {
3320 kind: crate::error::ParseErrorKind::Custom(
3321 "Expected a string literal for a feature name.".to_string(),
3322 ),
3323 span: self.current_span(),
3324 });
3325 }
3326
3327 while self.check(&TokenType::And) {
3329 self.advance(); if let TokenType::StringLiteral(sym) = self.peek().kind {
3331 features.push(sym);
3332 self.advance();
3333 } else {
3334 return Err(crate::error::ParseError {
3335 kind: crate::error::ParseErrorKind::Custom(
3336 "Expected a string literal for a feature name after 'and'.".to_string(),
3337 ),
3338 span: self.current_span(),
3339 });
3340 }
3341 }
3342 }
3343
3344 if self.check(&TokenType::For) {
3346 self.advance(); while !self.check(&TokenType::Period) && !self.check(&TokenType::EOF)
3348 && !self.check(&TokenType::Newline)
3349 && !matches!(self.peek().kind, TokenType::BlockHeader { .. })
3350 {
3351 self.advance();
3352 }
3353 }
3354
3355 if self.check(&TokenType::Period) {
3357 self.advance();
3358 }
3359
3360 let end_span = self.previous().span;
3361
3362 Ok(Stmt::Require {
3363 crate_name,
3364 version,
3365 features,
3366 span: crate::token::Span::new(start_span.start, end_span.end),
3367 })
3368 }
3369
3370 fn parse_stop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3373 self.advance(); let handle = self.parse_imperative_expr()?;
3376
3377 Ok(Stmt::StopTask { handle })
3378 }
3379
3380 fn parse_select_statement(&mut self) -> ParseResult<Stmt<'a>> {
3388 use crate::ast::stmt::SelectBranch;
3389
3390 self.advance(); if !self.check_article() {
3394 return Err(ParseError {
3395 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
3396 span: self.current_span(),
3397 });
3398 }
3399 self.advance();
3400
3401 if !self.check_word("first") {
3403 return Err(ParseError {
3404 kind: ParseErrorKind::ExpectedKeyword { keyword: "first".to_string() },
3405 span: self.current_span(),
3406 });
3407 }
3408 self.advance();
3409
3410 if !self.check_preposition_is("of") {
3412 return Err(ParseError {
3413 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
3414 span: self.current_span(),
3415 });
3416 }
3417 self.advance();
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 if !self.check(&TokenType::Indent) {
3430 return Err(ParseError {
3431 kind: ParseErrorKind::ExpectedStatement,
3432 span: self.current_span(),
3433 });
3434 }
3435 self.advance();
3436
3437 let mut branches = Vec::new();
3439 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3440 let branch = self.parse_select_branch()?;
3441 branches.push(branch);
3442 }
3443
3444 if self.check(&TokenType::Dedent) {
3446 self.advance();
3447 }
3448
3449 Ok(Stmt::Select { branches })
3450 }
3451
3452 fn parse_select_branch(&mut self) -> ParseResult<crate::ast::stmt::SelectBranch<'a>> {
3454 use crate::ast::stmt::SelectBranch;
3455
3456 if self.check(&TokenType::Receive) {
3457 self.advance(); let var = match &self.tokens[self.current].kind {
3460 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3461 let s = *sym;
3462 self.advance();
3463 s
3464 }
3465 _ => {
3466 return Err(ParseError {
3467 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
3468 span: self.current_span(),
3469 });
3470 }
3471 };
3472
3473 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3474 return Err(ParseError {
3475 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3476 span: self.current_span(),
3477 });
3478 }
3479 self.advance();
3480
3481 let pipe = self.parse_imperative_expr()?;
3482
3483 if !self.check(&TokenType::Colon) {
3485 return Err(ParseError {
3486 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3487 span: self.current_span(),
3488 });
3489 }
3490 self.advance();
3491
3492 let body = self.parse_indented_block()?;
3494
3495 Ok(SelectBranch::Receive { var, pipe, body })
3496 } else if self.check_word("after") {
3497 self.advance(); let milliseconds = self.parse_imperative_expr()?;
3500
3501 if self.check_word("seconds") || self.check_word("milliseconds") {
3503 self.advance();
3504 }
3505
3506 if !self.check(&TokenType::Colon) {
3508 return Err(ParseError {
3509 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3510 span: self.current_span(),
3511 });
3512 }
3513 self.advance();
3514
3515 let body = self.parse_indented_block()?;
3517
3518 Ok(SelectBranch::Timeout { milliseconds, body })
3519 } else {
3520 Err(ParseError {
3521 kind: ParseErrorKind::ExpectedKeyword { keyword: "Receive or After".to_string() },
3522 span: self.current_span(),
3523 })
3524 }
3525 }
3526
3527 fn parse_indented_block(&mut self) -> ParseResult<crate::ast::stmt::Block<'a>> {
3529 if !self.check(&TokenType::Indent) {
3531 return Err(ParseError {
3532 kind: ParseErrorKind::ExpectedStatement,
3533 span: self.current_span(),
3534 });
3535 }
3536 self.advance();
3537
3538 let mut stmts = Vec::new();
3539 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3540 let stmt = self.parse_statement()?;
3541 stmts.push(stmt);
3542 if self.check(&TokenType::Period) {
3543 self.advance();
3544 }
3545 }
3546
3547 if self.check(&TokenType::Dedent) {
3549 self.advance();
3550 }
3551
3552 let block = self.ctx.stmts.expect("imperative arenas not initialized")
3553 .alloc_slice(stmts.into_iter());
3554
3555 Ok(block)
3556 }
3557
3558 fn parse_give_statement(&mut self) -> ParseResult<Stmt<'a>> {
3559 self.advance(); let object = self.parse_imperative_expr()?;
3563
3564 if !self.check_to_preposition() {
3566 return Err(ParseError {
3567 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3568 span: self.current_span(),
3569 });
3570 }
3571 self.advance(); let recipient = self.parse_imperative_expr()?;
3575
3576 if let Expr::Identifier(sym) = object {
3578 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Moved);
3579 }
3580
3581 Ok(Stmt::Give { object, recipient })
3582 }
3583
3584 fn parse_show_statement(&mut self) -> ParseResult<Stmt<'a>> {
3585 self.advance(); let object = self.parse_condition()?;
3590
3591 let recipient = if self.check_to_preposition() {
3595 self.advance(); if self.check_article() {
3600 self.advance(); }
3602 if self.check(&TokenType::Console) {
3603 self.advance(); let show_sym = self.interner.intern("show");
3605 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3606 } else {
3607 self.parse_imperative_expr()?
3609 }
3610 } else {
3611 let show_sym = self.interner.intern("show");
3613 self.ctx.alloc_imperative_expr(Expr::Identifier(show_sym))
3614 };
3615
3616 if let Expr::Identifier(sym) = object {
3618 self.world_state.set_ownership_by_var(*sym, crate::drs::OwnershipState::Borrowed);
3619 }
3620
3621 Ok(Stmt::Show { object, recipient })
3622 }
3623
3624 fn parse_push_statement(&mut self) -> ParseResult<Stmt<'a>> {
3627 self.advance(); let value = self.parse_imperative_expr()?;
3631
3632 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3634 return Err(ParseError {
3635 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3636 span: self.current_span(),
3637 });
3638 }
3639 self.advance(); let collection = self.parse_imperative_expr()?;
3643
3644 Ok(Stmt::Push { value, collection })
3645 }
3646
3647 fn parse_pop_statement(&mut self) -> ParseResult<Stmt<'a>> {
3650 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3654 return Err(ParseError {
3655 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3656 span: self.current_span(),
3657 });
3658 }
3659 self.advance(); let collection = self.parse_imperative_expr()?;
3663
3664 let into = if self.check(&TokenType::Into) || self.check_preposition_is("into") {
3666 self.advance(); if let TokenType::Noun(sym) | TokenType::ProperName(sym) = &self.peek().kind {
3670 let sym = *sym;
3671 self.advance();
3672 Some(sym)
3673 } else if let Some(token) = self.tokens.get(self.current) {
3674 let sym = token.lexeme;
3676 self.advance();
3677 Some(sym)
3678 } else {
3679 return Err(ParseError {
3680 kind: ParseErrorKind::ExpectedIdentifier,
3681 span: self.current_span(),
3682 });
3683 }
3684 } else {
3685 None
3686 };
3687
3688 Ok(Stmt::Pop { collection, into })
3689 }
3690
3691 fn parse_add_statement(&mut self) -> ParseResult<Stmt<'a>> {
3694 self.advance(); let value = self.parse_imperative_expr()?;
3698
3699 if !self.check_preposition_is("to") && !self.check(&TokenType::To) {
3701 return Err(ParseError {
3702 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3703 span: self.current_span(),
3704 });
3705 }
3706 self.advance(); let collection = self.parse_imperative_expr()?;
3710
3711 Ok(Stmt::Add { value, collection })
3712 }
3713
3714 fn parse_remove_statement(&mut self) -> ParseResult<Stmt<'a>> {
3717 self.advance(); let value = self.parse_imperative_expr()?;
3721
3722 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3724 return Err(ParseError {
3725 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3726 span: self.current_span(),
3727 });
3728 }
3729 self.advance(); let collection = self.parse_imperative_expr()?;
3733
3734 Ok(Stmt::Remove { value, collection })
3735 }
3736
3737 fn parse_read_statement(&mut self) -> ParseResult<Stmt<'a>> {
3741 self.advance(); let var = self.expect_identifier()?;
3745
3746 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3748 return Err(ParseError {
3749 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3750 span: self.current_span(),
3751 });
3752 }
3753 self.advance(); if self.check_article() {
3757 self.advance();
3758 }
3759
3760 let source = if self.check(&TokenType::Console) {
3762 self.advance(); ReadSource::Console
3764 } else if self.check(&TokenType::File) {
3765 self.advance(); let path = self.parse_imperative_expr()?;
3767 ReadSource::File(path)
3768 } else {
3769 return Err(ParseError {
3770 kind: ParseErrorKind::ExpectedKeyword { keyword: "console or file".to_string() },
3771 span: self.current_span(),
3772 });
3773 };
3774
3775 Ok(Stmt::ReadFrom { var, source })
3776 }
3777
3778 fn parse_write_statement(&mut self) -> ParseResult<Stmt<'a>> {
3781 self.advance(); let content = self.parse_imperative_expr()?;
3785
3786 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
3788 return Err(ParseError {
3789 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
3790 span: self.current_span(),
3791 });
3792 }
3793 self.advance(); if !self.check(&TokenType::File) {
3797 return Err(ParseError {
3798 kind: ParseErrorKind::ExpectedKeyword { keyword: "file".to_string() },
3799 span: self.current_span(),
3800 });
3801 }
3802 self.advance(); let path = self.parse_imperative_expr()?;
3806
3807 Ok(Stmt::WriteFile { content, path })
3808 }
3809
3810 fn parse_zone_statement(&mut self) -> ParseResult<Stmt<'a>> {
3816 self.advance(); if self.check_article() {
3820 self.advance();
3821 }
3822
3823 if self.check(&TokenType::New) {
3825 self.advance();
3826 }
3827
3828 if !self.check(&TokenType::Zone) {
3830 return Err(ParseError {
3831 kind: ParseErrorKind::ExpectedKeyword { keyword: "zone".to_string() },
3832 span: self.current_span(),
3833 });
3834 }
3835 self.advance(); if !self.check(&TokenType::Called) {
3839 return Err(ParseError {
3840 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
3841 span: self.current_span(),
3842 });
3843 }
3844 self.advance(); let name = match &self.peek().kind {
3848 TokenType::StringLiteral(sym) => {
3849 let s = *sym;
3850 self.advance();
3851 s
3852 }
3853 TokenType::ProperName(sym) | TokenType::Noun(sym) | TokenType::Adjective(sym) => {
3854 let s = *sym;
3855 self.advance();
3856 s
3857 }
3858 _ => {
3859 let token = self.peek().clone();
3861 self.advance();
3862 token.lexeme
3863 }
3864 };
3865
3866 let mut capacity = None;
3867 let mut source_file = None;
3868
3869 if self.check(&TokenType::Mapped) {
3871 self.advance(); if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
3875 return Err(ParseError {
3876 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
3877 span: self.current_span(),
3878 });
3879 }
3880 self.advance(); if let TokenType::StringLiteral(path) = &self.peek().kind {
3884 source_file = Some(*path);
3885 self.advance();
3886 } else {
3887 return Err(ParseError {
3888 kind: ParseErrorKind::ExpectedKeyword { keyword: "file path string".to_string() },
3889 span: self.current_span(),
3890 });
3891 }
3892 }
3893 else if self.check_of_preposition() {
3895 self.advance(); if !self.check(&TokenType::Size) {
3899 return Err(ParseError {
3900 kind: ParseErrorKind::ExpectedKeyword { keyword: "size".to_string() },
3901 span: self.current_span(),
3902 });
3903 }
3904 self.advance(); let size_value = match &self.peek().kind {
3908 TokenType::Number(sym) => {
3909 let num_str = self.interner.resolve(*sym);
3910 let val = num_str.replace('_', "").parse::<usize>().unwrap_or(0);
3911 self.advance();
3912 val
3913 }
3914 TokenType::Cardinal(n) => {
3915 let val = *n as usize;
3916 self.advance();
3917 val
3918 }
3919 _ => {
3920 return Err(ParseError {
3921 kind: ParseErrorKind::ExpectedNumber,
3922 span: self.current_span(),
3923 });
3924 }
3925 };
3926
3927 let unit_multiplier = self.parse_size_unit()?;
3929 capacity = Some(size_value * unit_multiplier);
3930 }
3931
3932 if !self.check(&TokenType::Colon) {
3934 return Err(ParseError {
3935 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
3936 span: self.current_span(),
3937 });
3938 }
3939 self.advance(); if !self.check(&TokenType::Indent) {
3943 return Err(ParseError {
3944 kind: ParseErrorKind::ExpectedStatement,
3945 span: self.current_span(),
3946 });
3947 }
3948 self.advance(); let mut body_stmts = Vec::new();
3952 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
3953 let stmt = self.parse_statement()?;
3954 body_stmts.push(stmt);
3955 if self.check(&TokenType::Period) {
3956 self.advance();
3957 }
3958 }
3959
3960 if self.check(&TokenType::Dedent) {
3962 self.advance();
3963 }
3964
3965 let body = self.ctx.stmts.expect("imperative arenas not initialized")
3966 .alloc_slice(body_stmts.into_iter());
3967
3968 Ok(Stmt::Zone { name, capacity, source_file, body })
3969 }
3970
3971 fn parse_size_unit(&mut self) -> ParseResult<usize> {
3973 let token = self.peek().clone();
3974 let unit_str = self.interner.resolve(token.lexeme).to_uppercase();
3975 self.advance();
3976
3977 match unit_str.as_str() {
3978 "B" | "BYTES" | "BYTE" => Ok(1),
3979 "KB" | "KILOBYTE" | "KILOBYTES" => Ok(1024),
3980 "MB" | "MEGABYTE" | "MEGABYTES" => Ok(1024 * 1024),
3981 "GB" | "GIGABYTE" | "GIGABYTES" => Ok(1024 * 1024 * 1024),
3982 _ => Err(ParseError {
3983 kind: ParseErrorKind::ExpectedKeyword {
3984 keyword: "size unit (B, KB, MB, GB)".to_string(),
3985 },
3986 span: token.span,
3987 }),
3988 }
3989 }
3990
3991 fn parse_concurrent_block(&mut self) -> ParseResult<Stmt<'a>> {
4000 self.advance(); if !self.check(&TokenType::All) {
4004 return Err(ParseError {
4005 kind: ParseErrorKind::ExpectedKeyword { keyword: "all".to_string() },
4006 span: self.current_span(),
4007 });
4008 }
4009 self.advance(); if !self.check_of_preposition() {
4013 return Err(ParseError {
4014 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
4015 span: self.current_span(),
4016 });
4017 }
4018 self.advance(); if !self.check_article() {
4022 return Err(ParseError {
4023 kind: ParseErrorKind::ExpectedKeyword { keyword: "the".to_string() },
4024 span: self.current_span(),
4025 });
4026 }
4027 self.advance(); if !self.check(&TokenType::Following) {
4031 return Err(ParseError {
4032 kind: ParseErrorKind::ExpectedKeyword { keyword: "following".to_string() },
4033 span: self.current_span(),
4034 });
4035 }
4036 self.advance(); if !self.check(&TokenType::Colon) {
4040 return Err(ParseError {
4041 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4042 span: self.current_span(),
4043 });
4044 }
4045 self.advance(); if !self.check(&TokenType::Indent) {
4049 return Err(ParseError {
4050 kind: ParseErrorKind::ExpectedStatement,
4051 span: self.current_span(),
4052 });
4053 }
4054 self.advance(); let mut task_stmts = Vec::new();
4058 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4059 let stmt = self.parse_statement()?;
4060 task_stmts.push(stmt);
4061 if self.check(&TokenType::Period) {
4062 self.advance();
4063 }
4064 }
4065
4066 if self.check(&TokenType::Dedent) {
4068 self.advance();
4069 }
4070
4071 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
4072 .alloc_slice(task_stmts.into_iter());
4073
4074 Ok(Stmt::Concurrent { tasks })
4075 }
4076
4077 fn parse_parallel_block(&mut self) -> ParseResult<Stmt<'a>> {
4086 self.advance(); if !self.check(&TokenType::Colon) {
4090 return Err(ParseError {
4091 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4092 span: self.current_span(),
4093 });
4094 }
4095 self.advance(); if !self.check(&TokenType::Indent) {
4099 return Err(ParseError {
4100 kind: ParseErrorKind::ExpectedStatement,
4101 span: self.current_span(),
4102 });
4103 }
4104 self.advance(); let mut task_stmts = Vec::new();
4108 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4109 let stmt = self.parse_statement()?;
4110 task_stmts.push(stmt);
4111 if self.check(&TokenType::Period) {
4112 self.advance();
4113 }
4114 }
4115
4116 if self.check(&TokenType::Dedent) {
4118 self.advance();
4119 }
4120
4121 let tasks = self.ctx.stmts.expect("imperative arenas not initialized")
4122 .alloc_slice(task_stmts.into_iter());
4123
4124 Ok(Stmt::Parallel { tasks })
4125 }
4126
4127 fn parse_inspect_statement(&mut self) -> ParseResult<Stmt<'a>> {
4134 self.advance(); let target = self.parse_imperative_expr()?;
4138
4139 if !self.check(&TokenType::Colon) {
4141 return Err(ParseError {
4142 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4143 span: self.current_span(),
4144 });
4145 }
4146 self.advance(); if !self.check(&TokenType::Indent) {
4150 return Err(ParseError {
4151 kind: ParseErrorKind::ExpectedStatement,
4152 span: self.current_span(),
4153 });
4154 }
4155 self.advance(); let mut arms = Vec::new();
4158 let mut has_otherwise = false;
4159
4160 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4162 if self.check(&TokenType::Otherwise) {
4163 self.advance(); if !self.check(&TokenType::Colon) {
4167 return Err(ParseError {
4168 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4169 span: self.current_span(),
4170 });
4171 }
4172 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4176 self.advance(); let mut stmts = Vec::new();
4178 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4179 let stmt = self.parse_statement()?;
4180 stmts.push(stmt);
4181 if self.check(&TokenType::Period) {
4182 self.advance();
4183 }
4184 }
4185 if self.check(&TokenType::Dedent) {
4186 self.advance();
4187 }
4188 stmts
4189 } else {
4190 let stmt = self.parse_statement()?;
4192 if self.check(&TokenType::Period) {
4193 self.advance();
4194 }
4195 vec![stmt]
4196 };
4197
4198 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4199 .alloc_slice(body_stmts.into_iter());
4200
4201 arms.push(MatchArm { enum_name: None, variant: None, bindings: vec![], body });
4202 has_otherwise = true;
4203 break;
4204 }
4205
4206 if self.check(&TokenType::If) {
4207 let arm = self.parse_match_arm()?;
4209 arms.push(arm);
4210 } else if self.check(&TokenType::When) || self.check_word("When") {
4211 let arm = self.parse_when_arm()?;
4213 arms.push(arm);
4214 } else if self.check(&TokenType::Newline) {
4215 self.advance();
4217 } else {
4218 self.advance();
4220 }
4221 }
4222
4223 if self.check(&TokenType::Dedent) {
4225 self.advance();
4226 }
4227
4228 Ok(Stmt::Inspect { target, arms, has_otherwise })
4229 }
4230
4231 fn parse_match_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4233 self.advance(); if !self.check_word("it") {
4237 return Err(ParseError {
4238 kind: ParseErrorKind::ExpectedKeyword { keyword: "it".to_string() },
4239 span: self.current_span(),
4240 });
4241 }
4242 self.advance(); if !self.check(&TokenType::Is) {
4246 return Err(ParseError {
4247 kind: ParseErrorKind::ExpectedKeyword { keyword: "is".to_string() },
4248 span: self.current_span(),
4249 });
4250 }
4251 self.advance(); if self.check_article() {
4255 self.advance();
4256 }
4257
4258 let variant = self.expect_identifier()?;
4260
4261 let enum_name = self.find_variant(variant);
4263
4264 let bindings = if self.check(&TokenType::LParen) {
4266 self.parse_pattern_bindings()?
4267 } else {
4268 vec![]
4269 };
4270
4271 if !self.check(&TokenType::Colon) {
4273 return Err(ParseError {
4274 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4275 span: self.current_span(),
4276 });
4277 }
4278 self.advance(); if !self.check(&TokenType::Indent) {
4282 return Err(ParseError {
4283 kind: ParseErrorKind::ExpectedStatement,
4284 span: self.current_span(),
4285 });
4286 }
4287 self.advance(); let mut body_stmts = Vec::new();
4291 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4292 let stmt = self.parse_statement()?;
4293 body_stmts.push(stmt);
4294 if self.check(&TokenType::Period) {
4295 self.advance();
4296 }
4297 }
4298
4299 if self.check(&TokenType::Dedent) {
4301 self.advance();
4302 }
4303
4304 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4305 .alloc_slice(body_stmts.into_iter());
4306
4307 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4308 }
4309
4310 fn parse_when_arm(&mut self) -> ParseResult<MatchArm<'a>> {
4312 self.advance(); let variant = self.expect_identifier()?;
4316
4317 let (enum_name, variant_fields) = self.type_registry
4319 .as_ref()
4320 .and_then(|r| r.find_variant(variant).map(|(enum_name, vdef)| {
4321 let fields: Vec<_> = vdef.fields.iter().map(|f| f.name).collect();
4322 (Some(enum_name), fields)
4323 }))
4324 .unwrap_or((None, vec![]));
4325
4326 let bindings = if self.check(&TokenType::LParen) {
4328 let raw_bindings = self.parse_when_bindings()?;
4329 raw_bindings.into_iter().enumerate().map(|(i, binding)| {
4331 let field = variant_fields.get(i).copied().unwrap_or(binding);
4332 (field, binding)
4333 }).collect()
4334 } else {
4335 vec![]
4336 };
4337
4338 if !self.check(&TokenType::Colon) {
4340 return Err(ParseError {
4341 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4342 span: self.current_span(),
4343 });
4344 }
4345 self.advance(); let body_stmts = if self.check(&TokenType::Indent) {
4349 self.advance(); let mut stmts = Vec::new();
4351 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4352 let stmt = self.parse_statement()?;
4353 stmts.push(stmt);
4354 if self.check(&TokenType::Period) {
4355 self.advance();
4356 }
4357 }
4358 if self.check(&TokenType::Dedent) {
4359 self.advance();
4360 }
4361 stmts
4362 } else {
4363 let stmt = self.parse_statement()?;
4365 if self.check(&TokenType::Period) {
4366 self.advance();
4367 }
4368 vec![stmt]
4369 };
4370
4371 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4372 .alloc_slice(body_stmts.into_iter());
4373
4374 Ok(MatchArm { enum_name, variant: Some(variant), bindings, body })
4375 }
4376
4377 fn parse_when_bindings(&mut self) -> ParseResult<Vec<Symbol>> {
4379 self.advance(); let mut bindings = Vec::new();
4381
4382 loop {
4383 let binding = self.expect_identifier()?;
4384 bindings.push(binding);
4385
4386 if !self.check(&TokenType::Comma) {
4387 break;
4388 }
4389 self.advance(); }
4391
4392 if !self.check(&TokenType::RParen) {
4393 return Err(ParseError {
4394 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4395 span: self.current_span(),
4396 });
4397 }
4398 self.advance(); Ok(bindings)
4401 }
4402
4403 fn parse_pattern_bindings(&mut self) -> ParseResult<Vec<(Symbol, Symbol)>> {
4405 self.advance(); let mut bindings = Vec::new();
4407
4408 loop {
4409 let field = self.expect_identifier()?;
4410 let binding = if self.check(&TokenType::Colon) {
4411 self.advance(); self.expect_identifier()?
4413 } else {
4414 field };
4416 bindings.push((field, binding));
4417
4418 if !self.check(&TokenType::Comma) {
4419 break;
4420 }
4421 self.advance(); }
4423
4424 if !self.check(&TokenType::RParen) {
4425 return Err(ParseError {
4426 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4427 span: self.current_span(),
4428 });
4429 }
4430 self.advance(); Ok(bindings)
4433 }
4434
4435 fn parse_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4439 use crate::ast::Expr;
4440 let mut fields = Vec::new();
4441
4442 self.advance();
4444
4445 loop {
4446 let field_name = self.expect_identifier()?;
4448
4449 let value = self.parse_comparison()?;
4452
4453 fields.push((field_name, value));
4454
4455 if self.check(&TokenType::And) {
4457 self.advance(); continue;
4459 }
4460 break;
4461 }
4462
4463 Ok(fields)
4464 }
4465
4466 fn parse_variant_constructor_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4468 self.parse_constructor_fields()
4469 }
4470
4471 fn parse_struct_init_fields(&mut self) -> ParseResult<Vec<(Symbol, &'a Expr<'a>)>> {
4473 self.parse_constructor_fields()
4474 }
4475
4476 fn parse_generic_type_args(&mut self, type_name: Symbol) -> ParseResult<Vec<TypeExpr<'a>>> {
4480 if !self.is_generic_type(type_name) {
4482 return Ok(vec![]);
4483 }
4484
4485 if !self.check_preposition_is("of") {
4487 return Ok(vec![]); }
4489 self.advance(); let mut type_args = Vec::new();
4492 loop {
4493 let type_arg = self.parse_type_expression()?;
4495 type_args.push(type_arg);
4496
4497 if self.check(&TokenType::And) || self.check_to_preposition() {
4499 self.advance(); continue;
4501 }
4502 break;
4503 }
4504
4505 Ok(type_args)
4506 }
4507
4508 fn skip_type_def_content(&mut self) {
4512 while !self.is_at_end() {
4513 if matches!(
4515 self.tokens.get(self.current),
4516 Some(Token { kind: TokenType::BlockHeader { .. }, .. })
4517 ) {
4518 break;
4519 }
4520 self.advance();
4521 }
4522 }
4523
4524 fn parse_theorem_block(&mut self) -> ParseResult<Stmt<'a>> {
4532 use crate::ast::theorem::{TheoremBlock, ProofStrategy};
4533
4534 self.skip_whitespace_tokens();
4536
4537 if self.check(&TokenType::Colon) {
4542 self.advance();
4543 }
4544
4545 self.skip_whitespace_tokens();
4547
4548 let name = if let Some(token) = self.tokens.get(self.current) {
4550 match &token.kind {
4551 TokenType::Noun(_)
4552 | TokenType::ProperName(_)
4553 | TokenType::Verb { .. }
4554 | TokenType::Adjective(_) => {
4555 let name = self.interner.resolve(token.lexeme).to_string();
4556 self.advance();
4557 name
4558 }
4559 _ => {
4560 let lexeme = self.interner.resolve(token.lexeme);
4562 if !lexeme.is_empty() && lexeme.chars().next().map(|c| c.is_alphanumeric()).unwrap_or(false) {
4563 let name = lexeme.to_string();
4564 self.advance();
4565 name
4566 } else {
4567 "Anonymous".to_string()
4568 }
4569 }
4570 }
4571 } else {
4572 "Anonymous".to_string()
4573 };
4574
4575 self.skip_whitespace_tokens();
4576
4577 if self.check(&TokenType::Period) {
4579 self.advance();
4580 }
4581
4582 self.skip_whitespace_tokens();
4583
4584 let mut premises = Vec::new();
4587 while self.check(&TokenType::Given) {
4588 self.advance(); if self.check(&TokenType::Colon) {
4592 self.advance();
4593 }
4594
4595 self.skip_whitespace_tokens();
4596
4597 let premise_expr = self.parse_sentence()?;
4599 premises.push(premise_expr);
4600
4601 self.world_state.end_sentence();
4604
4605 if self.check(&TokenType::Period) {
4607 self.advance();
4608 }
4609
4610 self.skip_whitespace_tokens();
4611 }
4612
4613 let goal = if self.check(&TokenType::Prove) {
4615 self.advance(); if self.check(&TokenType::Colon) {
4618 self.advance();
4619 }
4620
4621 self.skip_whitespace_tokens();
4622
4623 let goal_expr = self.parse_sentence()?;
4624
4625 if self.check(&TokenType::Period) {
4626 self.advance();
4627 }
4628
4629 goal_expr
4630 } else {
4631 return Err(ParseError {
4632 kind: ParseErrorKind::ExpectedKeyword { keyword: "Prove".to_string() },
4633 span: self.current_span(),
4634 });
4635 };
4636
4637 self.skip_whitespace_tokens();
4638
4639 let strategy = if self.check(&TokenType::BlockHeader { block_type: crate::token::BlockType::Proof }) {
4641 self.advance();
4642 self.skip_whitespace_tokens();
4643
4644 if self.check(&TokenType::Colon) {
4645 self.advance();
4646 }
4647
4648 self.skip_whitespace_tokens();
4649
4650 if self.check(&TokenType::Auto) {
4651 self.advance();
4652 ProofStrategy::Auto
4653 } else {
4654 ProofStrategy::Auto
4656 }
4657 } else {
4658 ProofStrategy::Auto
4660 };
4661
4662 if self.check(&TokenType::Period) {
4664 self.advance();
4665 }
4666
4667 let theorem = TheoremBlock {
4668 name,
4669 premises,
4670 goal,
4671 strategy,
4672 };
4673
4674 Ok(Stmt::Theorem(theorem))
4675 }
4676
4677 fn skip_whitespace_tokens(&mut self) {
4679 while self.check(&TokenType::Newline) || self.check(&TokenType::Indent) || self.check(&TokenType::Dedent) {
4680 self.advance();
4681 }
4682 }
4683
4684 fn parse_function_def(&mut self) -> ParseResult<Stmt<'a>> {
4689 self.parse_function_def_with_flags(HashSet::new())
4690 }
4691
4692 fn parse_function_def_with_flags(&mut self, opt_flags: HashSet<OptFlag>) -> ParseResult<Stmt<'a>> {
4694 if self.check(&TokenType::To) || self.check_preposition_is("to") {
4696 self.advance();
4697 }
4698
4699 let mut is_native = if self.check(&TokenType::Native) {
4701 self.advance(); true
4703 } else {
4704 false
4705 };
4706
4707 let name = self.expect_identifier()?;
4709
4710 let mut parsed_generics: Vec<Symbol> = Vec::new();
4712 if self.check_preposition_is("of") {
4713 self.advance(); loop {
4715 if !self.check(&TokenType::LBracket) {
4716 return Err(ParseError {
4717 kind: ParseErrorKind::Custom("Expected '[TypeParam]' after 'of' in generic function".to_string()),
4718 span: self.current_span(),
4719 });
4720 }
4721 self.advance(); let type_param = self.expect_identifier()?;
4723 parsed_generics.push(type_param);
4724 if !self.check(&TokenType::RBracket) {
4725 return Err(ParseError {
4726 kind: ParseErrorKind::Custom("Expected ']' after type parameter name".to_string()),
4727 span: self.current_span(),
4728 });
4729 }
4730 self.advance(); if self.check_word("and") {
4732 self.advance(); } else {
4734 break;
4735 }
4736 }
4737 }
4738
4739 let mut params = Vec::new();
4741 while self.check(&TokenType::LParen) {
4742 self.advance(); if self.check(&TokenType::RParen) {
4746 self.advance(); break;
4748 }
4749
4750 loop {
4752 let param_name = self.expect_identifier()?;
4753
4754 if !self.check(&TokenType::Colon) {
4756 return Err(ParseError {
4757 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4758 span: self.current_span(),
4759 });
4760 }
4761 self.advance(); let param_type_expr = self.parse_type_expression()?;
4765 let param_type = self.ctx.alloc_type_expr(param_type_expr);
4766
4767 params.push((param_name, param_type));
4768
4769 if self.check(&TokenType::Comma) {
4771 self.advance(); continue;
4773 }
4774 break;
4775 }
4776
4777 if !self.check(&TokenType::RParen) {
4779 return Err(ParseError {
4780 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
4781 span: self.current_span(),
4782 });
4783 }
4784 self.advance(); if self.check_word("and") || self.check_preposition() || self.check(&TokenType::From) {
4789 self.advance();
4790 }
4791 }
4792
4793 let return_type = if self.check(&TokenType::Arrow) {
4795 self.advance(); let ret_type_expr = self.parse_type_expression()?;
4797 Some(self.ctx.alloc_type_expr(ret_type_expr))
4798 } else {
4799 None
4800 };
4801
4802 let mut native_path: Option<Symbol> = None;
4804 let mut is_exported = false;
4805 let mut export_target: Option<Symbol> = None;
4806
4807 if self.check_word("is") {
4808 self.advance(); if self.check(&TokenType::Native) {
4810 self.advance(); is_native = true;
4813 if let TokenType::StringLiteral(sym) = self.peek().kind {
4814 native_path = Some(sym);
4815 self.advance(); } else {
4817 return Err(ParseError {
4818 kind: ParseErrorKind::Custom(
4819 "Expected a string literal for native function path (e.g., is native \"reqwest::blocking::get\")".to_string()
4820 ),
4821 span: self.current_span(),
4822 });
4823 }
4824 } else if self.check_word("exported") {
4825 self.advance(); is_exported = true;
4828 if self.check_word("for") {
4829 self.advance(); let target_sym = self.expect_identifier()?;
4831 let target_str = self.interner.resolve(target_sym);
4832 if !target_str.eq_ignore_ascii_case("c") && !target_str.eq_ignore_ascii_case("wasm") {
4833 return Err(ParseError {
4834 kind: ParseErrorKind::Custom(
4835 format!("Unsupported export target \"{}\". Supported targets are \"c\" and \"wasm\".", target_str)
4836 ),
4837 span: self.current_span(),
4838 });
4839 }
4840 export_target = Some(target_sym);
4841 }
4842 }
4843 }
4844
4845 if is_native {
4847 if self.check(&TokenType::Period) {
4849 self.advance();
4850 }
4851 if self.check(&TokenType::Newline) {
4852 self.advance();
4853 }
4854
4855 let empty_body = self.ctx.stmts.expect("imperative arenas not initialized")
4857 .alloc_slice(std::iter::empty());
4858
4859 return Ok(Stmt::FunctionDef {
4860 name,
4861 generics: parsed_generics,
4862 params,
4863 body: empty_body,
4864 return_type,
4865 is_native: true,
4866 native_path,
4867 is_exported: false,
4868 export_target: None,
4869 opt_flags: opt_flags.clone(),
4870 });
4871 }
4872
4873 if !self.check(&TokenType::Colon) {
4875 return Err(ParseError {
4876 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
4877 span: self.current_span(),
4878 });
4879 }
4880 self.advance(); if !self.check(&TokenType::Indent) {
4884 return Err(ParseError {
4885 kind: ParseErrorKind::ExpectedStatement,
4886 span: self.current_span(),
4887 });
4888 }
4889 self.advance(); let mut body_stmts = Vec::new();
4893 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
4894 if self.check(&TokenType::Newline) {
4896 self.advance();
4897 continue;
4898 }
4899 if matches!(self.peek().kind, TokenType::BlockHeader { .. }) {
4901 break;
4902 }
4903 let stmt = self.parse_statement()?;
4904 body_stmts.push(stmt);
4905 if self.check(&TokenType::Period) {
4906 self.advance();
4907 }
4908 }
4909
4910 if self.check(&TokenType::Dedent) {
4912 self.advance();
4913 }
4914
4915 let body = self.ctx.stmts.expect("imperative arenas not initialized")
4917 .alloc_slice(body_stmts.into_iter());
4918
4919 Ok(Stmt::FunctionDef {
4920 name,
4921 generics: parsed_generics,
4922 params,
4923 body,
4924 return_type,
4925 is_native: false,
4926 native_path: None,
4927 is_exported,
4928 export_target,
4929 opt_flags,
4930 })
4931 }
4932
4933 fn parse_primary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
4935 use crate::ast::{Expr, Literal};
4936
4937 let token = self.peek().clone();
4938 match &token.kind {
4939 TokenType::New => {
4943 self.advance(); let base_type_name = self.expect_identifier()?;
4945
4946 let type_name = if self.check(&TokenType::From) {
4948 self.advance(); let module_name = self.expect_identifier()?;
4950 let module_str = self.interner.resolve(module_name);
4951 let base_str = self.interner.resolve(base_type_name);
4952 let qualified = format!("{}::{}", module_str, base_str);
4953 self.interner.intern(&qualified)
4954 } else {
4955 base_type_name
4956 };
4957
4958 if let Some(enum_name) = self.find_variant(type_name) {
4960 let fields = if self.check_word("with") {
4962 self.parse_variant_constructor_fields()?
4963 } else {
4964 vec![]
4965 };
4966 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
4967 enum_name,
4968 variant: type_name,
4969 fields,
4970 });
4971 return self.parse_field_access_chain(base);
4972 }
4973
4974 let type_args = self.parse_generic_type_args(type_name)?;
4976
4977 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
4980 self.parse_struct_init_fields()?
4981 } else {
4982 vec![]
4983 };
4984
4985 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
4986 return self.parse_field_access_chain(base);
4987 }
4988
4989 TokenType::Article(_) => {
4993 if let Some(next) = self.tokens.get(self.current + 1) {
4996 if matches!(next.kind, TokenType::Manifest) {
4997 self.advance(); return self.parse_primary_expr();
5000 }
5001 if matches!(next.kind, TokenType::Chunk) {
5002 self.advance(); return self.parse_primary_expr();
5005 }
5006 if matches!(next.kind, TokenType::Length) {
5007 self.advance(); return self.parse_primary_expr();
5009 }
5010 }
5011 if let Some(next) = self.tokens.get(self.current + 1) {
5013 if matches!(next.kind, TokenType::New) {
5014 self.advance(); self.advance(); let base_type_name = self.expect_identifier()?;
5017
5018 let type_name = if self.check(&TokenType::From) {
5020 self.advance(); let module_name = self.expect_identifier()?;
5022 let module_str = self.interner.resolve(module_name);
5023 let base_str = self.interner.resolve(base_type_name);
5024 let qualified = format!("{}::{}", module_str, base_str);
5025 self.interner.intern(&qualified)
5026 } else {
5027 base_type_name
5028 };
5029
5030 if let Some(enum_name) = self.find_variant(type_name) {
5032 let fields = if self.check_word("with") {
5034 self.parse_variant_constructor_fields()?
5035 } else {
5036 vec![]
5037 };
5038 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
5039 enum_name,
5040 variant: type_name,
5041 fields,
5042 });
5043 return self.parse_field_access_chain(base);
5044 }
5045
5046 let type_args = self.parse_generic_type_args(type_name)?;
5048
5049 let init_fields = if self.check_word("with") && !self.peek_word_at(1, "capacity") {
5052 self.parse_struct_init_fields()?
5053 } else {
5054 vec![]
5055 };
5056
5057 let base = self.ctx.alloc_imperative_expr(Expr::New { type_name, type_args, init_fields });
5058 return self.parse_field_access_chain(base);
5059 }
5060 }
5061 let sym = token.lexeme;
5063 self.advance();
5064 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5065 return self.parse_field_access_chain(base);
5066 }
5067
5068 TokenType::Item => {
5070 self.advance(); let index = if let TokenType::Number(sym) = &self.peek().kind {
5074 let sym = *sym;
5076 self.advance();
5077 let num_str = self.interner.resolve(sym);
5078 let index_val = num_str.parse::<i64>().unwrap_or(0);
5079
5080 if index_val == 0 {
5082 return Err(ParseError {
5083 kind: ParseErrorKind::ZeroIndex,
5084 span: self.current_span(),
5085 });
5086 }
5087
5088 self.ctx.alloc_imperative_expr(
5089 Expr::Literal(crate::ast::Literal::Number(index_val))
5090 )
5091 } else if self.check(&TokenType::LParen) {
5092 self.advance(); let inner = self.parse_imperative_expr()?;
5095 if !self.check(&TokenType::RParen) {
5096 return Err(ParseError {
5097 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5098 span: self.current_span(),
5099 });
5100 }
5101 self.advance(); inner
5103 } else if let TokenType::StringLiteral(sym) = self.peek().kind {
5104 let sym = sym;
5106 self.advance();
5107 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Text(sym)))
5108 } else if !self.check_preposition_is("of") {
5109 let word = self.interner.resolve(self.peek().lexeme);
5111 if word == "true" {
5112 self.advance();
5113 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(true)))
5114 } else if word == "false" {
5115 self.advance();
5116 self.ctx.alloc_imperative_expr(Expr::Literal(crate::ast::Literal::Boolean(false)))
5117 } else {
5118 let sym = self.peek().lexeme;
5120 self.advance();
5121 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5122 }
5123 } else {
5124 return Err(ParseError {
5125 kind: ParseErrorKind::ExpectedExpression,
5126 span: self.current_span(),
5127 });
5128 };
5129
5130 if !self.check_preposition_is("of") {
5132 return Err(ParseError {
5133 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5134 span: self.current_span(),
5135 });
5136 }
5137 self.advance(); let collection = self.parse_primary_expr()?;
5142
5143 Ok(self.ctx.alloc_imperative_expr(Expr::Index {
5144 collection,
5145 index,
5146 }))
5147 }
5148
5149 TokenType::Items => {
5152 let is_slice_syntax = if let Some(next) = self.tokens.get(self.current + 1) {
5156 matches!(next.kind, TokenType::Number(_) | TokenType::LParen)
5157 } else {
5158 false
5159 };
5160
5161 if !is_slice_syntax {
5162 let sym = token.lexeme;
5164 self.advance();
5165 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5166 return self.parse_field_access_chain(base);
5167 }
5168
5169 self.advance(); let start = if let TokenType::Number(sym) = &self.peek().kind {
5173 let sym = *sym;
5175 self.advance();
5176 let num_str = self.interner.resolve(sym);
5177 let start_val = num_str.parse::<i64>().unwrap_or(0);
5178
5179 if start_val == 0 {
5181 return Err(ParseError {
5182 kind: ParseErrorKind::ZeroIndex,
5183 span: self.current_span(),
5184 });
5185 }
5186
5187 self.ctx.alloc_imperative_expr(
5188 Expr::Literal(crate::ast::Literal::Number(start_val))
5189 )
5190 } else if self.check(&TokenType::LParen) {
5191 self.advance(); let inner = self.parse_imperative_expr()?;
5194 if !self.check(&TokenType::RParen) {
5195 return Err(ParseError {
5196 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5197 span: self.current_span(),
5198 });
5199 }
5200 self.advance(); inner
5202 } else if self.check(&TokenType::Length) {
5203 self.advance(); if self.check_preposition_is("of") {
5206 self.advance(); let target = self.parse_primary_expr()?;
5208 self.ctx.alloc_imperative_expr(Expr::Length { collection: target })
5209 } else {
5210 let sym = self.tokens[self.current - 1].lexeme;
5212 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5213 }
5214 } else if !self.check_preposition_is("through") {
5215 let sym = self.peek().lexeme;
5217 self.advance();
5218 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5219 } else {
5220 return Err(ParseError {
5221 kind: ParseErrorKind::ExpectedExpression,
5222 span: self.current_span(),
5223 });
5224 };
5225
5226 if !self.check_preposition_is("through") {
5228 return Err(ParseError {
5229 kind: ParseErrorKind::ExpectedKeyword { keyword: "through".to_string() },
5230 span: self.current_span(),
5231 });
5232 }
5233 self.advance(); let end = if let TokenType::Number(sym) = &self.peek().kind {
5237 let sym = *sym;
5239 self.advance();
5240 let num_str = self.interner.resolve(sym);
5241 let end_val = num_str.parse::<i64>().unwrap_or(0);
5242
5243 if end_val == 0 {
5245 return Err(ParseError {
5246 kind: ParseErrorKind::ZeroIndex,
5247 span: self.current_span(),
5248 });
5249 }
5250
5251 self.ctx.alloc_imperative_expr(
5252 Expr::Literal(crate::ast::Literal::Number(end_val))
5253 )
5254 } else if self.check(&TokenType::LParen) {
5255 self.advance(); let inner = self.parse_imperative_expr()?;
5258 if !self.check(&TokenType::RParen) {
5259 return Err(ParseError {
5260 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5261 span: self.current_span(),
5262 });
5263 }
5264 self.advance(); inner
5266 } else if self.check(&TokenType::Length) {
5267 self.advance(); if self.check_preposition_is("of") {
5270 self.advance(); let target = self.parse_primary_expr()?;
5272 self.ctx.alloc_imperative_expr(Expr::Length { collection: target })
5273 } else {
5274 let sym = self.tokens[self.current - 1].lexeme;
5276 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5277 }
5278 } else if !self.check_preposition_is("of") {
5279 let sym = self.peek().lexeme;
5281 self.advance();
5282 self.ctx.alloc_imperative_expr(Expr::Identifier(sym))
5283 } else {
5284 return Err(ParseError {
5285 kind: ParseErrorKind::ExpectedExpression,
5286 span: self.current_span(),
5287 });
5288 };
5289
5290 let collection = if self.check_preposition_is("of") {
5293 self.advance(); self.parse_imperative_expr()?
5295 } else {
5296 let items_sym = self.interner.intern("items");
5299 self.ctx.alloc_imperative_expr(Expr::Identifier(items_sym))
5300 };
5301
5302 Ok(self.ctx.alloc_imperative_expr(Expr::Slice {
5303 collection,
5304 start,
5305 end,
5306 }))
5307 }
5308
5309 TokenType::LBracket => {
5311 self.advance(); let mut items = Vec::new();
5314 if !self.check(&TokenType::RBracket) {
5315 loop {
5316 items.push(self.parse_imperative_expr()?);
5317 if !self.check(&TokenType::Comma) {
5318 break;
5319 }
5320 self.advance(); }
5322 }
5323
5324 if !self.check(&TokenType::RBracket) {
5325 return Err(ParseError {
5326 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
5327 span: self.current_span(),
5328 });
5329 }
5330 self.advance(); if items.is_empty() && self.check_word("of") {
5334 self.advance(); let type_name = self.expect_identifier()?;
5336 let seq_sym = self.interner.intern("Seq");
5338 return Ok(self.ctx.alloc_imperative_expr(Expr::New {
5339 type_name: seq_sym,
5340 type_args: vec![TypeExpr::Named(type_name)],
5341 init_fields: vec![],
5342 }));
5343 }
5344
5345 Ok(self.ctx.alloc_imperative_expr(Expr::List(items)))
5346 }
5347
5348 TokenType::Number(sym) => {
5349 let num_str = self.interner.resolve(*sym).to_string();
5350 self.advance();
5351
5352 if let TokenType::CalendarUnit(unit) = self.peek().kind {
5354 return self.parse_span_literal_from_num(&num_str);
5355 }
5356
5357 if num_str.contains('.') || num_str.contains('e') || num_str.contains('E') {
5359 let num = num_str.parse::<f64>().unwrap_or(0.0);
5360 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Float(num))))
5361 } else {
5362 let num = num_str.parse::<i64>().unwrap_or(0);
5363 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(num))))
5364 }
5365 }
5366
5367 TokenType::StringLiteral(sym) => {
5369 self.advance();
5370 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Text(*sym))))
5371 }
5372
5373 TokenType::InterpolatedString(sym) => {
5375 let raw = self.interner.resolve(*sym).to_string();
5376 self.advance();
5377 let parts = self.parse_interpolation_parts(&raw)?;
5378 Ok(self.ctx.alloc_imperative_expr(Expr::InterpolatedString(parts)))
5379 }
5380
5381 TokenType::CharLiteral(sym) => {
5383 let char_str = self.interner.resolve(*sym);
5384 let ch = char_str.chars().next().unwrap_or('\0');
5385 self.advance();
5386 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Char(ch))))
5387 }
5388
5389 TokenType::DurationLiteral { nanos, .. } => {
5391 let nanos = *nanos;
5392 self.advance();
5393 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Duration(nanos))))
5394 }
5395
5396 TokenType::DateLiteral { days } => {
5399 let days = *days;
5400 self.advance();
5401
5402 if self.check(&TokenType::At) {
5404 self.advance(); if let TokenType::TimeLiteral { nanos_from_midnight } = self.peek().kind {
5408 let time_nanos = nanos_from_midnight;
5409 self.advance(); let moment_nanos = (days as i64) * 86_400_000_000_000 + time_nanos;
5413 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Moment(moment_nanos))));
5414 } else {
5415 return Err(ParseError {
5416 kind: ParseErrorKind::ExpectedExpression,
5417 span: self.current_span(),
5418 });
5419 }
5420 }
5421
5422 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Date(days))))
5423 }
5424
5425 TokenType::TimeLiteral { nanos_from_midnight } => {
5427 let nanos = *nanos_from_midnight;
5428 self.advance();
5429 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Time(nanos))))
5430 }
5431
5432 TokenType::Nothing => {
5434 self.advance();
5435 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)))
5436 }
5437
5438 TokenType::Some => {
5440 self.advance(); let value = self.parse_imperative_expr()?;
5442 Ok(self.ctx.alloc_imperative_expr(Expr::OptionSome { value }))
5443 }
5444
5445 TokenType::Length => {
5447 let func_name = self.peek().lexeme;
5448
5449 if self.tokens.get(self.current + 1)
5451 .map(|t| matches!(t.kind, TokenType::LParen))
5452 .unwrap_or(false)
5453 {
5454 self.advance(); return self.parse_call_expr(func_name);
5456 }
5457
5458 self.advance(); if !self.check_preposition_is("of") {
5462 return Err(ParseError {
5463 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5464 span: self.current_span(),
5465 });
5466 }
5467 self.advance(); let collection = self.parse_primary_expr()?;
5472 Ok(self.ctx.alloc_imperative_expr(Expr::Length { collection }))
5473 }
5474
5475 TokenType::Copy => {
5477 let func_name = self.peek().lexeme;
5478
5479 if self.tokens.get(self.current + 1)
5481 .map(|t| matches!(t.kind, TokenType::LParen))
5482 .unwrap_or(false)
5483 {
5484 self.advance(); return self.parse_call_expr(func_name);
5486 }
5487
5488 self.advance(); if !self.check_preposition_is("of") {
5492 return Err(ParseError {
5493 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5494 span: self.current_span(),
5495 });
5496 }
5497 self.advance(); let expr = self.parse_imperative_expr()?;
5500 Ok(self.ctx.alloc_imperative_expr(Expr::Copy { expr }))
5501 }
5502
5503 TokenType::Manifest => {
5505 self.advance(); if !self.check_preposition_is("of") {
5509 return Err(ParseError {
5510 kind: ParseErrorKind::ExpectedKeyword { keyword: "of".to_string() },
5511 span: self.current_span(),
5512 });
5513 }
5514 self.advance(); let zone = self.parse_imperative_expr()?;
5517 Ok(self.ctx.alloc_imperative_expr(Expr::ManifestOf { zone }))
5518 }
5519
5520 TokenType::Chunk => {
5522 self.advance(); if !self.check(&TokenType::At) {
5526 return Err(ParseError {
5527 kind: ParseErrorKind::ExpectedKeyword { keyword: "at".to_string() },
5528 span: self.current_span(),
5529 });
5530 }
5531 self.advance(); let index = self.parse_imperative_expr()?;
5534
5535 if !self.check_preposition_is("in") && !self.check(&TokenType::In) {
5537 return Err(ParseError {
5538 kind: ParseErrorKind::ExpectedKeyword { keyword: "in".to_string() },
5539 span: self.current_span(),
5540 });
5541 }
5542 self.advance(); let zone = self.parse_imperative_expr()?;
5545 Ok(self.ctx.alloc_imperative_expr(Expr::ChunkAt { index, zone }))
5546 }
5547
5548 TokenType::Verb { lemma, .. } => {
5552 let word = self.interner.resolve(*lemma).to_lowercase();
5553 if word == "empty" {
5554 self.advance();
5555 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5556 }
5557 let sym = token.lexeme;
5559 self.advance();
5560 if self.check(&TokenType::LParen) {
5561 return self.parse_call_expr(sym);
5562 }
5563 self.verify_identifier_access(sym)?;
5565 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5566 self.parse_field_access_chain(base)
5567 }
5568
5569 TokenType::TemporalAdverb(_) | TokenType::ScopalAdverb(_) | TokenType::Adverb(_) => {
5571 let sym = token.lexeme;
5572 self.advance();
5573 if self.check(&TokenType::LParen) {
5574 return self.parse_call_expr(sym);
5575 }
5576 self.verify_identifier_access(sym)?;
5578 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5579 self.parse_field_access_chain(base)
5580 }
5581
5582 TokenType::Read | TokenType::Write | TokenType::File | TokenType::Console |
5585 TokenType::Add | TokenType::Remove => {
5586 let sym = token.lexeme;
5587 self.advance();
5588 if self.check(&TokenType::LParen) {
5589 return self.parse_call_expr(sym);
5590 }
5591 self.verify_identifier_access(sym)?;
5593 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5594 self.parse_field_access_chain(base)
5595 }
5596
5597 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
5600 let sym = *sym;
5601 let word = self.interner.resolve(sym);
5602
5603 if word == "true" {
5605 self.advance();
5606 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(true))));
5607 }
5608 if word == "false" {
5609 self.advance();
5610 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Boolean(false))));
5611 }
5612
5613 if word == "empty" {
5615 self.advance();
5616 return Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Nothing)));
5617 }
5618
5619 if word == "none" {
5621 self.advance();
5622 return Ok(self.ctx.alloc_imperative_expr(Expr::OptionNone));
5623 }
5624
5625 self.advance();
5627
5628 if self.check(&TokenType::LParen) {
5630 return self.parse_call_expr(sym);
5631 }
5632
5633 if let Some(enum_name) = self.find_variant(sym) {
5635 let fields = if self.check_word("with") {
5636 self.parse_variant_constructor_fields()?
5637 } else {
5638 vec![]
5639 };
5640 let base = self.ctx.alloc_imperative_expr(Expr::NewVariant {
5641 enum_name,
5642 variant: sym,
5643 fields,
5644 });
5645 return self.parse_field_access_chain(base);
5646 }
5647
5648 self.verify_identifier_access(sym)?;
5650 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5651 self.parse_field_access_chain(base)
5653 }
5654
5655 TokenType::Pronoun { .. } => {
5657 let sym = token.lexeme;
5658 self.advance();
5659 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5660 self.parse_field_access_chain(base)
5662 }
5663
5664 TokenType::Merge | TokenType::Increase => {
5666 let sym = token.lexeme;
5667 self.advance();
5668
5669 if self.check(&TokenType::LParen) {
5671 return self.parse_call_expr(sym);
5672 }
5673
5674 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5675 self.parse_field_access_chain(base)
5676 }
5677
5678 TokenType::Escape => {
5682 if self.tokens.get(self.current + 1).map_or(false, |t|
5683 matches!(t.kind, TokenType::To) || {
5684 if let TokenType::Preposition(sym) = t.kind {
5685 sym.is(self.interner, "to")
5686 } else {
5687 false
5688 }
5689 }
5690 ) {
5691 return self.parse_escape_expr();
5692 }
5693 let sym = token.lexeme;
5695 self.advance();
5696 if self.check(&TokenType::LParen) {
5697 return self.parse_call_expr(sym);
5698 }
5699 self.verify_identifier_access(sym)?;
5700 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5701 self.parse_field_access_chain(base)
5702 }
5703
5704 TokenType::Values | TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared | TokenType::Particle(_) | TokenType::Preposition(_) | TokenType::All => { let sym = token.lexeme;
5716 self.advance();
5717
5718 if self.check(&TokenType::LParen) {
5720 return self.parse_call_expr(sym);
5721 }
5722
5723 self.verify_identifier_access(sym)?;
5724 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5725 self.parse_field_access_chain(base)
5726 }
5727
5728 TokenType::Ambiguous { primary, alternatives } => {
5730 let sym = token.lexeme;
5733
5734 let is_identifier_token = match &**primary {
5736 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5737 TokenType::Verb { .. } => true,
5738 _ => alternatives.iter().any(|t| matches!(t,
5739 TokenType::Noun(_) | TokenType::Adjective(_) | TokenType::ProperName(_) |
5740 TokenType::Verb { .. }
5741 ))
5742 };
5743
5744 if is_identifier_token {
5745 self.advance();
5746
5747 if self.check(&TokenType::LParen) {
5749 return self.parse_call_expr(sym);
5750 }
5751
5752 self.verify_identifier_access(sym)?;
5753 let base = self.ctx.alloc_imperative_expr(Expr::Identifier(sym));
5754 self.parse_field_access_chain(base)
5756 } else {
5757 Err(ParseError {
5758 kind: ParseErrorKind::ExpectedExpression,
5759 span: self.current_span(),
5760 })
5761 }
5762 }
5763
5764 TokenType::LParen => {
5766 if let Some(closure) = self.try_parse(|p| p.parse_closure_expr()) {
5769 return Ok(closure);
5770 }
5771
5772 self.advance(); let first = self.parse_imperative_expr()?;
5775
5776 if self.check(&TokenType::Comma) {
5778 let mut items = vec![first];
5780 while self.check(&TokenType::Comma) {
5781 self.advance(); items.push(self.parse_imperative_expr()?);
5783 }
5784
5785 if !self.check(&TokenType::RParen) {
5786 return Err(ParseError {
5787 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5788 span: self.current_span(),
5789 });
5790 }
5791 self.advance(); let base = self.ctx.alloc_imperative_expr(Expr::Tuple(items));
5794 self.parse_field_access_chain(base)
5795 } else {
5796 if !self.check(&TokenType::RParen) {
5798 return Err(ParseError {
5799 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5800 span: self.current_span(),
5801 });
5802 }
5803 self.advance(); Ok(first)
5805 }
5806 }
5807
5808 TokenType::Call => {
5810 self.advance(); let function = match &self.peek().kind {
5812 TokenType::Noun(sym) | TokenType::Adjective(sym) => {
5813 let s = *sym;
5814 self.advance();
5815 s
5816 }
5817 TokenType::Verb { .. } | TokenType::Ambiguous { .. } => {
5818 let s = self.peek().lexeme;
5819 self.advance();
5820 s
5821 }
5822 _ => {
5823 return Err(ParseError {
5824 kind: ParseErrorKind::ExpectedIdentifier,
5825 span: self.current_span(),
5826 });
5827 }
5828 };
5829 let args = if self.check_preposition_is("with") {
5830 self.advance(); self.parse_call_arguments()?
5832 } else {
5833 Vec::new()
5834 };
5835 Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
5836 }
5837
5838 _ => {
5839 Err(ParseError {
5840 kind: ParseErrorKind::ExpectedExpression,
5841 span: self.current_span(),
5842 })
5843 }
5844 }
5845 }
5846
5847 fn parse_closure_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5850 use crate::ast::stmt::ClosureBody;
5851
5852 if !self.check(&TokenType::LParen) {
5854 return Err(ParseError {
5855 kind: ParseErrorKind::ExpectedExpression,
5856 span: self.current_span(),
5857 });
5858 }
5859 self.advance(); let mut params = Vec::new();
5863 if !self.check(&TokenType::RParen) {
5864 let name = self.expect_identifier()?;
5866 if !self.check(&TokenType::Colon) {
5867 return Err(ParseError {
5868 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
5869 span: self.current_span(),
5870 });
5871 }
5872 self.advance(); let ty = self.parse_type_expression()?;
5874 let ty_ref = self.ctx.alloc_type_expr(ty);
5875 params.push((name, ty_ref));
5876
5877 while self.check(&TokenType::Comma) {
5879 self.advance(); let name = self.expect_identifier()?;
5881 if !self.check(&TokenType::Colon) {
5882 return Err(ParseError {
5883 kind: ParseErrorKind::ExpectedKeyword { keyword: ":".to_string() },
5884 span: self.current_span(),
5885 });
5886 }
5887 self.advance(); let ty = self.parse_type_expression()?;
5889 let ty_ref = self.ctx.alloc_type_expr(ty);
5890 params.push((name, ty_ref));
5891 }
5892 }
5893
5894 if !self.check(&TokenType::RParen) {
5896 return Err(ParseError {
5897 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
5898 span: self.current_span(),
5899 });
5900 }
5901 self.advance(); if !self.check(&TokenType::Arrow) {
5905 return Err(ParseError {
5906 kind: ParseErrorKind::ExpectedKeyword { keyword: "->".to_string() },
5907 span: self.current_span(),
5908 });
5909 }
5910 self.advance(); let body = if self.check(&TokenType::Colon) {
5914 self.advance(); if !self.check(&TokenType::Indent) {
5917 return Err(ParseError {
5918 kind: ParseErrorKind::ExpectedStatement,
5919 span: self.current_span(),
5920 });
5921 }
5922 self.advance(); let mut block_stmts = Vec::new();
5925 while !self.check(&TokenType::Dedent) && !self.is_at_end() {
5926 let stmt = self.parse_statement()?;
5927 block_stmts.push(stmt);
5928 if self.check(&TokenType::Period) {
5929 self.advance();
5930 }
5931 }
5932 if self.check(&TokenType::Dedent) {
5933 self.advance(); }
5935
5936 let block = self.ctx.stmts.expect("imperative arenas not initialized")
5937 .alloc_slice(block_stmts.into_iter());
5938 ClosureBody::Block(block)
5939 } else {
5940 let expr = self.parse_condition()?;
5942 ClosureBody::Expression(expr)
5943 };
5944
5945 Ok(self.ctx.alloc_imperative_expr(Expr::Closure {
5946 params,
5947 body,
5948 return_type: None,
5949 }))
5950 }
5951
5952 fn parse_imperative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5956 self.parse_condition()
5957 }
5958
5959 fn parse_xor_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5962 let mut left = self.parse_additive_expr()?;
5963
5964 while self.check(&TokenType::Xor) {
5965 self.advance(); let right = self.parse_additive_expr()?;
5967 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5968 op: BinaryOpKind::BitXor,
5969 left,
5970 right,
5971 });
5972 }
5973
5974 Ok(left)
5975 }
5976
5977 fn parse_additive_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
5979 let mut left = self.parse_shift_expr()?;
5980
5981 loop {
5982 match &self.peek().kind {
5983 TokenType::Plus => {
5984 self.advance();
5985 let right = self.parse_shift_expr()?;
5986 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5987 op: BinaryOpKind::Add,
5988 left,
5989 right,
5990 });
5991 }
5992 TokenType::Minus => {
5993 self.advance();
5994 let right = self.parse_shift_expr()?;
5995 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
5996 op: BinaryOpKind::Subtract,
5997 left,
5998 right,
5999 });
6000 }
6001 TokenType::Combined => {
6003 self.advance(); if !self.check_preposition_is("with") {
6006 return Err(ParseError {
6007 kind: ParseErrorKind::ExpectedKeyword { keyword: "with".to_string() },
6008 span: self.current_span(),
6009 });
6010 }
6011 self.advance(); let right = self.parse_shift_expr()?;
6013 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
6014 op: BinaryOpKind::Concat,
6015 left,
6016 right,
6017 });
6018 }
6019 TokenType::Union => {
6021 self.advance(); let right = self.parse_shift_expr()?;
6023 left = self.ctx.alloc_imperative_expr(Expr::Union {
6024 left,
6025 right,
6026 });
6027 }
6028 TokenType::Intersection => {
6029 self.advance(); let right = self.parse_shift_expr()?;
6031 left = self.ctx.alloc_imperative_expr(Expr::Intersection {
6032 left,
6033 right,
6034 });
6035 }
6036 TokenType::Contains => {
6038 self.advance(); let value = self.parse_shift_expr()?;
6040 left = self.ctx.alloc_imperative_expr(Expr::Contains {
6041 collection: left,
6042 value,
6043 });
6044 }
6045 _ => break,
6046 }
6047 }
6048
6049 Ok(left)
6050 }
6051
6052 fn parse_shift_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6055 let mut left = self.parse_multiplicative_expr()?;
6056
6057 loop {
6058 if !self.check(&TokenType::Shifted) {
6059 break;
6060 }
6061 self.advance(); let is_left = self.check_word("left");
6064 if is_left {
6065 self.advance(); } else if self.check_word("right") {
6067 self.advance(); } else {
6069 return Err(ParseError {
6070 kind: ParseErrorKind::ExpectedKeyword { keyword: "left or right".to_string() },
6071 span: self.current_span(),
6072 });
6073 }
6074
6075 if !self.check_preposition_is("by") && !self.check_word("by") {
6077 return Err(ParseError {
6078 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
6079 span: self.current_span(),
6080 });
6081 }
6082 self.advance(); let right = self.parse_multiplicative_expr()?;
6085 let op = if is_left { BinaryOpKind::Shl } else { BinaryOpKind::Shr };
6086 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp { op, left, right });
6087 }
6088
6089 Ok(left)
6090 }
6091
6092 fn parse_unary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6094 use crate::ast::{Expr, Literal};
6095
6096 if self.check(&TokenType::Minus) {
6097 self.advance(); let operand = self.parse_unary_expr()?; return Ok(self.ctx.alloc_imperative_expr(Expr::BinaryOp {
6101 op: BinaryOpKind::Subtract,
6102 left: self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Number(0))),
6103 right: operand,
6104 }));
6105 }
6106 self.parse_primary_expr()
6107 }
6108
6109 fn parse_multiplicative_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6111 let mut left = self.parse_unary_expr()?;
6112
6113 loop {
6114 let op = match &self.peek().kind {
6115 TokenType::Star => {
6116 self.advance();
6117 BinaryOpKind::Multiply
6118 }
6119 TokenType::Slash => {
6120 self.advance();
6121 BinaryOpKind::Divide
6122 }
6123 TokenType::Percent => {
6124 self.advance();
6125 BinaryOpKind::Modulo
6126 }
6127 _ => break,
6128 };
6129 let right = self.parse_unary_expr()?;
6130 left = self.ctx.alloc_imperative_expr(Expr::BinaryOp {
6131 op,
6132 left,
6133 right,
6134 });
6135 }
6136
6137 Ok(left)
6138 }
6139
6140 fn try_parse_binary_op(&mut self) -> Option<BinaryOpKind> {
6142 match &self.peek().kind {
6143 TokenType::Plus => {
6144 self.advance();
6145 Some(BinaryOpKind::Add)
6146 }
6147 TokenType::Minus => {
6148 self.advance();
6149 Some(BinaryOpKind::Subtract)
6150 }
6151 TokenType::Star => {
6152 self.advance();
6153 Some(BinaryOpKind::Multiply)
6154 }
6155 TokenType::Slash => {
6156 self.advance();
6157 Some(BinaryOpKind::Divide)
6158 }
6159 _ => None,
6160 }
6161 }
6162
6163 fn parse_interpolation_parts(&mut self, raw: &str) -> ParseResult<Vec<crate::ast::stmt::StringPart<'a>>> {
6170 use crate::ast::stmt::StringPart;
6171
6172 let mut parts = Vec::new();
6173 let chars: Vec<char> = raw.chars().collect();
6174 let mut i = 0;
6175 let mut literal_buf = String::new();
6176
6177 while i < chars.len() {
6178 match chars[i] {
6179 '{' if i + 1 < chars.len() && chars[i + 1] == '{' => {
6180 literal_buf.push('{');
6182 i += 2;
6183 }
6184 '{' => {
6185 if !literal_buf.is_empty() {
6187 let sym = self.interner.intern(&literal_buf);
6188 parts.push(StringPart::Literal(sym));
6189 literal_buf.clear();
6190 }
6191
6192 let start = i + 1;
6194 let mut depth = 1;
6195 let mut j = start;
6196 while j < chars.len() && depth > 0 {
6197 if chars[j] == '{' { depth += 1; }
6198 if chars[j] == '}' { depth -= 1; }
6199 if depth > 0 { j += 1; }
6200 }
6201 if depth != 0 {
6202 return Err(ParseError {
6203 kind: crate::error::ParseErrorKind::Custom(
6204 "Unclosed interpolation brace in string".to_string()
6205 ),
6206 span: self.current_span(),
6207 });
6208 }
6209
6210 let hole_content: String = chars[start..j].iter().collect();
6211
6212 let (hole_after_debug, is_debug) = {
6217 if let Some(eq_pos) = hole_content.rfind('=') {
6218 let before_eq = hole_content[..eq_pos].trim();
6219 let is_double_eq = eq_pos > 0 && hole_content.as_bytes().get(eq_pos - 1) == Some(&b'=');
6222 let is_preceded_by_comparison = eq_pos > 0 && matches!(hole_content.as_bytes().get(eq_pos - 1), Some(b'!' | b'<' | b'>'));
6223 if !is_double_eq && !is_preceded_by_comparison
6224 && !before_eq.is_empty()
6225 && before_eq.chars().all(|c| c.is_alphanumeric() || c == '_')
6226 {
6227 (hole_content[..eq_pos].to_string() + &hole_content[eq_pos + 1..], true)
6228 } else {
6229 (hole_content.clone(), false)
6230 }
6231 } else {
6232 (hole_content.clone(), false)
6233 }
6234 };
6235
6236 let (expr_str, format_spec) = if let Some(colon_pos) = hole_after_debug.rfind(':') {
6238 let before = &hole_after_debug[..colon_pos];
6239 let after = &hole_after_debug[colon_pos + 1..];
6240 if !after.is_empty() && (after.starts_with('.') || after.starts_with('<') || after.starts_with('>') || after.starts_with('^') || after == "$" || after.chars().next().map_or(false, |c| c.is_ascii_digit())) {
6243 let valid = if after == "$" {
6245 true
6246 } else if after.starts_with('.') {
6247 after[1..].parse::<usize>().is_ok()
6248 } else if after.starts_with('<') || after.starts_with('>') || after.starts_with('^') {
6249 after[1..].parse::<usize>().is_ok()
6250 } else {
6251 after.parse::<usize>().is_ok()
6252 };
6253 if !valid {
6254 return Err(ParseError {
6255 kind: crate::error::ParseErrorKind::Custom(
6256 format!("Invalid format specifier `{}` in interpolation hole", after)
6257 ),
6258 span: self.current_span(),
6259 });
6260 }
6261 (before.to_string(), Some(after.to_string()))
6262 } else {
6263 (hole_after_debug.clone(), None)
6264 }
6265 } else {
6266 (hole_after_debug.clone(), None)
6267 };
6268
6269 let expr_source = expr_str.trim().to_string();
6271 if expr_source.is_empty() {
6272 return Err(ParseError {
6273 kind: crate::error::ParseErrorKind::Custom(
6274 "Empty interpolation hole in string".to_string()
6275 ),
6276 span: self.current_span(),
6277 });
6278 }
6279
6280 let sub_expr = {
6283 let mut sub_lexer = crate::lexer::Lexer::new(&expr_source, self.interner);
6284 let sub_tokens = sub_lexer.tokenize();
6285
6286 let saved_tokens = std::mem::replace(&mut self.tokens, sub_tokens);
6288 let saved_current = self.current;
6289 self.current = 0;
6290
6291 let result = self.parse_primary_or_binary_expr();
6292
6293 self.tokens = saved_tokens;
6295 self.current = saved_current;
6296
6297 result?
6298 };
6299
6300 let format_sym = format_spec.map(|s| self.interner.intern(&s));
6301 parts.push(StringPart::Expr {
6302 value: sub_expr,
6303 format_spec: format_sym,
6304 debug: is_debug,
6305 });
6306
6307 i = j + 1; }
6309 '}' if i + 1 < chars.len() && chars[i + 1] == '}' => {
6310 literal_buf.push('}');
6312 i += 2;
6313 }
6314 _ => {
6315 literal_buf.push(chars[i]);
6316 i += 1;
6317 }
6318 }
6319 }
6320
6321 if !literal_buf.is_empty() {
6323 let sym = self.interner.intern(&literal_buf);
6324 parts.push(StringPart::Literal(sym));
6325 }
6326
6327 Ok(parts)
6328 }
6329
6330 fn parse_primary_or_binary_expr(&mut self) -> ParseResult<&'a Expr<'a>> {
6332 self.parse_imperative_expr()
6333 }
6334
6335 fn parse_span_literal_from_num(&mut self, first_num_str: &str) -> ParseResult<&'a Expr<'a>> {
6336 use crate::ast::Literal;
6337 use crate::token::CalendarUnit;
6338
6339 let first_num = first_num_str.parse::<i32>().unwrap_or(0);
6340
6341 let unit = match self.peek().kind {
6343 TokenType::CalendarUnit(u) => u,
6344 _ => {
6345 return Err(ParseError {
6346 kind: ParseErrorKind::ExpectedKeyword { keyword: "calendar unit (day, week, month, year)".to_string() },
6347 span: self.current_span(),
6348 });
6349 }
6350 };
6351 self.advance(); let mut total_months: i32 = 0;
6355 let mut total_days: i32 = 0;
6356
6357 match unit {
6359 CalendarUnit::Day => total_days += first_num,
6360 CalendarUnit::Week => total_days += first_num * 7,
6361 CalendarUnit::Month => total_months += first_num,
6362 CalendarUnit::Year => total_months += first_num * 12,
6363 }
6364
6365 while self.check(&TokenType::And) {
6367 self.advance(); let next_num = match &self.peek().kind {
6371 TokenType::Number(sym) => {
6372 let num_str = self.interner.resolve(*sym).to_string();
6373 self.advance();
6374 num_str.parse::<i32>().unwrap_or(0)
6375 }
6376 _ => break, };
6378
6379 let next_unit = match self.peek().kind {
6381 TokenType::CalendarUnit(u) => {
6382 self.advance();
6383 u
6384 }
6385 _ => break, };
6387
6388 match next_unit {
6390 CalendarUnit::Day => total_days += next_num,
6391 CalendarUnit::Week => total_days += next_num * 7,
6392 CalendarUnit::Month => total_months += next_num,
6393 CalendarUnit::Year => total_months += next_num * 12,
6394 }
6395 }
6396
6397 Ok(self.ctx.alloc_imperative_expr(Expr::Literal(Literal::Span {
6398 months: total_months,
6399 days: total_days,
6400 })))
6401 }
6402
6403 fn parse_call_expr(&mut self, function: Symbol) -> ParseResult<&'a Expr<'a>> {
6405 use crate::ast::Expr;
6406
6407 self.advance(); let mut args = Vec::new();
6410 if !self.check(&TokenType::RParen) {
6411 loop {
6412 args.push(self.parse_imperative_expr()?);
6413 if !self.check(&TokenType::Comma) {
6414 break;
6415 }
6416 self.advance(); }
6418 }
6419
6420 if !self.check(&TokenType::RParen) {
6421 return Err(ParseError {
6422 kind: ParseErrorKind::ExpectedKeyword { keyword: ")".to_string() },
6423 span: self.current_span(),
6424 });
6425 }
6426 self.advance(); Ok(self.ctx.alloc_imperative_expr(Expr::Call { function, args }))
6429 }
6430
6431 fn parse_field_access_chain(&mut self, base: &'a Expr<'a>) -> ParseResult<&'a Expr<'a>> {
6434 use crate::ast::Expr;
6435
6436 let mut result = base;
6437
6438 loop {
6440 if self.check(&TokenType::Possessive) {
6441 self.advance(); let field = self.expect_identifier()?;
6444 result = self.ctx.alloc_imperative_expr(Expr::FieldAccess {
6445 object: result,
6446 field,
6447 });
6448 } else if self.check(&TokenType::LBracket) {
6449 self.advance(); let index = self.parse_imperative_expr()?;
6452
6453 if !self.check(&TokenType::RBracket) {
6454 return Err(ParseError {
6455 kind: ParseErrorKind::ExpectedKeyword { keyword: "]".to_string() },
6456 span: self.current_span(),
6457 });
6458 }
6459 self.advance(); result = self.ctx.alloc_imperative_expr(Expr::Index {
6462 collection: result,
6463 index,
6464 });
6465 } else {
6466 break;
6467 }
6468 }
6469
6470 Ok(result)
6471 }
6472
6473 fn verify_identifier_access(&self, sym: Symbol) -> ParseResult<()> {
6476 if self.mode != ParserMode::Imperative {
6477 return Ok(());
6478 }
6479
6480 if let Some(crate::drs::OwnershipState::Moved) = self.world_state.get_ownership_by_var(sym) {
6482 return Err(ParseError {
6483 kind: ParseErrorKind::UseAfterMove {
6484 name: self.interner.resolve(sym).to_string()
6485 },
6486 span: self.current_span(),
6487 });
6488 }
6489
6490 Ok(())
6491 }
6492
6493 fn expect_identifier(&mut self) -> ParseResult<Symbol> {
6494 let token = self.peek().clone();
6495 match &token.kind {
6496 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
6498 self.advance();
6499 Ok(*sym)
6500 }
6501 TokenType::Verb { .. } => {
6504 let sym = token.lexeme;
6505 self.advance();
6506 Ok(sym)
6507 }
6508 TokenType::Article(_) => {
6510 let sym = token.lexeme;
6511 self.advance();
6512 Ok(sym)
6513 }
6514 TokenType::Pronoun { .. } | TokenType::Items | TokenType::Values | TokenType::Item | TokenType::Nothing | TokenType::TemporalAdverb(_) |
6522 TokenType::ScopalAdverb(_) |
6523 TokenType::Adverb(_) |
6524 TokenType::Read |
6526 TokenType::Write |
6527 TokenType::File |
6528 TokenType::Console |
6529 TokenType::Merge |
6531 TokenType::Increase |
6532 TokenType::Decrease |
6533 TokenType::Tally |
6535 TokenType::SharedSet |
6536 TokenType::SharedSequence |
6537 TokenType::CollaborativeSequence |
6538 TokenType::Add |
6541 TokenType::Remove |
6542 TokenType::First |
6543 TokenType::Both | TokenType::Either | TokenType::Combined | TokenType::Shared | TokenType::All | TokenType::CalendarUnit(_) |
6551 TokenType::Focus(_) |
6553 TokenType::Particle(_) |
6555 TokenType::Preposition(_) |
6557 TokenType::Escape => {
6559 let sym = token.lexeme;
6561 self.advance();
6562 Ok(sym)
6563 }
6564 TokenType::Ambiguous { .. } => {
6565 let sym = token.lexeme;
6568 self.advance();
6569 Ok(sym)
6570 }
6571 _ => Err(ParseError {
6572 kind: ParseErrorKind::ExpectedIdentifier,
6573 span: self.current_span(),
6574 }),
6575 }
6576 }
6577
6578 fn consume_content_word_for_relative(&mut self) -> ParseResult<Symbol> {
6579 let t = self.advance().clone();
6580 match t.kind {
6581 TokenType::Noun(s) | TokenType::Adjective(s) => Ok(s),
6582 TokenType::ProperName(s) => Ok(s),
6583 TokenType::Verb { lemma, .. } => Ok(lemma),
6584 other => Err(ParseError {
6585 kind: ParseErrorKind::ExpectedContentWord { found: other },
6586 span: self.current_span(),
6587 }),
6588 }
6589 }
6590
6591 fn check_modal(&self) -> bool {
6592 matches!(
6593 self.peek().kind,
6594 TokenType::Must
6595 | TokenType::Shall
6596 | TokenType::Should
6597 | TokenType::Can
6598 | TokenType::May
6599 | TokenType::Cannot
6600 | TokenType::Could
6601 | TokenType::Would
6602 | TokenType::Might
6603 )
6604 }
6605
6606 fn check_pronoun(&self) -> bool {
6607 match &self.peek().kind {
6608 TokenType::Pronoun { case, .. } => {
6609 if self.noun_priority_mode && matches!(case, Case::Possessive) {
6611 return false;
6612 }
6613 true
6614 }
6615 TokenType::Ambiguous { primary, alternatives } => {
6616 if self.noun_priority_mode {
6618 let has_possessive = matches!(**primary, TokenType::Pronoun { case: Case::Possessive, .. })
6619 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { case: Case::Possessive, .. }));
6620 if has_possessive {
6621 return false;
6622 }
6623 }
6624 matches!(**primary, TokenType::Pronoun { .. })
6625 || alternatives.iter().any(|t| matches!(t, TokenType::Pronoun { .. }))
6626 }
6627 _ => false,
6628 }
6629 }
6630
6631 fn parse_atom(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
6632 if self.check_focus() {
6634 return self.parse_focus();
6635 }
6636
6637 if self.check_measure() {
6639 return self.parse_measure();
6640 }
6641
6642 if self.check_quantifier() {
6643 self.advance();
6644 return self.parse_quantified();
6645 }
6646
6647 if self.check_npi_quantifier() {
6648 return self.parse_npi_quantified();
6649 }
6650
6651 if self.check_temporal_npi() {
6652 return self.parse_temporal_npi();
6653 }
6654
6655 if self.match_token(&[TokenType::LParen]) {
6656 let expr = self.parse_sentence()?;
6657 self.consume(TokenType::RParen)?;
6658 return Ok(expr);
6659 }
6660
6661 if self.check_pronoun() {
6663 let token = self.advance().clone();
6664 let (gender, number) = match &token.kind {
6665 TokenType::Pronoun { gender, number, .. } => (*gender, *number),
6666 TokenType::Ambiguous { primary, alternatives } => {
6667 if let TokenType::Pronoun { gender, number, .. } = **primary {
6668 (gender, number)
6669 } else {
6670 alternatives.iter().find_map(|t| {
6671 if let TokenType::Pronoun { gender, number, .. } = t {
6672 Some((*gender, *number))
6673 } else {
6674 None
6675 }
6676 }).unwrap_or((Gender::Unknown, Number::Singular))
6677 }
6678 }
6679 _ => (Gender::Unknown, Number::Singular),
6680 };
6681
6682 let token_text = self.interner.resolve(token.lexeme);
6683
6684 if token_text.eq_ignore_ascii_case("it") && self.check_verb() {
6687 if let TokenType::Verb { lemma, time, .. } = &self.peek().kind {
6688 let lemma_str = self.interner.resolve(*lemma);
6689 if Lexer::is_weather_verb(lemma_str) {
6690 let verb = *lemma;
6691 let verb_time = *time;
6692 self.advance(); let event_var = self.get_event_var();
6695 let suppress_existential = self.drs.in_conditional_antecedent();
6696 if suppress_existential {
6697 let event_class = self.interner.intern("Event");
6698 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
6699 }
6700 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6701 event_var,
6702 verb,
6703 roles: self.ctx.roles.alloc_slice(vec![]), modifiers: self.ctx.syms.alloc_slice(vec![]),
6705 suppress_existential,
6706 world: None,
6707 })));
6708
6709 return Ok(match verb_time {
6710 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
6711 operator: TemporalOperator::Past,
6712 body: neo_event,
6713 }),
6714 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
6715 operator: TemporalOperator::Future,
6716 body: neo_event,
6717 }),
6718 _ => neo_event,
6719 });
6720 }
6721 }
6722 }
6723
6724 let resolved = if token_text.eq_ignore_ascii_case("i") {
6726 ResolvedPronoun::Constant(self.interner.intern("Speaker"))
6727 } else if token_text.eq_ignore_ascii_case("you") {
6728 ResolvedPronoun::Constant(self.interner.intern("Addressee"))
6729 } else {
6730 self.resolve_pronoun(gender, number)?
6732 };
6733
6734 if self.check_performative() {
6736 if let TokenType::Performative(act) = self.advance().kind.clone() {
6737 let sym = match resolved {
6738 ResolvedPronoun::Variable(s) | ResolvedPronoun::Constant(s) => s,
6739 };
6740 if self.check(&TokenType::To) {
6742 self.advance(); if self.check_verb() {
6745 let infinitive_verb = self.consume_verb();
6746
6747 let content = self.ctx.exprs.alloc(LogicExpr::Predicate {
6748 name: infinitive_verb,
6749 args: self.ctx.terms.alloc_slice([Term::Constant(sym)]),
6750 world: None,
6751 });
6752
6753 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6754 performer: sym,
6755 act_type: act,
6756 content,
6757 }));
6758 }
6759 }
6760
6761 if self.check(&TokenType::That) {
6763 self.advance();
6764 }
6765 let content = self.parse_sentence()?;
6766 return Ok(self.ctx.exprs.alloc(LogicExpr::SpeechAct {
6767 performer: sym,
6768 act_type: act,
6769 content,
6770 }));
6771 }
6772 }
6773
6774 return match resolved {
6777 ResolvedPronoun::Variable(sym) => self.parse_predicate_with_subject_as_var(sym),
6778 ResolvedPronoun::Constant(sym) => self.parse_predicate_with_subject(sym),
6779 };
6780 }
6781
6782 let _had_both = self.match_token(&[TokenType::Both]);
6785
6786 let subject = self.parse_noun_phrase(true)?;
6787
6788 if subject.definiteness == Some(Definiteness::Indefinite)
6794 || subject.definiteness == Some(Definiteness::Distal) {
6795 let gender = Self::infer_noun_gender(self.interner.resolve(subject.noun));
6796 let number = if Self::is_plural_noun(self.interner.resolve(subject.noun)) {
6797 Number::Plural
6798 } else {
6799 Number::Singular
6800 };
6801 self.drs.introduce_referent(subject.noun, subject.noun, gender, number);
6803 }
6804
6805 if self.check(&TokenType::And) {
6807 match self.try_parse_plural_subject(&subject) {
6808 Ok(Some(result)) => return Ok(result),
6809 Ok(None) => {} Err(e) => return Err(e), }
6812 }
6813
6814 if self.check_scopal_adverb() {
6816 return self.parse_scopal_adverb(&subject);
6817 }
6818
6819 if self.check(&TokenType::Comma) {
6821 let saved_pos = self.current;
6822 self.advance(); if self.check_pronoun() {
6826 let topic_attempt = self.try_parse(|p| {
6827 let token = p.peek().clone();
6828 let pronoun_features = match &token.kind {
6829 TokenType::Pronoun { gender, number, .. } => Some((*gender, *number)),
6830 TokenType::Ambiguous { primary, alternatives } => {
6831 if let TokenType::Pronoun { gender, number, .. } = **primary {
6832 Some((gender, number))
6833 } else {
6834 alternatives.iter().find_map(|t| {
6835 if let TokenType::Pronoun { gender, number, .. } = t {
6836 Some((*gender, *number))
6837 } else {
6838 None
6839 }
6840 })
6841 }
6842 }
6843 _ => None,
6844 };
6845
6846 if let Some((gender, number)) = pronoun_features {
6847 p.advance(); let resolved = p.resolve_pronoun(gender, number)?;
6849 let resolved_term = match resolved {
6850 ResolvedPronoun::Variable(s) => Term::Variable(s),
6851 ResolvedPronoun::Constant(s) => Term::Constant(s),
6852 };
6853
6854 if p.check_verb() {
6855 let verb = p.consume_verb();
6856 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6857 name: verb,
6858 args: p.ctx.terms.alloc_slice([
6859 resolved_term,
6860 Term::Constant(subject.noun),
6861 ]),
6862 world: None,
6863 });
6864 p.wrap_with_definiteness_full(&subject, predicate)
6865 } else {
6866 Err(ParseError {
6867 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6868 span: p.current_span(),
6869 })
6870 }
6871 } else {
6872 Err(ParseError {
6873 kind: ParseErrorKind::ExpectedContentWord { found: token.kind },
6874 span: p.current_span(),
6875 })
6876 }
6877 });
6878
6879 if let Some(result) = topic_attempt {
6880 return Ok(result);
6881 }
6882 }
6883
6884 if self.check_content_word() {
6886 let topic_attempt = self.try_parse(|p| {
6887 let real_subject = p.parse_noun_phrase(true)?;
6888 if p.check_verb() {
6889 let verb = p.consume_verb();
6890 let predicate = p.ctx.exprs.alloc(LogicExpr::Predicate {
6891 name: verb,
6892 args: p.ctx.terms.alloc_slice([
6893 Term::Constant(real_subject.noun),
6894 Term::Constant(subject.noun),
6895 ]),
6896 world: None,
6897 });
6898 p.wrap_with_definiteness_full(&subject, predicate)
6899 } else {
6900 Err(ParseError {
6901 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
6902 span: p.current_span(),
6903 })
6904 }
6905 });
6906
6907 if let Some(result) = topic_attempt {
6908 return Ok(result);
6909 }
6910 }
6911
6912 self.current = saved_pos;
6914 }
6915
6916 let mut relative_clause: Option<(Symbol, &'a LogicExpr<'a>)> = None;
6918 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
6919 self.advance();
6920 let var_name = self.next_var_name();
6921 let rel_pred = self.parse_relative_clause(var_name)?;
6922 relative_clause = Some((var_name, rel_pred));
6923 } else if matches!(self.peek().kind, TokenType::Article(_)) && self.is_contact_clause_pattern() {
6924 let var_name = self.next_var_name();
6927 let rel_pred = self.parse_relative_clause(var_name)?;
6928 relative_clause = Some((var_name, rel_pred));
6929 }
6930
6931 if let Some((var_name, rel_clause)) = relative_clause {
6933 if self.check_verb() {
6934 let (verb, verb_time, _, _) = self.consume_verb_with_metadata();
6935 let var_term = Term::Variable(var_name);
6936
6937 let event_var = self.get_event_var();
6938 let suppress_existential = self.drs.in_conditional_antecedent();
6939 let mut modifiers = vec![];
6940 if verb_time == Time::Past {
6941 modifiers.push(self.interner.intern("Past"));
6942 }
6943 let main_pred = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
6944 event_var,
6945 verb,
6946 roles: self.ctx.roles.alloc_slice(vec![
6947 (ThematicRole::Agent, var_term),
6948 ]),
6949 modifiers: self.ctx.syms.alloc_slice(modifiers),
6950 suppress_existential,
6951 world: None,
6952 })));
6953
6954 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6955 name: subject.noun,
6956 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6957 world: None,
6958 });
6959
6960 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6961 left: type_pred,
6962 op: TokenType::And,
6963 right: rel_clause,
6964 });
6965
6966 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6967 left: inner,
6968 op: TokenType::And,
6969 right: main_pred,
6970 });
6971
6972 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
6973 kind: QuantifierKind::Existential,
6974 variable: var_name,
6975 body,
6976 island_id: self.current_island,
6977 }));
6978 }
6979
6980 if self.is_at_end() || self.check(&TokenType::Period) || self.check(&TokenType::Comma) {
6983 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
6984 name: subject.noun,
6985 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
6986 world: None,
6987 });
6988
6989 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
6990 left: type_pred,
6991 op: TokenType::And,
6992 right: rel_clause,
6993 });
6994
6995 let uniqueness_body = if subject.definiteness == Some(Definiteness::Definite) {
6997 let y_var = self.next_var_name();
6998 let type_pred_y = self.ctx.exprs.alloc(LogicExpr::Predicate {
6999 name: subject.noun,
7000 args: self.ctx.terms.alloc_slice([Term::Variable(y_var)]),
7001 world: None,
7002 });
7003 let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
7004 left: self.ctx.terms.alloc(Term::Variable(y_var)),
7005 right: self.ctx.terms.alloc(Term::Variable(var_name)),
7006 });
7007 let uniqueness_cond = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7008 left: type_pred_y,
7009 op: TokenType::Implies,
7010 right: identity,
7011 });
7012 let uniqueness = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7013 kind: QuantifierKind::Universal,
7014 variable: y_var,
7015 body: uniqueness_cond,
7016 island_id: self.current_island,
7017 });
7018 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7019 left: body,
7020 op: TokenType::And,
7021 right: uniqueness,
7022 })
7023 } else {
7024 body
7025 };
7026
7027 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7028 kind: QuantifierKind::Existential,
7029 variable: var_name,
7030 body: uniqueness_body,
7031 island_id: self.current_island,
7032 }));
7033 }
7034
7035 relative_clause = Some((var_name, rel_clause));
7037 }
7038
7039 if self.check(&TokenType::Identity) {
7041 self.advance();
7042 let right = self.consume_content_word()?;
7043 return Ok(self.ctx.exprs.alloc(LogicExpr::Identity {
7044 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7045 right: self.ctx.terms.alloc(Term::Constant(right)),
7046 }));
7047 }
7048
7049 if self.check_modal() {
7050 if let Some((var_name, rel_clause)) = relative_clause {
7051 let modal_pred = self.parse_aspect_chain_with_term(Term::Variable(var_name))?;
7052
7053 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7054 name: subject.noun,
7055 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7056 world: None,
7057 });
7058
7059 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7060 left: type_pred,
7061 op: TokenType::And,
7062 right: rel_clause,
7063 });
7064
7065 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7066 left: inner,
7067 op: TokenType::And,
7068 right: modal_pred,
7069 });
7070
7071 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7072 kind: QuantifierKind::Existential,
7073 variable: var_name,
7074 body,
7075 island_id: self.current_island,
7076 }));
7077 }
7078
7079 let modal_pred = self.parse_aspect_chain(subject.noun)?;
7080 return self.wrap_with_definiteness_full(&subject, modal_pred);
7081 }
7082
7083 if self.check(&TokenType::Is) || self.check(&TokenType::Are)
7084 || self.check(&TokenType::Was) || self.check(&TokenType::Were)
7085 {
7086 let copula_time = if self.check(&TokenType::Was) || self.check(&TokenType::Were) {
7087 Time::Past
7088 } else {
7089 Time::Present
7090 };
7091 self.advance();
7092
7093 let is_negated = self.check(&TokenType::Not);
7095 if is_negated {
7096 self.advance(); }
7098
7099 let mut copula_temporal = None;
7101 if !is_negated {
7102 if self.check(&TokenType::Never) {
7103 self.advance();
7104 copula_temporal = Some(CopulaTemporal::Never);
7105 } else if let TokenType::Adverb(sym) | TokenType::ScopalAdverb(sym) | TokenType::TemporalAdverb(sym) = &self.peek().kind {
7106 let resolved = self.interner.resolve(*sym).to_string();
7107 if resolved == "Always" || resolved == "always" {
7108 self.advance();
7109 copula_temporal = Some(CopulaTemporal::Always);
7110 } else if resolved == "Eventually" || resolved == "eventually" {
7111 self.advance();
7112 copula_temporal = Some(CopulaTemporal::Eventually);
7113 }
7114 }
7115 }
7116
7117 if self.check_number() {
7120 let measure = self.parse_measure_phrase()?;
7121
7122 if self.check_comparative() {
7124 return self.parse_comparative(&subject, copula_time, Some(measure));
7125 }
7126
7127 if self.check_content_word() {
7129 let adj = self.consume_content_word()?;
7130 let result = self.ctx.exprs.alloc(LogicExpr::Predicate {
7131 name: adj,
7132 args: self.ctx.terms.alloc_slice([
7133 Term::Constant(subject.noun),
7134 *measure,
7135 ]),
7136 world: None,
7137 });
7138 return self.wrap_with_definiteness_full(&subject, result);
7139 }
7140
7141 if self.check(&TokenType::Period) || self.is_at_end() {
7144 if self.mode == ParserMode::Imperative {
7146 let variable = self.interner.resolve(subject.noun).to_string();
7147 let value = if let Term::Value { kind, .. } = measure {
7148 format!("{:?}", kind)
7149 } else {
7150 "value".to_string()
7151 };
7152 return Err(ParseError {
7153 kind: ParseErrorKind::IsValueEquality { variable, value },
7154 span: self.current_span(),
7155 });
7156 }
7157 let result = self.ctx.exprs.alloc(LogicExpr::Identity {
7158 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7159 right: measure,
7160 });
7161 return self.wrap_with_definiteness_full(&subject, result);
7162 }
7163 }
7164
7165 if self.check_comparative() {
7167 return self.parse_comparative(&subject, copula_time, None);
7168 }
7169
7170 if self.check(&TokenType::Period) || self.is_at_end() {
7172 let var = self.next_var_name();
7173 let body = self.ctx.exprs.alloc(LogicExpr::Identity {
7174 left: self.ctx.terms.alloc(Term::Variable(var)),
7175 right: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7176 });
7177 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7178 kind: QuantifierKind::Existential,
7179 variable: var,
7180 body,
7181 island_id: self.current_island,
7182 }));
7183 }
7184
7185 if self.check(&TokenType::Article(Definiteness::Definite)) {
7187 let saved_pos = self.current;
7188 self.advance();
7189 if self.check_superlative() {
7190 return self.parse_superlative(&subject);
7191 }
7192 self.current = saved_pos;
7193 }
7194
7195 if self.check_article() {
7197 let predicate_np = self.parse_noun_phrase(true)?;
7198 let predicate_noun = predicate_np.noun;
7199
7200 if self.event_reading_mode {
7203 let noun_str = self.interner.resolve(predicate_noun);
7204 if let Some(base_verb) = lexicon::lookup_agentive_noun(noun_str) {
7205 let event_adj = predicate_np.adjectives.iter().find(|adj| {
7207 lexicon::is_event_modifier_adjective(self.interner.resolve(**adj))
7208 });
7209
7210 if let Some(&adj_sym) = event_adj {
7211 let verb_sym = self.interner.intern(base_verb);
7213 let event_var = self.get_event_var();
7214
7215 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7216 name: verb_sym,
7217 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
7218 world: None,
7219 });
7220
7221 let agent_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7222 name: self.interner.intern("Agent"),
7223 args: self.ctx.terms.alloc_slice([
7224 Term::Variable(event_var),
7225 Term::Constant(subject.noun),
7226 ]),
7227 world: None,
7228 });
7229
7230 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7231 name: adj_sym,
7232 args: self.ctx.terms.alloc_slice([Term::Variable(event_var)]),
7233 world: None,
7234 });
7235
7236 let verb_agent = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7238 left: verb_pred,
7239 op: TokenType::And,
7240 right: agent_pred,
7241 });
7242
7243 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7245 left: verb_agent,
7246 op: TokenType::And,
7247 right: adj_pred,
7248 });
7249
7250 let event_reading = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7252 kind: QuantifierKind::Existential,
7253 variable: event_var,
7254 body,
7255 island_id: self.current_island,
7256 });
7257
7258 return self.wrap_with_definiteness(subject.definiteness, subject.noun, event_reading);
7259 }
7260 }
7261 }
7262
7263 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7264 let predicate_sort = lexicon::lookup_sort(self.interner.resolve(predicate_noun));
7265
7266 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
7267 if !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
7268 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7269 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7270 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_noun)),
7271 });
7272 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7273 }
7274 }
7275
7276 let mut predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
7279
7280 for &adj_sym in predicate_np.adjectives {
7282 let adj_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7283 name: adj_sym,
7284 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7285 world: None,
7286 });
7287 predicates.push(adj_pred);
7288 }
7289
7290 let noun_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7292 name: predicate_noun,
7293 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7294 world: None,
7295 });
7296 predicates.push(noun_pred);
7297
7298 let result = if predicates.len() == 1 {
7300 predicates[0]
7301 } else {
7302 let mut combined = predicates[0];
7303 for pred in &predicates[1..] {
7304 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7305 left: combined,
7306 op: TokenType::And,
7307 right: *pred,
7308 });
7309 }
7310 combined
7311 };
7312
7313 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7314 }
7315
7316 let prefer_adjective = if let TokenType::Ambiguous { primary, alternatives } = &self.peek().kind {
7319 let is_simple_verb = if let TokenType::Verb { aspect, .. } = **primary {
7320 aspect == Aspect::Simple
7321 } else {
7322 false
7323 };
7324 let has_adj_alt = alternatives.iter().any(|t| matches!(t, TokenType::Adjective(_)));
7325 is_simple_verb && has_adj_alt
7326 } else {
7327 false
7328 };
7329
7330 if !prefer_adjective && self.check_verb() {
7331 let (verb, _verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
7332
7333 if verb_class.is_stative() && verb_aspect == Aspect::Progressive {
7335 return Err(ParseError {
7336 kind: ParseErrorKind::StativeProgressiveConflict,
7337 span: self.current_span(),
7338 });
7339 }
7340
7341 let mut goal_args: Vec<Term<'a>> = Vec::new();
7344 while self.check_to_preposition() {
7345 self.advance(); let goal = self.parse_noun_phrase(true)?;
7347 goal_args.push(self.noun_phrase_to_term(&goal));
7348 }
7349
7350 if self.check_by_preposition() {
7352 self.advance(); let agent = self.parse_noun_phrase(true)?;
7354
7355 let mut args = vec![
7357 self.noun_phrase_to_term(&agent),
7358 self.noun_phrase_to_term(&subject),
7359 ];
7360 args.extend(goal_args);
7361
7362 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7363 name: verb,
7364 args: self.ctx.terms.alloc_slice(args),
7365 world: None,
7366 });
7367
7368 let with_time = if copula_time == Time::Past {
7369 self.ctx.exprs.alloc(LogicExpr::Temporal {
7370 operator: TemporalOperator::Past,
7371 body: predicate,
7372 })
7373 } else {
7374 predicate
7375 };
7376
7377 return self.wrap_with_definiteness(subject.definiteness, subject.noun, with_time);
7378 }
7379
7380 if copula_time == Time::Past && verb_aspect == Aspect::Simple
7385 && subject.definiteness != Some(Definiteness::Definite) {
7386 let var_name = self.next_var_name();
7388 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7389 name: verb,
7390 args: self.ctx.terms.alloc_slice([
7391 Term::Variable(var_name),
7392 Term::Constant(subject.noun),
7393 ]),
7394 world: None,
7395 });
7396
7397 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7398 name: subject.noun,
7399 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7400 world: None,
7401 });
7402
7403 let temporal = self.ctx.exprs.alloc(LogicExpr::Temporal {
7404 operator: TemporalOperator::Past,
7405 body: predicate,
7406 });
7407
7408 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7409 left: type_pred,
7410 op: TokenType::And,
7411 right: temporal,
7412 });
7413
7414 let result = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7415 kind: QuantifierKind::Existential,
7416 variable: var_name,
7417 body,
7418 island_id: self.current_island,
7419 });
7420
7421 if is_negated {
7423 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7424 op: TokenType::Not,
7425 operand: result,
7426 }));
7427 }
7428 return Ok(result);
7429 }
7430
7431 let verb_str = self.interner.resolve(verb).to_lowercase();
7434 let subject_term = if lexicon::is_intensional_predicate(&verb_str) {
7435 Term::Intension(subject.noun)
7436 } else {
7437 Term::Constant(subject.noun)
7438 };
7439
7440 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7441 name: verb,
7442 args: self.ctx.terms.alloc_slice([subject_term]),
7443 world: None,
7444 });
7445
7446 let with_aspect = if verb_aspect == Aspect::Progressive {
7447 let operator = if verb_class == VerbClass::Semelfactive {
7449 AspectOperator::Iterative
7450 } else {
7451 AspectOperator::Progressive
7452 };
7453 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7454 operator,
7455 body: predicate,
7456 })
7457 } else {
7458 predicate
7459 };
7460
7461 let with_time = if copula_time == Time::Past {
7462 self.ctx.exprs.alloc(LogicExpr::Temporal {
7463 operator: TemporalOperator::Past,
7464 body: with_aspect,
7465 })
7466 } else {
7467 with_aspect
7468 };
7469
7470 let final_expr = if is_negated {
7471 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7472 op: TokenType::Not,
7473 operand: with_time,
7474 })
7475 } else {
7476 with_time
7477 };
7478
7479 if subject.definiteness == Some(Definiteness::Definite) {
7483 return Ok(final_expr);
7484 }
7485
7486 return self.wrap_with_definiteness(subject.definiteness, subject.noun, final_expr);
7487 }
7488
7489 if let Some((var_name, rel_clause)) = relative_clause {
7491 let var_term = Term::Variable(var_name);
7492 let pred_word = self.consume_content_word()?;
7493
7494 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7495 name: pred_word,
7496 args: self.ctx.terms.alloc_slice([var_term]),
7497 world: None,
7498 });
7499
7500 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7501 name: subject.noun,
7502 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7503 world: None,
7504 });
7505
7506 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7507 left: type_pred,
7508 op: TokenType::And,
7509 right: rel_clause,
7510 });
7511
7512 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7513 left: inner,
7514 op: TokenType::And,
7515 right: main_pred,
7516 });
7517
7518 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7519 kind: QuantifierKind::Existential,
7520 variable: var_name,
7521 body,
7522 island_id: self.current_island,
7523 }));
7524 }
7525
7526 if let TokenType::ProperName(predicate_name) = self.peek().kind {
7531 self.advance(); let identity = self.ctx.exprs.alloc(LogicExpr::Identity {
7533 left: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7534 right: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7535 });
7536 let result = if is_negated {
7537 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7538 op: TokenType::Not,
7539 operand: identity,
7540 })
7541 } else {
7542 identity
7543 };
7544 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7545 }
7546
7547 let predicate_name = self.consume_content_word()?;
7550
7551 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
7553 let predicate_str = self.interner.resolve(predicate_name);
7554
7555 if let Some(s_sort) = subject_sort {
7557 if !crate::ontology::check_sort_compatibility(predicate_str, s_sort) {
7558 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7559 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7560 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7561 });
7562 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7563 }
7564 }
7565
7566 let predicate_sort = lexicon::lookup_sort(predicate_str);
7568 if let (Some(s_sort), Some(p_sort)) = (subject_sort, predicate_sort) {
7569 if s_sort != p_sort && !s_sort.is_compatible_with(p_sort) && !p_sort.is_compatible_with(s_sort) {
7570 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
7571 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
7572 vehicle: self.ctx.terms.alloc(Term::Constant(predicate_name)),
7573 });
7574 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
7575 }
7576 }
7577
7578 let predicate = self.ctx.exprs.alloc(LogicExpr::Predicate {
7579 name: predicate_name,
7580 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
7581 world: None,
7582 });
7583
7584 let result = if is_negated {
7586 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7587 op: TokenType::Not,
7588 operand: predicate,
7589 })
7590 } else {
7591 predicate
7592 };
7593
7594 let result = match copula_temporal {
7596 Some(CopulaTemporal::Always) => {
7597 self.ctx.exprs.alloc(LogicExpr::Temporal {
7598 operator: TemporalOperator::Always,
7599 body: result,
7600 })
7601 }
7602 Some(CopulaTemporal::Never) => {
7603 let negated = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7604 op: TokenType::Not,
7605 operand: predicate,
7606 });
7607 self.ctx.exprs.alloc(LogicExpr::Temporal {
7608 operator: TemporalOperator::Always,
7609 body: negated,
7610 })
7611 }
7612 Some(CopulaTemporal::Eventually) => {
7613 self.ctx.exprs.alloc(LogicExpr::Temporal {
7614 operator: TemporalOperator::Eventually,
7615 body: result,
7616 })
7617 }
7618 None => result,
7619 };
7620
7621 return self.wrap_with_definiteness(subject.definiteness, subject.noun, result);
7622 }
7623
7624 if self.check_auxiliary() && self.is_true_auxiliary_usage() {
7628 let aux_time = if let TokenType::Auxiliary(time) = self.advance().kind {
7629 time
7630 } else {
7631 Time::None
7632 };
7633 self.pending_time = Some(aux_time);
7634
7635 if self.match_token(&[TokenType::Not]) {
7637 self.negative_depth += 1;
7638
7639 if self.check(&TokenType::Ever) {
7641 self.advance();
7642 }
7643
7644 if self.check_verb() || self.check(&TokenType::Do) {
7646 let verb = if self.check(&TokenType::Do) {
7647 self.advance(); self.interner.intern("Do")
7649 } else {
7650 self.consume_verb()
7651 };
7652 let subject_term = self.noun_phrase_to_term(&subject);
7653
7654 if self.check_npi_object() {
7656 let npi_token = self.advance().kind.clone();
7657 let obj_var = self.next_var_name();
7658
7659 let restriction_name = match npi_token {
7660 TokenType::Anything => "Thing",
7661 TokenType::Anyone => "Person",
7662 _ => "Thing",
7663 };
7664
7665 let restriction_sym = self.interner.intern(restriction_name);
7666 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7667 name: restriction_sym,
7668 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7669 world: None,
7670 });
7671
7672 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7673 name: verb,
7674 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7675 world: None,
7676 });
7677
7678 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7679 left: obj_restriction,
7680 op: TokenType::And,
7681 right: verb_pred,
7682 });
7683
7684 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7685 kind: QuantifierKind::Existential,
7686 variable: obj_var,
7687 body,
7688 island_id: self.current_island,
7689 });
7690
7691 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7692 let with_time = match effective_time {
7693 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7694 operator: TemporalOperator::Past,
7695 body: quantified,
7696 }),
7697 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7698 operator: TemporalOperator::Future,
7699 body: quantified,
7700 }),
7701 _ => quantified,
7702 };
7703
7704 self.negative_depth -= 1;
7705 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7706 op: TokenType::Not,
7707 operand: with_time,
7708 }));
7709 }
7710
7711 if self.check_quantifier() {
7713 let quantifier_token = self.advance().kind.clone();
7714 let object_np = self.parse_noun_phrase(false)?;
7715 let obj_var = self.next_var_name();
7716
7717 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
7718 name: object_np.noun,
7719 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
7720 world: None,
7721 });
7722
7723 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7724 name: verb,
7725 args: self.ctx.terms.alloc_slice([subject_term.clone(), Term::Variable(obj_var)]),
7726 world: None,
7727 });
7728
7729 let (kind, body) = match quantifier_token {
7730 TokenType::Any => {
7731 if self.is_negative_context() {
7732 (
7733 QuantifierKind::Existential,
7734 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7735 left: obj_restriction,
7736 op: TokenType::And,
7737 right: verb_pred,
7738 }),
7739 )
7740 } else {
7741 (
7742 QuantifierKind::Universal,
7743 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7744 left: obj_restriction,
7745 op: TokenType::Implies,
7746 right: verb_pred,
7747 }),
7748 )
7749 }
7750 }
7751 TokenType::Some => (
7752 QuantifierKind::Existential,
7753 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7754 left: obj_restriction,
7755 op: TokenType::And,
7756 right: verb_pred,
7757 }),
7758 ),
7759 TokenType::All => (
7760 QuantifierKind::Universal,
7761 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7762 left: obj_restriction,
7763 op: TokenType::Implies,
7764 right: verb_pred,
7765 }),
7766 ),
7767 _ => (
7768 QuantifierKind::Existential,
7769 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7770 left: obj_restriction,
7771 op: TokenType::And,
7772 right: verb_pred,
7773 }),
7774 ),
7775 };
7776
7777 let quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
7778 kind,
7779 variable: obj_var,
7780 body,
7781 island_id: self.current_island,
7782 });
7783
7784 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7785 let with_time = match effective_time {
7786 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7787 operator: TemporalOperator::Past,
7788 body: quantified,
7789 }),
7790 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7791 operator: TemporalOperator::Future,
7792 body: quantified,
7793 }),
7794 _ => quantified,
7795 };
7796
7797 self.negative_depth -= 1;
7798 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7799 op: TokenType::Not,
7800 operand: with_time,
7801 }));
7802 }
7803
7804 let mut roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
7805
7806 let effective_time = self.pending_time.take().unwrap_or(Time::None);
7808 let mut modifiers: Vec<Symbol> = vec![];
7809 match effective_time {
7810 Time::Past => modifiers.push(self.interner.intern("Past")),
7811 Time::Future => modifiers.push(self.interner.intern("Future")),
7812 _ => {}
7813 }
7814
7815 if self.check_content_word() || self.check_article() || self.check_pronoun() {
7817 if self.check_pronoun() {
7818 let pronoun_token = self.advance();
7820 let pronoun_sym = pronoun_token.lexeme;
7821 roles.push((ThematicRole::Theme, Term::Constant(pronoun_sym)));
7822 } else {
7823 let object = self.parse_noun_phrase(false)?;
7824 let object_term = self.noun_phrase_to_term(&object);
7825 roles.push((ThematicRole::Theme, object_term));
7826 }
7827 }
7828
7829 let event_var = self.get_event_var();
7830 let suppress_existential = self.drs.in_conditional_antecedent();
7831 if suppress_existential {
7832 let event_class = self.interner.intern("Event");
7833 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7834 }
7835 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7836 event_var,
7837 verb,
7838 roles: self.ctx.roles.alloc_slice(roles),
7839 modifiers: self.ctx.syms.alloc_slice(modifiers),
7840 suppress_existential,
7841 world: None,
7842 })));
7843
7844 self.negative_depth -= 1;
7845 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
7846 op: TokenType::Not,
7847 operand: neo_event,
7848 }));
7849 }
7850
7851 self.negative_depth -= 1;
7852 }
7853 }
7855
7856 if self.check_presup_trigger() && !self.is_followed_by_np_object() && self.is_followed_by_gerund() {
7862 let presup_kind = match self.advance().kind {
7863 TokenType::PresupTrigger(kind) => kind,
7864 TokenType::Verb { lemma, .. } => {
7865 let s = self.interner.resolve(lemma).to_lowercase();
7866 crate::lexicon::lookup_presup_trigger(&s)
7867 .expect("Lexicon mismatch: Verb flagged as trigger but lookup failed")
7868 }
7869 _ => panic!("Expected presupposition trigger"),
7870 };
7871 return self.parse_presupposition(&subject, presup_kind);
7872 }
7873
7874 let noun_str = self.interner.resolve(subject.noun);
7876 let is_bare_plural = subject.definiteness.is_none()
7877 && subject.possessor.is_none()
7878 && Self::is_plural_noun(noun_str)
7879 && self.check_verb();
7880
7881 if is_bare_plural {
7882 let var_name = self.next_var_name();
7883 let (verb, verb_time, verb_aspect, _) = self.consume_verb_with_metadata();
7884
7885 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7886 name: subject.noun,
7887 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
7888 world: None,
7889 });
7890
7891 let mut args = vec![Term::Variable(var_name)];
7892 if self.check_content_word() {
7893 let object = self.parse_noun_phrase(false)?;
7894 args.push(self.noun_phrase_to_term(&object));
7895 }
7896
7897 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
7898 name: verb,
7899 args: self.ctx.terms.alloc_slice(args),
7900 world: None,
7901 });
7902
7903 let effective_time = self.pending_time.take().unwrap_or(verb_time);
7904 let with_time = match effective_time {
7905 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
7906 operator: TemporalOperator::Past,
7907 body: verb_pred,
7908 }),
7909 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
7910 operator: TemporalOperator::Future,
7911 body: verb_pred,
7912 }),
7913 _ => verb_pred,
7914 };
7915
7916 let with_aspect = if verb_aspect == Aspect::Progressive {
7917 self.ctx.exprs.alloc(LogicExpr::Aspectual {
7918 operator: AspectOperator::Progressive,
7919 body: with_time,
7920 })
7921 } else {
7922 with_time
7923 };
7924
7925 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
7926 left: type_pred,
7927 op: TokenType::Implies,
7928 right: with_aspect,
7929 });
7930
7931 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
7932 kind: QuantifierKind::Generic,
7933 variable: var_name,
7934 body,
7935 island_id: self.current_island,
7936 }));
7937 }
7938
7939 if self.check(&TokenType::Does) || self.check(&TokenType::Do) {
7941 self.advance(); let is_negated = self.match_token(&[TokenType::Not]);
7943
7944 if self.check_verb() {
7945 let verb = self.consume_verb();
7946 let verb_lemma = self.interner.resolve(verb).to_lowercase();
7947
7948 if self.check_wh_word() {
7950 let wh_token = self.advance().kind.clone();
7951 let is_who = matches!(wh_token, TokenType::Who);
7952 let is_what = matches!(wh_token, TokenType::What);
7953
7954 let is_sluicing = self.is_at_end() ||
7955 self.check(&TokenType::Period) ||
7956 self.check(&TokenType::Comma);
7957
7958 if is_sluicing {
7959 if let Some(template) = self.last_event_template.clone() {
7960 let wh_var = self.next_var_name();
7961 let subject_term = self.noun_phrase_to_term(&subject);
7962
7963 let roles: Vec<_> = if is_who {
7964 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7965 .chain(template.non_agent_roles.iter().cloned())
7966 .collect()
7967 } else if is_what {
7968 vec![
7969 (ThematicRole::Agent, subject_term.clone()),
7970 (ThematicRole::Theme, Term::Variable(wh_var)),
7971 ]
7972 } else {
7973 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
7974 .chain(template.non_agent_roles.iter().cloned())
7975 .collect()
7976 };
7977
7978 let event_var = self.get_event_var();
7979 let suppress_existential = self.drs.in_conditional_antecedent();
7980 if suppress_existential {
7981 let event_class = self.interner.intern("Event");
7982 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
7983 }
7984 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
7985 event_var,
7986 verb: template.verb,
7987 roles: self.ctx.roles.alloc_slice(roles),
7988 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
7989 suppress_existential,
7990 world: None,
7991 })));
7992
7993 let question = self.ctx.exprs.alloc(LogicExpr::Question {
7994 wh_variable: wh_var,
7995 body: reconstructed,
7996 });
7997
7998 let know_event_var = self.get_event_var();
7999 let suppress_existential2 = self.drs.in_conditional_antecedent();
8000 if suppress_existential2 {
8001 let event_class = self.interner.intern("Event");
8002 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8003 }
8004 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8005 event_var: know_event_var,
8006 verb,
8007 roles: self.ctx.roles.alloc_slice(vec![
8008 (ThematicRole::Agent, subject_term),
8009 (ThematicRole::Theme, Term::Proposition(question)),
8010 ]),
8011 modifiers: self.ctx.syms.alloc_slice(vec![]),
8012 suppress_existential: suppress_existential2,
8013 world: None,
8014 })));
8015
8016 let result = if is_negated {
8017 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8018 op: TokenType::Not,
8019 operand: know_event,
8020 })
8021 } else {
8022 know_event
8023 };
8024
8025 return self.wrap_with_definiteness_full(&subject, result);
8026 }
8027 }
8028 }
8029
8030 if verb_lemma == "exist" && is_negated {
8032 let var_name = self.next_var_name();
8034 let restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
8035 name: subject.noun,
8036 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8037 world: None,
8038 });
8039 let exists = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8040 kind: QuantifierKind::Existential,
8041 variable: var_name,
8042 body: restriction,
8043 island_id: self.current_island,
8044 });
8045 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8046 op: TokenType::Not,
8047 operand: exists,
8048 }));
8049 }
8050
8051 let subject_term = self.noun_phrase_to_term(&subject);
8054 let modifiers: Vec<Symbol> = vec![];
8055
8056 if self.check(&TokenType::Reflexive) {
8058 self.advance();
8059 let roles = vec![
8060 (ThematicRole::Agent, subject_term.clone()),
8061 (ThematicRole::Theme, subject_term),
8062 ];
8063 let event_var = self.get_event_var();
8064 let suppress_existential = self.drs.in_conditional_antecedent();
8065 if suppress_existential {
8066 let event_class = self.interner.intern("Event");
8067 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8068 }
8069 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8070 event_var,
8071 verb,
8072 roles: self.ctx.roles.alloc_slice(roles),
8073 modifiers: self.ctx.syms.alloc_slice(modifiers),
8074 suppress_existential,
8075 world: None,
8076 })));
8077
8078 let result = if is_negated {
8079 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8080 op: TokenType::Not,
8081 operand: neo_event,
8082 })
8083 } else {
8084 neo_event
8085 };
8086 return self.wrap_with_definiteness_full(&subject, result);
8087 }
8088
8089 if self.check_npi_quantifier() || self.check_quantifier() || self.check_article() {
8091 let (obj_quantifier, was_definite_article) = if self.check_npi_quantifier() {
8092 let tok = self.advance().kind.clone();
8094 (Some(tok), false)
8095 } else if self.check_quantifier() {
8096 (Some(self.advance().kind.clone()), false)
8097 } else {
8098 let art = self.advance().kind.clone();
8099 if let TokenType::Article(def) = art {
8100 if def == Definiteness::Indefinite {
8101 (Some(TokenType::Some), false)
8102 } else {
8103 (None, true)
8104 }
8105 } else {
8106 (None, false)
8107 }
8108 };
8109
8110 let object_np = self.parse_noun_phrase(false)?;
8111 let obj_var = self.next_var_name();
8112
8113 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8114 name: object_np.noun,
8115 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8116 world: None,
8117 });
8118
8119 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8121 self.advance();
8122 let rel_clause = self.parse_relative_clause(obj_var)?;
8123 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8124 left: type_pred,
8125 op: TokenType::And,
8126 right: rel_clause,
8127 })
8128 } else {
8129 type_pred
8130 };
8131
8132 let event_var = self.get_event_var();
8133 let suppress_existential = self.drs.in_conditional_antecedent();
8134 if suppress_existential {
8135 let event_class = self.interner.intern("Event");
8136 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8137 }
8138
8139 let roles = vec![
8140 (ThematicRole::Agent, subject_term),
8141 (ThematicRole::Theme, Term::Variable(obj_var)),
8142 ];
8143
8144 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8145 event_var,
8146 verb,
8147 roles: self.ctx.roles.alloc_slice(roles),
8148 modifiers: self.ctx.syms.alloc_slice(modifiers),
8149 suppress_existential,
8150 world: None,
8151 })));
8152
8153 let quantifier_kind = match &obj_quantifier {
8157 Some(TokenType::Any) if is_negated => QuantifierKind::Existential,
8158 Some(TokenType::All) => QuantifierKind::Universal,
8159 Some(TokenType::No) => QuantifierKind::Universal,
8160 _ => QuantifierKind::Existential,
8161 };
8162
8163 let obj_body = match &obj_quantifier {
8164 Some(TokenType::All) => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8165 left: obj_restriction,
8166 op: TokenType::Implies,
8167 right: neo_event,
8168 }),
8169 Some(TokenType::No) => {
8170 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8171 op: TokenType::Not,
8172 operand: neo_event,
8173 });
8174 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8175 left: obj_restriction,
8176 op: TokenType::Implies,
8177 right: neg,
8178 })
8179 }
8180 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8181 left: obj_restriction,
8182 op: TokenType::And,
8183 right: neo_event,
8184 }),
8185 };
8186
8187 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8188 kind: quantifier_kind,
8189 variable: obj_var,
8190 body: obj_body,
8191 island_id: self.current_island,
8192 });
8193
8194 let result = if is_negated && matches!(obj_quantifier, Some(TokenType::Any)) {
8196 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8197 op: TokenType::Not,
8198 operand: obj_quantified,
8199 })
8200 } else if is_negated {
8201 self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8203 op: TokenType::Not,
8204 operand: obj_quantified,
8205 })
8206 } else {
8207 obj_quantified
8208 };
8209
8210 return self.wrap_with_definiteness_full(&subject, result);
8211 }
8212
8213 let roles: Vec<(ThematicRole, Term<'a>)> = vec![(ThematicRole::Agent, subject_term)];
8215 let event_var = self.get_event_var();
8216 let suppress_existential = self.drs.in_conditional_antecedent();
8217 if suppress_existential {
8218 let event_class = self.interner.intern("Event");
8219 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8220 }
8221
8222 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8223 event_var,
8224 verb,
8225 roles: self.ctx.roles.alloc_slice(roles),
8226 modifiers: self.ctx.syms.alloc_slice(modifiers),
8227 suppress_existential,
8228 world: None,
8229 })));
8230
8231 if is_negated {
8232 return Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8233 op: TokenType::Not,
8234 operand: neo_event,
8235 }));
8236 }
8237 return Ok(neo_event);
8238 }
8239 }
8240
8241 let is_perfect_aux = if self.check_verb() {
8247 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
8248 word == "has" || word == "have" || word == "had"
8249 } else {
8250 false
8251 };
8252 if subject.definiteness == Some(Definiteness::Definite) && self.check_verb() && self.pending_time.is_none() && !is_perfect_aux {
8253 let saved_pos = self.current;
8254
8255 if let Some(garden_path_result) = self.try_parse(|p| {
8257 let (modifier_verb, _modifier_time, _, _) = p.consume_verb_with_metadata();
8258
8259 let mut pp_mods: Vec<&'a LogicExpr<'a>> = Vec::new();
8261 while p.check_preposition() {
8262 let prep = if let TokenType::Preposition(prep) = p.advance().kind {
8263 prep
8264 } else {
8265 break;
8266 };
8267 if p.check_article() || p.check_content_word() {
8268 let pp_obj = p.parse_noun_phrase(false)?;
8269 let pp_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8270 name: prep,
8271 args: p.ctx.terms.alloc_slice([Term::Variable(p.interner.intern("x")), Term::Constant(pp_obj.noun)]),
8272 world: None,
8273 });
8274 pp_mods.push(pp_pred);
8275 }
8276 }
8277
8278 if !p.check_verb() {
8280 return Err(ParseError {
8281 kind: ParseErrorKind::ExpectedVerb { found: p.peek().kind.clone() },
8282 span: p.current_span(),
8283 });
8284 }
8285
8286 let (main_verb, main_time, _, _) = p.consume_verb_with_metadata();
8287
8288 let var = p.interner.intern("x");
8290
8291 let type_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8293 name: subject.noun,
8294 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
8295 world: None,
8296 });
8297
8298 let mod_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8300 name: modifier_verb,
8301 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
8302 world: None,
8303 });
8304
8305 let main_pred = p.ctx.exprs.alloc(LogicExpr::Predicate {
8307 name: main_verb,
8308 args: p.ctx.terms.alloc_slice([Term::Variable(var)]),
8309 world: None,
8310 });
8311
8312 let mut body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
8314 left: type_pred,
8315 op: TokenType::And,
8316 right: mod_pred,
8317 });
8318
8319 for pp in pp_mods {
8321 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
8322 left: body,
8323 op: TokenType::And,
8324 right: pp,
8325 });
8326 }
8327
8328 body = p.ctx.exprs.alloc(LogicExpr::BinaryOp {
8330 left: body,
8331 op: TokenType::And,
8332 right: main_pred,
8333 });
8334
8335 let with_time = match main_time {
8337 Time::Past => p.ctx.exprs.alloc(LogicExpr::Temporal {
8338 operator: TemporalOperator::Past,
8339 body,
8340 }),
8341 Time::Future => p.ctx.exprs.alloc(LogicExpr::Temporal {
8342 operator: TemporalOperator::Future,
8343 body,
8344 }),
8345 _ => body,
8346 };
8347
8348 Ok(p.ctx.exprs.alloc(LogicExpr::Quantifier {
8350 kind: QuantifierKind::Existential,
8351 variable: var,
8352 body: with_time,
8353 island_id: p.current_island,
8354 }))
8355 }) {
8356 return Ok(garden_path_result);
8357 }
8358
8359 self.current = saved_pos;
8361 }
8362
8363 if self.check_modal() {
8364 return self.parse_aspect_chain(subject.noun);
8365 }
8366
8367 if self.check_content_word() {
8369 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
8370 if word == "has" || word == "have" || word == "had" {
8371 let is_perfect_aspect = if self.current + 1 < self.tokens.len() {
8373 let next_token = &self.tokens[self.current + 1].kind;
8374 matches!(
8375 next_token,
8376 TokenType::Verb { .. } | TokenType::Not
8377 ) && !matches!(next_token, TokenType::Number(_))
8378 } else {
8379 false
8380 };
8381 if is_perfect_aspect {
8382 return self.parse_aspect_chain(subject.noun);
8383 }
8384 }
8386 }
8387
8388 if self.check(&TokenType::Had) {
8390 return self.parse_aspect_chain(subject.noun);
8391 }
8392
8393 if self.check(&TokenType::Never) {
8395 self.advance();
8396 let verb = self.consume_verb();
8397 let subject_term = self.noun_phrase_to_term(&subject);
8398 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8399 name: verb,
8400 args: self.ctx.terms.alloc_slice([subject_term]),
8401 world: None,
8402 });
8403 let result = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8404 op: TokenType::Not,
8405 operand: verb_pred,
8406 });
8407 return self.wrap_with_definiteness_full(&subject, result);
8408 }
8409
8410 if self.check_verb() {
8411 let (mut verb, verb_time, verb_aspect, verb_class) = self.consume_verb_with_metadata();
8412
8413 let subject_sort = lexicon::lookup_sort(self.interner.resolve(subject.noun));
8415 let verb_str = self.interner.resolve(verb);
8416 if let Some(s_sort) = subject_sort {
8417 if !crate::ontology::check_sort_compatibility(verb_str, s_sort) {
8418 let metaphor = self.ctx.exprs.alloc(LogicExpr::Metaphor {
8419 tenor: self.ctx.terms.alloc(Term::Constant(subject.noun)),
8420 vehicle: self.ctx.terms.alloc(Term::Constant(verb)),
8421 });
8422 return self.wrap_with_definiteness(subject.definiteness, subject.noun, metaphor);
8423 }
8424 }
8425
8426 if self.is_control_verb(verb) {
8428 return self.parse_control_structure(&subject, verb, verb_time);
8429 }
8430
8431 if let Some((var_name, rel_clause)) = relative_clause {
8433 let main_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8434 name: verb,
8435 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8436 world: None,
8437 });
8438
8439 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8440 let with_time = match effective_time {
8441 Time::Past => self.ctx.exprs.alloc(LogicExpr::Temporal {
8442 operator: TemporalOperator::Past,
8443 body: main_pred,
8444 }),
8445 Time::Future => self.ctx.exprs.alloc(LogicExpr::Temporal {
8446 operator: TemporalOperator::Future,
8447 body: main_pred,
8448 }),
8449 _ => main_pred,
8450 };
8451
8452 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8454 name: subject.noun,
8455 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
8456 world: None,
8457 });
8458
8459 let inner = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8460 left: type_pred,
8461 op: TokenType::And,
8462 right: rel_clause,
8463 });
8464
8465 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8466 left: inner,
8467 op: TokenType::And,
8468 right: with_time,
8469 });
8470
8471 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
8472 kind: QuantifierKind::Existential,
8473 variable: var_name,
8474 body,
8475 island_id: self.current_island,
8476 }));
8477 }
8478
8479 let subject_term = self.noun_phrase_to_term(&subject);
8480 let mut args = vec![subject_term.clone()];
8481
8482 let unknown = self.interner.intern("?");
8483
8484 if self.check_wh_word() {
8486 let wh_token = self.advance().kind.clone();
8487
8488 let is_who = matches!(wh_token, TokenType::Who);
8490 let is_what = matches!(wh_token, TokenType::What);
8491
8492 let is_sluicing = self.is_at_end() ||
8494 self.check(&TokenType::Period) ||
8495 self.check(&TokenType::Comma);
8496
8497 if is_sluicing {
8498 if let Some(template) = self.last_event_template.clone() {
8500 let wh_var = self.next_var_name();
8501
8502 let roles: Vec<_> = if is_who {
8504 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
8506 .chain(template.non_agent_roles.iter().cloned())
8507 .collect()
8508 } else if is_what {
8509 vec![
8511 (ThematicRole::Agent, subject_term.clone()),
8512 (ThematicRole::Theme, Term::Variable(wh_var)),
8513 ]
8514 } else {
8515 std::iter::once((ThematicRole::Agent, Term::Variable(wh_var)))
8517 .chain(template.non_agent_roles.iter().cloned())
8518 .collect()
8519 };
8520
8521 let event_var = self.get_event_var();
8522 let suppress_existential = self.drs.in_conditional_antecedent();
8523 if suppress_existential {
8524 let event_class = self.interner.intern("Event");
8525 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8526 }
8527 let reconstructed = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8528 event_var,
8529 verb: template.verb,
8530 roles: self.ctx.roles.alloc_slice(roles),
8531 modifiers: self.ctx.syms.alloc_slice(template.modifiers.clone()),
8532 suppress_existential,
8533 world: None,
8534 })));
8535
8536 let question = self.ctx.exprs.alloc(LogicExpr::Question {
8537 wh_variable: wh_var,
8538 body: reconstructed,
8539 });
8540
8541 let know_event_var = self.get_event_var();
8543 let suppress_existential2 = self.drs.in_conditional_antecedent();
8544 if suppress_existential2 {
8545 let event_class = self.interner.intern("Event");
8546 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8547 }
8548 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8549 event_var: know_event_var,
8550 verb,
8551 roles: self.ctx.roles.alloc_slice(vec![
8552 (ThematicRole::Agent, subject_term),
8553 (ThematicRole::Theme, Term::Proposition(question)),
8554 ]),
8555 modifiers: self.ctx.syms.alloc_slice(vec![]),
8556 suppress_existential: suppress_existential2,
8557 world: None,
8558 })));
8559
8560 return self.wrap_with_definiteness_full(&subject, know_event);
8561 }
8562 }
8563
8564 let embedded = self.parse_embedded_wh_clause()?;
8566 let question = self.ctx.exprs.alloc(LogicExpr::Question {
8567 wh_variable: self.interner.intern("x"),
8568 body: embedded,
8569 });
8570
8571 let know_event_var = self.get_event_var();
8573 let suppress_existential = self.drs.in_conditional_antecedent();
8574 if suppress_existential {
8575 let event_class = self.interner.intern("Event");
8576 self.drs.introduce_referent(know_event_var, event_class, Gender::Neuter, Number::Singular);
8577 }
8578 let know_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8579 event_var: know_event_var,
8580 verb,
8581 roles: self.ctx.roles.alloc_slice(vec![
8582 (ThematicRole::Agent, subject_term),
8583 (ThematicRole::Theme, Term::Proposition(question)),
8584 ]),
8585 modifiers: self.ctx.syms.alloc_slice(vec![]),
8586 suppress_existential,
8587 world: None,
8588 })));
8589
8590 return self.wrap_with_definiteness_full(&subject, know_event);
8591 }
8592
8593 let mut object_term: Option<Term<'a>> = None;
8594 let mut second_object_term: Option<Term<'a>> = None;
8595 let mut object_superlative: Option<(Symbol, Symbol)> = None; if self.check(&TokenType::Reflexive) {
8597 self.advance();
8598 let term = self.noun_phrase_to_term(&subject);
8599 object_term = Some(term.clone());
8600 args.push(term);
8601
8602 if let TokenType::Particle(particle_sym) = self.peek().kind {
8604 let verb_str = self.interner.resolve(verb).to_lowercase();
8605 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8606 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8607 self.advance();
8608 verb = self.interner.intern(phrasal_lemma);
8609 }
8610 }
8611 } else if self.check_pronoun() {
8612 let token = self.advance().clone();
8613 if let TokenType::Pronoun { gender, number, .. } = token.kind {
8614 let resolved = self.resolve_pronoun(gender, number)?;
8615 let term = match resolved {
8616 ResolvedPronoun::Variable(s) => Term::Variable(s),
8617 ResolvedPronoun::Constant(s) => Term::Constant(s),
8618 };
8619 object_term = Some(term.clone());
8620 args.push(term);
8621
8622 if let TokenType::Particle(particle_sym) = self.peek().kind {
8624 let verb_str = self.interner.resolve(verb).to_lowercase();
8625 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8626 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8627 self.advance();
8628 verb = self.interner.intern(phrasal_lemma);
8629 }
8630 }
8631 }
8632 } else if self.check_quantifier() || self.check_article() {
8633 let (obj_quantifier, was_definite_article) = if self.check_quantifier() {
8635 (Some(self.advance().kind.clone()), false)
8636 } else {
8637 let art = self.advance().kind.clone();
8638 if let TokenType::Article(def) = art {
8639 if def == Definiteness::Indefinite {
8640 (Some(TokenType::Some), false)
8641 } else {
8642 (None, true) }
8644 } else {
8645 (None, false)
8646 }
8647 };
8648
8649 let object_np = self.parse_noun_phrase(false)?;
8650
8651 if let Some(adj) = object_np.superlative {
8653 object_superlative = Some((adj, object_np.noun));
8654 }
8655
8656 if let TokenType::Particle(particle_sym) = self.peek().kind {
8658 let verb_str = self.interner.resolve(verb).to_lowercase();
8659 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
8660 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
8661 self.advance(); verb = self.interner.intern(phrasal_lemma);
8663 }
8664 }
8665
8666 if let Some(obj_q) = obj_quantifier {
8667 let verb_str = self.interner.resolve(verb).to_lowercase();
8671 let is_opaque = lexicon::lookup_verb_db(&verb_str)
8672 .map(|meta| meta.features.contains(&lexicon::Feature::Opaque))
8673 .unwrap_or(false);
8674
8675 if is_opaque && matches!(obj_q, TokenType::Some) {
8676 let intension_term = Term::Intension(object_np.noun);
8678
8679 let event_var = self.get_event_var();
8681 let mut modifiers = self.collect_adverbs();
8682 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8683 match effective_time {
8684 Time::Past => modifiers.push(self.interner.intern("Past")),
8685 Time::Future => modifiers.push(self.interner.intern("Future")),
8686 _ => {}
8687 }
8688
8689 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8690 let roles = vec![
8691 (ThematicRole::Agent, subject_term_for_event),
8692 (ThematicRole::Theme, intension_term),
8693 ];
8694
8695 let suppress_existential = self.drs.in_conditional_antecedent();
8696 if suppress_existential {
8697 let event_class = self.interner.intern("Event");
8698 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8699 }
8700 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8701 event_var,
8702 verb,
8703 roles: self.ctx.roles.alloc_slice(roles),
8704 modifiers: self.ctx.syms.alloc_slice(modifiers),
8705 suppress_existential,
8706 world: None,
8707 })));
8708
8709 return self.wrap_with_definiteness_full(&subject, neo_event);
8710 }
8711
8712 let obj_var = self.next_var_name();
8713
8714 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8716 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8717 Number::Plural
8718 } else {
8719 Number::Singular
8720 };
8721 if object_np.definiteness == Some(Definiteness::Definite) {
8723 self.drs.introduce_referent_with_source(obj_var, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8724 } else {
8725 self.drs.introduce_referent(obj_var, object_np.noun, obj_gender, obj_number);
8726 }
8727
8728 let type_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8729 name: object_np.noun,
8730 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
8731 world: None,
8732 });
8733
8734 let obj_restriction = if self.check(&TokenType::That) || self.check(&TokenType::Who) {
8735 self.advance();
8736 let rel_clause = self.parse_relative_clause(obj_var)?;
8737 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8738 left: type_pred,
8739 op: TokenType::And,
8740 right: rel_clause,
8741 })
8742 } else {
8743 type_pred
8744 };
8745
8746 let event_var = self.get_event_var();
8747 let mut modifiers = self.collect_adverbs();
8748 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8749 match effective_time {
8750 Time::Past => modifiers.push(self.interner.intern("Past")),
8751 Time::Future => modifiers.push(self.interner.intern("Future")),
8752 _ => {}
8753 }
8754
8755 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8756 let roles = vec![
8757 (ThematicRole::Agent, subject_term_for_event),
8758 (ThematicRole::Theme, Term::Variable(obj_var)),
8759 ];
8760
8761 let template_roles = vec![
8764 (ThematicRole::Agent, subject_term_for_event),
8765 (ThematicRole::Theme, Term::Constant(object_np.noun)),
8766 ];
8767 self.capture_event_template(verb, &template_roles, &modifiers);
8768
8769 let suppress_existential = self.drs.in_conditional_antecedent();
8770 if suppress_existential {
8771 let event_class = self.interner.intern("Event");
8772 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8773 }
8774 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8775 event_var,
8776 verb,
8777 roles: self.ctx.roles.alloc_slice(roles),
8778 modifiers: self.ctx.syms.alloc_slice(modifiers),
8779 suppress_existential,
8780 world: None,
8781 })));
8782
8783 let obj_kind = match obj_q {
8784 TokenType::All => QuantifierKind::Universal,
8785 TokenType::Some => QuantifierKind::Existential,
8786 TokenType::No => QuantifierKind::Universal,
8787 TokenType::Most => QuantifierKind::Most,
8788 TokenType::Few => QuantifierKind::Few,
8789 TokenType::Many => QuantifierKind::Many,
8790 TokenType::Cardinal(n) => QuantifierKind::Cardinal(n),
8791 TokenType::AtLeast(n) => QuantifierKind::AtLeast(n),
8792 TokenType::AtMost(n) => QuantifierKind::AtMost(n),
8793 _ => QuantifierKind::Existential,
8794 };
8795
8796 let obj_body = match obj_q {
8797 TokenType::All => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8798 left: obj_restriction,
8799 op: TokenType::Implies,
8800 right: neo_event,
8801 }),
8802 TokenType::No => {
8803 let neg = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
8804 op: TokenType::Not,
8805 operand: neo_event,
8806 });
8807 self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8808 left: obj_restriction,
8809 op: TokenType::Implies,
8810 right: neg,
8811 })
8812 }
8813 _ => self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8814 left: obj_restriction,
8815 op: TokenType::And,
8816 right: neo_event,
8817 }),
8818 };
8819
8820 let obj_quantified = self.ctx.exprs.alloc(LogicExpr::Quantifier {
8822 kind: obj_kind,
8823 variable: obj_var,
8824 body: obj_body,
8825 island_id: self.current_island,
8826 });
8827
8828 return self.wrap_with_definiteness_full(&subject, obj_quantified);
8830 } else {
8831 if was_definite_article {
8836 let obj_gender = Self::infer_noun_gender(self.interner.resolve(object_np.noun));
8837 let obj_number = if Self::is_plural_noun(self.interner.resolve(object_np.noun)) {
8838 Number::Plural
8839 } else {
8840 Number::Singular
8841 };
8842 self.drs.introduce_referent_with_source(object_np.noun, object_np.noun, obj_gender, obj_number, ReferentSource::MainClause);
8844 }
8845
8846 let term = self.noun_phrase_to_term(&object_np);
8847 object_term = Some(term.clone());
8848 args.push(term);
8849 }
8850 } else if self.check_focus() {
8851 let focus_kind = if let TokenType::Focus(k) = self.advance().kind {
8852 k
8853 } else {
8854 FocusKind::Only
8855 };
8856
8857 let event_var = self.get_event_var();
8858 let mut modifiers = self.collect_adverbs();
8859 let effective_time = self.pending_time.take().unwrap_or(verb_time);
8860 match effective_time {
8861 Time::Past => modifiers.push(self.interner.intern("Past")),
8862 Time::Future => modifiers.push(self.interner.intern("Future")),
8863 _ => {}
8864 }
8865
8866 let subject_term_for_event = self.noun_phrase_to_term(&subject);
8867
8868 if self.check_preposition() {
8869 let prep_token = self.advance().clone();
8870 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
8871 sym
8872 } else {
8873 self.interner.intern("to")
8874 };
8875 let pp_obj = self.parse_noun_phrase(false)?;
8876 let pp_obj_term = Term::Constant(pp_obj.noun);
8877
8878 let roles = vec![(ThematicRole::Agent, subject_term_for_event)];
8879 let suppress_existential = self.drs.in_conditional_antecedent();
8880 if suppress_existential {
8881 let event_class = self.interner.intern("Event");
8882 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8883 }
8884 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8885 event_var,
8886 verb,
8887 roles: self.ctx.roles.alloc_slice(roles),
8888 modifiers: self.ctx.syms.alloc_slice(modifiers),
8889 suppress_existential,
8890 world: None,
8891 })));
8892
8893 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
8894 name: prep_name,
8895 args: self.ctx.terms.alloc_slice([Term::Variable(event_var), pp_obj_term]),
8896 world: None,
8897 });
8898
8899 let with_pp = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
8900 left: neo_event,
8901 op: TokenType::And,
8902 right: pp_pred,
8903 });
8904
8905 let focused_ref = self.ctx.terms.alloc(pp_obj_term);
8906 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8907 kind: focus_kind,
8908 focused: focused_ref,
8909 scope: with_pp,
8910 }));
8911 }
8912
8913 let focused_np = self.parse_noun_phrase(false)?;
8914 let focused_term = self.noun_phrase_to_term(&focused_np);
8915 args.push(focused_term.clone());
8916
8917 let roles = vec![
8918 (ThematicRole::Agent, subject_term_for_event),
8919 (ThematicRole::Theme, focused_term.clone()),
8920 ];
8921
8922 let suppress_existential = self.drs.in_conditional_antecedent();
8923 if suppress_existential {
8924 let event_class = self.interner.intern("Event");
8925 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
8926 }
8927 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
8928 event_var,
8929 verb,
8930 roles: self.ctx.roles.alloc_slice(roles),
8931 modifiers: self.ctx.syms.alloc_slice(modifiers),
8932 suppress_existential,
8933 world: None,
8934 })));
8935
8936 let focused_ref = self.ctx.terms.alloc(focused_term);
8937 return Ok(self.ctx.exprs.alloc(LogicExpr::Focus {
8938 kind: focus_kind,
8939 focused: focused_ref,
8940 scope: neo_event,
8941 }));
8942 } else if self.check_number() {
8943 let measure = self.parse_measure_phrase()?;
8945
8946 if self.check_content_word() {
8948 let noun_sym = self.consume_content_word()?;
8949 let count_term = *measure;
8951 object_term = Some(count_term.clone());
8952 args.push(count_term);
8953 second_object_term = Some(Term::Constant(noun_sym));
8954 args.push(Term::Constant(noun_sym));
8955 } else {
8956 object_term = Some(*measure);
8958 args.push(*measure);
8959 }
8960 } else if self.check_content_word() || self.check_article() {
8961 let object = self.parse_noun_phrase(false)?;
8962 if let Some(adj) = object.superlative {
8963 object_superlative = Some((adj, object.noun));
8964 }
8965
8966 let mut all_objects: Vec<Symbol> = vec![object.noun];
8968
8969 while self.check(&TokenType::And) {
8971 let saved = self.current;
8972 self.advance(); if self.check_content_word() || self.check_article() {
8974 let next_obj = match self.parse_noun_phrase(false) {
8975 Ok(np) => np,
8976 Err(_) => {
8977 self.current = saved;
8978 break;
8979 }
8980 };
8981 all_objects.push(next_obj.noun);
8982 } else {
8983 self.current = saved;
8984 break;
8985 }
8986 }
8987
8988 if self.check(&TokenType::Respectively) {
8990 let respectively_span = self.peek().span;
8991 if all_objects.len() > 1 {
8993 return Err(ParseError {
8994 kind: ParseErrorKind::RespectivelyLengthMismatch {
8995 subject_count: 1,
8996 object_count: all_objects.len(),
8997 },
8998 span: respectively_span,
8999 });
9000 }
9001 self.advance(); }
9004
9005 let term = self.noun_phrase_to_term(&object);
9007 object_term = Some(term.clone());
9008 args.push(term.clone());
9009
9010 if all_objects.len() > 1 {
9012 let obj_members: Vec<Term<'a>> = all_objects.iter()
9013 .map(|o| Term::Constant(*o))
9014 .collect();
9015 let obj_group = Term::Group(self.ctx.terms.alloc_slice(obj_members));
9016 args.pop();
9018 args.push(obj_group);
9019 }
9020
9021 if let TokenType::Particle(particle_sym) = self.peek().kind {
9023 let verb_str = self.interner.resolve(verb).to_lowercase();
9024 let particle_str = self.interner.resolve(particle_sym).to_lowercase();
9025 if let Some((phrasal_lemma, _class)) = crate::lexicon::lookup_phrasal_verb(&verb_str, &particle_str) {
9026 self.advance(); verb = self.interner.intern(phrasal_lemma);
9028 }
9029 }
9030
9031 if self.check_number() {
9033 let measure = self.parse_measure_phrase()?;
9034 second_object_term = Some(*measure);
9035 args.push(*measure);
9036 }
9037 else {
9039 let verb_str = self.interner.resolve(verb);
9040 if Lexer::is_ditransitive_verb(verb_str) && (self.check_content_word() || self.check_article()) {
9041 let second_np = self.parse_noun_phrase(false)?;
9042 let second_term = self.noun_phrase_to_term(&second_np);
9043 second_object_term = Some(second_term.clone());
9044 args.push(second_term);
9045 }
9046 }
9047 }
9048
9049 let mut pp_predicates: Vec<&'a LogicExpr<'a>> = Vec::new();
9050 while self.check_preposition() || self.check_to() {
9051 if self.check_preposition_is("within") && self.current + 1 < self.tokens.len()
9053 && matches!(self.tokens[self.current + 1].kind, TokenType::Cardinal(_) | TokenType::Number(_))
9054 {
9055 break;
9056 }
9057 let prep_token = self.advance().clone();
9058 let prep_name = if let TokenType::Preposition(sym) = prep_token.kind {
9059 sym
9060 } else if matches!(prep_token.kind, TokenType::To) {
9061 self.interner.intern("To")
9062 } else {
9063 continue;
9064 };
9065
9066 let pp_obj_term = if self.check(&TokenType::Reflexive) {
9067 self.advance();
9068 self.noun_phrase_to_term(&subject)
9069 } else if self.check_pronoun() {
9070 let token = self.advance().clone();
9071 if let TokenType::Pronoun { gender, number, .. } = token.kind {
9072 let resolved = self.resolve_pronoun(gender, number)?;
9073 match resolved {
9074 ResolvedPronoun::Variable(s) => Term::Variable(s),
9075 ResolvedPronoun::Constant(s) => Term::Constant(s),
9076 }
9077 } else {
9078 continue;
9079 }
9080 } else if self.check_content_word() || self.check_article() {
9081 let prep_obj = self.parse_noun_phrase(false)?;
9082 self.noun_phrase_to_term(&prep_obj)
9083 } else {
9084 continue;
9085 };
9086
9087 if self.pp_attach_to_noun {
9088 if let Some(ref obj) = object_term {
9089 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9091 name: prep_name,
9092 args: self.ctx.terms.alloc_slice([obj.clone(), pp_obj_term]),
9093 world: None,
9094 });
9095 pp_predicates.push(pp_pred);
9096 } else {
9097 args.push(pp_obj_term);
9098 }
9099 } else {
9100 let event_sym = self.get_event_var();
9102 let pp_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9103 name: prep_name,
9104 args: self.ctx.terms.alloc_slice([Term::Variable(event_sym), pp_obj_term]),
9105 world: None,
9106 });
9107 pp_predicates.push(pp_pred);
9108 }
9109 }
9110
9111 if self.check(&TokenType::That) || self.check(&TokenType::Who) {
9113 self.advance();
9114 let rel_var = self.next_var_name();
9115 let rel_pred = self.parse_relative_clause(rel_var)?;
9116 pp_predicates.push(rel_pred);
9117 }
9118
9119 let mut modifiers = self.collect_adverbs();
9121
9122 let effective_time = self.pending_time.take().unwrap_or(verb_time);
9124 match effective_time {
9125 Time::Past => modifiers.push(self.interner.intern("Past")),
9126 Time::Future => modifiers.push(self.interner.intern("Future")),
9127 _ => {}
9128 }
9129
9130 if verb_aspect == Aspect::Progressive {
9132 modifiers.push(self.interner.intern("Progressive"));
9133 } else if verb_aspect == Aspect::Perfect {
9134 modifiers.push(self.interner.intern("Perfect"));
9135 }
9136
9137 let mut roles: Vec<(ThematicRole, Term<'a>)> = Vec::new();
9139
9140 let verb_str_for_check = self.interner.resolve(verb).to_lowercase();
9142 let is_unaccusative = crate::lexicon::lookup_verb_db(&verb_str_for_check)
9143 .map(|meta| meta.features.contains(&crate::lexicon::Feature::Unaccusative))
9144 .unwrap_or(false);
9145
9146 let has_object = object_term.is_some() || second_object_term.is_some();
9148 let subject_role = if is_unaccusative && !has_object {
9149 ThematicRole::Theme
9150 } else {
9151 ThematicRole::Agent
9152 };
9153
9154 roles.push((subject_role, subject_term));
9155 if let Some(second_obj) = second_object_term {
9156 if let Some(first_obj) = object_term {
9158 roles.push((ThematicRole::Recipient, first_obj));
9159 }
9160 roles.push((ThematicRole::Theme, second_obj));
9161 } else if let Some(obj) = object_term {
9162 roles.push((ThematicRole::Theme, obj));
9164 }
9165
9166 let event_var = self.get_event_var();
9168
9169 self.capture_event_template(verb, &roles, &modifiers);
9171
9172 let suppress_existential = self.drs.in_conditional_antecedent();
9174 if suppress_existential {
9175 let event_class = self.interner.intern("Event");
9176 self.drs.introduce_referent(event_var, event_class, Gender::Neuter, Number::Singular);
9177 }
9178 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
9179 event_var,
9180 verb,
9181 roles: self.ctx.roles.alloc_slice(roles),
9182 modifiers: self.ctx.syms.alloc_slice(modifiers),
9183 suppress_existential,
9184 world: None,
9185 })));
9186
9187 let with_pps = if pp_predicates.is_empty() {
9189 neo_event
9190 } else {
9191 let mut combined = neo_event;
9192 for pp in pp_predicates {
9193 combined = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9194 left: combined,
9195 op: TokenType::And,
9196 right: pp,
9197 });
9198 }
9199 combined
9200 };
9201
9202 let with_aspect = if verb_aspect == Aspect::Progressive {
9204 if verb_class == crate::lexicon::VerbClass::Semelfactive {
9206 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9207 operator: AspectOperator::Iterative,
9208 body: with_pps,
9209 })
9210 } else {
9211 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9213 operator: AspectOperator::Progressive,
9214 body: with_pps,
9215 })
9216 }
9217 } else if verb_aspect == Aspect::Perfect {
9218 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9219 operator: AspectOperator::Perfect,
9220 body: with_pps,
9221 })
9222 } else if effective_time == Time::Present && verb_aspect == Aspect::Simple {
9223 if !verb_class.is_stative() {
9225 self.ctx.exprs.alloc(LogicExpr::Aspectual {
9226 operator: AspectOperator::Habitual,
9227 body: with_pps,
9228 })
9229 } else {
9230 with_pps
9232 }
9233 } else {
9234 with_pps
9235 };
9236
9237 let with_adverbs = with_aspect;
9238
9239 let with_temporal = if self.check_temporal_adverb() {
9241 let anchor = if let TokenType::TemporalAdverb(adv) = self.advance().kind.clone() {
9242 adv
9243 } else {
9244 panic!("Expected temporal adverb");
9245 };
9246 self.ctx.exprs.alloc(LogicExpr::TemporalAnchor {
9247 anchor,
9248 body: with_adverbs,
9249 })
9250 } else {
9251 with_adverbs
9252 };
9253
9254 let wrapped = self.wrap_with_definiteness_full(&subject, with_temporal)?;
9255
9256 if let Some((adj, noun)) = object_superlative {
9258 let superlative_expr = self.ctx.exprs.alloc(LogicExpr::Superlative {
9259 adjective: adj,
9260 subject: self.ctx.terms.alloc(Term::Constant(noun)),
9261 domain: noun,
9262 });
9263 return Ok(self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9264 left: wrapped,
9265 op: TokenType::And,
9266 right: superlative_expr,
9267 }));
9268 }
9269
9270 return Ok(wrapped);
9271 }
9272
9273 Ok(self.ctx.exprs.alloc(LogicExpr::Atom(subject.noun)))
9274 }
9275
9276 fn check_preposition(&self) -> bool {
9277 matches!(self.peek().kind, TokenType::Preposition(_))
9278 }
9279
9280 fn check_by_preposition(&self) -> bool {
9281 if let TokenType::Preposition(p) = self.peek().kind {
9282 p.is(self.interner, "by")
9283 } else {
9284 false
9285 }
9286 }
9287
9288 fn check_preposition_is(&self, word: &str) -> bool {
9289 if let TokenType::Preposition(p) = self.peek().kind {
9290 p.is(self.interner, word)
9291 } else {
9292 false
9293 }
9294 }
9295
9296 fn check_word(&self, word: &str) -> bool {
9298 let token = self.peek();
9299 let lexeme = self.interner.resolve(token.lexeme);
9300 lexeme.eq_ignore_ascii_case(word)
9301 }
9302
9303 fn peek_word_at(&self, offset: usize, word: &str) -> bool {
9304 if self.current + offset >= self.tokens.len() {
9305 return false;
9306 }
9307 let token = &self.tokens[self.current + offset];
9308 let lexeme = self.interner.resolve(token.lexeme);
9309 lexeme.eq_ignore_ascii_case(word)
9310 }
9311
9312 fn check_to_preposition(&self) -> bool {
9313 match self.peek().kind {
9314 TokenType::To => true,
9315 TokenType::Preposition(p) => p.is(self.interner, "to"),
9316 _ => false,
9317 }
9318 }
9319
9320 fn check_content_word(&self) -> bool {
9321 match &self.peek().kind {
9322 TokenType::Noun(_)
9323 | TokenType::Adjective(_)
9324 | TokenType::NonIntersectiveAdjective(_)
9325 | TokenType::Verb { .. }
9326 | TokenType::ProperName(_)
9327 | TokenType::Article(_)
9328 | TokenType::Performative(_) => true,
9329 TokenType::Ambiguous { primary, alternatives } => {
9330 Self::is_content_word_type(primary)
9331 || alternatives.iter().any(Self::is_content_word_type)
9332 }
9333 _ => false,
9334 }
9335 }
9336
9337 fn is_content_word_type(t: &TokenType) -> bool {
9338 matches!(
9339 t,
9340 TokenType::Noun(_)
9341 | TokenType::Adjective(_)
9342 | TokenType::NonIntersectiveAdjective(_)
9343 | TokenType::Verb { .. }
9344 | TokenType::ProperName(_)
9345 | TokenType::Article(_)
9346 | TokenType::Performative(_)
9347 )
9348 }
9349
9350 pub(super) fn try_wrap_bounded_delay(&mut self, expr: &'a LogicExpr<'a>) -> &'a LogicExpr<'a> {
9352 if !self.check_preposition_is("within") {
9353 return expr;
9354 }
9355 let has_number = if self.current + 1 < self.tokens.len() {
9356 matches!(self.tokens[self.current + 1].kind, TokenType::Cardinal(_) | TokenType::Number(_))
9357 } else {
9358 false
9359 };
9360 if !has_number {
9361 return expr;
9362 }
9363 self.advance(); let bound = match self.advance().kind {
9365 TokenType::Cardinal(n) => n,
9366 TokenType::Number(sym) => {
9367 let n_str = self.interner.resolve(sym);
9368 n_str.parse::<u32>().unwrap_or(1)
9369 }
9370 _ => 1,
9371 };
9372 if self.check_content_word() {
9374 let word = self.interner.resolve(self.peek().lexeme).to_lowercase();
9375 if word == "cycle" || word == "cycles" {
9376 self.advance();
9377 }
9378 }
9379 self.ctx.exprs.alloc(LogicExpr::Temporal {
9380 operator: TemporalOperator::BoundedEventually(bound),
9381 body: expr,
9382 })
9383 }
9384
9385 fn check_verb(&self) -> bool {
9386 match &self.peek().kind {
9387 TokenType::Verb { .. } => true,
9388 TokenType::Ambiguous { primary, alternatives } => {
9389 if self.noun_priority_mode {
9390 return false;
9391 }
9392 matches!(**primary, TokenType::Verb { .. })
9393 || alternatives.iter().any(|t| matches!(t, TokenType::Verb { .. }))
9394 }
9395 _ => false,
9396 }
9397 }
9398
9399 fn check_adverb(&self) -> bool {
9400 matches!(self.peek().kind, TokenType::Adverb(_))
9401 }
9402
9403 fn check_performative(&self) -> bool {
9404 matches!(self.peek().kind, TokenType::Performative(_))
9405 }
9406
9407 fn collect_adverbs(&mut self) -> Vec<Symbol> {
9408 let mut adverbs = Vec::new();
9409 while self.check_adverb() {
9410 if let TokenType::Adverb(adv) = self.advance().kind.clone() {
9411 adverbs.push(adv);
9412 }
9413 if self.check(&TokenType::And) {
9415 self.advance();
9416 }
9417 }
9418 adverbs
9419 }
9420
9421 fn check_auxiliary(&self) -> bool {
9422 matches!(self.peek().kind, TokenType::Auxiliary(_))
9423 }
9424
9425 fn is_true_auxiliary_usage(&self) -> bool {
9432 if self.current + 1 >= self.tokens.len() {
9433 return false;
9434 }
9435
9436 let next_token = &self.tokens[self.current + 1].kind;
9437
9438 if matches!(next_token, TokenType::Not) {
9440 return true;
9441 }
9442
9443 if matches!(next_token, TokenType::Verb { .. }) {
9445 return true;
9446 }
9447
9448 if matches!(
9450 next_token,
9451 TokenType::Pronoun { .. }
9452 | TokenType::Article(_)
9453 | TokenType::Noun(_)
9454 | TokenType::ProperName(_)
9455 ) {
9456 return false;
9457 }
9458
9459 true
9461 }
9462
9463 fn check_auxiliary_as_main_verb(&self) -> bool {
9466 if let TokenType::Auxiliary(Time::Past) = self.peek().kind {
9467 if self.current + 1 < self.tokens.len() {
9469 let next = &self.tokens[self.current + 1].kind;
9470 matches!(
9471 next,
9472 TokenType::Pronoun { .. }
9473 | TokenType::Article(_)
9474 | TokenType::Noun(_)
9475 | TokenType::ProperName(_)
9476 )
9477 } else {
9478 false
9479 }
9480 } else {
9481 false
9482 }
9483 }
9484
9485 fn parse_do_as_main_verb(&mut self, subject_term: Term<'a>) -> ParseResult<&'a LogicExpr<'a>> {
9488 let aux_token = self.advance();
9490 let verb_time = if let TokenType::Auxiliary(time) = aux_token.kind {
9491 time
9492 } else {
9493 Time::Past
9494 };
9495
9496 let verb = self.interner.intern("Do");
9498
9499 let object_term = if let TokenType::Pronoun { .. } = self.peek().kind {
9501 self.advance();
9503 let it_sym = self.interner.intern("it");
9506 Term::Constant(it_sym)
9507 } else {
9508 let object = self.parse_noun_phrase(false)?;
9509 self.noun_phrase_to_term(&object)
9510 };
9511
9512 let event_var = self.get_event_var();
9514 let suppress_existential = self.drs.in_conditional_antecedent();
9515
9516 let mut modifiers = Vec::new();
9517 if verb_time == Time::Past {
9518 modifiers.push(self.interner.intern("Past"));
9519 } else if verb_time == Time::Future {
9520 modifiers.push(self.interner.intern("Future"));
9521 }
9522
9523 let neo_event = self.ctx.exprs.alloc(LogicExpr::NeoEvent(Box::new(NeoEventData {
9524 event_var,
9525 verb,
9526 roles: self.ctx.roles.alloc_slice(vec![
9527 (ThematicRole::Agent, subject_term),
9528 (ThematicRole::Theme, object_term),
9529 ]),
9530 modifiers: self.ctx.syms.alloc_slice(modifiers),
9531 suppress_existential,
9532 world: None,
9533 })));
9534
9535 Ok(neo_event)
9536 }
9537
9538 fn check_to(&self) -> bool {
9539 matches!(self.peek().kind, TokenType::To)
9540 }
9541
9542 fn has_modal_subordination_ahead(&self) -> bool {
9546 for i in self.current..self.tokens.len() {
9549 match &self.tokens[i].kind {
9550 TokenType::Would | TokenType::Could | TokenType::Should | TokenType::Might => {
9551 return true;
9552 }
9553 TokenType::Period | TokenType::EOF => break,
9555 _ => {}
9556 }
9557 }
9558 false
9559 }
9560
9561 fn consume_verb(&mut self) -> Symbol {
9562 let t = self.advance().clone();
9563 match t.kind {
9564 TokenType::Verb { lemma, .. } => lemma,
9565 TokenType::Ambiguous { primary, .. } => match *primary {
9566 TokenType::Verb { lemma, .. } => lemma,
9567 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
9568 },
9569 _ => panic!("Expected verb, got {:?}", t.kind),
9570 }
9571 }
9572
9573 fn consume_verb_with_metadata(&mut self) -> (Symbol, Time, Aspect, VerbClass) {
9574 let t = self.advance().clone();
9575 match t.kind {
9576 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
9577 TokenType::Ambiguous { primary, .. } => match *primary {
9578 TokenType::Verb { lemma, time, aspect, class } => (lemma, time, aspect, class),
9579 _ => panic!("Expected verb in Ambiguous primary, got {:?}", primary),
9580 },
9581 _ => panic!("Expected verb, got {:?}", t.kind),
9582 }
9583 }
9584
9585 fn match_token(&mut self, types: &[TokenType]) -> bool {
9586 for t in types {
9587 if self.check(t) {
9588 self.advance();
9589 return true;
9590 }
9591 }
9592 false
9593 }
9594
9595 fn check_quantifier(&self) -> bool {
9596 matches!(
9597 self.peek().kind,
9598 TokenType::All
9599 | TokenType::No
9600 | TokenType::Some
9601 | TokenType::Any
9602 | TokenType::Most
9603 | TokenType::Few
9604 | TokenType::Many
9605 | TokenType::Cardinal(_)
9606 | TokenType::AtLeast(_)
9607 | TokenType::AtMost(_)
9608 )
9609 }
9610
9611 fn check_npi_quantifier(&self) -> bool {
9612 matches!(
9613 self.peek().kind,
9614 TokenType::Nobody | TokenType::Nothing | TokenType::NoOne
9615 )
9616 }
9617
9618 fn check_npi_object(&self) -> bool {
9619 matches!(
9620 self.peek().kind,
9621 TokenType::Anything | TokenType::Anyone
9622 )
9623 }
9624
9625 fn check_temporal_npi(&self) -> bool {
9626 matches!(
9627 self.peek().kind,
9628 TokenType::Ever | TokenType::Never
9629 )
9630 }
9631
9632 fn parse_npi_quantified(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9633 let npi_token = self.advance().kind.clone();
9634 let var_name = self.next_var_name();
9635
9636 let (restriction_name, is_person) = match npi_token {
9637 TokenType::Nobody | TokenType::NoOne => ("Person", true),
9638 TokenType::Nothing => ("Thing", false),
9639 _ => ("Thing", false),
9640 };
9641
9642 let restriction_sym = self.interner.intern(restriction_name);
9643 let subject_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9644 name: restriction_sym,
9645 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9646 world: None,
9647 });
9648
9649 self.negative_depth += 1;
9650
9651 let verb = self.consume_verb();
9652
9653 if self.check_npi_object() {
9654 let obj_npi_token = self.advance().kind.clone();
9655 let obj_var = self.next_var_name();
9656
9657 let obj_restriction_name = match obj_npi_token {
9658 TokenType::Anything => "Thing",
9659 TokenType::Anyone => "Person",
9660 _ => "Thing",
9661 };
9662
9663 let obj_restriction_sym = self.interner.intern(obj_restriction_name);
9664 let obj_restriction = self.ctx.exprs.alloc(LogicExpr::Predicate {
9665 name: obj_restriction_sym,
9666 args: self.ctx.terms.alloc_slice([Term::Variable(obj_var)]),
9667 world: None,
9668 });
9669
9670 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9671 name: verb,
9672 args: self.ctx.terms.alloc_slice([Term::Variable(var_name), Term::Variable(obj_var)]),
9673 world: None,
9674 });
9675
9676 let verb_and_obj = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9677 left: obj_restriction,
9678 op: TokenType::And,
9679 right: verb_pred,
9680 });
9681
9682 let inner_existential = self.ctx.exprs.alloc(LogicExpr::Quantifier {
9683 kind: crate::ast::QuantifierKind::Existential,
9684 variable: obj_var,
9685 body: verb_and_obj,
9686 island_id: self.current_island,
9687 });
9688
9689 self.negative_depth -= 1;
9690
9691 let negated = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9692 op: TokenType::Not,
9693 operand: inner_existential,
9694 });
9695
9696 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9697 left: subject_pred,
9698 op: TokenType::Implies,
9699 right: negated,
9700 });
9701
9702 return Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9703 kind: crate::ast::QuantifierKind::Universal,
9704 variable: var_name,
9705 body,
9706 island_id: self.current_island,
9707 }));
9708 }
9709
9710 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9711 name: verb,
9712 args: self.ctx.terms.alloc_slice([Term::Variable(var_name)]),
9713 world: None,
9714 });
9715
9716 self.negative_depth -= 1;
9717
9718 let negated_verb = self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9719 op: TokenType::Not,
9720 operand: verb_pred,
9721 });
9722
9723 let body = self.ctx.exprs.alloc(LogicExpr::BinaryOp {
9724 left: subject_pred,
9725 op: TokenType::Implies,
9726 right: negated_verb,
9727 });
9728
9729 Ok(self.ctx.exprs.alloc(LogicExpr::Quantifier {
9730 kind: crate::ast::QuantifierKind::Universal,
9731 variable: var_name,
9732 body,
9733 island_id: self.current_island,
9734 }))
9735 }
9736
9737 fn parse_temporal_npi(&mut self) -> ParseResult<&'a LogicExpr<'a>> {
9738 let npi_token = self.advance().kind.clone();
9739 let is_never = matches!(npi_token, TokenType::Never);
9740
9741 let subject = self.parse_noun_phrase(true)?;
9742
9743 if is_never {
9744 self.negative_depth += 1;
9745 }
9746
9747 let verb = self.consume_verb();
9748 let verb_pred = self.ctx.exprs.alloc(LogicExpr::Predicate {
9749 name: verb,
9750 args: self.ctx.terms.alloc_slice([Term::Constant(subject.noun)]),
9751 world: None,
9752 });
9753
9754 if is_never {
9755 self.negative_depth -= 1;
9756 Ok(self.ctx.exprs.alloc(LogicExpr::UnaryOp {
9757 op: TokenType::Not,
9758 operand: verb_pred,
9759 }))
9760 } else {
9761 Ok(verb_pred)
9762 }
9763 }
9764
9765 fn check(&self, kind: &TokenType) -> bool {
9766 if self.is_at_end() {
9767 return false;
9768 }
9769 std::mem::discriminant(&self.peek().kind) == std::mem::discriminant(kind)
9770 }
9771
9772 fn check_any(&self, kinds: &[TokenType]) -> bool {
9773 if self.is_at_end() {
9774 return false;
9775 }
9776 let current = std::mem::discriminant(&self.peek().kind);
9777 kinds.iter().any(|k| std::mem::discriminant(k) == current)
9778 }
9779
9780 fn check_article(&self) -> bool {
9781 matches!(self.peek().kind, TokenType::Article(_))
9782 }
9783
9784 fn advance(&mut self) -> &Token {
9785 if !self.is_at_end() {
9786 self.current += 1;
9787 }
9788 self.previous()
9789 }
9790
9791 fn is_at_end(&self) -> bool {
9792 self.peek().kind == TokenType::EOF
9793 }
9794
9795 fn peek(&self) -> &Token {
9796 &self.tokens[self.current]
9797 }
9798
9799 fn peek_next_is_string_literal(&self) -> bool {
9802 self.tokens.get(self.current + 1)
9803 .map(|t| matches!(t.kind, TokenType::StringLiteral(_)))
9804 .unwrap_or(false)
9805 }
9806
9807 fn previous(&self) -> &Token {
9808 &self.tokens[self.current - 1]
9809 }
9810
9811 fn current_span(&self) -> crate::token::Span {
9812 self.peek().span
9813 }
9814
9815 fn consume(&mut self, kind: TokenType) -> ParseResult<&Token> {
9816 if self.check(&kind) {
9817 Ok(self.advance())
9818 } else {
9819 Err(ParseError {
9820 kind: ParseErrorKind::UnexpectedToken {
9821 expected: kind,
9822 found: self.peek().kind.clone(),
9823 },
9824 span: self.current_span(),
9825 })
9826 }
9827 }
9828
9829 fn consume_content_word(&mut self) -> ParseResult<Symbol> {
9830 let t = self.advance().clone();
9831 match t.kind {
9832 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9833 TokenType::Article(_) => Ok(t.lexeme),
9835 TokenType::Number(s) => Ok(s),
9837 TokenType::ProperName(s) => {
9838 if self.mode == ParserMode::Imperative {
9840 if !self.drs.has_referent_by_variable(s) {
9841 return Err(ParseError {
9842 kind: ParseErrorKind::UndefinedVariable {
9843 name: self.interner.resolve(s).to_string()
9844 },
9845 span: t.span,
9846 });
9847 }
9848 return Ok(s);
9849 }
9850
9851 let s_str = self.interner.resolve(s);
9853 let gender = Self::infer_gender(s_str);
9854
9855 self.drs.introduce_proper_name(s, s, gender);
9857
9858 Ok(s)
9859 }
9860 TokenType::Verb { lemma, .. } => Ok(lemma),
9861 TokenType::Performative(s) => Ok(s),
9862 TokenType::Ambiguous { primary, .. } => {
9863 match *primary {
9864 TokenType::Noun(s) | TokenType::Adjective(s) | TokenType::NonIntersectiveAdjective(s) => Ok(s),
9865 TokenType::Verb { lemma, .. } => Ok(lemma),
9866 TokenType::Performative(s) => Ok(s),
9867 TokenType::ProperName(s) => {
9868 if self.mode == ParserMode::Imperative {
9870 if !self.drs.has_referent_by_variable(s) {
9871 return Err(ParseError {
9872 kind: ParseErrorKind::UndefinedVariable {
9873 name: self.interner.resolve(s).to_string()
9874 },
9875 span: t.span,
9876 });
9877 }
9878 return Ok(s);
9879 }
9880 let s_str = self.interner.resolve(s);
9882 let gender = Self::infer_gender(s_str);
9883 self.drs.introduce_proper_name(s, s, gender);
9884 Ok(s)
9885 }
9886 _ => Err(ParseError {
9887 kind: ParseErrorKind::ExpectedContentWord { found: *primary },
9888 span: self.current_span(),
9889 }),
9890 }
9891 }
9892 other => Err(ParseError {
9893 kind: ParseErrorKind::ExpectedContentWord { found: other },
9894 span: self.current_span(),
9895 }),
9896 }
9897 }
9898
9899 fn consume_copula(&mut self) -> ParseResult<()> {
9900 if self.match_token(&[TokenType::Is, TokenType::Are, TokenType::Was, TokenType::Were]) {
9901 Ok(())
9902 } else {
9903 Err(ParseError {
9904 kind: ParseErrorKind::ExpectedCopula,
9905 span: self.current_span(),
9906 })
9907 }
9908 }
9909
9910 fn check_comparative(&self) -> bool {
9911 matches!(self.peek().kind, TokenType::Comparative(_))
9912 }
9913
9914 fn is_contact_clause_pattern(&self) -> bool {
9915 let mut pos = self.current;
9918
9919 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Article(_)) {
9921 pos += 1;
9922 } else {
9923 return false;
9924 }
9925
9926 while pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Adjective(_)) {
9928 pos += 1;
9929 }
9930
9931 if pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Noun(_) | TokenType::ProperName(_) | TokenType::Adjective(_)) {
9933 pos += 1;
9934 } else {
9935 return false;
9936 }
9937
9938 pos < self.tokens.len() && matches!(self.tokens[pos].kind, TokenType::Verb { .. } | TokenType::Article(_))
9940 }
9941
9942 fn check_superlative(&self) -> bool {
9943 matches!(self.peek().kind, TokenType::Superlative(_))
9944 }
9945
9946 fn check_scopal_adverb(&self) -> bool {
9947 matches!(self.peek().kind, TokenType::ScopalAdverb(_))
9948 }
9949
9950 fn check_temporal_adverb(&self) -> bool {
9951 matches!(self.peek().kind, TokenType::TemporalAdverb(_))
9952 }
9953
9954 fn check_non_intersective_adjective(&self) -> bool {
9955 matches!(self.peek().kind, TokenType::NonIntersectiveAdjective(_))
9956 }
9957
9958 fn check_focus(&self) -> bool {
9959 matches!(self.peek().kind, TokenType::Focus(_))
9960 }
9961
9962 fn check_measure(&self) -> bool {
9963 matches!(self.peek().kind, TokenType::Measure(_))
9964 }
9965
9966 fn check_presup_trigger(&self) -> bool {
9967 match &self.peek().kind {
9968 TokenType::PresupTrigger(_) => true,
9969 TokenType::Verb { lemma, .. } => {
9970 let s = self.interner.resolve(*lemma).to_lowercase();
9971 crate::lexicon::lookup_presup_trigger(&s).is_some()
9972 }
9973 _ => false,
9974 }
9975 }
9976
9977 fn is_followed_by_np_object(&self) -> bool {
9978 if self.current + 1 >= self.tokens.len() {
9979 return false;
9980 }
9981 let next = &self.tokens[self.current + 1].kind;
9982 matches!(next,
9983 TokenType::ProperName(_) |
9984 TokenType::Article(_) |
9985 TokenType::Noun(_) |
9986 TokenType::Pronoun { .. } |
9987 TokenType::Reflexive |
9988 TokenType::Who |
9989 TokenType::What |
9990 TokenType::Where |
9991 TokenType::When |
9992 TokenType::Why
9993 )
9994 }
9995
9996 fn is_followed_by_gerund(&self) -> bool {
9997 if self.current + 1 >= self.tokens.len() {
9998 return false;
9999 }
10000 matches!(self.tokens[self.current + 1].kind, TokenType::Verb { .. })
10001 }
10002
10003 fn parse_spawn_statement(&mut self) -> ParseResult<Stmt<'a>> {
10009 self.advance(); if !self.check_article() {
10013 return Err(ParseError {
10014 kind: ParseErrorKind::ExpectedKeyword { keyword: "a/an".to_string() },
10015 span: self.current_span(),
10016 });
10017 }
10018 self.advance(); let agent_type = match &self.tokens[self.current].kind {
10022 TokenType::Noun(sym) | TokenType::ProperName(sym) => {
10023 let s = *sym;
10024 self.advance();
10025 s
10026 }
10027 _ => {
10028 return Err(ParseError {
10029 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent type".to_string() },
10030 span: self.current_span(),
10031 });
10032 }
10033 };
10034
10035 if !self.check(&TokenType::Called) {
10037 return Err(ParseError {
10038 kind: ParseErrorKind::ExpectedKeyword { keyword: "called".to_string() },
10039 span: self.current_span(),
10040 });
10041 }
10042 self.advance(); let name = if let TokenType::StringLiteral(sym) = &self.tokens[self.current].kind {
10046 let s = *sym;
10047 self.advance();
10048 s
10049 } else {
10050 return Err(ParseError {
10051 kind: ParseErrorKind::ExpectedKeyword { keyword: "agent name".to_string() },
10052 span: self.current_span(),
10053 });
10054 };
10055
10056 Ok(Stmt::Spawn { agent_type, name })
10057 }
10058
10059 fn parse_send_statement(&mut self) -> ParseResult<Stmt<'a>> {
10061 self.advance(); let message = self.parse_imperative_expr()?;
10065
10066 if !self.check_preposition_is("to") {
10068 return Err(ParseError {
10069 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
10070 span: self.current_span(),
10071 });
10072 }
10073 self.advance(); let destination = self.parse_imperative_expr()?;
10077
10078 Ok(Stmt::SendMessage { message, destination })
10079 }
10080
10081 fn parse_await_statement(&mut self) -> ParseResult<Stmt<'a>> {
10083 self.advance(); if self.check_word("response") {
10087 self.advance();
10088 }
10089
10090 if !self.check(&TokenType::From) && !self.check_preposition_is("from") {
10092 return Err(ParseError {
10093 kind: ParseErrorKind::ExpectedKeyword { keyword: "from".to_string() },
10094 span: self.current_span(),
10095 });
10096 }
10097 self.advance(); let source = self.parse_imperative_expr()?;
10101
10102 if !self.check_word("into") {
10104 return Err(ParseError {
10105 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
10106 span: self.current_span(),
10107 });
10108 }
10109 self.advance(); let into = match &self.tokens[self.current].kind {
10113 TokenType::Noun(sym) | TokenType::ProperName(sym) | TokenType::Adjective(sym) => {
10114 let s = *sym;
10115 self.advance();
10116 s
10117 }
10118 _ if self.check_content_word() => {
10120 let sym = self.tokens[self.current].lexeme;
10121 self.advance();
10122 sym
10123 }
10124 _ => {
10125 return Err(ParseError {
10126 kind: ParseErrorKind::ExpectedKeyword { keyword: "variable name".to_string() },
10127 span: self.current_span(),
10128 });
10129 }
10130 };
10131
10132 Ok(Stmt::AwaitMessage { source, into })
10133 }
10134
10135 fn parse_merge_statement(&mut self) -> ParseResult<Stmt<'a>> {
10141 self.advance(); let source = self.parse_imperative_expr()?;
10145
10146 if !self.check_word("into") {
10148 return Err(ParseError {
10149 kind: ParseErrorKind::ExpectedKeyword { keyword: "into".to_string() },
10150 span: self.current_span(),
10151 });
10152 }
10153 self.advance(); let target = self.parse_imperative_expr()?;
10157
10158 Ok(Stmt::MergeCrdt { source, target })
10159 }
10160
10161 fn parse_increase_statement(&mut self) -> ParseResult<Stmt<'a>> {
10163 self.advance(); let expr = self.parse_imperative_expr()?;
10167
10168 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
10170 (object, field)
10171 } else {
10172 return Err(ParseError {
10173 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
10174 span: self.current_span(),
10175 });
10176 };
10177
10178 if !self.check_preposition_is("by") {
10180 return Err(ParseError {
10181 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
10182 span: self.current_span(),
10183 });
10184 }
10185 self.advance(); let amount = self.parse_imperative_expr()?;
10189
10190 Ok(Stmt::IncreaseCrdt { object, field: *field, amount })
10191 }
10192
10193 fn parse_decrease_statement(&mut self) -> ParseResult<Stmt<'a>> {
10195 self.advance(); let expr = self.parse_imperative_expr()?;
10199
10200 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
10202 (object, field)
10203 } else {
10204 return Err(ParseError {
10205 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's count')".to_string() },
10206 span: self.current_span(),
10207 });
10208 };
10209
10210 if !self.check_preposition_is("by") {
10212 return Err(ParseError {
10213 kind: ParseErrorKind::ExpectedKeyword { keyword: "by".to_string() },
10214 span: self.current_span(),
10215 });
10216 }
10217 self.advance(); let amount = self.parse_imperative_expr()?;
10221
10222 Ok(Stmt::DecreaseCrdt { object, field: *field, amount })
10223 }
10224
10225 fn parse_append_statement(&mut self) -> ParseResult<Stmt<'a>> {
10227 self.advance(); let value = self.parse_imperative_expr()?;
10231
10232 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
10234 return Err(ParseError {
10235 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
10236 span: self.current_span(),
10237 });
10238 }
10239 self.advance(); let sequence = self.parse_imperative_expr()?;
10243
10244 Ok(Stmt::AppendToSequence { sequence, value })
10245 }
10246
10247 fn parse_resolve_statement(&mut self) -> ParseResult<Stmt<'a>> {
10249 self.advance(); let expr = self.parse_imperative_expr()?;
10253
10254 let (object, field) = if let Expr::FieldAccess { object, field } = expr {
10256 (object, field)
10257 } else {
10258 return Err(ParseError {
10259 kind: ParseErrorKind::ExpectedKeyword { keyword: "field access (e.g., 'x's title')".to_string() },
10260 span: self.current_span(),
10261 });
10262 };
10263
10264 if !self.check(&TokenType::To) && !self.check_preposition_is("to") {
10266 return Err(ParseError {
10267 kind: ParseErrorKind::ExpectedKeyword { keyword: "to".to_string() },
10268 span: self.current_span(),
10269 });
10270 }
10271 self.advance(); let value = self.parse_imperative_expr()?;
10275
10276 Ok(Stmt::ResolveConflict { object, field: *field, value })
10277 }
10278
10279}
10280