class Dice { /* This syntax is used automatically in the code. The arguments are parsed as the corresponding types and assigned as needed */ syntax from Arg(1{d}, rolls) "D" Arg(1{d}, sides); rolls: Int; sides: Int; } fn roll(dice: @Dice) -> Int { let res: Int = 0; let it: Int = 0; while it < dice.rolls { res = res + rand_int(1, dice.sides); it.inc(); } return *res; } let d1: Dice = 2D20; let d2: Dice = 5D6; let d3: Dice = 9D10; if d1.rolls != 2 || d1.sides != 20 { panic("Invalid d1"); } if d2.rolls != 5 || d2.sides != 6 { panic("Invalid d2"); } if d3.rolls != 9 || d3.sides != 10 { panic("Invalid d3"); } let it: Int = 0; while it < 1000 { let r: Int = d3.roll(); if r < d3.rolls || r > d3.rolls * d3.sides { panic("Invalid roll"); } it.inc(); } class InnerDice { syntax from "[" Arg(1{d} "D" 1{d}, inner_dice) "]"; inner_dice: Dice; } let id: InnerDice = [7D4]; if id.inner_dice.rolls != 7 || id.inner_dice.sides != 4 { panic("Invalid inner dice"); }