Files
storybook/src/syntax/ast.rs

287 lines
6.3 KiB
Rust
Raw Normal View History

/// 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<Declaration>,
}
/// 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<String>,
pub kind: UseKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum UseKind {
Single, // use foo::bar
Grouped(Vec<String>), // use foo::{bar, baz}
Wildcard, // use foo::*
}
/// Character definition
#[derive(Debug, Clone, PartialEq)]
pub struct Character {
pub name: String,
pub species: Option<String>, // `: Species` - what the character fundamentally is
pub fields: Vec<Field>,
pub template: Option<Vec<String>>, // `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<Field>,
pub strict: bool,
pub includes: Vec<String>,
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<Value>, Box<Value>), // For templates: 20..40
Time(Time),
Duration(Duration),
Identifier(Vec<String>), // Qualified path reference
List(Vec<Value>),
Object(Vec<Field>),
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<String>, // Template path
pub overrides: Vec<OverrideOp>,
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<ArcState>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ArcState {
pub name: String,
pub on_enter: Option<Vec<Field>>,
pub transitions: Vec<Transition>,
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<ScheduleBlock>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ScheduleBlock {
pub start: Time,
pub end: Time,
pub activity: String,
pub fields: Vec<Field>,
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<BehaviorNode>), // ? operator
Sequence(Vec<BehaviorNode>), // > operator (context-dependent)
Condition(Expr),
Action(String, Vec<Field>), // Action name + parameters
Decorator(String, Box<BehaviorNode>),
SubTree(Vec<String>), // Reference to another behavior
}
/// Institution definition
#[derive(Debug, Clone, PartialEq)]
pub struct Institution {
pub name: String,
pub fields: Vec<Field>,
pub span: Span,
}
/// Relationship definition
#[derive(Debug, Clone, PartialEq)]
pub struct Relationship {
pub name: String,
pub participants: Vec<Participant>,
pub fields: Vec<Field>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Participant {
pub role: Option<String>, // "as parent"
pub name: Vec<String>, // Qualified path
pub self_block: Option<Vec<Field>>,
pub other_block: Option<Vec<Field>>,
pub span: Span,
}
/// Location definition
#[derive(Debug, Clone, PartialEq)]
pub struct Location {
pub name: String,
pub fields: Vec<Field>,
pub span: Span,
}
/// Species definition
#[derive(Debug, Clone, PartialEq)]
pub struct Species {
pub name: String,
pub includes: Vec<String>,
pub fields: Vec<Field>,
pub span: Span,
}
/// Enum definition
#[derive(Debug, Clone, PartialEq)]
pub struct EnumDecl {
pub name: String,
pub variants: Vec<String>,
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<String>),
FieldAccess(Box<Expr>, String),
Comparison(Box<Expr>, CompOp, Box<Expr>),
Logical(Box<Expr>, LogicalOp, Box<Expr>),
Unary(UnaryOp, Box<Expr>),
Quantifier(QuantifierKind, String, Box<Expr>, Box<Expr>), /* 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,
}