noahlang 0.0.0-stage → 2.0.3

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/README.md CHANGED
@@ -1,3 +1,384 @@
1
- # Temporary Holding Version
1
+ # NoahLang for VS Code
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Syntax highlighting, snippets, and language support for **NoahLang** — a small, indentation-based teaching language.
4
+
5
+ > **Interpreter:** v1.1.0 · **Extension:** 0.1.0
6
+
7
+ ## Features
8
+
9
+ - Syntax highlighting for `.noah` files
10
+ - Snippets for common statements
11
+ - Variable declarations with `let`
12
+ - Variable reassignment with `set`
13
+ - Output with `write`
14
+ - Function definitions and calls
15
+ - `if` / `else` conditionals
16
+ - Arithmetic, comparison operators, strings, booleans, and `null`
17
+
18
+ > Hover documentation, live diagnostics, formatting, pipelines, loops, indexing, pattern-matching function clauses, and string interpolation are not documented as implemented features here because they are not supported by the interpreter source currently provided.
19
+
20
+ ## Table of contents
21
+
22
+ - [Install](#install)
23
+ - [Quick start](#quick-start)
24
+ - [Language guide](#language-guide)
25
+ - [Comments](#comments)
26
+ - [Variables](#variables)
27
+ - [Values](#values)
28
+ - [Operators](#operators)
29
+ - [Conditionals](#conditionals)
30
+ - [Functions](#functions)
31
+ - [Built-in functions](#built-in-functions)
32
+ - [Examples](#examples)
33
+ - [CLI](#cli)
34
+ - [Error format](#error-format)
35
+ - [Cheat sheet](#cheat-sheet)
36
+ - [VS Code extension development](#-vs-code-extension-development)
37
+ - [Contributing](#contributing)
38
+ - [License](#license)
39
+
40
+ ---
41
+
42
+ ## Install
43
+
44
+ ### Run the interpreter
45
+
46
+ Make sure [Node.js](https://nodejs.org/) is installed. Save the interpreter as `noah.js`, then run a NoahLang file:
47
+
48
+ ```bash
49
+ node noah.js hello.noah
50
+ ```
51
+
52
+ If the `noah` command has been installed and configured on your system, you can run:
53
+
54
+ ```bash
55
+ noah hello.noah
56
+ ```
57
+
58
+ ### Install the VS Code extension from source
59
+
60
+ From the extension repository:
61
+
62
+ ```bash
63
+ git clone https://github.com/NoahKahenge/noahlang-vscode
64
+ cd noahlang-vscode
65
+ npm install
66
+ ```
67
+
68
+ Package and install the extension using the scripts configured in your repository. For example, if `vsce` and a `package` script are configured:
69
+
70
+ ```bash
71
+ npm run package
72
+ code --install-extension noahlang-0.1.0.vsix
73
+ ```
74
+
75
+ The repository URL, script names, and generated VSIX filename should be checked against the actual project before running these commands.
76
+
77
+ ---
78
+
79
+ ## Quick start
80
+
81
+ Create a file named `hello.noah`:
82
+
83
+ ```noah
84
+ let name = "world"
85
+ write "Hello, " + name
86
+ ```
87
+
88
+ Run it:
89
+
90
+ ```bash
91
+ node noah.js hello.noah
92
+ ```
93
+
94
+ Expected output:
95
+
96
+ ```text
97
+ Hello, world
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Language guide
103
+
104
+ NoahLang uses indentation to group statements inside functions and conditionals. Blocks begin with a colon (`:`), and their statements must be indented. Tabs are treated as four spaces by the interpreter.
105
+
106
+ ### Comments
107
+
108
+ Use `//` for single-line comments. Comments can also appear after a statement.
109
+
110
+ ```noah
111
+ // This is a comment
112
+ let x = 10 // This is a trailing comment
113
+ write x
114
+ ```
115
+
116
+ ### Variables
117
+
118
+ | Form | Meaning |
119
+ |---|---|
120
+ | `let name = expression` | Declare or assign a variable in the current environment. |
121
+ | `set name = expression` | Reassign an existing variable. The name must already exist in the current environment. |
122
+
123
+ Example:
124
+
125
+ ```noah
126
+ let age = 42
127
+ set age = age + 1
128
+ write age
129
+ ```
130
+
131
+ Output:
132
+
133
+ ```text
134
+ 43
135
+ ```
136
+
137
+ Using `set` before declaring a variable with `let` produces an error:
138
+
139
+ ```noah
140
+ set score = 100
141
+ ```
142
+
143
+ ### Values
144
+
145
+ | Type | Examples |
146
+ |---|---|
147
+ | Number | `42`, `3.14`, `-7` |
148
+ | String | `"hello"`, `'hi'`, `"line\nbreak"` |
149
+ | Boolean | `true`, `false` |
150
+ | Null | `null` |
151
+ | Array-like value | `collect(1, 2, 3)` |
152
+
153
+ `collect(...)` currently returns a JavaScript array from the interpreter's built-in function. Array indexing and array-specific helper functions are not implemented in the provided interpreter.
154
+
155
+ ### Operators
156
+
157
+ | Operators | Meaning |
158
+ |---|---|
159
+ | `(...)` | Grouping expressions |
160
+ | Unary `-`, `+` | Negative or positive numeric value |
161
+ | `*`, `/`, `%` | Multiplication, division, remainder |
162
+ | `+`, `-` | Addition or subtraction; `+` concatenates when either operand is a string |
163
+ | `==`, `!=` | Strict equality and inequality |
164
+ | `<`, `>`, `<=`, `>=` | Comparisons |
165
+
166
+ Division by zero raises a NoahLang error. Arithmetic operations convert operands to numbers where needed.
167
+
168
+ ### Conditionals
169
+
170
+ Use `if` and `else` with an indented block:
171
+
172
+ ```noah
173
+ let score = 72
174
+
175
+ if score >= 50:
176
+ write "Pass"
177
+ else:
178
+ write "Try again"
179
+ ```
180
+
181
+ The condition is evaluated using JavaScript truthiness. Comparisons such as `score >= 50` return a Boolean.
182
+
183
+ The currently provided interpreter supports `if` and `else`. Chained `else if` and conditional expressions have not been implemented in this version.
184
+
185
+ ### Functions
186
+
187
+ Define functions using `define name(parameters):` followed by an indented body.
188
+
189
+ ```noah
190
+ define greet(name):
191
+ write "Hello, " + name
192
+
193
+ greet("Noah")
194
+ ```
195
+
196
+ Output:
197
+
198
+ ```text
199
+ Hello, Noah
200
+ ```
201
+
202
+ Functions can accept parameters and use `return` to return a value:
203
+
204
+ ```noah
205
+ define add(a, b):
206
+ return a + b
207
+
208
+ let result = add(5, 7)
209
+ write result
210
+ ```
211
+
212
+ Output:
213
+
214
+ ```text
215
+ 12
216
+ ```
217
+
218
+ A function that reaches the end without an explicit `return` returns `null`.
219
+
220
+ The current interpreter does not support the brace-based function syntax (`define greet() { ... }`) or the multi-clause pattern-matching syntax shown in some proposed NoahLang examples.
221
+
222
+ ### Built-in functions
223
+
224
+ | Function | Current behavior |
225
+ |---|---|
226
+ | `write(...)` | The expression-level built-in prints its arguments separated by spaces. The `write expression` statement also prints a value. |
227
+ | `collect(a, b, ...)` | Returns the supplied arguments as an array. |
228
+ | `receive()` | Returns the next value supplied through the interpreter's `input` option, if one exists. Otherwise, it raises an error because interactive input is not enabled in this build. |
229
+
230
+ For example, `collect(1, 2, 3)` returns an array, but array indexing and functions such as `len`, `append`, and `remove` are not currently implemented.
231
+
232
+ ---
233
+
234
+ ## Examples
235
+
236
+ ### Variable reassignment
237
+
238
+ ```noah
239
+ let x = 5
240
+ set x = x + 1
241
+ write x
242
+ ```
243
+
244
+ Output:
245
+
246
+ ```text
247
+ 6
248
+ ```
249
+
250
+ ### Conditional and reassignment
251
+
252
+ ```noah
253
+ let x = 5
254
+
255
+ if x >= 5:
256
+ set x = x - 1
257
+
258
+ write x
259
+ ```
260
+
261
+ Output:
262
+
263
+ ```text
264
+ 4
265
+ ```
266
+
267
+ ### Function with a return value
268
+
269
+ ```noah
270
+ define square(n):
271
+ return n * n
272
+
273
+ write square(7)
274
+ ```
275
+
276
+ Output:
277
+
278
+ ```text
279
+ 49
280
+ ```
281
+
282
+ ### String concatenation
283
+
284
+ ```noah
285
+ let name = "Noah"
286
+ write "Hello, " + name
287
+ ```
288
+
289
+ Output:
290
+
291
+ ```text
292
+ Hello, Noah
293
+ ```
294
+
295
+ ---
296
+
297
+ ## CLI
298
+
299
+ ```text
300
+ noah <file.noah> Run a NoahLang program
301
+ noah --version Display the interpreter version
302
+ noah -v Display the interpreter version
303
+ ```
304
+
305
+ If you run the interpreter directly with Node.js:
306
+
307
+ ```bash
308
+ node noah.js --version
309
+ node noah.js hello.noah
310
+ ```
311
+
312
+ The current interpreter prints `NoahLang 1.1.0` for the version command. It does not currently implement `--help`, interactive terminal input, or piped input for `receive()`.
313
+
314
+ ### Exit codes
315
+
316
+ - `0`: successful execution or successful version display
317
+ - `1`: missing filename, missing file, or a language/runtime error
318
+
319
+ ---
320
+
321
+ ## Error format
322
+
323
+ Errors are printed to the terminal in this form:
324
+
325
+ ```text
326
+ NoahLang error: Line 3: undefined variable 'score'
327
+ ```
328
+
329
+ The interpreter reports the line number and error description. Column numbers and source-line caret diagnostics are not currently implemented.
330
+
331
+ ---
332
+
333
+ ## Cheat sheet
334
+
335
+ | Task | Syntax |
336
+ |---|---|
337
+ | Comment | `// note` |
338
+ | Declare a variable | `let x = 5` |
339
+ | Reassign a variable | `set x = 6` |
340
+ | Print a value | `write x` |
341
+ | Concatenate strings | `write "Hello, " + name` |
342
+ | Define a function | `define greet(name):` |
343
+ | Call a function | `greet("Noah")` |
344
+ | Return a value | `return value` |
345
+ | Conditional | `if condition:` |
346
+ | Alternative branch | `else:` |
347
+ | Create an array-like value | `collect(1, 2, 3)` |
348
+
349
+ ---
350
+
351
+ ## VS Code extension development
352
+
353
+ This repository is intended to provide NoahLang language support in Visual Studio Code. The exact extension features depend on the files and contributions configured in the repository's `package.json`.
354
+
355
+ Common VS Code extension project files include:
356
+
357
+ - `package.json` — extension metadata and contributed features
358
+ - `syntaxes/noahlang.tmLanguage.json` — TextMate syntax grammar
359
+ - `snippets/noahlang.json` — editor snippets
360
+ - `language-configuration.json` — comments, brackets, and indentation settings
361
+ - `examples/` — sample `.noah` programs
362
+
363
+ Open the repository in VS Code and press **F5** to launch an Extension Development Host if the project has a debug configuration set up.
364
+
365
+ To package the extension, ensure the VS Code Extension Manager (`vsce`) and a packaging script are configured. Do not assume a particular script or output filename until you verify the repository's `package.json`.
366
+
367
+ ---
368
+
369
+ ## Contributing
370
+
371
+ Issues and pull requests are welcome.
372
+
373
+ 1. Create a branch for your change.
374
+ 2. Keep documentation examples consistent with the interpreter's implemented syntax.
375
+ 3. Add or update `.noah` examples when introducing language features.
376
+ 4. Test examples using the interpreter before documenting them as supported.
377
+
378
+ ---
379
+
380
+ ## License
381
+
382
+ MIT © Noah Kahenge
383
+
384
+ If the repository uses a different license, update this section to match the project's `LICENSE` file.
package/lib/Forge.noah ADDED
@@ -0,0 +1,197 @@
1
+ // lib/Forge.noah — NoahLang web library (extended)
2
+ // Layout functions: nav, hero, cards, columns, footer.
3
+ // CSS lives in style.css (linked from done()).
4
+ // v2.0.2 syntax: every define ends with end define.
5
+
6
+ let __pageTitle = ""
7
+ let __pageBody = ""
8
+ let __nextId = 0
9
+
10
+ define escapeHtml(text)
11
+ let out = ""
12
+ let i = 0
13
+ while i < len(text)
14
+ let ch = text[i]
15
+ if ch == "<"
16
+ set out = out + "&lt;"
17
+ else if ch == ">"
18
+ set out = out + "&gt;"
19
+ else if ch == "&"
20
+ set out = out + "&amp;"
21
+ else if ch == "\""
22
+ set out = out + "&quot;"
23
+ else
24
+ set out = out + ch
25
+ end if
26
+ set i = i + 1
27
+ end while
28
+ return out
29
+ end define
30
+
31
+ define newId(prefix)
32
+ set __nextId = __nextId + 1
33
+ return prefix + "-" + str(__nextId)
34
+ end define
35
+
36
+ define addRaw(html)
37
+ set __pageBody = __pageBody + html + "\n"
38
+ end define
39
+
40
+ define page(name)
41
+ set __pageTitle = name
42
+ set __pageBody = ""
43
+ set __nextId = 0
44
+ end define
45
+
46
+ define head1(text)
47
+ let html = "<h1>" + escapeHtml(text) + "</h1>"
48
+ addRaw(html)
49
+ return html
50
+ end define
51
+
52
+ define head2(text)
53
+ let html = "<h2>" + escapeHtml(text) + "</h2>"
54
+ addRaw(html)
55
+ return html
56
+ end define
57
+
58
+ define head3(text)
59
+ let html = "<h3>" + escapeHtml(text) + "</h3>"
60
+ addRaw(html)
61
+ return html
62
+ end define
63
+
64
+ define para(content)
65
+ let html = "<p>" + escapeHtml(content) + "</p>"
66
+ addRaw(html)
67
+ return html
68
+ end define
69
+
70
+ define line(content)
71
+ let html = "<span>" + escapeHtml(content) + "</span>"
72
+ addRaw(html)
73
+ return html
74
+ end define
75
+
76
+ define code(content)
77
+ let html = "<pre><code>" + escapeHtml(content) + "</code></pre>"
78
+ addRaw(html)
79
+ return html
80
+ end define
81
+
82
+ define link(url, label)
83
+ let html = "<a href=\"" + escapeHtml(url) + "\">" + escapeHtml(label) + "</a>"
84
+ addRaw(html)
85
+ return html
86
+ end define
87
+
88
+ define button(label, eventId)
89
+ let handler = "fetch('/__event?id=" + escapeHtml(eventId) + "').then(function()\{location.reload()\})"
90
+ let html = "<button onclick=\"" + handler + "\">" + escapeHtml(label) + "</button>"
91
+ addRaw(html)
92
+ return html
93
+ end define
94
+
95
+ define section(className)
96
+ addRaw("<section class=\"" + escapeHtml(className) + "\">")
97
+ end define
98
+
99
+ define endSection()
100
+ addRaw("</section>")
101
+ end define
102
+
103
+ define container()
104
+ addRaw("<div class=\"container\">")
105
+ end define
106
+
107
+ define endContainer()
108
+ addRaw("</div>")
109
+ end define
110
+
111
+ define navStart(brand)
112
+ addRaw("<nav class=\"nav\"><div class=\"container nav-inner\">")
113
+ addRaw("<a class=\"brand\" href=\"/\">" + escapeHtml(brand) + "</a>")
114
+ addRaw("<div class=\"nav-links\">")
115
+ end define
116
+
117
+ define navItem(url, label)
118
+ addRaw("<a href=\"" + escapeHtml(url) + "\">" + escapeHtml(label) + "</a>")
119
+ end define
120
+
121
+ define navEnd()
122
+ addRaw("</div></div></nav>")
123
+ end define
124
+
125
+ define hero(title, subtitle, ctaLabel, ctaUrl)
126
+ addRaw("<header class=\"hero\"><div class=\"container\">")
127
+ addRaw("<h1>" + escapeHtml(title) + "</h1>")
128
+ addRaw("<p class=\"lead\">" + escapeHtml(subtitle) + "</p>")
129
+ if ctaLabel != "" and ctaUrl != ""
130
+ addRaw("<a class=\"btn\" href=\"" + escapeHtml(ctaUrl) + "\">" + escapeHtml(ctaLabel) + "</a>")
131
+ end if
132
+ addRaw("</div></header>")
133
+ end define
134
+
135
+ define cardsStart()
136
+ addRaw("<div class=\"cards\">")
137
+ end define
138
+
139
+ define card(title, body)
140
+ addRaw("<div class=\"card\">")
141
+ addRaw("<h3>" + escapeHtml(title) + "</h3>")
142
+ addRaw("<p>" + escapeHtml(body) + "</p>")
143
+ addRaw("</div>")
144
+ end define
145
+
146
+ define cardsEnd()
147
+ addRaw("</div>")
148
+ end define
149
+
150
+ define columnsStart()
151
+ addRaw("<div class=\"columns\">")
152
+ end define
153
+
154
+ define columnStart()
155
+ addRaw("<div class=\"column\">")
156
+ end define
157
+
158
+ define columnEnd()
159
+ addRaw("</div>")
160
+ end define
161
+
162
+ define columnsEnd()
163
+ addRaw("</div>")
164
+ end define
165
+
166
+ define bulletsStart()
167
+ addRaw("<ul>")
168
+ end define
169
+
170
+ define bullet(text)
171
+ addRaw("<li>" + escapeHtml(text) + "</li>")
172
+ end define
173
+
174
+ define bulletsEnd()
175
+ addRaw("</ul>")
176
+ end define
177
+
178
+ define footer(brand, year)
179
+ addRaw("<footer class=\"footer\"><div class=\"container\">")
180
+ addRaw("<p>&copy; " + escapeHtml(str(year)) + " " + escapeHtml(brand) + ". All rights reserved.</p>")
181
+ addRaw("</div></footer>")
182
+ end define
183
+
184
+ define img(src, alt)
185
+ addRaw("<img src=\"" + escapeHtml(src) + "\" alt=\"" + escapeHtml(alt) + "\" class=\"img\">")
186
+ end define
187
+
188
+ define raw(html)
189
+ addRaw(html)
190
+ return html
191
+ end define
192
+
193
+ define done()
194
+ let html = "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>" + escapeHtml(__pageTitle) + "</title>\n<link rel=\"stylesheet\" href=\"style.css\">\n</head>\n<body>\n" + __pageBody + "</body>\n</html>"
195
+ writeToFile("index.html", html)
196
+ return html
197
+ end define
package/lib/style.css ADDED
@@ -0,0 +1,41 @@
1
+ *, *::before, *::after { box-sizing: border-box; }
2
+ body {
3
+ margin: 0;
4
+ font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
5
+ color: #1a1a1a;
6
+ line-height: 1.6;
7
+ background: #fafaf8;
8
+ }
9
+ .container { max-width: 960px; margin: 0 auto; padding: 0 24px; }
10
+
11
+ .nav { background: #fff; border-bottom: 1px solid #e5e5e5; position: sticky; top: 0; z-index: 10; }
12
+ .nav-inner { display: flex; justify-content: space-between; align-items: center; padding: 16px 24px; }
13
+ .brand { font-weight: 700; font-size: 1.1em; color: #1a1a1a; text-decoration: none; }
14
+ .nav-links a { color: #555; text-decoration: none; margin-left: 24px; font-size: 0.95em; }
15
+ .nav-links a:hover { color: #000; }
16
+
17
+ .hero { background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%); color: #fff; padding: 80px 0; text-align: center; }
18
+ .hero h1 { font-size: 2.5em; margin: 0 0 16px; }
19
+ .hero .lead { font-size: 1.2em; color: #ccc; margin: 0 0 32px; }
20
+ .btn { display: inline-block; background: #fff; color: #1a1a1a; padding: 12px 28px; border-radius: 6px; text-decoration: none; font-weight: 600; }
21
+ .btn:hover { transform: translateY(-1px); }
22
+
23
+ section { padding: 64px 0; }
24
+ h2 { font-size: 1.8em; margin: 0 0 24px; color: #1a1a1a; }
25
+ h3 { font-size: 1.2em; margin: 0 0 12px; }
26
+ p { margin: 0 0 16px; }
27
+
28
+ .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px; margin-top: 32px; }
29
+ .card { background: #fff; border: 1px solid #e5e5e5; border-radius: 8px; padding: 24px; }
30
+ .card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
31
+
32
+ .columns { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: start; }
33
+ @media (max-width: 640px) {
34
+ .columns { grid-template-columns: 1fr; }
35
+ .hero h1 { font-size: 1.8em; }
36
+ }
37
+
38
+ .footer { background: #1a1a1a; color: #999; padding: 32px 0; text-align: center; font-size: 0.9em; margin-top: 64px; }
39
+ .img { max-width: 100%; height: auto; border-radius: 8px; }
40
+ ul { padding-left: 20px; margin: 0 0 16px; }
41
+ li { margin-bottom: 8px; }