/// Source location for error reporting #[derive(Debug, Clone, PartialEq)] pub struct Span { pub start: usize, pub end: usize, } impl Span { pub fn new(start: usize, end: usize) -> Self { Self { start, end } } } /// Top-level file containing multiple declarations #[derive(Debug, Clone, PartialEq)] pub struct File { pub declarations: Vec, } /// Any top-level declaration #[derive(Debug, Clone, PartialEq)] pub enum Declaration { Use(UseDecl), Character(Character), Template(Template), LifeArc(LifeArc), Schedule(Schedule), Behavior(Behavior), Institution(Institution), Relationship(Relationship), Location(Location), Species(Species), Enum(EnumDecl), } /// Use statement for importing definitions #[derive(Debug, Clone, PartialEq)] pub struct UseDecl { pub path: Vec, pub kind: UseKind, pub span: Span, } #[derive(Debug, Clone, PartialEq)] pub enum UseKind { Single, // use foo::bar Grouped(Vec), // use foo::{bar, baz} Wildcard, // use foo::* } /// Character definition #[derive(Debug, Clone, PartialEq)] pub struct Character { pub name: String, pub species: Option, // `: Species` - what the character fundamentally is pub fields: Vec, pub template: Option>, // `from Template1, Template2` pub span: Span, } /// Template definition (like Character but allows range values) #[derive(Debug, Clone, PartialEq)] pub struct Template { pub name: String, pub fields: Vec, pub strict: bool, pub includes: Vec, pub span: Span, } /// Field in a structured definition #[derive(Debug, Clone, PartialEq)] pub struct Field { pub name: String, pub value: Value, pub span: Span, } /// Field value types #[derive(Debug, Clone, PartialEq)] pub enum Value { Int(i64), Float(f64), String(String), Bool(bool), Range(Box, Box), // For templates: 20..40 Time(Time), Duration(Duration), Identifier(Vec), // Qualified path reference List(Vec), Object(Vec), ProseBlock(ProseBlock), Override(Override), } /// Time literal (HH:MM or HH:MM:SS) #[derive(Debug, Clone, PartialEq)] pub struct Time { pub hour: u8, pub minute: u8, pub second: u8, } /// Duration literal (e.g., 2h30m) #[derive(Debug, Clone, PartialEq)] pub struct Duration { pub hours: u32, pub minutes: u32, pub seconds: u32, } /// Prose block with tag #[derive(Debug, Clone, PartialEq)] pub struct ProseBlock { pub tag: String, pub content: String, pub span: Span, } /// Override specification for template instantiation #[derive(Debug, Clone, PartialEq)] pub struct Override { pub base: Vec, // Template path pub overrides: Vec, pub span: Span, } #[derive(Debug, Clone, PartialEq)] pub enum OverrideOp { Set(Field), // field: value Remove(String), // remove field Append(Field), // append field } /// Life arc state machine #[derive(Debug, Clone, PartialEq)] pub struct LifeArc { pub name: String, pub states: Vec, pub span: Span, } #[derive(Debug, Clone, PartialEq)] pub struct ArcState { pub name: String, pub on_enter: Option>, pub transitions: Vec, pub span: Span, } #[derive(Debug, Clone, PartialEq)] pub struct Transition { pub to: String, pub condition: Expr, pub span: Span, } /// Schedule definition #[derive(Debug, Clone, PartialEq)] pub struct Schedule { pub name: String, pub blocks: Vec, pub span: Span, } #[derive(Debug, Clone, PartialEq)] pub struct ScheduleBlock { pub start: Time, pub end: Time, pub activity: String, pub fields: Vec, pub span: Span, } /// Behavior tree definition #[derive(Debug, Clone, PartialEq)] pub struct Behavior { pub name: String, pub root: BehaviorNode, pub span: Span, } #[derive(Debug, Clone, PartialEq)] pub enum BehaviorNode { Selector(Vec), // ? operator Sequence(Vec), // > operator (context-dependent) Condition(Expr), Action(String, Vec), // Action name + parameters Decorator(String, Box), SubTree(Vec), // Reference to another behavior } /// Institution definition #[derive(Debug, Clone, PartialEq)] pub struct Institution { pub name: String, pub fields: Vec, pub span: Span, } /// Relationship definition #[derive(Debug, Clone, PartialEq)] pub struct Relationship { pub name: String, pub participants: Vec, pub fields: Vec, pub span: Span, } #[derive(Debug, Clone, PartialEq)] pub struct Participant { pub role: Option, // "as parent" pub name: Vec, // Qualified path pub self_block: Option>, pub other_block: Option>, pub span: Span, } /// Location definition #[derive(Debug, Clone, PartialEq)] pub struct Location { pub name: String, pub fields: Vec, pub span: Span, } /// Species definition #[derive(Debug, Clone, PartialEq)] pub struct Species { pub name: String, pub includes: Vec, pub fields: Vec, pub span: Span, } /// Enum definition #[derive(Debug, Clone, PartialEq)] pub struct EnumDecl { pub name: String, pub variants: Vec, pub span: Span, } /// Expression AST for conditions and queries #[derive(Debug, Clone, PartialEq)] pub enum Expr { IntLit(i64), FloatLit(f64), StringLit(String), BoolLit(bool), Identifier(Vec), FieldAccess(Box, String), Comparison(Box, CompOp, Box), Logical(Box, LogicalOp, Box), Unary(UnaryOp, Box), Quantifier(QuantifierKind, String, Box, Box), /* forall/exists x in collection: * predicate */ } #[derive(Debug, Clone, Copy, PartialEq)] pub enum CompOp { Eq, // == Ne, // != Lt, // < Le, // <= Gt, // > Ge, // >= } #[derive(Debug, Clone, Copy, PartialEq)] pub enum LogicalOp { And, Or, } #[derive(Debug, Clone, Copy, PartialEq)] pub enum UnaryOp { Not, Neg, } #[derive(Debug, Clone, Copy, PartialEq)] pub enum QuantifierKind { ForAll, Exists, }