@user-synax/synax 0.0.1
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 +91 -0
- package/SPEC.md +159 -0
- package/dist/cli.js +741 -0
- package/dist/index.js +684 -0
- package/examples/fibonacci.snx +14 -0
- package/examples/fizzbuzz.snx +34 -0
- package/examples/greet.snx +5 -0
- package/examples/hello.snx +1 -0
- package/examples/if-else.snx +7 -0
- package/examples/loop.snx +3 -0
- package/examples/variables.snx +2 -0
- package/package.json +49 -0
- package/src/ast.ts +151 -0
- package/src/cli.ts +101 -0
- package/src/codegen.ts +236 -0
- package/src/diagnostics.ts +63 -0
- package/src/index.ts +11 -0
- package/src/lexer.ts +438 -0
- package/src/parser.ts +441 -0
- package/synax.d.ts +236 -0
- package/synax.html +281 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Synax 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,91 @@
|
|
|
1
|
+
# Synax
|
|
2
|
+
|
|
3
|
+
Synax is a custom scripting language that transpiles to JavaScript. You write
|
|
4
|
+
Synax source; the `synax` CLI compiles it down to plain, readable JavaScript.
|
|
5
|
+
|
|
6
|
+
The language is still being designed — the authoritative description of its
|
|
7
|
+
grammar and semantics lives in [SPEC.md](./SPEC.md). There is also
|
|
8
|
+
[synax.html](./synax.html): a single-file docs page with a live in-browser
|
|
9
|
+
playground (the whole compiler is inlined — open it, no server needed).
|
|
10
|
+
|
|
11
|
+
## Status
|
|
12
|
+
|
|
13
|
+
The pipeline is implemented end to end: source is lexed, parsed into an AST, and
|
|
14
|
+
compiled to JavaScript. See SPEC.md §9 for what is deliberately out of scope.
|
|
15
|
+
|
|
16
|
+
Two semantics were decided while building the code generator:
|
|
17
|
+
|
|
18
|
+
- `for i in 1..5` is **inclusive** of the upper bound (compiles to `i <= 5`).
|
|
19
|
+
- `+` keeps JavaScript's coercion, so `"n=" + 5` concatenates rather than
|
|
20
|
+
erroring.
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- [Bun](https://bun.sh) — package manager, test runner, and runtime
|
|
25
|
+
|
|
26
|
+
No external dependencies are used; everything runs on the Bun standard library.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
The package ships a `synax` binary and a typed library API:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
bun add synax # or: npm install synax
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Compile a file with the CLI:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
synax program.snx # prints JavaScript to stdout
|
|
40
|
+
synax examples/loop.snx # ships with the package
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or use it from code:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { generate, Lexer, Parser } from "synax";
|
|
47
|
+
|
|
48
|
+
const source = 'print "Hello, World!"';
|
|
49
|
+
const js = generate(new Parser(new Lexer(source).tokenize()).parse());
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Getting started (from source)
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
bun install # install dependencies (none yet)
|
|
56
|
+
bun test # run the test suite
|
|
57
|
+
bun run src/cli.ts <file> # compile a Synax source file to stdout
|
|
58
|
+
bun run src/cli.ts examples/loop.snx
|
|
59
|
+
bun run build # bundle the CLI and library into dist/
|
|
60
|
+
bun run docs # regenerate synax.html (docs + playground)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The compiler prints JavaScript to stdout and diagnostics to stderr, exiting
|
|
64
|
+
non-zero on a lexer, parser, or file error, so it works in a shell pipeline.
|
|
65
|
+
Diagnostics point at the source:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
examples/bad.snx:1:7: error: Unexpected character "@"
|
|
69
|
+
1 | print @
|
|
70
|
+
| ^
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Set `SYNAX_DEBUG=1` to include a stack trace for an internal compiler error.
|
|
74
|
+
|
|
75
|
+
There is also a `bun run build` script that bundles the CLI into `dist/`.
|
|
76
|
+
|
|
77
|
+
## Project layout
|
|
78
|
+
|
|
79
|
+
| Path | Purpose |
|
|
80
|
+
| ---------------- | ------------------------------------ |
|
|
81
|
+
| `src/lexer.ts` | Source text → tokens |
|
|
82
|
+
| `src/ast.ts` | AST node type definitions |
|
|
83
|
+
| `src/parser.ts` | Tokens → AST |
|
|
84
|
+
| `src/codegen.ts` | AST → JavaScript |
|
|
85
|
+
| `src/diagnostics.ts` | Positioned errors → code frames |
|
|
86
|
+
| `src/cli.ts` | Command-line entrypoint |
|
|
87
|
+
| `src/index.ts` | Public API re-exports |
|
|
88
|
+
| `examples/` | Sample `.snx` programs |
|
|
89
|
+
| `tests/` | Test suite (`bun test`) |
|
|
90
|
+
| `SPEC.md` | Language specification |
|
|
91
|
+
| `synax.d.ts` | Type declarations for the published package |
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# <Synax> — Language Specification
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## 1. Overview
|
|
6
|
+
|
|
7
|
+
- **Name:** [ Synax ]
|
|
8
|
+
- **File extension:** [ .snx ]
|
|
9
|
+
- **One-line philosophy:** [ "Reads closer to plain English than Python, no braces, no semicolons" ]
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 2. Design Principles
|
|
14
|
+
|
|
15
|
+
1. [ No curly braces — use a closing keyword instead ]
|
|
16
|
+
2. [ No semicolons, ever ]
|
|
17
|
+
3. [ One way to write a thing, not several ]
|
|
18
|
+
4. [ Prefer a plain-English keyword over a symbol when both are equally clear ]
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 3. Lexical Grammar (Tokens)
|
|
23
|
+
|
|
24
|
+
| Category | Rule | Example |
|
|
25
|
+
| ----------- | ----------------------------------------------------------------- | ------------------------------------------ |
|
|
26
|
+
| Keywords | [set, print, if, else, end, fn, for, in] | `set`, `if`, `fn`, `end` |
|
|
27
|
+
| Identifiers | [ starts with letter/underscore, then letters/digits/underscore ] | `name`, `age`, `greet`, i |
|
|
28
|
+
| Numbers | [ int and float literals] | `42`, `3.14` |
|
|
29
|
+
| Strings | [ double-quoted, + used for concat, no interpolation used yet ] | `"Hello, World!"` |
|
|
30
|
+
| Comments | [ single-line # multi-line syntax /# #/ ] | `# single line comment, /# #/ double line` |
|
|
31
|
+
| Operators | [ = assign, + concat/add, >= compare, .. range ] | `=`, `+`, `>=`, `..` |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 4. Grammar Rules
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
program := statement*
|
|
39
|
+
|
|
40
|
+
statement := varDecl | printStmt | ifStmt | fnDecl | forStmt | exprStmt
|
|
41
|
+
|
|
42
|
+
varDecl := "set" IDENT "=" expression
|
|
43
|
+
printStmt := "print" expression
|
|
44
|
+
ifStmt := "if" expression statement* ("else" statement*)? "end"
|
|
45
|
+
fnDecl := "fn" IDENT "(" paramList? ")" statement* "end"
|
|
46
|
+
forStmt := "for" IDENT "in" expression ".." expression statement* "end"
|
|
47
|
+
exprStmt := expression
|
|
48
|
+
|
|
49
|
+
paramList := IDENT ("," IDENT)*
|
|
50
|
+
argList := expression ("," expression)*
|
|
51
|
+
|
|
52
|
+
expression := comparison
|
|
53
|
+
comparison := term ((">=" | "<=" | ">" | "<" | "==" | "!=") term)*
|
|
54
|
+
term := factor (("+" | "-") factor)*
|
|
55
|
+
factor := primary (("*" | "/") primary)*
|
|
56
|
+
primary := NUMBER | STRING | IDENT | "(" expression ")" | functionCall
|
|
57
|
+
functionCall:= IDENT "(" argList? ")"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 5. Operator Precedence
|
|
63
|
+
|
|
64
|
+
Highest binds tightest. Fill top to bottom.
|
|
65
|
+
|
|
66
|
+
| Rank | Operator(s) | Associativity |
|
|
67
|
+
| ---- | ------------------- | ------------- |
|
|
68
|
+
| 1 | [ == != > < >= <= ] | [ left ] |
|
|
69
|
+
| 2 | [ + - ] | [ left ] |
|
|
70
|
+
| 3 | [ * / ] | [ left ] |
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 6. Semantics
|
|
75
|
+
|
|
76
|
+
Scoping: function-scoped — name in greet(name) only exists inside that fn ... end block. (Not directly tested by your examples, but matches your "keep it minimal" principle — confirm this is what you want.)
|
|
77
|
+
Typing: dynamic — no type annotations anywhere in your examples.
|
|
78
|
+
Truthy/falsy: not shown yet — decide what if treats as false (usually 0, "", and a null-type value).
|
|
79
|
+
Mutability: set used for both set x = 5 and set age = 19 — simplest option is set also handles reassignment (no separate const), matching your minimal-syntax goal. Flag it if you want an immutable-by-default version instead.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 7. Standard Library (MVP only)
|
|
84
|
+
|
|
85
|
+
The bare minimum to run a real program. Add nothing beyond this list for v1.
|
|
86
|
+
|
|
87
|
+
- [ ] `print(...)`
|
|
88
|
+
- [ ] string/number conversion
|
|
89
|
+
- [ ] [ ]
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 8. Example Programs
|
|
94
|
+
|
|
95
|
+
Write these by hand in your syntax. This is the most important section — do it before section 4.
|
|
96
|
+
|
|
97
|
+
**Hello World**
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
[ print "Hello, World!" ]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Variable + print**
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
[
|
|
107
|
+
set x = 5
|
|
108
|
+
print x
|
|
109
|
+
]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**If / else**
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
[
|
|
116
|
+
set age = 19
|
|
117
|
+
|
|
118
|
+
if age >= 18
|
|
119
|
+
print "adult"
|
|
120
|
+
else
|
|
121
|
+
print "minor"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Function**
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
[
|
|
131
|
+
fn greet(name)
|
|
132
|
+
print "Hello, " + name
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
greet("Ayush")
|
|
136
|
+
]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Loop**
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
[
|
|
143
|
+
for i in 1..5
|
|
144
|
+
print i
|
|
145
|
+
end
|
|
146
|
+
]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 9. Non-Goals for v1
|
|
152
|
+
|
|
153
|
+
Explicitly out of scope — revisit after the MVP works.
|
|
154
|
+
|
|
155
|
+
- Classes / OOP
|
|
156
|
+
- Modules / imports
|
|
157
|
+
- Async
|
|
158
|
+
- Generics / static type checking
|
|
159
|
+
- [ ]
|