feat: implement storybook DSL with template composition and validation
Add complete domain-specific language for authoring narrative content for agent simulations. Features: - Complete parser using LALRPOP + logos lexer - Template composition (includes + multiple inheritance) - Strict mode validation for templates - Reserved keyword protection - Semantic validators (trait ranges, schedule overlaps, life arcs, behaviors) - Name resolution and cross-reference tracking - CLI tool (validate, inspect, query commands) - Query API with filtering - 260 comprehensive tests (unit, integration, property-based) Implementation phases: - Phase 1 (Parser): Complete - Phase 2 (Resolution + Validation): Complete - Phase 3 (Public API + CLI): Complete BREAKING CHANGE: Initial implementation
This commit is contained in:
54
tests/examples/all_types.sb
Normal file
54
tests/examples/all_types.sb
Normal file
@@ -0,0 +1,54 @@
|
||||
// Test all static types
|
||||
|
||||
character Martha {
|
||||
age: 34
|
||||
name: "Martha Baker"
|
||||
}
|
||||
|
||||
template GenericPerson {
|
||||
age: 20..60
|
||||
energy: 0.5..1.0
|
||||
}
|
||||
|
||||
enum BondType {
|
||||
romantic,
|
||||
familial,
|
||||
friendship
|
||||
}
|
||||
|
||||
institution Bakery {
|
||||
name: "Martha's Bakery"
|
||||
address: downtown
|
||||
capacity: 10
|
||||
}
|
||||
|
||||
location Downtown {
|
||||
name: "Downtown District"
|
||||
population: 50000
|
||||
}
|
||||
|
||||
species Human {
|
||||
lifespan: 80
|
||||
intelligence: high
|
||||
}
|
||||
|
||||
schedule DailyRoutine {
|
||||
06:00 -> 07:00: wake_up
|
||||
07:00 -> 09:00: breakfast
|
||||
09:00 -> 17:00: work
|
||||
17:00 -> 18:00: dinner
|
||||
22:00 -> 06:00: sleep
|
||||
}
|
||||
|
||||
relationship Spousal {
|
||||
Martha
|
||||
David
|
||||
bond: 0.9
|
||||
relationship_type: romantic
|
||||
}
|
||||
|
||||
relationship ParentChild {
|
||||
Martha as parent
|
||||
Tommy as child
|
||||
bond: 1.0
|
||||
}
|
||||
50
tests/examples/behavior_and_lifearc.sb
Normal file
50
tests/examples/behavior_and_lifearc.sb
Normal file
@@ -0,0 +1,50 @@
|
||||
// Test behavior trees and life arcs
|
||||
|
||||
life_arc Childhood {
|
||||
state infant {
|
||||
on ready -> toddler
|
||||
}
|
||||
state toddler {
|
||||
on ready -> child
|
||||
}
|
||||
state child {
|
||||
on ready -> teen
|
||||
}
|
||||
}
|
||||
|
||||
behavior SimpleBehavior {
|
||||
walk_around
|
||||
}
|
||||
|
||||
behavior SequenceBehavior {
|
||||
> {
|
||||
check_energy
|
||||
move_to_location
|
||||
perform_action
|
||||
}
|
||||
}
|
||||
|
||||
behavior SelectorBehavior {
|
||||
? {
|
||||
try_option_a
|
||||
try_option_b
|
||||
fallback
|
||||
}
|
||||
}
|
||||
|
||||
behavior NestedBehavior {
|
||||
> {
|
||||
? {
|
||||
check_condition_a
|
||||
check_condition_b
|
||||
}
|
||||
perform_action
|
||||
}
|
||||
}
|
||||
|
||||
behavior WithSubtree {
|
||||
> {
|
||||
@helpers::check_preconditions
|
||||
main_action
|
||||
}
|
||||
}
|
||||
68
tests/examples/bidirectional_relationships.sb
Normal file
68
tests/examples/bidirectional_relationships.sb
Normal file
@@ -0,0 +1,68 @@
|
||||
// Test bidirectional relationship resolution
|
||||
// Relationships can be declared from either participant's perspective
|
||||
|
||||
// Simple relationship with no self/other blocks
|
||||
relationship Friendship {
|
||||
Alice
|
||||
Bob
|
||||
bond: 0.8
|
||||
years_known: 5
|
||||
}
|
||||
|
||||
// Relationship with roles
|
||||
relationship Marriage {
|
||||
Martha as spouse
|
||||
David as spouse
|
||||
bond: 0.9
|
||||
anniversary: "2015-06-20"
|
||||
}
|
||||
|
||||
// Relationship with self/other blocks from one perspective
|
||||
relationship ParentChild {
|
||||
Martha as parent self {
|
||||
responsibility: 1.0
|
||||
protective: 0.9
|
||||
} other {
|
||||
dependent: 0.8
|
||||
}
|
||||
Tommy as child
|
||||
}
|
||||
|
||||
// Asymmetric relationship - different roles
|
||||
relationship EmployerEmployee {
|
||||
Martha as employer self {
|
||||
authority: 0.9
|
||||
} other {
|
||||
respect: 0.8
|
||||
}
|
||||
Elena as employee
|
||||
}
|
||||
|
||||
// Complex relationship with shared and participant-specific fields
|
||||
relationship RomanticPartnership {
|
||||
Alice as partner self {
|
||||
love: 0.95
|
||||
trust: 0.9
|
||||
} other {
|
||||
attraction: 0.85
|
||||
respect: 0.95
|
||||
}
|
||||
Charlie as partner
|
||||
|
||||
// Shared fields
|
||||
commitment: 0.85
|
||||
compatibility: 0.9
|
||||
}
|
||||
|
||||
// Multiple relationships between same people with different names
|
||||
relationship Friendship2 {
|
||||
Alice
|
||||
Charlie
|
||||
bond: 0.7
|
||||
}
|
||||
|
||||
relationship Coworkers {
|
||||
Alice
|
||||
Charlie
|
||||
workplace: "TechCorp"
|
||||
}
|
||||
34
tests/examples/comparisons.sb
Normal file
34
tests/examples/comparisons.sb
Normal file
@@ -0,0 +1,34 @@
|
||||
// Test comparison expressions in life arcs
|
||||
|
||||
life_arc AgeProgression {
|
||||
state child {
|
||||
on age > 12 -> teen
|
||||
}
|
||||
state teen {
|
||||
on age >= 18 -> adult
|
||||
}
|
||||
state adult {
|
||||
on age > 65 -> senior
|
||||
}
|
||||
}
|
||||
|
||||
life_arc EnergyStates {
|
||||
state rested {
|
||||
on energy < 0.3 -> tired
|
||||
}
|
||||
state tired {
|
||||
on energy <= 0.1 -> exhausted
|
||||
}
|
||||
state exhausted {
|
||||
on energy >= 0.5 -> rested
|
||||
}
|
||||
}
|
||||
|
||||
life_arc HealthStates {
|
||||
state healthy {
|
||||
on health < 50 -> sick
|
||||
}
|
||||
state sick {
|
||||
on health >= 80 -> healthy
|
||||
}
|
||||
}
|
||||
40
tests/examples/equality.sb
Normal file
40
tests/examples/equality.sb
Normal file
@@ -0,0 +1,40 @@
|
||||
// Test equality expressions in life arcs
|
||||
|
||||
life_arc NameCheck {
|
||||
state checking {
|
||||
on name is "Alice" -> found_alice
|
||||
on name is "Bob" -> found_bob
|
||||
}
|
||||
state found_alice {
|
||||
on ready -> checking
|
||||
}
|
||||
state found_bob {
|
||||
on ready -> checking
|
||||
}
|
||||
}
|
||||
|
||||
life_arc StatusCheck {
|
||||
state monitoring {
|
||||
on status is active -> active_state
|
||||
on status is inactive -> inactive_state
|
||||
}
|
||||
state active_state {
|
||||
on status is inactive -> inactive_state
|
||||
}
|
||||
state inactive_state {
|
||||
on status is active -> active_state
|
||||
}
|
||||
}
|
||||
|
||||
life_arc FlagCheck {
|
||||
state idle {
|
||||
on completed is true -> done
|
||||
on completed is false -> working
|
||||
}
|
||||
state working {
|
||||
on completed is true -> done
|
||||
}
|
||||
state done {
|
||||
on completed is false -> working
|
||||
}
|
||||
}
|
||||
113
tests/examples/field_access.sb
Normal file
113
tests/examples/field_access.sb
Normal file
@@ -0,0 +1,113 @@
|
||||
// Test field access in relationship contexts
|
||||
|
||||
relationship Marriage {
|
||||
PersonA as spouse
|
||||
PersonB as spouse
|
||||
|
||||
self {
|
||||
bond: 0.8
|
||||
}
|
||||
other {
|
||||
bond: 0.8
|
||||
}
|
||||
}
|
||||
|
||||
life_arc RelationshipDynamics {
|
||||
state stable {
|
||||
// Field access with comparisons
|
||||
on self.bond < 0.3 -> troubled
|
||||
on other.bond < 0.3 -> troubled
|
||||
on self.bond > 0.9 and other.bond > 0.9 -> thriving
|
||||
}
|
||||
|
||||
state troubled {
|
||||
on self.bond > 0.7 and other.bond > 0.7 -> stable
|
||||
on self.bond < 0.1 or other.bond < 0.1 -> broken
|
||||
}
|
||||
|
||||
state thriving {
|
||||
on self.bond < 0.8 or other.bond < 0.8 -> stable
|
||||
}
|
||||
|
||||
state broken {
|
||||
on self.bond > 0.5 and other.bond > 0.5 -> troubled
|
||||
}
|
||||
}
|
||||
|
||||
life_arc CharacterStates {
|
||||
state monitoring {
|
||||
// Field access with self
|
||||
on self.age > 18 -> adult
|
||||
on self.energy < 0.2 -> exhausted
|
||||
on self.health < 30 -> sick
|
||||
|
||||
// Field access with equality
|
||||
on self.status is active -> active_state
|
||||
on self.ready is true -> ready_state
|
||||
}
|
||||
|
||||
state adult {
|
||||
on self.age < 18 -> monitoring
|
||||
}
|
||||
|
||||
state exhausted {
|
||||
on self.energy > 0.7 -> monitoring
|
||||
}
|
||||
|
||||
state sick {
|
||||
on self.health > 80 -> monitoring
|
||||
}
|
||||
|
||||
state active_state {
|
||||
on self.status is inactive -> monitoring
|
||||
}
|
||||
|
||||
state ready_state {
|
||||
on self.ready is false -> monitoring
|
||||
}
|
||||
}
|
||||
|
||||
life_arc ComplexFieldAccess {
|
||||
state checking {
|
||||
// Nested field access patterns
|
||||
on self.stats.health > 50 -> healthy
|
||||
on other.profile.age < 18 -> young_other
|
||||
|
||||
// Field access with logical operators
|
||||
on self.energy > 0.5 and self.health > 70 -> strong
|
||||
on not self.ready -> waiting
|
||||
on self.completed is true or other.completed is true -> done
|
||||
|
||||
// Mixed field access and regular identifiers
|
||||
on self.score > threshold -> passed
|
||||
on other.level is beginner and difficulty > 5 -> too_hard
|
||||
}
|
||||
|
||||
state healthy {
|
||||
on self.stats.health < 30 -> checking
|
||||
}
|
||||
|
||||
state young_other {
|
||||
on other.profile.age >= 18 -> checking
|
||||
}
|
||||
|
||||
state strong {
|
||||
on self.energy < 0.3 or self.health < 50 -> checking
|
||||
}
|
||||
|
||||
state waiting {
|
||||
on self.ready -> checking
|
||||
}
|
||||
|
||||
state done {
|
||||
on self.completed is false and other.completed is false -> checking
|
||||
}
|
||||
|
||||
state passed {
|
||||
on self.score < threshold -> checking
|
||||
}
|
||||
|
||||
state too_hard {
|
||||
on other.level is advanced or difficulty < 3 -> checking
|
||||
}
|
||||
}
|
||||
95
tests/examples/logical_operators.sb
Normal file
95
tests/examples/logical_operators.sb
Normal file
@@ -0,0 +1,95 @@
|
||||
// Test logical operators in life arc transitions
|
||||
|
||||
life_arc ComplexConditions {
|
||||
state monitoring {
|
||||
// AND operator
|
||||
on age > 18 and status is active -> adult_active
|
||||
on energy > 0.5 and health > 80 -> healthy_energetic
|
||||
|
||||
// OR operator
|
||||
on tired or hungry -> needs_rest
|
||||
on age < 5 or age > 65 -> dependent
|
||||
|
||||
// NOT operator
|
||||
on not ready -> waiting
|
||||
on not completed -> in_progress
|
||||
}
|
||||
|
||||
state adult_active {
|
||||
on age < 18 or status is inactive -> monitoring
|
||||
}
|
||||
|
||||
state healthy_energetic {
|
||||
on energy < 0.3 or health < 50 -> monitoring
|
||||
}
|
||||
|
||||
state needs_rest {
|
||||
on not tired and not hungry -> monitoring
|
||||
}
|
||||
|
||||
state dependent {
|
||||
on age >= 5 and age <= 65 -> monitoring
|
||||
}
|
||||
|
||||
state waiting {
|
||||
on ready -> monitoring
|
||||
}
|
||||
|
||||
state in_progress {
|
||||
on completed -> monitoring
|
||||
}
|
||||
}
|
||||
|
||||
life_arc NestedLogic {
|
||||
state checking {
|
||||
// Complex nested conditions
|
||||
on age > 18 and status is active and energy > 0.5 -> triple_and
|
||||
on tired or hungry or sick -> any_problem
|
||||
on not ready and not completed -> both_false
|
||||
|
||||
// Mixed operators
|
||||
on age > 21 and status is verified or is_admin -> allowed
|
||||
on health > 50 and not sick or emergency -> proceed
|
||||
}
|
||||
|
||||
state triple_and {
|
||||
on age < 18 or status is inactive or energy < 0.5 -> checking
|
||||
}
|
||||
|
||||
state any_problem {
|
||||
on not tired and not hungry and not sick -> checking
|
||||
}
|
||||
|
||||
state both_false {
|
||||
on ready or completed -> checking
|
||||
}
|
||||
|
||||
state allowed {
|
||||
on age < 21 and status is unverified and not is_admin -> checking
|
||||
}
|
||||
|
||||
state proceed {
|
||||
on health < 50 and sick and not emergency -> checking
|
||||
}
|
||||
}
|
||||
|
||||
life_arc BooleanLogic {
|
||||
state idle {
|
||||
// Boolean literals with operators
|
||||
on enabled is true and paused is false -> running
|
||||
on enabled is false or error is true -> stopped
|
||||
on not initialized -> initializing
|
||||
}
|
||||
|
||||
state running {
|
||||
on enabled is false or paused is true -> idle
|
||||
}
|
||||
|
||||
state stopped {
|
||||
on enabled is true and error is false -> idle
|
||||
}
|
||||
|
||||
state initializing {
|
||||
on initialized -> idle
|
||||
}
|
||||
}
|
||||
76
tests/examples/name_resolution.sb
Normal file
76
tests/examples/name_resolution.sb
Normal file
@@ -0,0 +1,76 @@
|
||||
// Test name resolution and duplicate detection
|
||||
|
||||
// These are all unique names - should register successfully
|
||||
character Alice {
|
||||
age: 30
|
||||
name: "Alice Smith"
|
||||
}
|
||||
|
||||
character Bob {
|
||||
age: 35
|
||||
name: "Bob Jones"
|
||||
}
|
||||
|
||||
template PersonTemplate {
|
||||
age: 18..80
|
||||
health: 0.0..1.0
|
||||
}
|
||||
|
||||
enum Status {
|
||||
active,
|
||||
inactive,
|
||||
pending
|
||||
}
|
||||
|
||||
life_arc AgeProgression {
|
||||
state young {
|
||||
on age > 18 -> adult
|
||||
}
|
||||
state adult {
|
||||
on age > 65 -> senior
|
||||
}
|
||||
state senior {}
|
||||
}
|
||||
|
||||
schedule DailyRoutine {
|
||||
06:00 -> 08:00: wake_up
|
||||
08:00 -> 17:00: work
|
||||
17:00 -> 22:00: evening
|
||||
22:00 -> 06:00: sleep
|
||||
}
|
||||
|
||||
behavior SimpleBehavior {
|
||||
walk_around
|
||||
}
|
||||
|
||||
institution Library {
|
||||
name: "City Library"
|
||||
capacity: 100
|
||||
}
|
||||
|
||||
relationship Friendship {
|
||||
Alice
|
||||
Bob
|
||||
bond: 0.8
|
||||
}
|
||||
|
||||
location Park {
|
||||
name: "Central Park"
|
||||
}
|
||||
|
||||
species Human {
|
||||
lifespan: 80
|
||||
}
|
||||
|
||||
// All names above are unique and should be registered in the name table
|
||||
// The name table can be queried by kind:
|
||||
// - Characters: Alice, Bob
|
||||
// - Templates: PersonTemplate
|
||||
// - Enums: Status
|
||||
// - LifeArcs: AgeProgression
|
||||
// - Schedules: DailyRoutine
|
||||
// - Behaviors: SimpleBehavior
|
||||
// - Institutions: Library
|
||||
// - Relationships: Friendship
|
||||
// - Locations: Park
|
||||
// - Species: Human
|
||||
89
tests/examples/override_values.sb
Normal file
89
tests/examples/override_values.sb
Normal file
@@ -0,0 +1,89 @@
|
||||
// Test override as field values
|
||||
|
||||
template HumanNeeds {
|
||||
sleep: 0.8
|
||||
food: 0.7
|
||||
social: 0.5
|
||||
health: 0.6
|
||||
}
|
||||
|
||||
template BakerSchedule {
|
||||
work_start: 6
|
||||
work_end: 14
|
||||
lunch_time: 12
|
||||
}
|
||||
|
||||
// Override in field value - set operations
|
||||
character Alice {
|
||||
name: "Alice"
|
||||
needs: @HumanNeeds {
|
||||
sleep: 0.9
|
||||
social: 0.7
|
||||
}
|
||||
}
|
||||
|
||||
// Override with remove operation
|
||||
character Bob {
|
||||
name: "Bob"
|
||||
needs: @HumanNeeds {
|
||||
remove social
|
||||
sleep: 0.6
|
||||
}
|
||||
}
|
||||
|
||||
// Override with append operation
|
||||
character Carol {
|
||||
name: "Carol"
|
||||
needs: @HumanNeeds {
|
||||
append creativity: 0.8
|
||||
food: 0.9
|
||||
}
|
||||
}
|
||||
|
||||
// Override with mixed operations
|
||||
character David {
|
||||
name: "David"
|
||||
needs: @HumanNeeds {
|
||||
sleep: 0.95
|
||||
remove social
|
||||
append exercise: 0.7
|
||||
}
|
||||
}
|
||||
|
||||
// Multiple overrides in same character
|
||||
character Elena {
|
||||
name: "Elena"
|
||||
needs: @HumanNeeds {
|
||||
sleep: 0.7
|
||||
food: 0.8
|
||||
}
|
||||
daily_schedule: @BakerSchedule {
|
||||
work_start: 5
|
||||
remove lunch_time
|
||||
}
|
||||
}
|
||||
|
||||
// Empty override (inherits all)
|
||||
character Frank {
|
||||
name: "Frank"
|
||||
needs: @HumanNeeds {
|
||||
}
|
||||
}
|
||||
|
||||
// Only removes
|
||||
character Grace {
|
||||
name: "Grace"
|
||||
needs: @HumanNeeds {
|
||||
remove sleep
|
||||
remove food
|
||||
}
|
||||
}
|
||||
|
||||
// Only appends
|
||||
character Henry {
|
||||
name: "Henry"
|
||||
needs: @HumanNeeds {
|
||||
append rest: 0.5
|
||||
append work: 0.8
|
||||
}
|
||||
}
|
||||
74
tests/examples/relationship_merging.sb
Normal file
74
tests/examples/relationship_merging.sb
Normal file
@@ -0,0 +1,74 @@
|
||||
// Demonstration of relationship merging
|
||||
// The same relationship can be declared multiple times from different perspectives
|
||||
// The resolver will merge them into a single relationship
|
||||
|
||||
// First, define characters
|
||||
character Alice {
|
||||
age: 30
|
||||
name: "Alice"
|
||||
}
|
||||
|
||||
character Bob {
|
||||
age: 32
|
||||
name: "Bob"
|
||||
}
|
||||
|
||||
// Declare the relationship from Alice's perspective
|
||||
// In a multi-file system, this might be in alice.sb
|
||||
relationship Friendship_AliceBob {
|
||||
Alice self {
|
||||
// Alice's feelings about the friendship
|
||||
trust: 0.9
|
||||
enjoyment: 0.95
|
||||
} other {
|
||||
// How Alice perceives Bob
|
||||
reliability: 0.85
|
||||
humor: 0.9
|
||||
}
|
||||
Bob
|
||||
}
|
||||
|
||||
// Same relationship from Bob's perspective
|
||||
// In a multi-file system, this might be in bob.sb
|
||||
relationship Friendship_AliceBob {
|
||||
Bob self {
|
||||
// Bob's feelings about the friendship
|
||||
trust: 0.85
|
||||
enjoyment: 0.9
|
||||
} other {
|
||||
// How Bob perceives Alice
|
||||
reliability: 0.95
|
||||
humor: 0.8
|
||||
}
|
||||
Alice
|
||||
}
|
||||
|
||||
// The resolver will:
|
||||
// 1. Recognize these as the same relationship (same participants + name)
|
||||
// 2. Merge the self/other blocks appropriately
|
||||
// 3. Validate that shared fields (if any) have the same values
|
||||
|
||||
// Example with shared fields
|
||||
relationship Professional_AliceBob {
|
||||
Alice self {
|
||||
respect: 0.9
|
||||
}
|
||||
Bob
|
||||
|
||||
// Shared field - must have same value in all declarations
|
||||
workplace: "TechCorp"
|
||||
}
|
||||
|
||||
// Same relationship, same shared field value
|
||||
relationship Professional_AliceBob {
|
||||
Bob self {
|
||||
respect: 0.85
|
||||
}
|
||||
Alice
|
||||
|
||||
// This MUST match the value in the other declaration
|
||||
workplace: "TechCorp"
|
||||
}
|
||||
|
||||
// Note: If the shared field values differed, the resolver would
|
||||
// report a validation error about conflicting values
|
||||
37
tests/examples/use_statements.sb
Normal file
37
tests/examples/use_statements.sb
Normal file
@@ -0,0 +1,37 @@
|
||||
// Test use statement syntax
|
||||
// Note: Multi-file resolution not yet implemented,
|
||||
// but syntax is parsed and validated
|
||||
|
||||
// Single import - import one specific item
|
||||
use characters::Martha;
|
||||
use templates::GenericPerson;
|
||||
use enums::BondType;
|
||||
|
||||
// Grouped import - import multiple items from same module
|
||||
use characters::{David, Tommy, Elena};
|
||||
use behaviors::{WorkAtBakery, SocialInteraction, DailyRoutine};
|
||||
|
||||
// Wildcard import - import everything from a module
|
||||
use locations::*;
|
||||
use schedules::*;
|
||||
|
||||
// Nested paths work too
|
||||
use world::characters::npcs::Merchant;
|
||||
use schema::core::needs::Hunger;
|
||||
|
||||
// After imports, define local declarations
|
||||
character LocalCharacter {
|
||||
age: 25
|
||||
name: "Local Person"
|
||||
}
|
||||
|
||||
template LocalTemplate {
|
||||
age: 20..60
|
||||
energy: 0.5..1.0
|
||||
}
|
||||
|
||||
enum LocalEnum {
|
||||
option_a,
|
||||
option_b,
|
||||
option_c
|
||||
}
|
||||
54
tests/examples/validation_errors.sb
Normal file
54
tests/examples/validation_errors.sb
Normal file
@@ -0,0 +1,54 @@
|
||||
// Test semantic validation errors
|
||||
|
||||
// Valid bond values (should parse and validate)
|
||||
relationship GoodFriendship {
|
||||
Alice
|
||||
Bob
|
||||
bond: 0.8
|
||||
}
|
||||
|
||||
// Invalid bond value - too high (should validate with error)
|
||||
// relationship BadFriendship1 {
|
||||
// Carol
|
||||
// David
|
||||
// bond: 1.5 // Error: bond > 1.0
|
||||
// }
|
||||
|
||||
// Invalid bond value - negative (should validate with error)
|
||||
// relationship BadFriendship2 {
|
||||
// Elena
|
||||
// Frank
|
||||
// bond: -0.1 // Error: bond < 0.0
|
||||
// }
|
||||
|
||||
// Valid age
|
||||
character YoungPerson {
|
||||
age: 25
|
||||
}
|
||||
|
||||
// Invalid age - negative (commented to allow file to parse)
|
||||
// character InvalidPerson1 {
|
||||
// age: -5 // Error: age < 0
|
||||
// }
|
||||
|
||||
// Invalid age - too high (commented to allow file to parse)
|
||||
// character InvalidPerson2 {
|
||||
// age: 200 // Error: age > 150
|
||||
// }
|
||||
|
||||
// Valid life arc with proper transitions
|
||||
life_arc ValidLifeArc {
|
||||
state start {
|
||||
on ready -> end
|
||||
}
|
||||
state end {
|
||||
// Terminal state
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid life arc - transition to non-existent state (commented)
|
||||
// life_arc InvalidLifeArc {
|
||||
// state start {
|
||||
// on ready -> nonexistent // Error: state 'nonexistent' not defined
|
||||
// }
|
||||
// }
|
||||
Reference in New Issue
Block a user