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.
- package/LICENSE +21 -0
- package/README.md +158 -0
- package/dist/environment.d.ts +45 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +95 -0
- package/dist/environment.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +199 -0
- package/dist/index.js.map +1 -0
- package/dist/interpreter.d.ts +121 -0
- package/dist/interpreter.d.ts.map +1 -0
- package/dist/interpreter.js +564 -0
- package/dist/interpreter.js.map +1 -0
- package/dist/lexer.d.ts +76 -0
- package/dist/lexer.d.ts.map +1 -0
- package/dist/lexer.js +371 -0
- package/dist/lexer.js.map +1 -0
- package/dist/parser.d.ts +64 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +543 -0
- package/dist/parser.js.map +1 -0
- package/dist/types.d.ts +205 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +92 -0
- package/dist/types.js.map +1 -0
- package/docs/DOCUMENTATION.md +904 -0
- package/package.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GGLang Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
<]()
|
|
15
|
+
[]()
|
|
16
|
+
[]()
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 🕹️ What is GGLang?
|
|
21
|
+
|
|
22
|
+
**GGLang** is a toy programming language where every keyword is a gaming term. Variables are **equipped**, functions are **skills**, loops are **grinds**, and errors are **glitches**. It's built entirely in TypeScript and is designed to make learning about interpreters and compilers fun.
|
|
23
|
+
|
|
24
|
+
Instead of writing boring old `if / else`, you embark on a `quest` — and if things go south, you `retreat`. Instead of a `while` loop, you `grind` until you're done. Your programs don't just *start* — they `spawn`.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## ✨ Features
|
|
29
|
+
|
|
30
|
+
| Feature | Description |
|
|
31
|
+
|---|---|
|
|
32
|
+
| 🎮 **Gaming keywords** | Every keyword maps to a gaming concept |
|
|
33
|
+
| 🧮 **Full expressions** | Arithmetic, comparison, logical, and assignment operators |
|
|
34
|
+
| 🔁 **Control flow** | `quest` / `side_quest` / `retreat` (if/else if/else) |
|
|
35
|
+
| 🔄 **Loops** | `grind` (while) with `rage_quit` (break) and `respawn` (continue) |
|
|
36
|
+
| ⚔️ **Functions** | `skill` (function) with `loot` (return) and recursion support |
|
|
37
|
+
| 🛡️ **Error handling** | `boss_fight` / `revive` / `glitch` (try/catch/throw) |
|
|
38
|
+
| 📢 **I/O** | `broadcast` (print) and `interact` (input) |
|
|
39
|
+
| 📝 **Comments** | Single-line `//` and multi-line `/* */` |
|
|
40
|
+
| 🏗️ **Built with TypeScript** | Clean, hackable, and easy to extend |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 🚀 Quick Start
|
|
45
|
+
|
|
46
|
+
### Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Clone the repository
|
|
50
|
+
git clone <repo-url>
|
|
51
|
+
cd toy-programming-language
|
|
52
|
+
|
|
53
|
+
# Install dependencies
|
|
54
|
+
npm install
|
|
55
|
+
|
|
56
|
+
# Build the project
|
|
57
|
+
npm run build
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Hello, World!
|
|
61
|
+
|
|
62
|
+
Create a file called `hello.gg`:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
spawn {
|
|
66
|
+
broadcast("Hello, World!");
|
|
67
|
+
broadcast("Welcome to GGLang! 🎮");
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Run it:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm start -- hello.gg
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Try the REPL
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm start
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 📖 A Taste of GGLang
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
spawn {
|
|
89
|
+
// Equip your variables like items in your inventory
|
|
90
|
+
equip playerName = interact("Enter your name, adventurer: ");
|
|
91
|
+
equip health = 100;
|
|
92
|
+
artifact maxHealth = 100; // Artifacts are constants — permanent relics
|
|
93
|
+
|
|
94
|
+
// Define a skill (function)
|
|
95
|
+
skill battleCry(name) {
|
|
96
|
+
broadcast("⚔️ " + name + " charges into battle!");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Embark on a quest (if/else)
|
|
100
|
+
quest (health == maxHealth) {
|
|
101
|
+
battleCry(playerName);
|
|
102
|
+
} retreat {
|
|
103
|
+
broadcast("You need to heal first!");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Grind through enemies (while loop)
|
|
107
|
+
equip enemiesDefeated = 0;
|
|
108
|
+
grind (enemiesDefeated < 5) {
|
|
109
|
+
broadcast("Enemy #" + (enemiesDefeated + 1) + " defeated!");
|
|
110
|
+
enemiesDefeated += 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
broadcast("GG, " + playerName + "! 🏆");
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 📚 Documentation
|
|
120
|
+
|
|
121
|
+
For the complete language reference, syntax guide, and example programs, see the **[Full Documentation](docs/DOCUMENTATION.md)**.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 📂 Example Programs
|
|
126
|
+
|
|
127
|
+
| File | Description |
|
|
128
|
+
|---|---|
|
|
129
|
+
| [`hello.gg`](examples/hello.gg) | Hello World — your first spawn |
|
|
130
|
+
| [`fibonacci.gg`](examples/fibonacci.gg) | Recursive Fibonacci sequence |
|
|
131
|
+
| [`fizzbuzz.gg`](examples/fizzbuzz.gg) | Classic FizzBuzz challenge |
|
|
132
|
+
| [`adventure.gg`](examples/adventure.gg) | Mini text adventure game |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 🗺️ Keyword Cheat Sheet
|
|
137
|
+
|
|
138
|
+
| Concept | GGLang | You'd normally write… |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| Start program | `spawn { }` | `main()` |
|
|
141
|
+
| Variable | `equip x = 5;` | `let x = 5;` |
|
|
142
|
+
| Constant | `artifact PI = 3.14;` | `const PI = 3.14;` |
|
|
143
|
+
| Print | `broadcast("hi");` | `console.log("hi");` |
|
|
144
|
+
| If / Else if / Else | `quest / side_quest / retreat` | `if / else if / else` |
|
|
145
|
+
| While loop | `grind (cond) { }` | `while (cond) { }` |
|
|
146
|
+
| Break / Continue | `rage_quit / respawn` | `break / continue` |
|
|
147
|
+
| Function / Return | `skill fn() { loot val; }` | `function fn() { return val; }` |
|
|
148
|
+
| True / False / Null | `victory / defeat / phantom` | `true / false / null` |
|
|
149
|
+
| Try / Catch | `boss_fight { } revive(e) { }` | `try { } catch(e) { }` |
|
|
150
|
+
| Throw error | `glitch "msg";` | `throw "msg";` |
|
|
151
|
+
| Input | `interact("prompt")` | `readline("prompt")` |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 📄 License
|
|
156
|
+
|
|
157
|
+
This project is licensed under the **MIT License** — do whatever you want with it. GG! 🎮
|
|
158
|
+
]]>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { RuntimeValue } from './types';
|
|
2
|
+
export declare class Environment {
|
|
3
|
+
/** Map of variable names to their entries in the current scope */
|
|
4
|
+
private variables;
|
|
5
|
+
/** Reference to the enclosing (parent) scope, or null for global */
|
|
6
|
+
private parent;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new environment scope.
|
|
9
|
+
* @param parent - The enclosing environment. Omit for the global scope.
|
|
10
|
+
*/
|
|
11
|
+
constructor(parent?: Environment);
|
|
12
|
+
/**
|
|
13
|
+
* Declares a new variable in the current scope.
|
|
14
|
+
* Throws if a variable with the same name already exists in this scope.
|
|
15
|
+
*
|
|
16
|
+
* @param name - The variable name
|
|
17
|
+
* @param value - The initial value
|
|
18
|
+
* @param constant - Whether this variable is a constant (artifact)
|
|
19
|
+
*/
|
|
20
|
+
declare(name: string, value: RuntimeValue, constant: boolean): void;
|
|
21
|
+
/**
|
|
22
|
+
* Looks up a variable by name, walking up the parent chain.
|
|
23
|
+
* Throws GGRuntimeError if the variable is not found in any scope.
|
|
24
|
+
*
|
|
25
|
+
* @param name - The variable name to look up
|
|
26
|
+
* @returns The variable's current runtime value
|
|
27
|
+
*/
|
|
28
|
+
get(name: string): RuntimeValue;
|
|
29
|
+
/**
|
|
30
|
+
* Updates an existing variable's value, walking up the parent chain.
|
|
31
|
+
* Throws if the variable is not found or if it's a constant (artifact).
|
|
32
|
+
*
|
|
33
|
+
* @param name - The variable name to update
|
|
34
|
+
* @param value - The new value to assign
|
|
35
|
+
*/
|
|
36
|
+
set(name: string, value: RuntimeValue): void;
|
|
37
|
+
/**
|
|
38
|
+
* Checks whether a variable exists in the current scope or any parent scope.
|
|
39
|
+
*
|
|
40
|
+
* @param name - The variable name to check
|
|
41
|
+
* @returns true if the variable is declared somewhere in the scope chain
|
|
42
|
+
*/
|
|
43
|
+
has(name: string): boolean;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAkB,MAAM,SAAS,CAAC;AAavD,qBAAa,WAAW;IACtB,kEAAkE;IAClE,OAAO,CAAC,SAAS,CAA6B;IAE9C,oEAAoE;IACpE,OAAO,CAAC,MAAM,CAAqB;IAEnC;;;OAGG;gBACS,MAAM,CAAC,EAAE,WAAW;IAKhC;;;;;;;OAOG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAUnE;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAkB/B;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI;IA2B5C;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAW3B"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// GGLang — Environment (Scope Management)
|
|
4
|
+
// Manages variable declarations, lookups, and assignments
|
|
5
|
+
// with support for lexical scoping via parent chain traversal.
|
|
6
|
+
// ============================================================
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.Environment = void 0;
|
|
9
|
+
const types_1 = require("./types");
|
|
10
|
+
// ---- Environment Class ----
|
|
11
|
+
class Environment {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new environment scope.
|
|
14
|
+
* @param parent - The enclosing environment. Omit for the global scope.
|
|
15
|
+
*/
|
|
16
|
+
constructor(parent) {
|
|
17
|
+
this.variables = new Map();
|
|
18
|
+
this.parent = parent ?? null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Declares a new variable in the current scope.
|
|
22
|
+
* Throws if a variable with the same name already exists in this scope.
|
|
23
|
+
*
|
|
24
|
+
* @param name - The variable name
|
|
25
|
+
* @param value - The initial value
|
|
26
|
+
* @param constant - Whether this variable is a constant (artifact)
|
|
27
|
+
*/
|
|
28
|
+
declare(name, value, constant) {
|
|
29
|
+
if (this.variables.has(name)) {
|
|
30
|
+
throw new types_1.GGRuntimeError(`Variable '${name}' is already equipped in this scope! Cannot re-declare.`);
|
|
31
|
+
}
|
|
32
|
+
this.variables.set(name, { value, constant });
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Looks up a variable by name, walking up the parent chain.
|
|
36
|
+
* Throws GGRuntimeError if the variable is not found in any scope.
|
|
37
|
+
*
|
|
38
|
+
* @param name - The variable name to look up
|
|
39
|
+
* @returns The variable's current runtime value
|
|
40
|
+
*/
|
|
41
|
+
get(name) {
|
|
42
|
+
const entry = this.variables.get(name);
|
|
43
|
+
if (entry !== undefined) {
|
|
44
|
+
return entry.value;
|
|
45
|
+
}
|
|
46
|
+
// Walk up the scope chain
|
|
47
|
+
if (this.parent) {
|
|
48
|
+
return this.parent.get(name);
|
|
49
|
+
}
|
|
50
|
+
// Variable not found in any scope
|
|
51
|
+
throw new types_1.GGRuntimeError(`Variable '${name}' is not equipped! You must equip it before using it.`);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Updates an existing variable's value, walking up the parent chain.
|
|
55
|
+
* Throws if the variable is not found or if it's a constant (artifact).
|
|
56
|
+
*
|
|
57
|
+
* @param name - The variable name to update
|
|
58
|
+
* @param value - The new value to assign
|
|
59
|
+
*/
|
|
60
|
+
set(name, value) {
|
|
61
|
+
const entry = this.variables.get(name);
|
|
62
|
+
if (entry !== undefined) {
|
|
63
|
+
// Found in current scope — check if it's a constant
|
|
64
|
+
if (entry.constant) {
|
|
65
|
+
throw new types_1.GGRuntimeError(`Cannot reassign artifact '${name}'! Artifacts are immutable legendary items.`);
|
|
66
|
+
}
|
|
67
|
+
entry.value = value;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Walk up the scope chain
|
|
71
|
+
if (this.parent) {
|
|
72
|
+
this.parent.set(name, value);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Variable not found in any scope
|
|
76
|
+
throw new types_1.GGRuntimeError(`Variable '${name}' is not equipped! You must equip it before assigning to it.`);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Checks whether a variable exists in the current scope or any parent scope.
|
|
80
|
+
*
|
|
81
|
+
* @param name - The variable name to check
|
|
82
|
+
* @returns true if the variable is declared somewhere in the scope chain
|
|
83
|
+
*/
|
|
84
|
+
has(name) {
|
|
85
|
+
if (this.variables.has(name)) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
if (this.parent) {
|
|
89
|
+
return this.parent.has(name);
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.Environment = Environment;
|
|
95
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,0CAA0C;AAC1C,0DAA0D;AAC1D,+DAA+D;AAC/D,+DAA+D;;;AAE/D,mCAAuD;AAWvD,8BAA8B;AAE9B,MAAa,WAAW;IAOtB;;;OAGG;IACH,YAAY,MAAoB;QAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,IAAI,CAAC;IAC/B,CAAC;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,IAAY,EAAE,KAAmB,EAAE,QAAiB;QAC1D,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,sBAAc,CACtB,aAAa,IAAI,yDAAyD,CAC3E,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAChD,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,IAAY;QACd,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC,KAAK,CAAC;QACrB,CAAC;QAED,0BAA0B;QAC1B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,kCAAkC;QAClC,MAAM,IAAI,sBAAc,CACtB,aAAa,IAAI,uDAAuD,CACzE,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,IAAY,EAAE,KAAmB;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,oDAAoD;YACpD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,MAAM,IAAI,sBAAc,CACtB,6BAA6B,IAAI,6CAA6C,CAC/E,CAAC;YACJ,CAAC;YAED,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YACpB,OAAO;QACT,CAAC;QAED,0BAA0B;QAC1B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,kCAAkC;QAClC,MAAM,IAAI,sBAAc,CACtB,aAAa,IAAI,8DAA8D,CAChF,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,IAAY;QACd,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AA9GD,kCA8GC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
// ============================================================
|
|
4
|
+
// GGLang — CLI Entry Point
|
|
5
|
+
// Run a .gg source file or start an interactive REPL session.
|
|
6
|
+
//
|
|
7
|
+
// Usage:
|
|
8
|
+
// gglang <filename.gg> — execute a source file
|
|
9
|
+
// gglang — start the REPL
|
|
10
|
+
// ============================================================
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const readline = __importStar(require("readline"));
|
|
48
|
+
const lexer_1 = require("./lexer");
|
|
49
|
+
const parser_1 = require("./parser");
|
|
50
|
+
const interpreter_1 = require("./interpreter");
|
|
51
|
+
// ---- Constants ----
|
|
52
|
+
const VERSION = '1.0.0';
|
|
53
|
+
const VICTORY_BANNER = '\n🏆 VICTORY ROYALE! Program executed successfully.\n';
|
|
54
|
+
const GAME_OVER_BANNER = '\n💀 GAME OVER!\n';
|
|
55
|
+
// ============================================================
|
|
56
|
+
// File Execution Mode
|
|
57
|
+
// ============================================================
|
|
58
|
+
/**
|
|
59
|
+
* Reads a .gg source file, tokenizes it, parses the AST,
|
|
60
|
+
* and executes it through the interpreter.
|
|
61
|
+
*
|
|
62
|
+
* @param filePath - Path to the .gg source file
|
|
63
|
+
*/
|
|
64
|
+
function runFile(filePath) {
|
|
65
|
+
// Resolve to an absolute path
|
|
66
|
+
const resolvedPath = path.resolve(filePath);
|
|
67
|
+
// Check that the file exists
|
|
68
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
69
|
+
console.error(`${GAME_OVER_BANNER}❌ File not found: ${resolvedPath}`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
// Read the source code
|
|
73
|
+
const source = fs.readFileSync(resolvedPath, 'utf-8');
|
|
74
|
+
try {
|
|
75
|
+
// Pipeline: Source → Tokens → AST → Execution
|
|
76
|
+
const lexer = new lexer_1.Lexer();
|
|
77
|
+
const tokens = lexer.tokenize(source);
|
|
78
|
+
const parser = new parser_1.Parser();
|
|
79
|
+
const program = parser.parse(tokens);
|
|
80
|
+
const interpreter = new interpreter_1.Interpreter();
|
|
81
|
+
interpreter.execute(program);
|
|
82
|
+
console.log(VICTORY_BANNER);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error(GAME_OVER_BANNER);
|
|
86
|
+
if (error instanceof Error) {
|
|
87
|
+
console.error(` ${error.message}\n`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
console.error(` Unknown error: ${error}\n`);
|
|
91
|
+
}
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// ============================================================
|
|
96
|
+
// REPL Mode (Read-Eval-Print Loop)
|
|
97
|
+
// ============================================================
|
|
98
|
+
/**
|
|
99
|
+
* Starts an interactive REPL session.
|
|
100
|
+
* Each line is independently lexed, parsed, and executed.
|
|
101
|
+
* State persists across lines (same interpreter instance).
|
|
102
|
+
*
|
|
103
|
+
* In REPL mode, the `spawn { }` wrapper is NOT required —
|
|
104
|
+
* statements are executed directly.
|
|
105
|
+
*/
|
|
106
|
+
function startRepl() {
|
|
107
|
+
// Print the welcome banner
|
|
108
|
+
console.log('');
|
|
109
|
+
console.log('╔══════════════════════════════════════════════╗');
|
|
110
|
+
console.log('║ 🎮 GGLang REPL v' + VERSION + ' — Type your code, hero! ║');
|
|
111
|
+
console.log('║ Type "exit" or press Ctrl+C to quit. ║');
|
|
112
|
+
console.log('╚══════════════════════════════════════════════╝');
|
|
113
|
+
console.log('');
|
|
114
|
+
// Create readline interface for interactive input
|
|
115
|
+
const rl = readline.createInterface({
|
|
116
|
+
input: process.stdin,
|
|
117
|
+
output: process.stdout,
|
|
118
|
+
prompt: '⚔️ > ',
|
|
119
|
+
});
|
|
120
|
+
// Persistent interpreter instance — state carries across lines
|
|
121
|
+
const interpreter = new interpreter_1.Interpreter();
|
|
122
|
+
// Buffer for multi-line input (tracks unmatched braces)
|
|
123
|
+
let inputBuffer = '';
|
|
124
|
+
let braceDepth = 0;
|
|
125
|
+
rl.prompt();
|
|
126
|
+
rl.on('line', (line) => {
|
|
127
|
+
const trimmed = line.trim();
|
|
128
|
+
// ---- Exit command ----
|
|
129
|
+
if (trimmed === 'exit' && braceDepth === 0) {
|
|
130
|
+
console.log('\n👋 GG, hero! Until next time.\n');
|
|
131
|
+
rl.close();
|
|
132
|
+
process.exit(0);
|
|
133
|
+
}
|
|
134
|
+
// Accumulate input and track brace depth for multi-line blocks
|
|
135
|
+
inputBuffer += line + '\n';
|
|
136
|
+
braceDepth += countChar(line, '{') - countChar(line, '}');
|
|
137
|
+
// If braces are balanced, attempt to execute the buffered input
|
|
138
|
+
if (braceDepth <= 0) {
|
|
139
|
+
braceDepth = 0;
|
|
140
|
+
const source = inputBuffer.trim();
|
|
141
|
+
inputBuffer = '';
|
|
142
|
+
if (source.length === 0) {
|
|
143
|
+
rl.prompt();
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
// In REPL mode, we wrap the input so it doesn't need `spawn { }`
|
|
148
|
+
const lexer = new lexer_1.Lexer();
|
|
149
|
+
const tokens = lexer.tokenize(source);
|
|
150
|
+
const parser = new parser_1.Parser();
|
|
151
|
+
const program = parser.parse(tokens);
|
|
152
|
+
interpreter.execute(program);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
if (error instanceof Error) {
|
|
156
|
+
console.error(` 💥 ${error.message}`);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
console.error(` 💥 Unknown error: ${error}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
rl.prompt();
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Still waiting for more input — show continuation prompt
|
|
166
|
+
process.stdout.write('... ');
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
rl.on('close', () => {
|
|
170
|
+
console.log('\n👋 GG, hero! Until next time.\n');
|
|
171
|
+
process.exit(0);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// ---- Utilities ----
|
|
175
|
+
/**
|
|
176
|
+
* Counts occurrences of a character in a string.
|
|
177
|
+
* Used for tracking brace depth in the REPL.
|
|
178
|
+
*/
|
|
179
|
+
function countChar(str, char) {
|
|
180
|
+
let count = 0;
|
|
181
|
+
for (const c of str) {
|
|
182
|
+
if (c === char)
|
|
183
|
+
count++;
|
|
184
|
+
}
|
|
185
|
+
return count;
|
|
186
|
+
}
|
|
187
|
+
// ============================================================
|
|
188
|
+
// Main — Parse CLI args and dispatch
|
|
189
|
+
// ============================================================
|
|
190
|
+
const filename = process.argv[2];
|
|
191
|
+
if (filename) {
|
|
192
|
+
// File execution mode
|
|
193
|
+
runFile(filename);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// Interactive REPL mode
|
|
197
|
+
startRepl();
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Program } from './types';
|
|
2
|
+
export declare class Interpreter {
|
|
3
|
+
/** The top-level global environment */
|
|
4
|
+
private globalEnv;
|
|
5
|
+
constructor();
|
|
6
|
+
/**
|
|
7
|
+
* Executes a parsed GGLang program.
|
|
8
|
+
* Iterates over every statement in the program body and executes it
|
|
9
|
+
* within the global environment.
|
|
10
|
+
*
|
|
11
|
+
* @param program - The AST root node (Program)
|
|
12
|
+
*/
|
|
13
|
+
execute(program: Program): void;
|
|
14
|
+
/**
|
|
15
|
+
* Dispatches a statement to its corresponding handler based on type.
|
|
16
|
+
*
|
|
17
|
+
* @param stmt - The AST statement node
|
|
18
|
+
* @param env - The current environment scope
|
|
19
|
+
*/
|
|
20
|
+
private executeStatement;
|
|
21
|
+
/**
|
|
22
|
+
* equip / artifact — Declare a new variable or constant.
|
|
23
|
+
*/
|
|
24
|
+
private executeVariableDeclaration;
|
|
25
|
+
/**
|
|
26
|
+
* name = expr — Assign a new value to an existing variable.
|
|
27
|
+
*/
|
|
28
|
+
private executeAssignment;
|
|
29
|
+
/**
|
|
30
|
+
* name += expr (and -=, *=, /=) — Compound assignment.
|
|
31
|
+
* Reads the current value, applies the operator, and writes back.
|
|
32
|
+
*/
|
|
33
|
+
private executeCompoundAssignment;
|
|
34
|
+
/**
|
|
35
|
+
* broadcast(expr) — Print a value to stdout with GGLang formatting.
|
|
36
|
+
* Strings are printed without surrounding quotes.
|
|
37
|
+
* null → 'phantom', true → 'victory', false → 'defeat'
|
|
38
|
+
*/
|
|
39
|
+
private executePrint;
|
|
40
|
+
/**
|
|
41
|
+
* quest / side_quest / retreat — Conditional branching.
|
|
42
|
+
*/
|
|
43
|
+
private executeIf;
|
|
44
|
+
/**
|
|
45
|
+
* grind { ... } — While loop with break/continue support.
|
|
46
|
+
*/
|
|
47
|
+
private executeWhile;
|
|
48
|
+
/**
|
|
49
|
+
* skill name(params) { ... } — Declare a function with closure capture.
|
|
50
|
+
* The function remembers the environment where it was declared.
|
|
51
|
+
*/
|
|
52
|
+
private executeFunctionDeclaration;
|
|
53
|
+
/**
|
|
54
|
+
* loot expr — Return a value from a function.
|
|
55
|
+
* Throws a ReturnSignal that carries the return value up the stack.
|
|
56
|
+
*/
|
|
57
|
+
private executeReturn;
|
|
58
|
+
/**
|
|
59
|
+
* glitch expr — Throw a runtime error with a user-defined message.
|
|
60
|
+
*/
|
|
61
|
+
private executeThrow;
|
|
62
|
+
/**
|
|
63
|
+
* boss_fight { ... } revive(err) { ... } — Try/catch for error handling.
|
|
64
|
+
* Only catches GGRuntimeError (user-level errors), not internal signals.
|
|
65
|
+
*/
|
|
66
|
+
private executeTryCatch;
|
|
67
|
+
/**
|
|
68
|
+
* Evaluates an expression node and returns its runtime value.
|
|
69
|
+
*
|
|
70
|
+
* @param expr - The AST expression node
|
|
71
|
+
* @param env - The current environment scope
|
|
72
|
+
* @returns The evaluated RuntimeValue
|
|
73
|
+
*/
|
|
74
|
+
private evaluateExpression;
|
|
75
|
+
/**
|
|
76
|
+
* Evaluates binary expressions: arithmetic, comparison, and string concatenation.
|
|
77
|
+
*/
|
|
78
|
+
private evaluateBinaryExpression;
|
|
79
|
+
/**
|
|
80
|
+
* Evaluates unary expressions: negation (-) and logical not (!).
|
|
81
|
+
*/
|
|
82
|
+
private evaluateUnaryExpression;
|
|
83
|
+
/**
|
|
84
|
+
* Evaluates logical expressions with short-circuit semantics.
|
|
85
|
+
* && returns the first falsy value or the last value.
|
|
86
|
+
* || returns the first truthy value or the last value.
|
|
87
|
+
*/
|
|
88
|
+
private evaluateLogicalExpression;
|
|
89
|
+
/**
|
|
90
|
+
* Evaluates a function call expression.
|
|
91
|
+
* Handles the built-in 'interact' function (reads user input from stdin)
|
|
92
|
+
* and user-defined functions (with closure support).
|
|
93
|
+
*/
|
|
94
|
+
private evaluateCallExpression;
|
|
95
|
+
/**
|
|
96
|
+
* Executes a block of statements in a new child scope.
|
|
97
|
+
* This ensures variables declared inside the block don't leak out.
|
|
98
|
+
*/
|
|
99
|
+
private executeBlock;
|
|
100
|
+
/**
|
|
101
|
+
* Determines the truthiness of a GGLang value.
|
|
102
|
+
* - false, null, 0, and "" are falsy
|
|
103
|
+
* - Everything else (including functions) is truthy
|
|
104
|
+
*/
|
|
105
|
+
private isTruthy;
|
|
106
|
+
/**
|
|
107
|
+
* Asserts that a value is a number, throwing a runtime error if not.
|
|
108
|
+
* Used by arithmetic operators to enforce type safety.
|
|
109
|
+
*/
|
|
110
|
+
private assertNumber;
|
|
111
|
+
/**
|
|
112
|
+
* Formats a RuntimeValue for display (used by broadcast and string coercion).
|
|
113
|
+
* - Strings are returned as-is (no surrounding quotes)
|
|
114
|
+
* - null → 'phantom'
|
|
115
|
+
* - true → 'victory', false → 'defeat'
|
|
116
|
+
* - Numbers are stringified normally
|
|
117
|
+
* - Functions show as '<skill name>'
|
|
118
|
+
*/
|
|
119
|
+
private formatValue;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=interpreter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../src/interpreter.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,OAAO,EAqBR,MAAM,SAAS,CAAC;AA0EjB,qBAAa,WAAW;IACtB,uCAAuC;IACvC,OAAO,CAAC,SAAS,CAAc;;IAQ/B;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAQ/B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAiDxB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAQlC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAgDjC;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,OAAO,CAAC,SAAS;IAqBjB;;OAEG;IACH,OAAO,CAAC,YAAY;IAgBpB;;;OAGG;IACH,OAAO,CAAC,0BAA0B;IAclC;;;OAGG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAmBvB;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAoC1B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAqEhC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAkB/B;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IAsBjC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAiE9B;;;OAGG;IACH,OAAO,CAAC,YAAY;IAOpB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAUpB;;;;;;;OAOG;IACH,OAAO,CAAC,WAAW;CAUpB"}
|