-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathdebug_effect.ail
More file actions
86 lines (69 loc) · 2.94 KB
/
Copy pathdebug_effect.ail
File metadata and controls
86 lines (69 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
-- Debug Effect Example
-- Demonstrates structured tracing and assertions using the Debug ghost effect
--
-- Debug is a "ghost effect" — fully invisible:
-- - No ! {Debug} needed in function signatures
-- - No --caps Debug needed at runtime
-- - No [effects].max needed in ailang.toml
-- - Debug.log and Debug.check are write-only from AILANG
-- - Only the host can collect debug output (printed to stderr)
-- - In release builds, Debug becomes zero-cost no-ops
-- - --log-level filters output (debug, info, warn, error, none)
--
-- Note: We use "check" instead of "assert" because "assert" is a reserved keyword
--
-- Run: ailang run --caps IO --entry main examples/runnable/debug_effect.ail
-- Filtered: ailang run --caps IO --log-level warn --entry main examples/runnable/debug_effect.ail
-- Release: ailang run --release --caps IO --entry main examples/runnable/debug_effect.ail
module examples/runnable/debug_effect
import std/debug as Debug
-- A simple entity type for demonstration
type Entity = { id: int, name: string, health: int }
-- Update an entity's health with debug tracing
-- Note: No ! {Debug} needed — ghost effect is invisible
func damage(e: Entity, amount: int) -> Entity {
Debug.log("Damaging entity ${show(e.id)} by ${show(amount)}");
Debug.check(amount >= 0, "damage amount must be non-negative");
let new_health = e.health - amount;
Debug.check(new_health >= 0, "health should not go negative");
{ id: e.id, name: e.name, health: new_health }
}
-- Heal an entity with debug tracing
func heal(e: Entity, amount: int) -> Entity {
Debug.log("Healing entity ${show(e.id)} by ${show(amount)}");
Debug.check(amount >= 0, "heal amount must be non-negative");
let new_health = e.health + amount;
let capped_health = if new_health > 100 then 100 else new_health;
{ id: e.id, name: e.name, health: capped_health }
}
-- Process a list of entities with debug logging
func process_entities(entities: [Entity]) -> [Entity] {
Debug.log("Processing entities");
match entities {
[] => [],
e :: rest => {
Debug.log("Processing: ${e.name}");
let updated = damage(e, 10);
updated :: process_entities(rest)
}
}
}
-- Main entry point — only IO is declared, Debug is invisible
export func main() -> () ! {IO} {
println("Debug Effect Demo");
println("=================");
-- Create some entities
let hero = { id: 1, name: "Hero", health: 100 };
let monster = { id: 2, name: "Goblin", health: 30 };
Debug.log("Starting game tick");
Debug.check(hero.health > 0, "hero must be alive");
-- Simulate combat
let damaged_hero = damage(hero, 25);
let healed_hero = heal(damaged_hero, 10);
println("Hero health: ${show(healed_hero.health)}");
-- Process multiple entities
let entities = [hero, monster];
let updated = process_entities(entities);
Debug.log("Game tick complete");
println("Demo complete!")
}