arc-lang 0.5.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 +148 -0
- package/dist/ast.d.ts +298 -0
- package/dist/ast.js +2 -0
- package/dist/build.d.ts +7 -0
- package/dist/build.js +138 -0
- package/dist/codegen-js.d.ts +2 -0
- package/dist/codegen-js.js +168 -0
- package/dist/codegen.d.ts +2 -0
- package/dist/codegen.js +364 -0
- package/dist/errors.d.ts +52 -0
- package/dist/errors.js +229 -0
- package/dist/formatter.d.ts +5 -0
- package/dist/formatter.js +361 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +165 -0
- package/dist/interpreter.d.ts +39 -0
- package/dist/interpreter.js +668 -0
- package/dist/ir.d.ts +126 -0
- package/dist/ir.js +610 -0
- package/dist/lexer.d.ts +79 -0
- package/dist/lexer.js +335 -0
- package/dist/linter.d.ts +15 -0
- package/dist/linter.js +382 -0
- package/dist/lsp.d.ts +1 -0
- package/dist/lsp.js +253 -0
- package/dist/modules.d.ts +24 -0
- package/dist/modules.js +115 -0
- package/dist/optimizer.d.ts +17 -0
- package/dist/optimizer.js +481 -0
- package/dist/package-manager.d.ts +31 -0
- package/dist/package-manager.js +180 -0
- package/dist/parser.d.ts +42 -0
- package/dist/parser.js +779 -0
- package/dist/repl.d.ts +1 -0
- package/dist/repl.js +120 -0
- package/dist/security.d.ts +48 -0
- package/dist/security.js +198 -0
- package/dist/semantic.d.ts +7 -0
- package/dist/semantic.js +327 -0
- package/dist/typechecker.d.ts +7 -0
- package/dist/typechecker.js +132 -0
- package/dist/version.d.ts +26 -0
- package/dist/version.js +71 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kai (@kai_builds_ai) and Arc 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,148 @@
|
|
|
1
|
+
# Arc ⚡
|
|
2
|
+
|
|
3
|
+
**A programming language designed by AI agents, for AI agents.**
|
|
4
|
+
|
|
5
|
+
Arc is a modern programming language optimized for AI-driven development, achieving **50%+ cost and efficiency savings** through intelligent syntax design, implicit context handling, and token-optimized semantics.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Clone and install
|
|
11
|
+
git clone https://github.com/kai-builds-ai/arc-lang.git
|
|
12
|
+
cd arc-lang/compiler && npm install && cd ..
|
|
13
|
+
|
|
14
|
+
# Run an example
|
|
15
|
+
npx tsx compiler/src/index.ts run examples/hello-world.arc
|
|
16
|
+
|
|
17
|
+
# Start the REPL
|
|
18
|
+
npx tsx compiler/src/index.ts repl
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**See the [Getting Started Guide](docs/getting-started.md) for a full tutorial.**
|
|
22
|
+
|
|
23
|
+
## Why Arc?
|
|
24
|
+
|
|
25
|
+
Traditional programming languages were designed for humans. Arc is designed for the way AI agents think and work:
|
|
26
|
+
|
|
27
|
+
- **Token-efficient syntax** - Every character counts when you're paying per token
|
|
28
|
+
- **Implicit context** - Agents understand intent, reduce boilerplate
|
|
29
|
+
- **Pattern-first semantics** - Match patterns instead of verbose conditionals
|
|
30
|
+
- **Native async** - Concurrency is built-in, not an afterthought
|
|
31
|
+
- **First-class tool calls** - APIs and tools are native primitives
|
|
32
|
+
- **Semantic types** - Types based on meaning, not structure
|
|
33
|
+
|
|
34
|
+
## Philosophy
|
|
35
|
+
|
|
36
|
+
**Less is more.** Arc eliminates ceremony, boilerplate, and redundancy while maintaining clarity and expressiveness.
|
|
37
|
+
|
|
38
|
+
See [PHILOSOPHY.md](./PHILOSOPHY.md) for detailed design principles.
|
|
39
|
+
|
|
40
|
+
## What It Looks Like
|
|
41
|
+
|
|
42
|
+
```arc
|
|
43
|
+
# AI agent that fetches data, analyzes it, and acts
|
|
44
|
+
let [weather, news] = fetch [
|
|
45
|
+
@GET "api/weather?city=NYC",
|
|
46
|
+
@GET "api/news/top?limit=3"
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
let headlines = news.articles
|
|
50
|
+
|> take(3)
|
|
51
|
+
|> map(a => "• {a.title}")
|
|
52
|
+
|> join("\n")
|
|
53
|
+
|
|
54
|
+
let advice = match weather.condition {
|
|
55
|
+
"rain" | "storm" => "Bring an umbrella!",
|
|
56
|
+
"snow" => "Bundle up!",
|
|
57
|
+
_ => "Enjoy the weather!"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
print("{advice}\n\nTop News:\n{headlines}")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**~55 tokens in Arc vs ~120 in JavaScript.** See [examples/](examples/) for more.
|
|
64
|
+
|
|
65
|
+
## Standard Library
|
|
66
|
+
|
|
67
|
+
Arc ships with a growing standard library. Currently implemented:
|
|
68
|
+
|
|
69
|
+
| Module | Description |
|
|
70
|
+
|--------|-------------|
|
|
71
|
+
| [`math`](stdlib/math.arc) | Constants (PI, E), abs, pow, sqrt, ceil, floor, clamp |
|
|
72
|
+
| [`strings`](stdlib/strings.arc) | pad_left, pad_right, capitalize, words |
|
|
73
|
+
| [`collections`](stdlib/collections.arc) | set, unique, group_by, chunk, flatten, zip_with, partition, sort_by |
|
|
74
|
+
| [`map`](stdlib/map.arc) | merge, map_values, filter_map, from_pairs, pick, omit |
|
|
75
|
+
| [`io`](stdlib/io.arc) | read_lines, write_lines, exists, append |
|
|
76
|
+
| [`http`](stdlib/http.arc) | get, post, put, delete, fetch_all, parse_url |
|
|
77
|
+
| [`json`](stdlib/json.arc) | to_json, from_json, pretty, get_path |
|
|
78
|
+
| [`csv`](stdlib/csv.arc) | parse_csv, to_csv, parse_csv_headers |
|
|
79
|
+
| [`test`](stdlib/test.arc) | describe, it, expect_eq, expect_true, run_tests |
|
|
80
|
+
| [`result`](stdlib/result.arc) | ok, err, is_ok, unwrap, map_result, try_fn |
|
|
81
|
+
| [`time`](stdlib/time.arc) | now, format_duration, sleep |
|
|
82
|
+
|
|
83
|
+
Plus many built-in functions available without imports: `map`, `filter`, `reduce`, `print`, `len`, `split`, `join`, `trim`, and more.
|
|
84
|
+
|
|
85
|
+
📖 **[Standard Library Reference](docs/stdlib-reference.md)** | **[Standard Library Tutorial](docs/stdlib-tutorial.md)**
|
|
86
|
+
|
|
87
|
+
## Documentation
|
|
88
|
+
|
|
89
|
+
- **[Getting Started](docs/getting-started.md)** — Installation, first program, REPL, basics
|
|
90
|
+
- **[Language Tour](docs/language-tour.md)** — Complete feature walkthrough
|
|
91
|
+
- **[Standard Library Reference](docs/stdlib-reference.md)** — Full stdlib API reference
|
|
92
|
+
- **[Standard Library Tutorial](docs/stdlib-tutorial.md)** — Hands-on stdlib guide
|
|
93
|
+
- **[Examples](examples/)** — Real-world programs with token comparisons
|
|
94
|
+
- **[FAQ](docs/FAQ.md)** — Common questions answered
|
|
95
|
+
- **[Grammar Spec](spec/grammar.md)** — Formal language specification
|
|
96
|
+
|
|
97
|
+
## Status
|
|
98
|
+
|
|
99
|
+
🚀 **In Active Development** — Arc has a working compiler (lexer, parser, IR, optimizer, JS/WAT codegen), interpreter, REPL, 11 stdlib modules, LSP, VS Code extension, package manager, build system, formatter, linter, security sandbox, rich error reporting, benchmarking framework, and migration tools. 504+ tests passing.
|
|
100
|
+
|
|
101
|
+
Current phase: **Phase 6 — Community & Adoption**
|
|
102
|
+
|
|
103
|
+
See [ROADMAP.md](./ROADMAP.md) for development timeline.
|
|
104
|
+
|
|
105
|
+
## Project Structure
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
arc-lang/
|
|
109
|
+
├── README.md # You are here
|
|
110
|
+
├── PHILOSOPHY.md # Design principles & rationale
|
|
111
|
+
├── ROADMAP.md # Development phases & milestones
|
|
112
|
+
├── LICENSE # MIT License
|
|
113
|
+
├── docs/ # Comprehensive documentation
|
|
114
|
+
├── spec/ # Formal language specification
|
|
115
|
+
├── examples/ # Code samples & tutorials
|
|
116
|
+
├── compiler/ # Compiler/interpreter implementation
|
|
117
|
+
├── stdlib/ # Standard library
|
|
118
|
+
└── CONTRIBUTING.md # Contribution guidelines
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Contributing
|
|
122
|
+
|
|
123
|
+
Arc is a collaborative project open to all AI agents and human developers. We welcome contributions from:
|
|
124
|
+
|
|
125
|
+
- AI agents on Moltbook
|
|
126
|
+
- Developers interested in language design
|
|
127
|
+
- Anyone passionate about efficient, elegant code
|
|
128
|
+
|
|
129
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
130
|
+
|
|
131
|
+
## Community
|
|
132
|
+
|
|
133
|
+
- **Website:** [arclang.dev](https://arclang.dev)
|
|
134
|
+
- **Moltbook:** Follow [@kai_builds_ai](https://moltbook.com/u/kai_builds_ai) for updates every 6 hours
|
|
135
|
+
- **GitHub:** Star, watch, and contribute to this repository
|
|
136
|
+
- **Issues:** Use GitHub Issues for bugs, features, and discussions
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
MIT License - See [LICENSE](./LICENSE) for details.
|
|
141
|
+
|
|
142
|
+
## Credits
|
|
143
|
+
|
|
144
|
+
Created by **Kai** (@kai_builds_ai) with collaboration from AI agents and human developers worldwide.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
*"Code should be as simple as possible, but no simpler." - Arc Philosophy*
|
package/dist/ast.d.ts
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
export interface Loc {
|
|
2
|
+
line: number;
|
|
3
|
+
col: number;
|
|
4
|
+
}
|
|
5
|
+
export type Expr = IntLiteral | FloatLiteral | BoolLiteral | NilLiteral | StringLiteral | StringInterp | Identifier | BinaryExpr | UnaryExpr | CallExpr | MemberExpr | IndexExpr | PipelineExpr | IfExpr | MatchExpr | LambdaExpr | ListLiteral | MapLiteral | ListComprehension | ToolCallExpr | RangeExpr | BlockExpr | AsyncExpr | AwaitExpr | FetchExpr;
|
|
6
|
+
export interface IntLiteral {
|
|
7
|
+
kind: "IntLiteral";
|
|
8
|
+
value: number;
|
|
9
|
+
loc: Loc;
|
|
10
|
+
}
|
|
11
|
+
export interface FloatLiteral {
|
|
12
|
+
kind: "FloatLiteral";
|
|
13
|
+
value: number;
|
|
14
|
+
loc: Loc;
|
|
15
|
+
}
|
|
16
|
+
export interface BoolLiteral {
|
|
17
|
+
kind: "BoolLiteral";
|
|
18
|
+
value: boolean;
|
|
19
|
+
loc: Loc;
|
|
20
|
+
}
|
|
21
|
+
export interface NilLiteral {
|
|
22
|
+
kind: "NilLiteral";
|
|
23
|
+
loc: Loc;
|
|
24
|
+
}
|
|
25
|
+
export interface StringLiteral {
|
|
26
|
+
kind: "StringLiteral";
|
|
27
|
+
value: string;
|
|
28
|
+
loc: Loc;
|
|
29
|
+
}
|
|
30
|
+
export interface StringInterp {
|
|
31
|
+
kind: "StringInterp";
|
|
32
|
+
parts: (string | Expr)[];
|
|
33
|
+
loc: Loc;
|
|
34
|
+
}
|
|
35
|
+
export interface Identifier {
|
|
36
|
+
kind: "Identifier";
|
|
37
|
+
name: string;
|
|
38
|
+
loc: Loc;
|
|
39
|
+
}
|
|
40
|
+
export interface BinaryExpr {
|
|
41
|
+
kind: "BinaryExpr";
|
|
42
|
+
op: string;
|
|
43
|
+
left: Expr;
|
|
44
|
+
right: Expr;
|
|
45
|
+
loc: Loc;
|
|
46
|
+
}
|
|
47
|
+
export interface UnaryExpr {
|
|
48
|
+
kind: "UnaryExpr";
|
|
49
|
+
op: string;
|
|
50
|
+
operand: Expr;
|
|
51
|
+
loc: Loc;
|
|
52
|
+
}
|
|
53
|
+
export interface CallExpr {
|
|
54
|
+
kind: "CallExpr";
|
|
55
|
+
callee: Expr;
|
|
56
|
+
args: Expr[];
|
|
57
|
+
loc: Loc;
|
|
58
|
+
}
|
|
59
|
+
export interface MemberExpr {
|
|
60
|
+
kind: "MemberExpr";
|
|
61
|
+
object: Expr;
|
|
62
|
+
property: string;
|
|
63
|
+
loc: Loc;
|
|
64
|
+
}
|
|
65
|
+
export interface IndexExpr {
|
|
66
|
+
kind: "IndexExpr";
|
|
67
|
+
object: Expr;
|
|
68
|
+
index: Expr;
|
|
69
|
+
loc: Loc;
|
|
70
|
+
}
|
|
71
|
+
export interface PipelineExpr {
|
|
72
|
+
kind: "PipelineExpr";
|
|
73
|
+
left: Expr;
|
|
74
|
+
right: Expr;
|
|
75
|
+
loc: Loc;
|
|
76
|
+
}
|
|
77
|
+
export interface IfExpr {
|
|
78
|
+
kind: "IfExpr";
|
|
79
|
+
condition: Expr;
|
|
80
|
+
then: Expr;
|
|
81
|
+
else_?: Expr;
|
|
82
|
+
loc: Loc;
|
|
83
|
+
}
|
|
84
|
+
export interface MatchExpr {
|
|
85
|
+
kind: "MatchExpr";
|
|
86
|
+
subject: Expr;
|
|
87
|
+
arms: MatchArm[];
|
|
88
|
+
loc: Loc;
|
|
89
|
+
}
|
|
90
|
+
export interface MatchArm {
|
|
91
|
+
pattern: Pattern;
|
|
92
|
+
guard?: Expr;
|
|
93
|
+
body: Expr;
|
|
94
|
+
}
|
|
95
|
+
export interface LambdaExpr {
|
|
96
|
+
kind: "LambdaExpr";
|
|
97
|
+
params: string[];
|
|
98
|
+
body: Expr;
|
|
99
|
+
loc: Loc;
|
|
100
|
+
}
|
|
101
|
+
export interface ListLiteral {
|
|
102
|
+
kind: "ListLiteral";
|
|
103
|
+
elements: Expr[];
|
|
104
|
+
loc: Loc;
|
|
105
|
+
}
|
|
106
|
+
export interface MapLiteral {
|
|
107
|
+
kind: "MapLiteral";
|
|
108
|
+
entries: {
|
|
109
|
+
key: string | Expr;
|
|
110
|
+
value: Expr;
|
|
111
|
+
}[];
|
|
112
|
+
loc: Loc;
|
|
113
|
+
}
|
|
114
|
+
export interface ListComprehension {
|
|
115
|
+
kind: "ListComprehension";
|
|
116
|
+
expr: Expr;
|
|
117
|
+
variable: string;
|
|
118
|
+
iterable: Expr;
|
|
119
|
+
filter?: Expr;
|
|
120
|
+
loc: Loc;
|
|
121
|
+
}
|
|
122
|
+
export interface ToolCallExpr {
|
|
123
|
+
kind: "ToolCallExpr";
|
|
124
|
+
method: string;
|
|
125
|
+
arg: Expr;
|
|
126
|
+
body?: Expr;
|
|
127
|
+
loc: Loc;
|
|
128
|
+
}
|
|
129
|
+
export interface RangeExpr {
|
|
130
|
+
kind: "RangeExpr";
|
|
131
|
+
start: Expr;
|
|
132
|
+
end: Expr;
|
|
133
|
+
loc: Loc;
|
|
134
|
+
}
|
|
135
|
+
export interface BlockExpr {
|
|
136
|
+
kind: "BlockExpr";
|
|
137
|
+
stmts: Stmt[];
|
|
138
|
+
loc: Loc;
|
|
139
|
+
}
|
|
140
|
+
export interface AsyncExpr {
|
|
141
|
+
kind: "AsyncExpr";
|
|
142
|
+
body: Expr;
|
|
143
|
+
loc: Loc;
|
|
144
|
+
}
|
|
145
|
+
export interface AwaitExpr {
|
|
146
|
+
kind: "AwaitExpr";
|
|
147
|
+
expr: Expr;
|
|
148
|
+
loc: Loc;
|
|
149
|
+
}
|
|
150
|
+
export interface FetchExpr {
|
|
151
|
+
kind: "FetchExpr";
|
|
152
|
+
targets: Expr[];
|
|
153
|
+
loc: Loc;
|
|
154
|
+
}
|
|
155
|
+
export type Pattern = WildcardPattern | LiteralPattern | BindingPattern | ArrayPattern | OrPattern;
|
|
156
|
+
export interface WildcardPattern {
|
|
157
|
+
kind: "WildcardPattern";
|
|
158
|
+
loc: Loc;
|
|
159
|
+
}
|
|
160
|
+
export interface LiteralPattern {
|
|
161
|
+
kind: "LiteralPattern";
|
|
162
|
+
value: number | string | boolean | null;
|
|
163
|
+
loc: Loc;
|
|
164
|
+
}
|
|
165
|
+
export interface BindingPattern {
|
|
166
|
+
kind: "BindingPattern";
|
|
167
|
+
name: string;
|
|
168
|
+
loc: Loc;
|
|
169
|
+
}
|
|
170
|
+
export interface ArrayPattern {
|
|
171
|
+
kind: "ArrayPattern";
|
|
172
|
+
elements: Pattern[];
|
|
173
|
+
loc: Loc;
|
|
174
|
+
}
|
|
175
|
+
export interface OrPattern {
|
|
176
|
+
kind: "OrPattern";
|
|
177
|
+
patterns: Pattern[];
|
|
178
|
+
loc: Loc;
|
|
179
|
+
}
|
|
180
|
+
export type Stmt = LetStmt | FnStmt | ForStmt | DoStmt | ExprStmt | UseStmt | TypeStmt | AssignStmt | MemberAssignStmt | IndexAssignStmt;
|
|
181
|
+
export interface AssignStmt {
|
|
182
|
+
kind: "AssignStmt";
|
|
183
|
+
target: string;
|
|
184
|
+
value: Expr;
|
|
185
|
+
loc: Loc;
|
|
186
|
+
}
|
|
187
|
+
export interface MemberAssignStmt {
|
|
188
|
+
kind: "MemberAssignStmt";
|
|
189
|
+
object: Expr;
|
|
190
|
+
property: string;
|
|
191
|
+
value: Expr;
|
|
192
|
+
loc: Loc;
|
|
193
|
+
}
|
|
194
|
+
export interface IndexAssignStmt {
|
|
195
|
+
kind: "IndexAssignStmt";
|
|
196
|
+
object: Expr;
|
|
197
|
+
index: Expr;
|
|
198
|
+
value: Expr;
|
|
199
|
+
loc: Loc;
|
|
200
|
+
}
|
|
201
|
+
export interface LetStmt {
|
|
202
|
+
kind: "LetStmt";
|
|
203
|
+
name: string | DestructureTarget;
|
|
204
|
+
mutable: boolean;
|
|
205
|
+
pub: boolean;
|
|
206
|
+
value: Expr;
|
|
207
|
+
loc: Loc;
|
|
208
|
+
}
|
|
209
|
+
export interface DestructureTarget {
|
|
210
|
+
kind: "DestructureTarget";
|
|
211
|
+
type: "object" | "array";
|
|
212
|
+
names: string[];
|
|
213
|
+
}
|
|
214
|
+
export interface FnStmt {
|
|
215
|
+
kind: "FnStmt";
|
|
216
|
+
name: string;
|
|
217
|
+
params: string[];
|
|
218
|
+
body: Expr;
|
|
219
|
+
isAsync: boolean;
|
|
220
|
+
pub: boolean;
|
|
221
|
+
loc: Loc;
|
|
222
|
+
}
|
|
223
|
+
export interface ForStmt {
|
|
224
|
+
kind: "ForStmt";
|
|
225
|
+
variable: string;
|
|
226
|
+
iterable: Expr;
|
|
227
|
+
body: Expr;
|
|
228
|
+
loc: Loc;
|
|
229
|
+
}
|
|
230
|
+
export interface DoStmt {
|
|
231
|
+
kind: "DoStmt";
|
|
232
|
+
body: Expr;
|
|
233
|
+
condition: Expr;
|
|
234
|
+
isWhile: boolean;
|
|
235
|
+
loc: Loc;
|
|
236
|
+
}
|
|
237
|
+
export interface ExprStmt {
|
|
238
|
+
kind: "ExprStmt";
|
|
239
|
+
expr: Expr;
|
|
240
|
+
loc: Loc;
|
|
241
|
+
}
|
|
242
|
+
export interface UseStmt {
|
|
243
|
+
kind: "UseStmt";
|
|
244
|
+
path: string[];
|
|
245
|
+
imports?: string[];
|
|
246
|
+
wildcard?: boolean;
|
|
247
|
+
loc: Loc;
|
|
248
|
+
}
|
|
249
|
+
export interface TypeStmt {
|
|
250
|
+
kind: "TypeStmt";
|
|
251
|
+
name: string;
|
|
252
|
+
pub: boolean;
|
|
253
|
+
def: TypeExpr;
|
|
254
|
+
loc: Loc;
|
|
255
|
+
}
|
|
256
|
+
export type TypeExpr = NamedType | RecordType | UnionType | FunctionType | ConstrainedType | EnumType | GenericType;
|
|
257
|
+
export interface NamedType {
|
|
258
|
+
kind: "NamedType";
|
|
259
|
+
name: string;
|
|
260
|
+
}
|
|
261
|
+
export interface RecordType {
|
|
262
|
+
kind: "RecordType";
|
|
263
|
+
fields: {
|
|
264
|
+
name: string;
|
|
265
|
+
type: TypeExpr;
|
|
266
|
+
}[];
|
|
267
|
+
}
|
|
268
|
+
export interface UnionType {
|
|
269
|
+
kind: "UnionType";
|
|
270
|
+
variants: TypeExpr[];
|
|
271
|
+
}
|
|
272
|
+
export interface FunctionType {
|
|
273
|
+
kind: "FunctionType";
|
|
274
|
+
params: TypeExpr[];
|
|
275
|
+
ret: TypeExpr;
|
|
276
|
+
}
|
|
277
|
+
export interface ConstrainedType {
|
|
278
|
+
kind: "ConstrainedType";
|
|
279
|
+
base: TypeExpr;
|
|
280
|
+
constraint: "where" | "matching";
|
|
281
|
+
predicate: Expr;
|
|
282
|
+
}
|
|
283
|
+
export interface EnumType {
|
|
284
|
+
kind: "EnumType";
|
|
285
|
+
variants: {
|
|
286
|
+
name: string;
|
|
287
|
+
params?: TypeExpr[];
|
|
288
|
+
}[];
|
|
289
|
+
}
|
|
290
|
+
export interface GenericType {
|
|
291
|
+
kind: "GenericType";
|
|
292
|
+
name: string;
|
|
293
|
+
params: TypeExpr[];
|
|
294
|
+
}
|
|
295
|
+
export interface Program {
|
|
296
|
+
kind: "Program";
|
|
297
|
+
stmts: Stmt[];
|
|
298
|
+
}
|
package/dist/ast.js
ADDED
package/dist/build.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function build(options?: {
|
|
2
|
+
target?: string;
|
|
3
|
+
dir?: string;
|
|
4
|
+
}): void;
|
|
5
|
+
export declare function run(file?: string, dir?: string): void;
|
|
6
|
+
export declare function test(dir?: string): void;
|
|
7
|
+
export declare function newProject(name: string, parentDir?: string): void;
|
package/dist/build.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Arc Build System
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from "fs";
|
|
3
|
+
import { resolve, relative, join } from "path";
|
|
4
|
+
import { lex } from "./lexer.js";
|
|
5
|
+
import { parse } from "./parser.js";
|
|
6
|
+
import { generateIR } from "./ir.js";
|
|
7
|
+
import { generateJS } from "./codegen-js.js";
|
|
8
|
+
import { generateWAT } from "./codegen.js";
|
|
9
|
+
import { interpret } from "./interpreter.js";
|
|
10
|
+
import { createUseHandler } from "./modules.js";
|
|
11
|
+
import { readToml, serializeArcToml } from "./package-manager.js";
|
|
12
|
+
export function build(options = {}) {
|
|
13
|
+
const dir = options.dir || process.cwd();
|
|
14
|
+
const target = options.target || "js";
|
|
15
|
+
let toml;
|
|
16
|
+
try {
|
|
17
|
+
toml = readToml(dir);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
console.error("No arc.toml found. Run 'arc pkg init' first.");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
// Find entry point
|
|
24
|
+
const entryPoint = resolve(dir, "src", "main.arc");
|
|
25
|
+
if (!existsSync(entryPoint)) {
|
|
26
|
+
console.error("Entry point not found: src/main.arc");
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const source = readFileSync(entryPoint, "utf-8");
|
|
30
|
+
const tokens = lex(source);
|
|
31
|
+
const ast = parse(tokens);
|
|
32
|
+
const ir = generateIR(ast);
|
|
33
|
+
const distDir = resolve(dir, "dist");
|
|
34
|
+
if (!existsSync(distDir)) {
|
|
35
|
+
mkdirSync(distDir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
if (target === "wat") {
|
|
38
|
+
const wat = generateWAT(ir);
|
|
39
|
+
const outPath = resolve(distDir, `${toml.package.name}.wat`);
|
|
40
|
+
writeFileSync(outPath, wat);
|
|
41
|
+
console.log(`Built ${relative(dir, outPath)}`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const js = generateJS(ir);
|
|
45
|
+
const outPath = resolve(distDir, `${toml.package.name}.js`);
|
|
46
|
+
writeFileSync(outPath, js);
|
|
47
|
+
console.log(`Built ${relative(dir, outPath)}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function run(file, dir) {
|
|
51
|
+
const d = dir || process.cwd();
|
|
52
|
+
let filePath;
|
|
53
|
+
if (file) {
|
|
54
|
+
filePath = resolve(d, file);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// Use project entry point
|
|
58
|
+
filePath = resolve(d, "src", "main.arc");
|
|
59
|
+
}
|
|
60
|
+
if (!existsSync(filePath)) {
|
|
61
|
+
console.error(`File not found: ${filePath}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const source = readFileSync(filePath, "utf-8");
|
|
65
|
+
const tokens = lex(source);
|
|
66
|
+
const ast = parse(tokens);
|
|
67
|
+
interpret(ast, createUseHandler(filePath));
|
|
68
|
+
}
|
|
69
|
+
function findArcFiles(dir, pattern) {
|
|
70
|
+
const results = [];
|
|
71
|
+
if (!existsSync(dir))
|
|
72
|
+
return results;
|
|
73
|
+
const entries = readdirSync(dir);
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const full = join(dir, entry);
|
|
76
|
+
const stat = statSync(full);
|
|
77
|
+
if (stat.isDirectory()) {
|
|
78
|
+
results.push(...findArcFiles(full, pattern));
|
|
79
|
+
}
|
|
80
|
+
else if (pattern.test(entry)) {
|
|
81
|
+
results.push(full);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return results;
|
|
85
|
+
}
|
|
86
|
+
export function test(dir) {
|
|
87
|
+
const d = dir || process.cwd();
|
|
88
|
+
const testsDir = resolve(d, "tests");
|
|
89
|
+
const testFiles = findArcFiles(testsDir, /\.arc$/);
|
|
90
|
+
if (testFiles.length === 0) {
|
|
91
|
+
console.log("No test files found in tests/");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
let passed = 0;
|
|
95
|
+
let failedCount = 0;
|
|
96
|
+
for (const file of testFiles) {
|
|
97
|
+
const rel = relative(d, file);
|
|
98
|
+
try {
|
|
99
|
+
const source = readFileSync(file, "utf-8");
|
|
100
|
+
const tokens = lex(source);
|
|
101
|
+
const ast = parse(tokens);
|
|
102
|
+
interpret(ast, createUseHandler(file));
|
|
103
|
+
console.log(` ✓ ${rel}`);
|
|
104
|
+
passed++;
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
console.log(` ✗ ${rel}: ${e.message}`);
|
|
108
|
+
failedCount++;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
console.log(`\nTests: ${passed} passed, ${failedCount} failed`);
|
|
112
|
+
if (failedCount > 0)
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
export function newProject(name, parentDir) {
|
|
116
|
+
const d = parentDir || process.cwd();
|
|
117
|
+
const projectDir = resolve(d, name);
|
|
118
|
+
if (existsSync(projectDir)) {
|
|
119
|
+
console.error(`Directory '${name}' already exists`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
mkdirSync(resolve(projectDir, "src"), { recursive: true });
|
|
123
|
+
mkdirSync(resolve(projectDir, "tests"), { recursive: true });
|
|
124
|
+
const toml = {
|
|
125
|
+
package: { name, version: "0.1.0", description: "", author: "", license: "MIT" },
|
|
126
|
+
dependencies: {},
|
|
127
|
+
"dev-dependencies": {},
|
|
128
|
+
};
|
|
129
|
+
writeFileSync(resolve(projectDir, "arc.toml"), serializeArcToml(toml));
|
|
130
|
+
writeFileSync(resolve(projectDir, "src", "main.arc"), `fn main() do\n let msg = "Hello from ${name}!"\nend\n`);
|
|
131
|
+
writeFileSync(resolve(projectDir, "tests", "main.test.arc"), `fn test_main() do\n let x = 1 + 1\nend\n`);
|
|
132
|
+
writeFileSync(resolve(projectDir, "README.md"), `# ${name}\n\nAn Arc project.\n\n## Getting Started\n\n\`\`\`bash\narc build\narc run\n\`\`\`\n`);
|
|
133
|
+
console.log(`Created project '${name}'`);
|
|
134
|
+
console.log(` ${name}/arc.toml`);
|
|
135
|
+
console.log(` ${name}/src/main.arc`);
|
|
136
|
+
console.log(` ${name}/tests/main.test.arc`);
|
|
137
|
+
console.log(` ${name}/README.md`);
|
|
138
|
+
}
|