gglang 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,904 @@
1
+ <![CDATA[# ๐Ÿ“– GGLang โ€” Complete Language Documentation
2
+
3
+ > **Version 1.0** ยท The Gaming-Themed Programming Language
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Getting Started](#getting-started)
10
+ 2. [Language Basics](#language-basics)
11
+ 3. [Variables & Constants](#variables--constants)
12
+ 4. [Data Types](#data-types)
13
+ 5. [Operators](#operators)
14
+ 6. [Control Flow](#control-flow)
15
+ 7. [Loops](#loops)
16
+ 8. [Functions](#functions)
17
+ 9. [Input / Output](#input--output)
18
+ 10. [Error Handling](#error-handling)
19
+ 11. [Complete Example Programs](#complete-example-programs)
20
+ 12. [Keyword Reference Table](#keyword-reference-table)
21
+
22
+ ---
23
+
24
+ ## Getting Started
25
+
26
+ ### Installation
27
+
28
+ ```bash
29
+ # Clone the repository
30
+ git clone <repo-url>
31
+ cd toy-programming-language
32
+
33
+ # Install dependencies
34
+ npm install
35
+
36
+ # Build the project
37
+ npm run build
38
+ ```
39
+
40
+ ### Running a GGLang File
41
+
42
+ GGLang source files use the `.gg` extension. To run a program:
43
+
44
+ ```bash
45
+ npm start -- path/to/your/program.gg
46
+ ```
47
+
48
+ For example:
49
+
50
+ ```bash
51
+ npm start -- examples/hello.gg
52
+ ```
53
+
54
+ ### Using the REPL
55
+
56
+ Launch the interactive Read-Eval-Print Loop by running without arguments:
57
+
58
+ ```bash
59
+ npm start
60
+ ```
61
+
62
+ In the REPL, you can type GGLang expressions and statements directly and see results immediately. Type `exit` or press `Ctrl+C` to quit.
63
+
64
+ ---
65
+
66
+ ## Language Basics
67
+
68
+ ### Program Structure
69
+
70
+ Every GGLang program is wrapped in a `spawn { }` block. This is the entry point โ€” like a player spawning into the game world.
71
+
72
+ ```
73
+ spawn {
74
+ // Your code goes here
75
+ }
76
+ ```
77
+
78
+ Everything outside `spawn { }` is ignored. You must have exactly one `spawn` block.
79
+
80
+ ### Comments
81
+
82
+ GGLang supports two styles of comments:
83
+
84
+ ```
85
+ // This is a single-line comment
86
+
87
+ /*
88
+ This is a
89
+ multi-line comment
90
+ */
91
+ ```
92
+
93
+ ### Semicolons
94
+
95
+ Statements must end with a semicolon (`;`).
96
+
97
+ ```
98
+ equip x = 10; // โœ… Correct
99
+ broadcast("hello"); // โœ… Correct
100
+ equip y = 20 // โŒ Missing semicolon
101
+ ```
102
+
103
+ ### Blocks
104
+
105
+ Code blocks are delimited by curly braces `{ }`. They are used with control flow statements, loops, functions, and error handling.
106
+
107
+ ```
108
+ quest (x > 0) {
109
+ broadcast("positive");
110
+ }
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Variables & Constants
116
+
117
+ ### Variables: `equip`
118
+
119
+ Use `equip` to declare a mutable variable โ€” like equipping an item to your inventory.
120
+
121
+ ```
122
+ spawn {
123
+ equip health = 100;
124
+ equip playerName = "Hero";
125
+ equip isAlive = victory;
126
+
127
+ // Variables can be reassigned
128
+ health = 75;
129
+ playerName = "Champion";
130
+ }
131
+ ```
132
+
133
+ Variables must be initialized at declaration. They can be reassigned at any time.
134
+
135
+ ### Constants: `artifact`
136
+
137
+ Use `artifact` to declare an immutable constant โ€” artifacts are permanent relics that never change.
138
+
139
+ ```
140
+ spawn {
141
+ artifact maxHealth = 100;
142
+ artifact gameName = "Dungeon Quest";
143
+ artifact PI = 3.14159;
144
+
145
+ // maxHealth = 200; // โŒ Error! Artifacts cannot be reassigned
146
+ }
147
+ ```
148
+
149
+ ### Scope
150
+
151
+ Variables and constants are block-scoped. A variable declared inside a block is only accessible within that block and its nested blocks.
152
+
153
+ ```
154
+ spawn {
155
+ equip outer = "I'm outside";
156
+
157
+ quest (victory) {
158
+ equip inner = "I'm inside";
159
+ broadcast(outer); // โœ… Can access outer variable
160
+ broadcast(inner); // โœ… Can access inner variable
161
+ }
162
+
163
+ broadcast(outer); // โœ… Still accessible
164
+ // broadcast(inner); // โŒ Error! inner is not defined here
165
+ }
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Data Types
171
+
172
+ GGLang supports four primitive data types:
173
+
174
+ ### Numbers
175
+
176
+ Integer and floating-point numbers. No distinction between the two.
177
+
178
+ ```
179
+ spawn {
180
+ equip age = 25;
181
+ equip pi = 3.14159;
182
+ equip negative = -42;
183
+ equip zero = 0;
184
+ }
185
+ ```
186
+
187
+ ### Strings
188
+
189
+ Text enclosed in double quotes (`"`) or single quotes (`'`). Strings can be concatenated with `+`.
190
+
191
+ ```
192
+ spawn {
193
+ equip greeting = "Hello, World!";
194
+ equip name = 'GGLang';
195
+ equip full = greeting + " Welcome to " + name + "!";
196
+
197
+ // Numbers are auto-converted when concatenated with strings
198
+ equip level = 5;
199
+ broadcast("You are level " + level); // "You are level 5"
200
+ }
201
+ ```
202
+
203
+ ### Booleans
204
+
205
+ `victory` for true, `defeat` for false.
206
+
207
+ ```
208
+ spawn {
209
+ equip isWinning = victory;
210
+ equip isGameOver = defeat;
211
+
212
+ quest (isWinning) {
213
+ broadcast("You're winning!");
214
+ }
215
+ }
216
+ ```
217
+
218
+ ### Null
219
+
220
+ `phantom` represents the absence of a value โ€” like a phantom, there's nothing there.
221
+
222
+ ```
223
+ spawn {
224
+ equip result = phantom;
225
+
226
+ quest (result == phantom) {
227
+ broadcast("Nothing here... ๐Ÿ‘ป");
228
+ }
229
+ }
230
+ ```
231
+
232
+ ---
233
+
234
+ ## Operators
235
+
236
+ ### Arithmetic Operators
237
+
238
+ | Operator | Description | Example | Result |
239
+ |----------|--------------- |---------------|--------|
240
+ | `+` | Addition | `10 + 3` | `13` |
241
+ | `-` | Subtraction | `10 - 3` | `7` |
242
+ | `*` | Multiplication | `10 * 3` | `30` |
243
+ | `/` | Division | `10 / 3` | `3.33โ€ฆ`|
244
+ | `%` | Modulo | `10 % 3` | `1` |
245
+
246
+ The `+` operator also works for string concatenation:
247
+
248
+ ```
249
+ "Hello" + " " + "World" // "Hello World"
250
+ "Level: " + 5 // "Level: 5"
251
+ ```
252
+
253
+ ### Comparison Operators
254
+
255
+ | Operator | Description | Example | Result |
256
+ |----------|-----------------------|------------|-----------|
257
+ | `==` | Equal to | `5 == 5` | `victory` |
258
+ | `!=` | Not equal to | `5 != 3` | `victory` |
259
+ | `>` | Greater than | `5 > 3` | `victory` |
260
+ | `<` | Less than | `5 < 3` | `defeat` |
261
+ | `>=` | Greater than or equal | `5 >= 5` | `victory` |
262
+ | `<=` | Less than or equal | `3 <= 5` | `victory` |
263
+
264
+ ### Logical Operators
265
+
266
+ | Operator | Description | Example | Result |
267
+ |----------|-------------|----------------------------|-----------|
268
+ | `&&` | Logical AND | `victory && defeat` | `defeat` |
269
+ | `\|\|` | Logical OR | `victory \|\| defeat` | `victory` |
270
+ | `!` | Logical NOT | `!defeat` | `victory` |
271
+
272
+ ### Assignment Operators
273
+
274
+ | Operator | Description | Equivalent To |
275
+ |----------|---------------------|---------------|
276
+ | `=` | Assignment | `x = 5` |
277
+ | `+=` | Add and assign | `x = x + 5` |
278
+ | `-=` | Subtract and assign | `x = x - 5` |
279
+ | `*=` | Multiply and assign | `x = x * 5` |
280
+ | `/=` | Divide and assign | `x = x / 5` |
281
+
282
+ ```
283
+ spawn {
284
+ equip score = 0;
285
+ score += 10; // score is now 10
286
+ score *= 2; // score is now 20
287
+ score -= 5; // score is now 15
288
+ score /= 3; // score is now 5
289
+ }
290
+ ```
291
+
292
+ ### Operator Precedence
293
+
294
+ From **highest** to **lowest** precedence:
295
+
296
+ | Precedence | Operators | Description |
297
+ |------------|---------------------|----------------------|
298
+ | 1 (highest)| `!`, unary `-` | Logical NOT, negation |
299
+ | 2 | `*`, `/`, `%` | Multiplication, Division, Modulo |
300
+ | 3 | `+`, `-` | Addition, Subtraction |
301
+ | 4 | `>`, `<`, `>=`, `<=`| Comparison |
302
+ | 5 | `==`, `!=` | Equality |
303
+ | 6 | `&&` | Logical AND |
304
+ | 7 (lowest) | `\|\|` | Logical OR |
305
+
306
+ Use parentheses `( )` to override precedence:
307
+
308
+ ```
309
+ equip result = (2 + 3) * 4; // 20, not 14
310
+ ```
311
+
312
+ ---
313
+
314
+ ## Control Flow
315
+
316
+ ### `quest` (if)
317
+
318
+ Execute a block of code when a condition is `victory` (true).
319
+
320
+ ```
321
+ spawn {
322
+ equip health = 75;
323
+
324
+ quest (health > 50) {
325
+ broadcast("You're doing fine!");
326
+ }
327
+ }
328
+ ```
329
+
330
+ ### `side_quest` (else if)
331
+
332
+ Check additional conditions when the previous `quest` or `side_quest` was `defeat` (false).
333
+
334
+ ```
335
+ spawn {
336
+ equip score = 85;
337
+
338
+ quest (score >= 90) {
339
+ broadcast("S Rank! ๐ŸŒŸ");
340
+ } side_quest (score >= 80) {
341
+ broadcast("A Rank! โญ");
342
+ } side_quest (score >= 70) {
343
+ broadcast("B Rank");
344
+ } side_quest (score >= 60) {
345
+ broadcast("C Rank");
346
+ }
347
+ }
348
+ ```
349
+
350
+ ### `retreat` (else)
351
+
352
+ The fallback block when all previous conditions are `defeat`.
353
+
354
+ ```
355
+ spawn {
356
+ equip level = 3;
357
+
358
+ quest (level >= 10) {
359
+ broadcast("You are a veteran!");
360
+ } side_quest (level >= 5) {
361
+ broadcast("You are experienced.");
362
+ } retreat {
363
+ broadcast("You are a beginner.");
364
+ }
365
+ }
366
+ ```
367
+
368
+ ### Nesting
369
+
370
+ Control flow statements can be nested:
371
+
372
+ ```
373
+ spawn {
374
+ equip class = "mage";
375
+ equip level = 15;
376
+
377
+ quest (class == "mage") {
378
+ quest (level >= 10) {
379
+ broadcast("You can cast Fireball! ๐Ÿ”ฅ");
380
+ } retreat {
381
+ broadcast("Keep training your magic...");
382
+ }
383
+ } side_quest (class == "warrior") {
384
+ broadcast("Swing that sword! โš”๏ธ");
385
+ }
386
+ }
387
+ ```
388
+
389
+ ---
390
+
391
+ ## Loops
392
+
393
+ ### `grind` (while)
394
+
395
+ Repeat a block of code as long as a condition is `victory` (true). Perfect for grinding levels.
396
+
397
+ ```
398
+ spawn {
399
+ equip level = 1;
400
+
401
+ grind (level <= 10) {
402
+ broadcast("Level " + level + " reached!");
403
+ level += 1;
404
+ }
405
+
406
+ broadcast("Max level! ๐ŸŽ‰");
407
+ }
408
+ ```
409
+
410
+ ### `rage_quit` (break)
411
+
412
+ Exit a loop immediately โ€” you've had enough.
413
+
414
+ ```
415
+ spawn {
416
+ equip attempts = 0;
417
+
418
+ grind (victory) { // Infinite loop
419
+ attempts += 1;
420
+ broadcast("Attempt #" + attempts);
421
+
422
+ quest (attempts >= 5) {
423
+ broadcast("That's it, I'm done!");
424
+ rage_quit;
425
+ }
426
+ }
427
+
428
+ broadcast("Rage quit after " + attempts + " attempts.");
429
+ }
430
+ ```
431
+
432
+ ### `respawn` (continue)
433
+
434
+ Skip the rest of the current iteration and jump to the next one โ€” like respawning to try again.
435
+
436
+ ```
437
+ spawn {
438
+ equip i = 0;
439
+
440
+ grind (i < 10) {
441
+ i += 1;
442
+
443
+ // Skip even numbers
444
+ quest (i % 2 == 0) {
445
+ respawn;
446
+ }
447
+
448
+ broadcast(i); // Only prints odd numbers: 1, 3, 5, 7, 9
449
+ }
450
+ }
451
+ ```
452
+
453
+ ### Loop Patterns
454
+
455
+ **Counting loop:**
456
+ ```
457
+ equip i = 0;
458
+ grind (i < 10) {
459
+ // do something
460
+ i += 1;
461
+ }
462
+ ```
463
+
464
+ **Sentinel loop (until condition):**
465
+ ```
466
+ equip input = "";
467
+ grind (input != "quit") {
468
+ input = interact("Enter command (or 'quit'): ");
469
+ broadcast("You entered: " + input);
470
+ }
471
+ ```
472
+
473
+ **Infinite loop with break:**
474
+ ```
475
+ grind (victory) {
476
+ // do something
477
+ quest (someCondition) {
478
+ rage_quit;
479
+ }
480
+ }
481
+ ```
482
+
483
+ ---
484
+
485
+ ## Functions
486
+
487
+ ### `skill` (function)
488
+
489
+ Define reusable skills (functions) with `skill`. Functions can accept parameters and return values.
490
+
491
+ ```
492
+ spawn {
493
+ skill greet(name) {
494
+ broadcast("Hello, " + name + "! ๐Ÿ‘‹");
495
+ }
496
+
497
+ greet("Player"); // "Hello, Player! ๐Ÿ‘‹"
498
+ greet("GGLang"); // "Hello, GGLang! ๐Ÿ‘‹"
499
+ }
500
+ ```
501
+
502
+ ### `loot` (return)
503
+
504
+ Return a value from a skill using `loot` โ€” the reward for executing the skill.
505
+
506
+ ```
507
+ spawn {
508
+ skill add(a, b) {
509
+ loot a + b;
510
+ }
511
+
512
+ skill square(n) {
513
+ loot n * n;
514
+ }
515
+
516
+ equip sum = add(3, 4); // 7
517
+ equip squared = square(5); // 25
518
+ broadcast(add(10, square(3))); // 19
519
+ }
520
+ ```
521
+
522
+ ### Multiple Parameters
523
+
524
+ Functions can take any number of parameters:
525
+
526
+ ```
527
+ spawn {
528
+ skill calculateDamage(base, level, multiplier) {
529
+ loot base + (level * multiplier);
530
+ }
531
+
532
+ equip damage = calculateDamage(10, 5, 1.5);
533
+ broadcast("Damage dealt: " + damage); // "Damage dealt: 17.5"
534
+ }
535
+ ```
536
+
537
+ ### Early Return
538
+
539
+ `loot` immediately exits the function, like returning loot and leaving the dungeon:
540
+
541
+ ```
542
+ spawn {
543
+ skill absoluteValue(n) {
544
+ quest (n < 0) {
545
+ loot -n;
546
+ }
547
+ loot n;
548
+ }
549
+
550
+ broadcast(absoluteValue(-42)); // 42
551
+ broadcast(absoluteValue(7)); // 7
552
+ }
553
+ ```
554
+
555
+ ### Recursion
556
+
557
+ Skills can call themselves โ€” perfect for recursive algorithms:
558
+
559
+ ```
560
+ spawn {
561
+ // Factorial using recursion
562
+ skill factorial(n) {
563
+ quest (n <= 1) {
564
+ loot 1;
565
+ }
566
+ loot n * factorial(n - 1);
567
+ }
568
+
569
+ broadcast("5! = " + factorial(5)); // "5! = 120"
570
+ broadcast("10! = " + factorial(10)); // "10! = 3628800"
571
+ }
572
+ ```
573
+
574
+ ### Functions Without Return
575
+
576
+ If a skill doesn't use `loot`, it implicitly returns `phantom`:
577
+
578
+ ```
579
+ spawn {
580
+ skill sayHello() {
581
+ broadcast("Hello!");
582
+ }
583
+
584
+ equip result = sayHello();
585
+ broadcast(result); // phantom
586
+ }
587
+ ```
588
+
589
+ ---
590
+
591
+ ## Input / Output
592
+
593
+ ### `broadcast` (print)
594
+
595
+ Output a value to the console. Accepts any data type.
596
+
597
+ ```
598
+ spawn {
599
+ broadcast("Hello, World!"); // String
600
+ broadcast(42); // Number
601
+ broadcast(victory); // Boolean
602
+ broadcast(3 + 4); // Expression result
603
+ broadcast("Score: " + 100); // String concatenation
604
+ }
605
+ ```
606
+
607
+ ### `interact` (input)
608
+
609
+ Read input from the user. `interact` takes an optional prompt string and returns the user's input as a string.
610
+
611
+ ```
612
+ spawn {
613
+ equip name = interact("What is your name? ");
614
+ equip age = interact("How old are you? ");
615
+
616
+ broadcast("Hello, " + name + "! You are " + age + " years old.");
617
+ }
618
+ ```
619
+
620
+ > **Note:** `interact` always returns a **string**. If you need a number, you may need to use it in an arithmetic context where auto-conversion occurs.
621
+
622
+ ---
623
+
624
+ ## Error Handling
625
+
626
+ ### `boss_fight` / `revive` (try / catch)
627
+
628
+ Wrap risky code in a `boss_fight` block. If a `glitch` (error) is thrown, execution jumps to the `revive` block.
629
+
630
+ ```
631
+ spawn {
632
+ boss_fight {
633
+ broadcast("Entering the boss room...");
634
+ glitch "The boss is too powerful!";
635
+ broadcast("This line never executes.");
636
+ } revive (error) {
637
+ broadcast("Caught a glitch: " + error);
638
+ }
639
+
640
+ broadcast("Game continues after recovery.");
641
+ }
642
+ ```
643
+
644
+ **Output:**
645
+ ```
646
+ Entering the boss room...
647
+ Caught a glitch: The boss is too powerful!
648
+ Game continues after recovery.
649
+ ```
650
+
651
+ ### `glitch` (throw)
652
+
653
+ Throw an error with a message. This immediately exits the current execution and jumps to the nearest `revive` block.
654
+
655
+ ```
656
+ spawn {
657
+ skill divide(a, b) {
658
+ quest (b == 0) {
659
+ glitch "Cannot divide by zero!";
660
+ }
661
+ loot a / b;
662
+ }
663
+
664
+ boss_fight {
665
+ broadcast(divide(10, 2)); // 5
666
+ broadcast(divide(10, 0)); // Throws!
667
+ } revive (err) {
668
+ broadcast("Error: " + err);
669
+ }
670
+ }
671
+ ```
672
+
673
+ ### Nested Error Handling
674
+
675
+ `boss_fight` blocks can be nested. The innermost `revive` catches the error:
676
+
677
+ ```
678
+ spawn {
679
+ boss_fight {
680
+ broadcast("Outer boss fight...");
681
+
682
+ boss_fight {
683
+ broadcast("Inner boss fight...");
684
+ glitch "Inner glitch!";
685
+ } revive (e) {
686
+ broadcast("Inner revive caught: " + e);
687
+ }
688
+
689
+ broadcast("Outer continues normally.");
690
+ } revive (e) {
691
+ broadcast("Outer revive caught: " + e);
692
+ }
693
+ }
694
+ ```
695
+
696
+ **Output:**
697
+ ```
698
+ Outer boss fight...
699
+ Inner boss fight...
700
+ Inner revive caught: Inner glitch!
701
+ Outer continues normally.
702
+ ```
703
+
704
+ ### Unhandled Glitches
705
+
706
+ If a `glitch` is thrown outside of any `boss_fight`, the program crashes with an error message:
707
+
708
+ ```
709
+ spawn {
710
+ glitch "Fatal error!";
711
+ // Program terminates here
712
+ }
713
+ ```
714
+
715
+ ---
716
+
717
+ ## Complete Example Programs
718
+
719
+ ### Hello World
720
+
721
+ ```
722
+ // hello.gg โ€” Your first GGLang program
723
+ spawn {
724
+ broadcast("Hello, World!");
725
+ broadcast("Welcome to GGLang! ๐ŸŽฎ");
726
+ }
727
+ ```
728
+
729
+ ### FizzBuzz
730
+
731
+ ```
732
+ // fizzbuzz.gg โ€” The classic interview question, GGLang style
733
+ spawn {
734
+ equip i = 1;
735
+ grind (i <= 30) {
736
+ quest (i % 15 == 0) {
737
+ broadcast("FizzBuzz");
738
+ } side_quest (i % 3 == 0) {
739
+ broadcast("Fizz");
740
+ } side_quest (i % 5 == 0) {
741
+ broadcast("Buzz");
742
+ } retreat {
743
+ broadcast(i);
744
+ }
745
+ i = i + 1;
746
+ }
747
+ }
748
+ ```
749
+
750
+ ### Fibonacci (Recursive)
751
+
752
+ ```
753
+ // fibonacci.gg โ€” Fibonacci with recursion
754
+ spawn {
755
+ skill fibonacci(n) {
756
+ quest (n <= 1) {
757
+ loot n;
758
+ }
759
+ loot fibonacci(n - 1) + fibonacci(n - 2);
760
+ }
761
+
762
+ equip i = 0;
763
+ grind (i <= 15) {
764
+ broadcast("fibonacci(" + i + ") = " + fibonacci(i));
765
+ i = i + 1;
766
+ }
767
+ }
768
+ ```
769
+
770
+ ### Number Guessing Game
771
+
772
+ ```
773
+ // guess.gg โ€” Guess the secret number
774
+ spawn {
775
+ artifact secret = 7;
776
+ artifact maxAttempts = 5;
777
+
778
+ broadcast("๐ŸŽฎ Guess the number between 1 and 10!");
779
+ broadcast("You have " + maxAttempts + " attempts.");
780
+
781
+ equip attempts = 0;
782
+ equip won = defeat;
783
+
784
+ grind (attempts < maxAttempts && won == defeat) {
785
+ attempts += 1;
786
+ equip guess = interact("Attempt " + attempts + "/" + maxAttempts + " โ€” Enter your guess: ");
787
+
788
+ quest (guess == secret) {
789
+ broadcast("๐ŸŽ‰ Correct! You won in " + attempts + " attempts!");
790
+ won = victory;
791
+ } side_quest (guess < secret) {
792
+ broadcast("๐Ÿ“ˆ Too low! Try higher.");
793
+ } retreat {
794
+ broadcast("๐Ÿ“‰ Too high! Try lower.");
795
+ }
796
+ }
797
+
798
+ quest (won == defeat) {
799
+ broadcast("๐Ÿ’€ Game over! The number was " + secret + ".");
800
+ }
801
+ }
802
+ ```
803
+
804
+ ### Calculator
805
+
806
+ ```
807
+ // calculator.gg โ€” A simple calculator
808
+ spawn {
809
+ skill calculate(a, op, b) {
810
+ quest (op == "+") {
811
+ loot a + b;
812
+ } side_quest (op == "-") {
813
+ loot a - b;
814
+ } side_quest (op == "*") {
815
+ loot a * b;
816
+ } side_quest (op == "/") {
817
+ quest (b == 0) {
818
+ glitch "Division by zero!";
819
+ }
820
+ loot a / b;
821
+ } side_quest (op == "%") {
822
+ loot a % b;
823
+ } retreat {
824
+ glitch "Unknown operator: " + op;
825
+ }
826
+ }
827
+
828
+ broadcast("๐Ÿงฎ GGLang Calculator");
829
+ broadcast("Type 'quit' to exit.");
830
+
831
+ grind (victory) {
832
+ equip a = interact("Enter first number (or 'quit'): ");
833
+ quest (a == "quit") {
834
+ rage_quit;
835
+ }
836
+
837
+ equip op = interact("Enter operator (+, -, *, /, %): ");
838
+ equip b = interact("Enter second number: ");
839
+
840
+ boss_fight {
841
+ equip result = calculate(a, op, b);
842
+ broadcast("๐Ÿ“Š Result: " + a + " " + op + " " + b + " = " + result);
843
+ } revive (err) {
844
+ broadcast("โŒ Error: " + err);
845
+ }
846
+ }
847
+
848
+ broadcast("Thanks for calculating! GG ๐ŸŽฎ");
849
+ }
850
+ ```
851
+
852
+ ---
853
+
854
+ ## Keyword Reference Table
855
+
856
+ | GGLang Keyword | Traditional Equivalent | Description |
857
+ |---|---|---|
858
+ | `spawn { }` | `main()` / program start | Entry point โ€” player spawns into the game |
859
+ | `equip` | `let` / `var` | Declare a mutable variable |
860
+ | `artifact` | `const` | Declare an immutable constant |
861
+ | `broadcast` | `print` / `console.log` | Output a value to the console |
862
+ | `interact("โ€ฆ")` | `input` / `readline` | Read user input (returns string) |
863
+ | `quest` | `if` | Conditional โ€” embark on a quest |
864
+ | `side_quest` | `else if` | Alternative conditional path |
865
+ | `retreat` | `else` | Fallback when all conditions fail |
866
+ | `grind` | `while` | Loop โ€” keep grinding |
867
+ | `rage_quit` | `break` | Exit the loop immediately |
868
+ | `respawn` | `continue` | Skip to the next loop iteration |
869
+ | `skill` | `function` | Define a reusable function |
870
+ | `loot` | `return` | Return a value from a function |
871
+ | `victory` | `true` | Boolean true |
872
+ | `defeat` | `false` | Boolean false |
873
+ | `phantom` | `null` | Absence of a value |
874
+ | `boss_fight` | `try` | Attempt risky code |
875
+ | `revive` | `catch` | Handle an error |
876
+ | `glitch` | `throw` | Throw an error |
877
+
878
+ ---
879
+
880
+ ## Supported Operators โ€” Quick Reference
881
+
882
+ | Category | Operators |
883
+ |---|---|
884
+ | **Arithmetic** | `+` `-` `*` `/` `%` |
885
+ | **Comparison** | `==` `!=` `>` `<` `>=` `<=` |
886
+ | **Logical** | `&&` `\|\|` `!` |
887
+ | **Assignment** | `=` `+=` `-=` `*=` `/=` |
888
+
889
+ ---
890
+
891
+ ## File Extension
892
+
893
+ All GGLang source files use the `.gg` extension.
894
+
895
+ ```
896
+ my_program.gg
897
+ hello.gg
898
+ adventure.gg
899
+ ```
900
+
901
+ ---
902
+
903
+ *GG! ๐ŸŽฎ โ€” Happy coding with GGLang!*
904
+ ]]>