@xnoxs/flux-lang 4.0.7 → 4.0.9
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/CHANGELOG.md +0 -12
- package/dist/flux-cli.js +558 -550
- package/dist/flux.cjs.js +3689 -5548
- package/dist/flux.esm.js +3691 -5545
- package/dist/flux.min.js +95 -356
- package/index.js +10 -9
- package/package.json +5 -4
- package/src/config.js +86 -101
- package/src/formatter.js +100 -105
- package/src/self/bundler.flux +16 -21
- package/src/self/bundler.js +28 -16
- package/src/self/checker.js +2 -0
- package/src/self/cli.flux +220 -274
- package/src/self/cli.js +59 -123
- package/src/self/codegen.js +811 -1
- package/src/self/config.flux +28 -36
- package/src/self/config.js +32 -33
- package/src/self/css-preprocessor.js +3 -1
- package/src/self/formatter.js +2 -0
- package/src/self/index.flux +87 -0
- package/src/self/jsx.js +4 -2
- package/src/self/lexer.js +8 -6
- package/src/self/linter.js +2 -0
- package/src/self/mangler.js +2 -0
- package/src/self/parser.js +2 -0
- package/src/self/pkg.flux +136 -39
- package/src/self/pkg.js +125 -36
- package/src/self/sourcemap.js +2 -0
- package/src/self/stdlib.js +2 -0
- package/src/self/test-runner.js +2 -0
- package/src/self/transpiler.js +2 -0
- package/src/self/type-checker.js +2 -0
- package/src/stdlib.js +218 -731
- package/dist/transpiler.js +0 -4
package/dist/flux-cli.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
/*!
|
|
1
|
+
/*!
|
|
2
|
+
* flux-lang v4.0.9
|
|
3
|
+
* Flux — A modern language that transpiles to JavaScript. Python-clean syntax, TypeScript-level safety, Rust-inspired pattern matching.
|
|
4
|
+
* (c) 2026 Flux Lang Contributors
|
|
5
|
+
* Released under the MIT License
|
|
6
|
+
*/
|
|
2
7
|
"use strict";
|
|
3
8
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
9
|
var __commonJS = (cb, mod) => function __require() {
|
|
@@ -9,9 +14,10 @@ var __commonJS = (cb, mod) => function __require() {
|
|
|
9
14
|
}
|
|
10
15
|
};
|
|
11
16
|
|
|
12
|
-
//
|
|
17
|
+
// src/lexer.js
|
|
13
18
|
var require_lexer = __commonJS({
|
|
14
|
-
"
|
|
19
|
+
"src/lexer.js"(exports2, module2) {
|
|
20
|
+
"use strict";
|
|
15
21
|
var T = { NUMBER: "NUMBER", STRING: "STRING", BOOL: "BOOL", NULL: "NULL", IDENT: "IDENT", VAR: "VAR", VAL: "VAL", FN: "FN", RETURN: "RETURN", IF: "IF", ELSE: "ELSE", FOR: "FOR", IN: "IN", WHILE: "WHILE", BREAK: "BREAK", CONTINUE: "CONTINUE", DO: "DO", CLASS: "CLASS", EXTENDS: "EXTENDS", SELF: "SELF", NEW: "NEW", INTERFACE: "INTERFACE", IMPLEMENTS: "IMPLEMENTS", PRIVATE: "PRIVATE", PUBLIC: "PUBLIC", PROTECTED: "PROTECTED", READONLY: "READONLY", STATIC: "STATIC", ABSTRACT: "ABSTRACT", OVERRIDE: "OVERRIDE", MATCH: "MATCH", WHEN: "WHEN", IMPORT: "IMPORT", EXPORT: "EXPORT", FROM: "FROM", AS: "AS", DEFAULT: "DEFAULT", AND: "AND", OR: "OR", NOT: "NOT", ASYNC: "ASYNC", AWAIT: "AWAIT", TRY: "TRY", CATCH: "CATCH", FINALLY: "FINALLY", THROW: "THROW", TYPEOF: "TYPEOF", INSTANCEOF: "INSTANCEOF", TYPE: "TYPE", ENUM: "ENUM", SATISFIES: "SATISFIES", IS: "IS", CONST: "CONST", PLUS: "PLUS", MINUS: "MINUS", STAR: "STAR", SLASH: "SLASH", PERCENT: "PERCENT", REGEX: "REGEX", STARSTAR: "STARSTAR", EQ: "EQ", EQEQ: "EQEQ", NEQ: "NEQ", EQEQEQ: "EQEQEQ", NEQEQ: "NEQEQ", LT: "LT", LTE: "LTE", GT: "GT", GTE: "GTE", PLUSEQ: "PLUSEQ", MINUSEQ: "MINUSEQ", STAREQ: "STAREQ", SLASHEQ: "SLASHEQ", PERCENTEQ: "PERCENTEQ", PLUSPLUS: "PLUSPLUS", MINUSMINUS: "MINUSMINUS", AMPERSAND: "AMPERSAND", ANDAND: "ANDAND", PIPEB: "PIPEB", OROR: "OROR", CARET: "CARET", TILDE: "TILDE", LSHIFT: "LSHIFT", RSHIFT: "RSHIFT", ARROW: "ARROW", FATARROW: "FATARROW", PIPE: "PIPE", DOTDOT: "DOTDOT", DOTDOTDOT: "DOTDOTDOT", WILDCARD: "WILDCARD", NULLISH: "NULLISH", QUESTIONDOT: "QUESTIONDOT", BANG: "BANG", AT: "AT", LPAREN: "LPAREN", RPAREN: "RPAREN", LBRACKET: "LBRACKET", RBRACKET: "RBRACKET", LBRACE: "LBRACE", RBRACE: "RBRACE", COMMA: "COMMA", DOT: "DOT", COLON: "COLON", QUESTION: "QUESTION", NEWLINE: "NEWLINE", INDENT: "INDENT", DEDENT: "DEDENT", EOF: "EOF" };
|
|
16
22
|
module2.exports.T = T;
|
|
17
23
|
var TokenType = T;
|
|
@@ -78,7 +84,7 @@ var require_lexer = __commonJS({
|
|
|
78
84
|
if (e == "n") {
|
|
79
85
|
s += "\n";
|
|
80
86
|
} else if (e == "t") {
|
|
81
|
-
s += "
|
|
87
|
+
s += " ";
|
|
82
88
|
} else if (e == "`") {
|
|
83
89
|
s += "`";
|
|
84
90
|
} else if (e == "\\") {
|
|
@@ -129,7 +135,7 @@ var require_lexer = __commonJS({
|
|
|
129
135
|
if (e == "n") {
|
|
130
136
|
text += "\n";
|
|
131
137
|
} else if (e == "t") {
|
|
132
|
-
text += "
|
|
138
|
+
text += " ";
|
|
133
139
|
} else if (e == '"') {
|
|
134
140
|
text += '"';
|
|
135
141
|
} else if (e == "'") {
|
|
@@ -246,8 +252,8 @@ var require_lexer = __commonJS({
|
|
|
246
252
|
if (bol) {
|
|
247
253
|
bol = false;
|
|
248
254
|
let indent = 0;
|
|
249
|
-
while (this.ch() == " " || this.ch() == "
|
|
250
|
-
if (this.ch() == "
|
|
255
|
+
while (this.ch() == " " || this.ch() == " ") {
|
|
256
|
+
if (this.ch() == " ") {
|
|
251
257
|
indent = indent + 4;
|
|
252
258
|
} else {
|
|
253
259
|
indent = indent + 1;
|
|
@@ -299,7 +305,7 @@ var require_lexer = __commonJS({
|
|
|
299
305
|
}
|
|
300
306
|
continue;
|
|
301
307
|
}
|
|
302
|
-
if (cur == " " || cur == "
|
|
308
|
+
if (cur == " " || cur == " ") {
|
|
303
309
|
this.adv();
|
|
304
310
|
continue;
|
|
305
311
|
}
|
|
@@ -383,7 +389,7 @@ var require_lexer = __commonJS({
|
|
|
383
389
|
if (e == "n") {
|
|
384
390
|
sq += "\n";
|
|
385
391
|
} else if (e == "t") {
|
|
386
|
-
sq += "
|
|
392
|
+
sq += " ";
|
|
387
393
|
} else if (e == "r") {
|
|
388
394
|
sq += "\r";
|
|
389
395
|
} else if (e == "'") {
|
|
@@ -617,9 +623,10 @@ var require_lexer = __commonJS({
|
|
|
617
623
|
}
|
|
618
624
|
});
|
|
619
625
|
|
|
620
|
-
//
|
|
626
|
+
// src/parser.js
|
|
621
627
|
var require_parser = __commonJS({
|
|
622
|
-
"
|
|
628
|
+
"src/parser.js"(exports2, module2) {
|
|
629
|
+
"use strict";
|
|
623
630
|
var { T } = require_lexer();
|
|
624
631
|
function makeParseError(msg, tok) {
|
|
625
632
|
const line = (tok == null ? void 0 : tok.line) ?? "?";
|
|
@@ -2129,41 +2136,42 @@ var require_parser = __commonJS({
|
|
|
2129
2136
|
}
|
|
2130
2137
|
});
|
|
2131
2138
|
|
|
2132
|
-
//
|
|
2139
|
+
// src/codegen.js
|
|
2133
2140
|
var require_codegen = __commonJS({
|
|
2134
|
-
"
|
|
2141
|
+
"src/codegen.js"(exports2, module2) {
|
|
2142
|
+
"use strict";
|
|
2135
2143
|
var { Lexer, lexerize, T } = require_lexer();
|
|
2136
2144
|
var { Parser, makeParser } = require_parser();
|
|
2137
|
-
function
|
|
2138
|
-
const ci =
|
|
2145
|
+
function extractFormatSpec(raw) {
|
|
2146
|
+
const ci = raw.lastIndexOf(":");
|
|
2139
2147
|
if (ci < 1) {
|
|
2140
2148
|
return null;
|
|
2141
2149
|
}
|
|
2142
|
-
const spec =
|
|
2150
|
+
const spec = raw.slice(ci + 1).trim();
|
|
2143
2151
|
if (spec.length > 0 && /[.<>^,dbeEfFgGoOxXs%bcn]/.test(spec) && /^([.<>^0\-+ #,]*[0-9]*\.?[0-9]*[dbeEfFgGoOxXs%bcn]?[,]?)$/.test(spec)) {
|
|
2144
|
-
return { expr:
|
|
2152
|
+
return { expr: raw.slice(0, ci).trim(), fmt: spec };
|
|
2145
2153
|
}
|
|
2146
2154
|
return null;
|
|
2147
2155
|
}
|
|
2148
|
-
var
|
|
2149
|
-
function
|
|
2156
|
+
var FMT_HELPER = "function _fmt(v, s) {\n if (s === ',') return (+v).toLocaleString();\n if (s === '%') return ((+v)*100).toFixed(0)+'%';\n var m = s.match(/^([0-9,]*)?\\.([0-9]+)([fdgGeEb%x])$/);\n if (m) {\n var d=+m[2], t=m[3], comma=s[0]===',';\n if (t==='f'||t==='d') return comma ? (+v).toLocaleString(void 0,{minimumFractionDigits:d,maximumFractionDigits:d}) : (+v).toFixed(d);\n if (t==='e'||t==='E') return (+v).toExponential(d);\n if (t==='%') return ((+v)*100).toFixed(d)+'%';\n if (t==='b') return Math.round(+v).toString(2);\n if (t==='x') return Math.round(+v).toString(16);\n }\n var m2 = s.match(/^([0-9]*)d$/); if (m2) return Math.round(+v).toString();\n return String(v);\n}";
|
|
2157
|
+
function buildClassRegistry(ast) {
|
|
2150
2158
|
const reg = {};
|
|
2151
|
-
for (const
|
|
2152
|
-
const n =
|
|
2159
|
+
for (const node of ast.body) {
|
|
2160
|
+
const n = node.type == "ExportDecl" ? node.decl : node;
|
|
2153
2161
|
if (n.type == "ClassDecl") {
|
|
2154
2162
|
reg[n.name] = { fields: n.fields, superClass: n.superClass };
|
|
2155
2163
|
}
|
|
2156
2164
|
}
|
|
2157
2165
|
return reg;
|
|
2158
2166
|
}
|
|
2159
|
-
function
|
|
2160
|
-
const vis =
|
|
2161
|
-
if (!
|
|
2167
|
+
function getAllFields(name, reg, visited) {
|
|
2168
|
+
const vis = visited ?? /* @__PURE__ */ new Set([]);
|
|
2169
|
+
if (!name || !reg[name] || vis.has(name)) {
|
|
2162
2170
|
return [];
|
|
2163
2171
|
}
|
|
2164
|
-
vis.add(
|
|
2165
|
-
const parent =
|
|
2166
|
-
return [...parent, ...
|
|
2172
|
+
vis.add(name);
|
|
2173
|
+
const parent = getAllFields(reg[name].superClass, reg, vis);
|
|
2174
|
+
return [...parent, ...reg[name].fields];
|
|
2167
2175
|
}
|
|
2168
2176
|
var CodeGenerator = class {
|
|
2169
2177
|
constructor(ind, level, lines, clsReg, smBuilder, _needsFmt, _loopDepth, _fnDepth, _version) {
|
|
@@ -2186,11 +2194,11 @@ var require_codegen = __commonJS({
|
|
|
2186
2194
|
}
|
|
2187
2195
|
return s;
|
|
2188
2196
|
}
|
|
2189
|
-
emit(
|
|
2190
|
-
this.lines.push(this.i() +
|
|
2197
|
+
emit(s) {
|
|
2198
|
+
this.lines.push(this.i() + s);
|
|
2191
2199
|
}
|
|
2192
|
-
emitRaw(
|
|
2193
|
-
this.lines.push(
|
|
2200
|
+
emitRaw(s) {
|
|
2201
|
+
this.lines.push(s);
|
|
2194
2202
|
}
|
|
2195
2203
|
blank() {
|
|
2196
2204
|
this.lines.push("");
|
|
@@ -2203,171 +2211,171 @@ var require_codegen = __commonJS({
|
|
|
2203
2211
|
this.level = this.level - 1;
|
|
2204
2212
|
}
|
|
2205
2213
|
}
|
|
2206
|
-
generate(
|
|
2207
|
-
this.clsReg =
|
|
2214
|
+
generate(ast) {
|
|
2215
|
+
this.clsReg = buildClassRegistry(ast);
|
|
2208
2216
|
this.lines = [];
|
|
2209
2217
|
this.level = 0;
|
|
2210
2218
|
this._needsFmt = false;
|
|
2211
2219
|
this.emit("// Generated by Flux Transpiler v" + (this._version ?? "3.5.3") + " (self-hosted)");
|
|
2212
2220
|
this.emit('"use strict";');
|
|
2213
2221
|
this.blank();
|
|
2214
|
-
for (const
|
|
2215
|
-
this.genStmt(
|
|
2222
|
+
for (const node of ast.body) {
|
|
2223
|
+
this.genStmt(node);
|
|
2216
2224
|
}
|
|
2217
2225
|
if (this._needsFmt) {
|
|
2218
|
-
this.lines.splice(2, 0,
|
|
2226
|
+
this.lines.splice(2, 0, FMT_HELPER);
|
|
2219
2227
|
}
|
|
2220
2228
|
return { code: this.lines.join("\n"), smBuilder: this.smBuilder };
|
|
2221
2229
|
}
|
|
2222
|
-
genStmt(
|
|
2223
|
-
if (
|
|
2224
|
-
this.genVar(
|
|
2225
|
-
} else if (
|
|
2226
|
-
this.genDestructure(
|
|
2227
|
-
} else if (
|
|
2228
|
-
this.genFn(
|
|
2229
|
-
} else if (
|
|
2230
|
-
this.genClass(
|
|
2231
|
-
} else if (
|
|
2232
|
-
this.genIf(
|
|
2233
|
-
} else if (
|
|
2234
|
-
this.genFor(
|
|
2235
|
-
} else if (
|
|
2236
|
-
this.genWhile(
|
|
2237
|
-
} else if (
|
|
2238
|
-
this.genMatch(
|
|
2239
|
-
} else if (
|
|
2240
|
-
this.genReturn(
|
|
2241
|
-
} else if (
|
|
2242
|
-
this.genTryCatch(
|
|
2243
|
-
} else if (
|
|
2244
|
-
this.genThrow(
|
|
2245
|
-
} else if (
|
|
2246
|
-
this.genDoWhile(
|
|
2247
|
-
} else if (
|
|
2230
|
+
genStmt(node) {
|
|
2231
|
+
if (node.type == "VarDecl") {
|
|
2232
|
+
this.genVar(node);
|
|
2233
|
+
} else if (node.type == "DestructureDecl") {
|
|
2234
|
+
this.genDestructure(node);
|
|
2235
|
+
} else if (node.type == "FnDecl") {
|
|
2236
|
+
this.genFn(node, "");
|
|
2237
|
+
} else if (node.type == "ClassDecl") {
|
|
2238
|
+
this.genClass(node);
|
|
2239
|
+
} else if (node.type == "IfStmt") {
|
|
2240
|
+
this.genIf(node);
|
|
2241
|
+
} else if (node.type == "ForInStmt") {
|
|
2242
|
+
this.genFor(node);
|
|
2243
|
+
} else if (node.type == "WhileStmt") {
|
|
2244
|
+
this.genWhile(node);
|
|
2245
|
+
} else if (node.type == "MatchStmt") {
|
|
2246
|
+
this.genMatch(node);
|
|
2247
|
+
} else if (node.type == "ReturnStmt") {
|
|
2248
|
+
this.genReturn(node);
|
|
2249
|
+
} else if (node.type == "TryCatchStmt") {
|
|
2250
|
+
this.genTryCatch(node);
|
|
2251
|
+
} else if (node.type == "ThrowStmt") {
|
|
2252
|
+
this.genThrow(node);
|
|
2253
|
+
} else if (node.type == "DoWhileStmt") {
|
|
2254
|
+
this.genDoWhile(node);
|
|
2255
|
+
} else if (node.type == "BreakStmt") {
|
|
2248
2256
|
this.emit("break;");
|
|
2249
|
-
} else if (
|
|
2257
|
+
} else if (node.type == "ContinueStmt") {
|
|
2250
2258
|
this.emit("continue;");
|
|
2251
|
-
} else if (
|
|
2252
|
-
this.genImport(
|
|
2253
|
-
} else if (
|
|
2254
|
-
this.genExport(
|
|
2255
|
-
} else if (
|
|
2256
|
-
this.genTypeDecl(
|
|
2257
|
-
} else if (
|
|
2258
|
-
this.genInterfaceDecl(
|
|
2259
|
-
} else if (
|
|
2260
|
-
this.genEnumDecl(
|
|
2261
|
-
} else if (
|
|
2259
|
+
} else if (node.type == "ImportDecl") {
|
|
2260
|
+
this.genImport(node);
|
|
2261
|
+
} else if (node.type == "ExportDecl") {
|
|
2262
|
+
this.genExport(node);
|
|
2263
|
+
} else if (node.type == "TypeDecl") {
|
|
2264
|
+
this.genTypeDecl(node);
|
|
2265
|
+
} else if (node.type == "InterfaceDecl") {
|
|
2266
|
+
this.genInterfaceDecl(node);
|
|
2267
|
+
} else if (node.type == "EnumDecl") {
|
|
2268
|
+
this.genEnumDecl(node);
|
|
2269
|
+
} else if (node.type == "DeclareDecl") {
|
|
2262
2270
|
return;
|
|
2263
|
-
} else if (
|
|
2264
|
-
this.emit(this.genExpr(
|
|
2271
|
+
} else if (node.type == "ExprStmt") {
|
|
2272
|
+
this.emit(this.genExpr(node.expr) + ";");
|
|
2265
2273
|
} else {
|
|
2266
|
-
throw new Error(`Unknown statement: ${
|
|
2274
|
+
throw new Error(`Unknown statement: ${node.type}`);
|
|
2267
2275
|
}
|
|
2268
2276
|
}
|
|
2269
|
-
genVar(
|
|
2270
|
-
const kw =
|
|
2271
|
-
const init =
|
|
2272
|
-
this.emit(kw + " " +
|
|
2277
|
+
genVar(node) {
|
|
2278
|
+
const kw = node.kind == "val" ? "const" : "let";
|
|
2279
|
+
const init = node.init ? " = " + this.genExpr(node.init) : "";
|
|
2280
|
+
this.emit(kw + " " + node.name + init + ";");
|
|
2273
2281
|
}
|
|
2274
|
-
genObjPair(
|
|
2275
|
-
if (
|
|
2276
|
-
return "..." + this.genExpr(
|
|
2282
|
+
genObjPair(p) {
|
|
2283
|
+
if (p.spread) {
|
|
2284
|
+
return "..." + this.genExpr(p.value);
|
|
2277
2285
|
}
|
|
2278
|
-
const isIdent = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(
|
|
2279
|
-
const keyStr = isIdent ?
|
|
2280
|
-
if (isIdent &&
|
|
2281
|
-
return
|
|
2286
|
+
const isIdent = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(p.key);
|
|
2287
|
+
const keyStr = isIdent ? p.key : '"' + p.key + '"';
|
|
2288
|
+
if (isIdent && p.value && p.value.type == "Identifier" && p.value.name == p.key) {
|
|
2289
|
+
return p.key;
|
|
2282
2290
|
}
|
|
2283
|
-
return keyStr + ": " + this.genExpr(
|
|
2291
|
+
return keyStr + ": " + this.genExpr(p.value);
|
|
2284
2292
|
}
|
|
2285
|
-
genDestructProp(
|
|
2286
|
-
if (
|
|
2287
|
-
return "..." +
|
|
2293
|
+
genDestructProp(p) {
|
|
2294
|
+
if (p.rest) {
|
|
2295
|
+
return "..." + p.key;
|
|
2288
2296
|
}
|
|
2289
|
-
let
|
|
2290
|
-
if (
|
|
2291
|
-
|
|
2297
|
+
let s = p.alias != p.key ? p.key + ": " + p.alias : p.key;
|
|
2298
|
+
if (p.defaultVal) {
|
|
2299
|
+
s = s + " = " + this.genExpr(p.defaultVal);
|
|
2292
2300
|
}
|
|
2293
|
-
return
|
|
2301
|
+
return s;
|
|
2294
2302
|
}
|
|
2295
|
-
genDestructItem(
|
|
2296
|
-
if (!
|
|
2303
|
+
genDestructItem(p) {
|
|
2304
|
+
if (!p) {
|
|
2297
2305
|
return "";
|
|
2298
2306
|
}
|
|
2299
|
-
if (
|
|
2300
|
-
return "..." +
|
|
2307
|
+
if (p.rest) {
|
|
2308
|
+
return "..." + p.name;
|
|
2301
2309
|
}
|
|
2302
|
-
let
|
|
2303
|
-
if (
|
|
2304
|
-
|
|
2310
|
+
let s = p.name;
|
|
2311
|
+
if (p.defaultVal) {
|
|
2312
|
+
s = s + " = " + this.genExpr(p.defaultVal);
|
|
2305
2313
|
}
|
|
2306
|
-
return
|
|
2314
|
+
return s;
|
|
2307
2315
|
}
|
|
2308
|
-
genDestructure(
|
|
2309
|
-
const kw =
|
|
2310
|
-
const init = this.genExpr(
|
|
2311
|
-
if (
|
|
2312
|
-
const props =
|
|
2316
|
+
genDestructure(node) {
|
|
2317
|
+
const kw = node.kind == "val" ? "const" : "let";
|
|
2318
|
+
const init = this.genExpr(node.init);
|
|
2319
|
+
if (node.patternType == "object") {
|
|
2320
|
+
const props = node.pattern.map((p) => this.genDestructProp(p)).join(", ");
|
|
2313
2321
|
this.emit(kw + " { " + props + " } = " + init + ";");
|
|
2314
2322
|
} else {
|
|
2315
|
-
const items =
|
|
2323
|
+
const items = node.pattern.map((p) => this.genDestructItem(p)).join(", ");
|
|
2316
2324
|
this.emit(kw + " [" + items + "] = " + init + ";");
|
|
2317
2325
|
}
|
|
2318
2326
|
}
|
|
2319
|
-
genFn(
|
|
2320
|
-
const asyncKw =
|
|
2321
|
-
const
|
|
2322
|
-
const params =
|
|
2323
|
-
if (
|
|
2324
|
-
this.emit(
|
|
2327
|
+
genFn(node, prefix) {
|
|
2328
|
+
const asyncKw = node.async ? "async " : "";
|
|
2329
|
+
const name = node.name ?? "";
|
|
2330
|
+
const params = node.params.map((p) => p.rest ? "..." + p.name : p.defaultVal ? p.name + " = " + this.genExpr(p.defaultVal) : p.name).join(", ");
|
|
2331
|
+
if (node.inline) {
|
|
2332
|
+
this.emit(prefix + asyncKw + "function " + name + "(" + params + ") { return " + this.genExpr(node.body) + "; }");
|
|
2325
2333
|
} else {
|
|
2326
|
-
this.emit(
|
|
2334
|
+
this.emit(prefix + asyncKw + "function " + name + "(" + params + ") {");
|
|
2327
2335
|
this.indIn();
|
|
2328
2336
|
this._fnDepth = this._fnDepth + 1;
|
|
2329
|
-
for (const
|
|
2330
|
-
this.genStmt(
|
|
2337
|
+
for (const s of node.body) {
|
|
2338
|
+
this.genStmt(s);
|
|
2331
2339
|
}
|
|
2332
2340
|
this._fnDepth = this._fnDepth - 1;
|
|
2333
2341
|
this.indOut();
|
|
2334
2342
|
this.emit("}");
|
|
2335
2343
|
}
|
|
2336
2344
|
}
|
|
2337
|
-
genClass(
|
|
2338
|
-
const ext =
|
|
2339
|
-
this.emit("class " +
|
|
2345
|
+
genClass(node) {
|
|
2346
|
+
const ext = node.superClass ? " extends " + node.superClass : "";
|
|
2347
|
+
this.emit("class " + node.name + ext + " {");
|
|
2340
2348
|
this.indIn();
|
|
2341
|
-
const allFields =
|
|
2349
|
+
const allFields = getAllFields(node.name, this.clsReg, null);
|
|
2342
2350
|
if (allFields.length > 0) {
|
|
2343
|
-
const params = allFields.map((
|
|
2351
|
+
const params = allFields.map((f) => f.name).join(", ");
|
|
2344
2352
|
this.emit("constructor(" + params + ") {");
|
|
2345
2353
|
this.indIn();
|
|
2346
|
-
if (
|
|
2347
|
-
const parentFields =
|
|
2354
|
+
if (node.superClass && this.clsReg[node.superClass]) {
|
|
2355
|
+
const parentFields = getAllFields(node.superClass, this.clsReg, null);
|
|
2348
2356
|
if (parentFields.length > 0) {
|
|
2349
|
-
this.emit("super(" + parentFields.map((
|
|
2357
|
+
this.emit("super(" + parentFields.map((f) => f.name).join(", ") + ");");
|
|
2350
2358
|
}
|
|
2351
2359
|
}
|
|
2352
|
-
for (const
|
|
2353
|
-
this.emit("this." +
|
|
2360
|
+
for (const f of node.fields) {
|
|
2361
|
+
this.emit("this." + f.name + " = " + f.name + ";");
|
|
2354
2362
|
}
|
|
2355
2363
|
this.indOut();
|
|
2356
2364
|
this.emit("}");
|
|
2357
2365
|
this.blank();
|
|
2358
2366
|
}
|
|
2359
|
-
for (const
|
|
2360
|
-
const asyncKw =
|
|
2361
|
-
const staticKw =
|
|
2362
|
-
const params =
|
|
2363
|
-
if (
|
|
2364
|
-
this.emit(staticKw + asyncKw +
|
|
2367
|
+
for (const m of node.methods) {
|
|
2368
|
+
const asyncKw = m.async ? "async " : "";
|
|
2369
|
+
const staticKw = m.modifiers && m.modifiers.has("static") ? "static " : "";
|
|
2370
|
+
const params = m.params.map((p) => p.rest ? "..." + p.name : p.defaultVal ? p.name + " = " + this.genExpr(p.defaultVal) : p.name).join(", ");
|
|
2371
|
+
if (m.inline) {
|
|
2372
|
+
this.emit(staticKw + asyncKw + m.name + "(" + params + ") { return " + this.genExpr(m.body) + "; }");
|
|
2365
2373
|
} else {
|
|
2366
|
-
this.emit(staticKw + asyncKw +
|
|
2374
|
+
this.emit(staticKw + asyncKw + m.name + "(" + params + ") {");
|
|
2367
2375
|
this.indIn();
|
|
2368
2376
|
this._fnDepth = this._fnDepth + 1;
|
|
2369
|
-
for (const
|
|
2370
|
-
this.genStmt(
|
|
2377
|
+
for (const s of m.body) {
|
|
2378
|
+
this.genStmt(s);
|
|
2371
2379
|
}
|
|
2372
2380
|
this._fnDepth = this._fnDepth - 1;
|
|
2373
2381
|
this.indOut();
|
|
@@ -2379,71 +2387,71 @@ var require_codegen = __commonJS({
|
|
|
2379
2387
|
this.emit("}");
|
|
2380
2388
|
this.blank();
|
|
2381
2389
|
}
|
|
2382
|
-
genIf(
|
|
2383
|
-
this.emit("if (" + this.genExpr(
|
|
2390
|
+
genIf(node) {
|
|
2391
|
+
this.emit("if (" + this.genExpr(node.cond) + ") {");
|
|
2384
2392
|
this.indIn();
|
|
2385
|
-
for (const
|
|
2386
|
-
this.genStmt(
|
|
2393
|
+
for (const s of node.then) {
|
|
2394
|
+
this.genStmt(s);
|
|
2387
2395
|
}
|
|
2388
2396
|
this.indOut();
|
|
2389
2397
|
this.emit("}");
|
|
2390
|
-
for (const
|
|
2391
|
-
this.emitRaw(this.i() + "else if (" + this.genExpr(
|
|
2398
|
+
for (const ei of node.elseifs) {
|
|
2399
|
+
this.emitRaw(this.i() + "else if (" + this.genExpr(ei.cond) + ") {");
|
|
2392
2400
|
this.indIn();
|
|
2393
|
-
for (const
|
|
2394
|
-
this.genStmt(
|
|
2401
|
+
for (const s of ei.body) {
|
|
2402
|
+
this.genStmt(s);
|
|
2395
2403
|
}
|
|
2396
2404
|
this.indOut();
|
|
2397
2405
|
this.emit("}");
|
|
2398
2406
|
}
|
|
2399
|
-
if (
|
|
2407
|
+
if (node.else_) {
|
|
2400
2408
|
this.emitRaw(this.i() + "else {");
|
|
2401
2409
|
this.indIn();
|
|
2402
|
-
for (const
|
|
2403
|
-
this.genStmt(
|
|
2410
|
+
for (const s of node.else_) {
|
|
2411
|
+
this.genStmt(s);
|
|
2404
2412
|
}
|
|
2405
2413
|
this.indOut();
|
|
2406
2414
|
this.emit("}");
|
|
2407
2415
|
}
|
|
2408
2416
|
}
|
|
2409
|
-
genFor(
|
|
2410
|
-
const varName =
|
|
2411
|
-
const iter =
|
|
2417
|
+
genFor(node) {
|
|
2418
|
+
const varName = node["var"];
|
|
2419
|
+
const iter = node.iter;
|
|
2412
2420
|
if (iter.type == "RangeExpr") {
|
|
2413
|
-
const
|
|
2421
|
+
const s = this.genExpr(iter.start);
|
|
2414
2422
|
const e = this.genExpr(iter.end);
|
|
2415
|
-
this.emit("for (let " + varName + " = " +
|
|
2416
|
-
} else if (
|
|
2423
|
+
this.emit("for (let " + varName + " = " + s + "; " + varName + " < " + e + "; " + varName + "++) {");
|
|
2424
|
+
} else if (node.isAwait) {
|
|
2417
2425
|
this.emit("for await (const " + varName + " of " + this.genExpr(iter) + ") {");
|
|
2418
2426
|
} else {
|
|
2419
2427
|
this.emit("for (const " + varName + " of " + this.genExpr(iter) + ") {");
|
|
2420
2428
|
}
|
|
2421
2429
|
this._loopDepth = this._loopDepth + 1;
|
|
2422
2430
|
this.indIn();
|
|
2423
|
-
for (const
|
|
2424
|
-
this.genStmt(
|
|
2431
|
+
for (const s of node.body) {
|
|
2432
|
+
this.genStmt(s);
|
|
2425
2433
|
}
|
|
2426
2434
|
this.indOut();
|
|
2427
2435
|
this._loopDepth = this._loopDepth - 1;
|
|
2428
2436
|
this.emit("}");
|
|
2429
2437
|
}
|
|
2430
|
-
genWhile(
|
|
2431
|
-
this.emit("while (" + this.genExpr(
|
|
2438
|
+
genWhile(node) {
|
|
2439
|
+
this.emit("while (" + this.genExpr(node.cond) + ") {");
|
|
2432
2440
|
this._loopDepth = this._loopDepth + 1;
|
|
2433
2441
|
this.indIn();
|
|
2434
|
-
for (const
|
|
2435
|
-
this.genStmt(
|
|
2442
|
+
for (const s of node.body) {
|
|
2443
|
+
this.genStmt(s);
|
|
2436
2444
|
}
|
|
2437
2445
|
this.indOut();
|
|
2438
2446
|
this._loopDepth = this._loopDepth - 1;
|
|
2439
2447
|
this.emit("}");
|
|
2440
2448
|
}
|
|
2441
|
-
genMatch(
|
|
2442
|
-
const subj = this.genExpr(
|
|
2443
|
-
const arms =
|
|
2449
|
+
genMatch(node) {
|
|
2450
|
+
const subj = this.genExpr(node.subject);
|
|
2451
|
+
const arms = node.arms;
|
|
2444
2452
|
let hasOpenIf = false;
|
|
2445
|
-
for (const
|
|
2446
|
-
const pat =
|
|
2453
|
+
for (const arm of arms) {
|
|
2454
|
+
const pat = arm.pattern;
|
|
2447
2455
|
let cond = "";
|
|
2448
2456
|
const bindings = [];
|
|
2449
2457
|
if (pat.type == "WildcardPat") {
|
|
@@ -2455,8 +2463,8 @@ var require_codegen = __commonJS({
|
|
|
2455
2463
|
} else if (pat.type == "VariantPat") {
|
|
2456
2464
|
cond = subj + '?.__type === "' + pat.variant + '"';
|
|
2457
2465
|
let bi = 0;
|
|
2458
|
-
for (const
|
|
2459
|
-
bindings.push("const " +
|
|
2466
|
+
for (const b of pat.bindings) {
|
|
2467
|
+
bindings.push("const " + b + " = " + subj + ".__args[" + bi + "];");
|
|
2460
2468
|
bi = bi + 1;
|
|
2461
2469
|
}
|
|
2462
2470
|
} else {
|
|
@@ -2467,10 +2475,10 @@ var require_codegen = __commonJS({
|
|
|
2467
2475
|
cond = subj + " === " + patExpr;
|
|
2468
2476
|
}
|
|
2469
2477
|
}
|
|
2470
|
-
if (
|
|
2471
|
-
const guardSrc = this.genExpr(
|
|
2478
|
+
if (arm.guard) {
|
|
2479
|
+
const guardSrc = this.genExpr(arm.guard);
|
|
2472
2480
|
if (bindings.length > 0) {
|
|
2473
|
-
const rebindings = bindings.map((
|
|
2481
|
+
const rebindings = bindings.map((bx) => bx.replace("const ", "var ")).join(" ");
|
|
2474
2482
|
const iife = "(function(){ " + rebindings + " return (" + guardSrc + "); }())";
|
|
2475
2483
|
cond = cond ? "(" + cond + ") && " + iife : iife;
|
|
2476
2484
|
} else {
|
|
@@ -2489,11 +2497,11 @@ var require_codegen = __commonJS({
|
|
|
2489
2497
|
this.emitRaw(this.i() + "else {");
|
|
2490
2498
|
}
|
|
2491
2499
|
this.indIn();
|
|
2492
|
-
for (const
|
|
2493
|
-
this.emit(
|
|
2500
|
+
for (const b of bindings) {
|
|
2501
|
+
this.emit(b);
|
|
2494
2502
|
}
|
|
2495
|
-
if (
|
|
2496
|
-
const exprSrc = this.genExpr(
|
|
2503
|
+
if (arm.inline) {
|
|
2504
|
+
const exprSrc = this.genExpr(arm.body[0].expr);
|
|
2497
2505
|
if (this._loopDepth > 0) {
|
|
2498
2506
|
this.emit(exprSrc + ";");
|
|
2499
2507
|
} else if (this._fnDepth > 0) {
|
|
@@ -2502,114 +2510,114 @@ var require_codegen = __commonJS({
|
|
|
2502
2510
|
this.emit(exprSrc + ";");
|
|
2503
2511
|
}
|
|
2504
2512
|
} else {
|
|
2505
|
-
for (const
|
|
2506
|
-
this.genStmt(
|
|
2513
|
+
for (const s of arm.body) {
|
|
2514
|
+
this.genStmt(s);
|
|
2507
2515
|
}
|
|
2508
2516
|
}
|
|
2509
2517
|
this.indOut();
|
|
2510
2518
|
this.emit("}");
|
|
2511
2519
|
}
|
|
2512
2520
|
}
|
|
2513
|
-
genInterfaceDecl(
|
|
2521
|
+
genInterfaceDecl(node) {
|
|
2514
2522
|
this.blank();
|
|
2515
|
-
this.emit("// interface " +
|
|
2523
|
+
this.emit("// interface " + node.name);
|
|
2516
2524
|
this.blank();
|
|
2517
2525
|
}
|
|
2518
|
-
genEnumDecl(
|
|
2526
|
+
genEnumDecl(node) {
|
|
2519
2527
|
this.blank();
|
|
2520
|
-
const pairs =
|
|
2521
|
-
this.emit("const " +
|
|
2528
|
+
const pairs = node.members.map((m) => m.name + ": " + this.genExpr(m.value)).join(", ");
|
|
2529
|
+
this.emit("const " + node.name + " = Object.freeze({ " + pairs + " });");
|
|
2522
2530
|
this.blank();
|
|
2523
2531
|
}
|
|
2524
|
-
genTypeDecl(
|
|
2532
|
+
genTypeDecl(node) {
|
|
2525
2533
|
this.blank();
|
|
2526
|
-
this.emit("// ADT type: " +
|
|
2527
|
-
for (const
|
|
2528
|
-
if (
|
|
2529
|
-
this.emit("const " +
|
|
2534
|
+
this.emit("// ADT type: " + node.name);
|
|
2535
|
+
for (const v of node.variants) {
|
|
2536
|
+
if (v.fields.length == 0) {
|
|
2537
|
+
this.emit("const " + v.name + ' = Object.freeze({ __type: "' + v.name + '", __args: [] });');
|
|
2530
2538
|
} else {
|
|
2531
|
-
const params =
|
|
2532
|
-
const argsArr = "[" +
|
|
2533
|
-
const fieldsObj =
|
|
2534
|
-
this.emit("function " +
|
|
2539
|
+
const params = v.fields.join(", ");
|
|
2540
|
+
const argsArr = "[" + v.fields.join(", ") + "]";
|
|
2541
|
+
const fieldsObj = v.fields.map((f) => f + ": " + f).join(", ");
|
|
2542
|
+
this.emit("function " + v.name + "(" + params + ') { return Object.freeze({ __type: "' + v.name + '", __args: ' + argsArr + ", " + fieldsObj + " }); }");
|
|
2535
2543
|
}
|
|
2536
2544
|
}
|
|
2537
2545
|
this.blank();
|
|
2538
2546
|
}
|
|
2539
|
-
genReturn(
|
|
2540
|
-
if (
|
|
2541
|
-
this.emit("return " + this.genExpr(
|
|
2547
|
+
genReturn(node) {
|
|
2548
|
+
if (node.value) {
|
|
2549
|
+
this.emit("return " + this.genExpr(node.value) + ";");
|
|
2542
2550
|
} else {
|
|
2543
2551
|
this.emit("return;");
|
|
2544
2552
|
}
|
|
2545
2553
|
}
|
|
2546
|
-
genTryCatch(
|
|
2554
|
+
genTryCatch(node) {
|
|
2547
2555
|
this.emit("try {");
|
|
2548
2556
|
this.indIn();
|
|
2549
|
-
for (const
|
|
2550
|
-
this.genStmt(
|
|
2557
|
+
for (const s of node.tryBody) {
|
|
2558
|
+
this.genStmt(s);
|
|
2551
2559
|
}
|
|
2552
2560
|
this.indOut();
|
|
2553
2561
|
this.emit("}");
|
|
2554
|
-
if (
|
|
2555
|
-
const param =
|
|
2562
|
+
if (node.catchBody) {
|
|
2563
|
+
const param = node.catchParam ? "(" + node.catchParam + ")" : "(_err)";
|
|
2556
2564
|
this.emitRaw(this.i() + "catch " + param + " {");
|
|
2557
2565
|
this.indIn();
|
|
2558
|
-
for (const
|
|
2559
|
-
this.genStmt(
|
|
2566
|
+
for (const s of node.catchBody) {
|
|
2567
|
+
this.genStmt(s);
|
|
2560
2568
|
}
|
|
2561
2569
|
this.indOut();
|
|
2562
2570
|
this.emit("}");
|
|
2563
2571
|
}
|
|
2564
|
-
if (
|
|
2572
|
+
if (node.finallyBody) {
|
|
2565
2573
|
this.emitRaw(this.i() + "finally {");
|
|
2566
2574
|
this.indIn();
|
|
2567
|
-
for (const
|
|
2568
|
-
this.genStmt(
|
|
2575
|
+
for (const s of node.finallyBody) {
|
|
2576
|
+
this.genStmt(s);
|
|
2569
2577
|
}
|
|
2570
2578
|
this.indOut();
|
|
2571
2579
|
this.emit("}");
|
|
2572
2580
|
}
|
|
2573
2581
|
}
|
|
2574
|
-
genThrow(
|
|
2575
|
-
this.emit("throw " + this.genExpr(
|
|
2582
|
+
genThrow(node) {
|
|
2583
|
+
this.emit("throw " + this.genExpr(node.value) + ";");
|
|
2576
2584
|
}
|
|
2577
|
-
genDoWhile(
|
|
2585
|
+
genDoWhile(node) {
|
|
2578
2586
|
this.emit("do {");
|
|
2579
2587
|
this.indIn();
|
|
2580
|
-
for (const
|
|
2581
|
-
this.genStmt(
|
|
2588
|
+
for (const s of node.body) {
|
|
2589
|
+
this.genStmt(s);
|
|
2582
2590
|
}
|
|
2583
2591
|
this.indOut();
|
|
2584
|
-
this.emit("} while (" + this.genExpr(
|
|
2585
|
-
}
|
|
2586
|
-
genImport(
|
|
2587
|
-
const src = String(
|
|
2588
|
-
if (
|
|
2589
|
-
this.emit("const " +
|
|
2590
|
-
} else if (
|
|
2591
|
-
this.emit("const " +
|
|
2592
|
-
} else if (
|
|
2593
|
-
const parts =
|
|
2592
|
+
this.emit("} while (" + this.genExpr(node.cond) + ");");
|
|
2593
|
+
}
|
|
2594
|
+
genImport(node) {
|
|
2595
|
+
const src = String(node.source);
|
|
2596
|
+
if (node.namespaceName) {
|
|
2597
|
+
this.emit("const " + node.namespaceName + ' = require("' + src + '");');
|
|
2598
|
+
} else if (node.defaultName) {
|
|
2599
|
+
this.emit("const " + node.defaultName + ' = require("' + src + '");');
|
|
2600
|
+
} else if (node.names.length) {
|
|
2601
|
+
const parts = node.names.map((n) => typeof n == "string" ? n : n.name != n.alias ? n.name + ": " + n.alias : n.name).join(", ");
|
|
2594
2602
|
this.emit("const { " + parts + ' } = require("' + src + '");');
|
|
2595
2603
|
}
|
|
2596
2604
|
}
|
|
2597
|
-
genExport(
|
|
2598
|
-
if (
|
|
2599
|
-
this.emit("module.exports = " + this.genExpr(
|
|
2605
|
+
genExport(node) {
|
|
2606
|
+
if (node.isDefault) {
|
|
2607
|
+
this.emit("module.exports = " + this.genExpr(node.decl) + ";");
|
|
2600
2608
|
return;
|
|
2601
2609
|
}
|
|
2602
|
-
const decl =
|
|
2610
|
+
const decl = node.decl;
|
|
2603
2611
|
if (decl.type == "FnDecl") {
|
|
2604
2612
|
const asyncKw = decl.async ? "async " : "";
|
|
2605
|
-
const params = decl.params.map((
|
|
2613
|
+
const params = decl.params.map((p) => p.rest ? "..." + p.name : p.defaultVal ? p.name + " = " + this.genExpr(p.defaultVal) : p.name).join(", ");
|
|
2606
2614
|
if (decl.inline) {
|
|
2607
2615
|
this.emit(asyncKw + "function " + decl.name + "(" + params + ") { return " + this.genExpr(decl.body) + "; }");
|
|
2608
2616
|
} else {
|
|
2609
2617
|
this.emit(asyncKw + "function " + decl.name + "(" + params + ") {");
|
|
2610
2618
|
this.indIn();
|
|
2611
|
-
for (const
|
|
2612
|
-
this.genStmt(
|
|
2619
|
+
for (const s of decl.body) {
|
|
2620
|
+
this.genStmt(s);
|
|
2613
2621
|
}
|
|
2614
2622
|
this.indOut();
|
|
2615
2623
|
this.emit("}");
|
|
@@ -2620,8 +2628,8 @@ var require_codegen = __commonJS({
|
|
|
2620
2628
|
this.emit("module.exports." + decl.name + " = " + decl.name + ";");
|
|
2621
2629
|
} else if (decl.type == "TypeDecl") {
|
|
2622
2630
|
this.genTypeDecl(decl);
|
|
2623
|
-
for (const
|
|
2624
|
-
this.emit("module.exports." +
|
|
2631
|
+
for (const v of decl.variants) {
|
|
2632
|
+
this.emit("module.exports." + v.name + " = " + v.name + ";");
|
|
2625
2633
|
}
|
|
2626
2634
|
} else if (decl.type == "InterfaceDecl") {
|
|
2627
2635
|
this.genInterfaceDecl(decl);
|
|
@@ -2636,112 +2644,112 @@ var require_codegen = __commonJS({
|
|
|
2636
2644
|
this.genStmt(decl);
|
|
2637
2645
|
}
|
|
2638
2646
|
}
|
|
2639
|
-
genExpr(
|
|
2640
|
-
if (!
|
|
2647
|
+
genExpr(node) {
|
|
2648
|
+
if (!node) {
|
|
2641
2649
|
return "undefined";
|
|
2642
2650
|
}
|
|
2643
|
-
if (
|
|
2644
|
-
return String(
|
|
2651
|
+
if (node.type == "NumberLit") {
|
|
2652
|
+
return String(node.value);
|
|
2645
2653
|
}
|
|
2646
|
-
if (
|
|
2647
|
-
return String(
|
|
2654
|
+
if (node.type == "BoolLit") {
|
|
2655
|
+
return String(node.value);
|
|
2648
2656
|
}
|
|
2649
|
-
if (
|
|
2657
|
+
if (node.type == "NullLit") {
|
|
2650
2658
|
return "null";
|
|
2651
2659
|
}
|
|
2652
|
-
if (
|
|
2660
|
+
if (node.type == "SelfExpr") {
|
|
2653
2661
|
return "this";
|
|
2654
2662
|
}
|
|
2655
|
-
if (
|
|
2656
|
-
return
|
|
2663
|
+
if (node.type == "Identifier") {
|
|
2664
|
+
return node.name == "print" ? "console.log" : node.name;
|
|
2657
2665
|
}
|
|
2658
|
-
if (
|
|
2659
|
-
return JSON.stringify(
|
|
2666
|
+
if (node.type == "StringLit") {
|
|
2667
|
+
return JSON.stringify(node.value);
|
|
2660
2668
|
}
|
|
2661
|
-
if (
|
|
2662
|
-
return "/" +
|
|
2669
|
+
if (node.type == "RegexLit") {
|
|
2670
|
+
return "/" + node.value.pattern + "/" + node.value.flags;
|
|
2663
2671
|
}
|
|
2664
|
-
if (
|
|
2665
|
-
return this.genTemplate(
|
|
2672
|
+
if (node.type == "TemplateLit") {
|
|
2673
|
+
return this.genTemplate(node.parts);
|
|
2666
2674
|
}
|
|
2667
|
-
if (
|
|
2668
|
-
return "(" + this.genExpr(
|
|
2675
|
+
if (node.type == "BinaryExpr") {
|
|
2676
|
+
return "(" + this.genExpr(node.left) + " " + node.op + " " + this.genExpr(node.right) + ")";
|
|
2669
2677
|
}
|
|
2670
|
-
if (
|
|
2671
|
-
return
|
|
2678
|
+
if (node.type == "UnaryExpr") {
|
|
2679
|
+
return node.op + this.genExpr(node.operand);
|
|
2672
2680
|
}
|
|
2673
|
-
if (
|
|
2674
|
-
if (
|
|
2675
|
-
return
|
|
2681
|
+
if (node.type == "UpdateExpr") {
|
|
2682
|
+
if (node.prefix) {
|
|
2683
|
+
return node.op + this.genExpr(node.operand);
|
|
2676
2684
|
}
|
|
2677
|
-
return this.genExpr(
|
|
2685
|
+
return this.genExpr(node.operand) + node.op;
|
|
2678
2686
|
}
|
|
2679
|
-
if (
|
|
2680
|
-
return "(" + this.genExpr(
|
|
2687
|
+
if (node.type == "TernaryExpr") {
|
|
2688
|
+
return "(" + this.genExpr(node.cond) + " ? " + this.genExpr(node.then) + " : " + this.genExpr(node.else_) + ")";
|
|
2681
2689
|
}
|
|
2682
|
-
if (
|
|
2683
|
-
return this.genExpr(
|
|
2690
|
+
if (node.type == "AssignExpr") {
|
|
2691
|
+
return this.genExpr(node.target) + " " + node.op + " " + this.genExpr(node.value);
|
|
2684
2692
|
}
|
|
2685
|
-
if (
|
|
2686
|
-
return "await " + this.genExpr(
|
|
2693
|
+
if (node.type == "AwaitExpr") {
|
|
2694
|
+
return "await " + this.genExpr(node.operand);
|
|
2687
2695
|
}
|
|
2688
|
-
if (
|
|
2689
|
-
return "typeof " + this.genExpr(
|
|
2696
|
+
if (node.type == "TypeofExpr") {
|
|
2697
|
+
return "typeof " + this.genExpr(node.operand);
|
|
2690
2698
|
}
|
|
2691
|
-
if (
|
|
2692
|
-
return "..." + this.genExpr(
|
|
2699
|
+
if (node.type == "SpreadExpr") {
|
|
2700
|
+
return "..." + this.genExpr(node.expr);
|
|
2693
2701
|
}
|
|
2694
|
-
if (
|
|
2695
|
-
const callee = this.genExpr(
|
|
2696
|
-
const args =
|
|
2702
|
+
if (node.type == "CallExpr") {
|
|
2703
|
+
const callee = this.genExpr(node.callee);
|
|
2704
|
+
const args = node.args.map((a) => this.genExpr(a)).join(", ");
|
|
2697
2705
|
return callee + "(" + args + ")";
|
|
2698
2706
|
}
|
|
2699
|
-
if (
|
|
2700
|
-
const objSrc = this.genExpr(
|
|
2701
|
-
const wrapped =
|
|
2702
|
-
return wrapped + "." +
|
|
2707
|
+
if (node.type == "MemberExpr") {
|
|
2708
|
+
const objSrc = this.genExpr(node.obj);
|
|
2709
|
+
const wrapped = node.obj.type == "NumberLit" ? "(" + objSrc + ")" : objSrc;
|
|
2710
|
+
return wrapped + "." + node.prop;
|
|
2703
2711
|
}
|
|
2704
|
-
if (
|
|
2705
|
-
return this.genExpr(
|
|
2712
|
+
if (node.type == "OptMemberExpr") {
|
|
2713
|
+
return this.genExpr(node.obj) + "?." + node.prop;
|
|
2706
2714
|
}
|
|
2707
|
-
if (
|
|
2708
|
-
return this.genExpr(
|
|
2715
|
+
if (node.type == "OptIndexExpr") {
|
|
2716
|
+
return this.genExpr(node.obj) + "?.[" + this.genExpr(node.idx) + "]";
|
|
2709
2717
|
}
|
|
2710
|
-
if (
|
|
2711
|
-
const args =
|
|
2712
|
-
return this.genExpr(
|
|
2718
|
+
if (node.type == "OptCallExpr") {
|
|
2719
|
+
const args = node.args.map((a) => this.genExpr(a)).join(", ");
|
|
2720
|
+
return this.genExpr(node.callee) + "?.(" + args + ")";
|
|
2713
2721
|
}
|
|
2714
|
-
if (
|
|
2715
|
-
return this.genExpr(
|
|
2722
|
+
if (node.type == "IndexExpr") {
|
|
2723
|
+
return this.genExpr(node.obj) + "[" + this.genExpr(node.idx) + "]";
|
|
2716
2724
|
}
|
|
2717
|
-
if (
|
|
2718
|
-
const args =
|
|
2719
|
-
return "new " +
|
|
2725
|
+
if (node.type == "NewExpr") {
|
|
2726
|
+
const args = node.args.map((a) => this.genExpr(a)).join(", ");
|
|
2727
|
+
return "new " + node.callee + "(" + args + ")";
|
|
2720
2728
|
}
|
|
2721
|
-
if (
|
|
2722
|
-
const params =
|
|
2723
|
-
return "(" + params + ") => " + this.genExpr(
|
|
2729
|
+
if (node.type == "LambdaExpr") {
|
|
2730
|
+
const params = node.params.map((p) => p.rest ? "..." + p.name : p.name).join(", ");
|
|
2731
|
+
return "(" + params + ") => " + this.genExpr(node.body);
|
|
2724
2732
|
}
|
|
2725
|
-
if (
|
|
2726
|
-
const asyncKw =
|
|
2727
|
-
const params =
|
|
2728
|
-
if (
|
|
2729
|
-
return asyncKw + "function(" + params + ") { return " + this.genExpr(
|
|
2733
|
+
if (node.type == "FnDecl") {
|
|
2734
|
+
const asyncKw = node.async ? "async " : "";
|
|
2735
|
+
const params = node.params.map((p) => p.rest ? "..." + p.name : p.defaultVal ? p.name + " = " + this.genExpr(p.defaultVal) : p.name).join(", ");
|
|
2736
|
+
if (node.inline) {
|
|
2737
|
+
return asyncKw + "function(" + params + ") { return " + this.genExpr(node.body) + "; }";
|
|
2730
2738
|
}
|
|
2731
2739
|
const saved = this.lines.length;
|
|
2732
2740
|
const savedLevel = this.level;
|
|
2733
2741
|
this.emit(asyncKw + "function(" + params + ") {");
|
|
2734
2742
|
this.indIn();
|
|
2735
|
-
for (const
|
|
2736
|
-
this.genStmt(
|
|
2743
|
+
for (const s of node.body) {
|
|
2744
|
+
this.genStmt(s);
|
|
2737
2745
|
}
|
|
2738
2746
|
this.indOut();
|
|
2739
2747
|
this.emit("}");
|
|
2740
|
-
const block = this.lines.splice(saved).map((
|
|
2748
|
+
const block = this.lines.splice(saved).map((l) => l.trimStart()).join(" ");
|
|
2741
2749
|
this.level = savedLevel;
|
|
2742
2750
|
return block;
|
|
2743
2751
|
}
|
|
2744
|
-
if (
|
|
2752
|
+
if (node.type == "MatchStmt") {
|
|
2745
2753
|
const saved = this.lines.length;
|
|
2746
2754
|
const savedLevel = this.level;
|
|
2747
2755
|
const savedLoop = this._loopDepth;
|
|
@@ -2749,53 +2757,53 @@ var require_codegen = __commonJS({
|
|
|
2749
2757
|
this._fnDepth = this._fnDepth + 1;
|
|
2750
2758
|
this.emit("(() => {");
|
|
2751
2759
|
this.indIn();
|
|
2752
|
-
this.genMatch(
|
|
2760
|
+
this.genMatch(node);
|
|
2753
2761
|
this.indOut();
|
|
2754
2762
|
this.emit("})()");
|
|
2755
2763
|
this._fnDepth = this._fnDepth - 1;
|
|
2756
2764
|
this._loopDepth = savedLoop;
|
|
2757
|
-
const block = this.lines.splice(saved).map((
|
|
2765
|
+
const block = this.lines.splice(saved).map((l) => l.trimStart()).join(" ");
|
|
2758
2766
|
this.level = savedLevel;
|
|
2759
2767
|
return block;
|
|
2760
2768
|
}
|
|
2761
|
-
if (
|
|
2762
|
-
return "[" +
|
|
2769
|
+
if (node.type == "ArrayExpr") {
|
|
2770
|
+
return "[" + node.items.map((i) => this.genExpr(i)).join(", ") + "]";
|
|
2763
2771
|
}
|
|
2764
|
-
if (
|
|
2765
|
-
const pairs =
|
|
2772
|
+
if (node.type == "ObjectExpr") {
|
|
2773
|
+
const pairs = node.pairs.map((p) => this.genObjPair(p)).join(", ");
|
|
2766
2774
|
return "{ " + pairs + " }";
|
|
2767
2775
|
}
|
|
2768
|
-
if (
|
|
2769
|
-
return "Array.from({ length: " + this.genExpr(
|
|
2776
|
+
if (node.type == "RangeExpr") {
|
|
2777
|
+
return "Array.from({ length: " + this.genExpr(node.end) + " - " + this.genExpr(node.start) + " }, (_, i) => i + " + this.genExpr(node.start) + ")";
|
|
2770
2778
|
}
|
|
2771
|
-
if (
|
|
2772
|
-
return this.genPipe(
|
|
2779
|
+
if (node.type == "PipeExpr") {
|
|
2780
|
+
return this.genPipe(node);
|
|
2773
2781
|
}
|
|
2774
|
-
if (
|
|
2775
|
-
return this.genExpr(
|
|
2782
|
+
if (node.type == "CastExpr") {
|
|
2783
|
+
return this.genExpr(node.expr);
|
|
2776
2784
|
}
|
|
2777
|
-
if (
|
|
2778
|
-
return "Object.freeze(" + this.genExpr(
|
|
2785
|
+
if (node.type == "AsConstExpr") {
|
|
2786
|
+
return "Object.freeze(" + this.genExpr(node.expr) + ")";
|
|
2779
2787
|
}
|
|
2780
|
-
if (
|
|
2781
|
-
return this.genExpr(
|
|
2788
|
+
if (node.type == "SatisfiesExpr") {
|
|
2789
|
+
return this.genExpr(node.expr);
|
|
2782
2790
|
}
|
|
2783
|
-
if (
|
|
2784
|
-
return this.genExpr(
|
|
2791
|
+
if (node.type == "IsExpr") {
|
|
2792
|
+
return this.genExpr(node.expr);
|
|
2785
2793
|
}
|
|
2786
|
-
if (
|
|
2787
|
-
return this.genExpr(
|
|
2794
|
+
if (node.type == "NonNullExpr") {
|
|
2795
|
+
return this.genExpr(node.expr);
|
|
2788
2796
|
}
|
|
2789
|
-
throw new Error(`Unknown expression: ${
|
|
2797
|
+
throw new Error(`Unknown expression: ${node.type}`);
|
|
2790
2798
|
}
|
|
2791
|
-
genTemplate(
|
|
2799
|
+
genTemplate(parts) {
|
|
2792
2800
|
let result = "`";
|
|
2793
|
-
for (const
|
|
2794
|
-
if (
|
|
2795
|
-
result +=
|
|
2801
|
+
for (const p of parts) {
|
|
2802
|
+
if (p.type == "text") {
|
|
2803
|
+
result += p.value.replace(/`/g, "\\`").replace(/\$/g, "\\$");
|
|
2796
2804
|
} else {
|
|
2797
|
-
const fmtInfo =
|
|
2798
|
-
const exprSrc = fmtInfo ? fmtInfo.expr :
|
|
2805
|
+
const fmtInfo = extractFormatSpec(p.value);
|
|
2806
|
+
const exprSrc = fmtInfo ? fmtInfo.expr : p.value;
|
|
2799
2807
|
const fmt = fmtInfo ? fmtInfo.fmt : null;
|
|
2800
2808
|
try {
|
|
2801
2809
|
const tokens = lexerize(exprSrc).tokenize();
|
|
@@ -2807,42 +2815,43 @@ var require_codegen = __commonJS({
|
|
|
2807
2815
|
} else {
|
|
2808
2816
|
result += "${" + gen + "}";
|
|
2809
2817
|
}
|
|
2810
|
-
} catch (
|
|
2811
|
-
result += "${" +
|
|
2818
|
+
} catch (err) {
|
|
2819
|
+
result += "${" + p.value + "}";
|
|
2812
2820
|
}
|
|
2813
2821
|
}
|
|
2814
2822
|
}
|
|
2815
2823
|
result += "`";
|
|
2816
2824
|
return result;
|
|
2817
2825
|
}
|
|
2818
|
-
genPipe(
|
|
2819
|
-
const left = this.genExpr(
|
|
2820
|
-
const right =
|
|
2826
|
+
genPipe(node) {
|
|
2827
|
+
const left = this.genExpr(node.left);
|
|
2828
|
+
const right = node.right;
|
|
2821
2829
|
if (right.type == "Identifier") {
|
|
2822
2830
|
return this.genExpr(right) + "(" + left + ")";
|
|
2823
2831
|
}
|
|
2824
2832
|
if (right.type == "CallExpr") {
|
|
2825
2833
|
const fn_ = this.genExpr(right.callee);
|
|
2826
|
-
const rest = right.args.map((
|
|
2834
|
+
const rest = right.args.map((a) => this.genExpr(a)).join(", ");
|
|
2827
2835
|
return rest ? fn_ + "(" + left + ", " + rest + ")" : fn_ + "(" + left + ")";
|
|
2828
2836
|
}
|
|
2829
2837
|
return "(" + this.genExpr(right) + ")(" + left + ")";
|
|
2830
2838
|
}
|
|
2831
2839
|
};
|
|
2832
2840
|
module2.exports.CodeGenerator = CodeGenerator;
|
|
2833
|
-
function makeCodeGen(
|
|
2834
|
-
const ind = (
|
|
2835
|
-
const smb = (
|
|
2836
|
-
const ver = (
|
|
2841
|
+
function makeCodeGen(opts) {
|
|
2842
|
+
const ind = (opts == null ? void 0 : opts.indent) ?? " ";
|
|
2843
|
+
const smb = (opts == null ? void 0 : opts.smBuilder) ?? null;
|
|
2844
|
+
const ver = (opts == null ? void 0 : opts.version) ?? "3.5.3";
|
|
2837
2845
|
return new CodeGenerator(ind, 0, [], {}, smb, false, 0, ver);
|
|
2838
2846
|
}
|
|
2839
2847
|
module2.exports.makeCodeGen = makeCodeGen;
|
|
2840
2848
|
}
|
|
2841
2849
|
});
|
|
2842
2850
|
|
|
2843
|
-
//
|
|
2851
|
+
// src/css-preprocessor.js
|
|
2844
2852
|
var require_css_preprocessor = __commonJS({
|
|
2845
|
-
"
|
|
2853
|
+
"src/css-preprocessor.js"(exports2, module2) {
|
|
2854
|
+
"use strict";
|
|
2846
2855
|
var CSS_PROP_MAP = { bg: "background", fg: "color", p: "padding", px: "padding-inline", py: "padding-block", pt: "padding-top", pb: "padding-bottom", pl: "padding-left", pr: "padding-right", m: "margin", mx: "margin-inline", my: "margin-block", mt: "margin-top", mb: "margin-bottom", ml: "margin-left", mr: "margin-right", radius: "border-radius", w: "width", h: "height", "min-w": "min-width", "max-w": "max-width", "min-h": "min-height", "max-h": "max-height", gap: "gap", "col-gap": "column-gap", "row-gap": "row-gap", text: "font-size", font: "font-family", weight: "font-weight", tracking: "letter-spacing", leading: "line-height", shadow: "box-shadow", opacity: "opacity", border: "border", outline: "outline", transition: "transition", cursor: "cursor", overflow: "overflow", "overflow-x": "overflow-x", "overflow-y": "overflow-y", z: "z-index", transform: "transform", content: "content", resize: "resize", appearance: "appearance", "object-fit": "object-fit", "accent-color": "accent-color", direction: "flex-direction", wrap: "flex-wrap", align: "align-items", justify: "justify-content", "align-self": "align-self", "justify-self": "justify-self", grow: "flex-grow", shrink: "flex-shrink", basis: "flex-basis", order: "order", cols: "grid-template-columns", rows: "grid-template-rows", "col-span": "grid-column", "row-span": "grid-row", "place-items": "place-items", "place-content": "place-content", "list-style": "list-style", "text-align": "text-align", decoration: "text-decoration", "text-transform": "text-transform", "white-space": "white-space", "word-break": "word-break", "user-select": "user-select", "pointer-events": "pointer-events", "vertical-align": "vertical-align", backdrop: "backdrop-filter", filter: "filter", clip: "clip-path", animation: "animation", position: "position", top: "top", right: "right", bottom: "bottom", left: "left", inset: "inset", color: "color", background: "background" };
|
|
2847
2856
|
module2.exports.CSS_PROP_MAP = CSS_PROP_MAP;
|
|
2848
2857
|
var CSS_BOOL_MAP = { flex: "display: flex", grid: "display: grid", block: "display: block", inline: "display: inline", "inline-flex": "display: inline-flex", "inline-block": "display: inline-block", "inline-grid": "display: inline-grid", bold: "font-weight: 700", italic: "font-style: italic", relative: "position: relative", absolute: "position: absolute", fixed: "position: fixed", sticky: "position: sticky", hidden: "display: none", pointer: "cursor: pointer", underline: "text-decoration: underline", "line-through": "text-decoration: line-through", capitalize: "text-transform: capitalize", uppercase: "text-transform: uppercase", lowercase: "text-transform: lowercase", truncate: "overflow: hidden; text-overflow: ellipsis; white-space: nowrap", "select-none": "user-select: none", "no-wrap": "white-space: nowrap", "no-list": "list-style: none", "no-outline": "outline: none", "no-border": "border: none", "no-bg": "background: transparent", "no-padding": "padding: 0", "no-margin": "margin: 0", "no-resize": "resize: none", center: "text-align: center", "items-center": "align-items: center", "justify-center": "justify-content: center", "place-center": "place-items: center", "flex-col": "flex-direction: column", "flex-row": "flex-direction: row", "flex-wrap": "flex-wrap: wrap", "flex-1": "flex: 1", "w-full": "width: 100%", "h-full": "height: 100%", "w-screen": "width: 100vw", "h-screen": "height: 100vh", "box-border": "box-sizing: border-box" };
|
|
@@ -3112,7 +3121,7 @@ var require_css_preprocessor = __commonJS({
|
|
|
3112
3121
|
const charAfter = this.src[this.pos + 3] ?? "";
|
|
3113
3122
|
if (!/[a-zA-Z0-9_]/.test(charBefore) && !/[a-zA-Z0-9_]/.test(charAfter)) {
|
|
3114
3123
|
let j = this.pos + 3;
|
|
3115
|
-
while (j < this.src.length && (this.src[j] == " " || this.src[j] == "
|
|
3124
|
+
while (j < this.src.length && (this.src[j] == " " || this.src[j] == " " || this.src[j] == "\n" || this.src[j] == "\r")) {
|
|
3116
3125
|
j = j + 1;
|
|
3117
3126
|
}
|
|
3118
3127
|
if (this.src[j] == "{") {
|
|
@@ -3201,9 +3210,9 @@ var require_css_preprocessor = __commonJS({
|
|
|
3201
3210
|
}
|
|
3202
3211
|
});
|
|
3203
3212
|
|
|
3204
|
-
//
|
|
3213
|
+
// src/jsx.js
|
|
3205
3214
|
var require_jsx = __commonJS({
|
|
3206
|
-
"
|
|
3215
|
+
"src/jsx.js"(exports2, module2) {
|
|
3207
3216
|
"use strict";
|
|
3208
3217
|
var JSX_STYLE_VALUE_PROPS = { bg: (v) => "background:" + v, fg: (v) => "color:" + v, color: (v) => "color:" + v, p: (v) => "padding:" + v, px: (v) => "paddingLeft:" + v + ",paddingRight:" + v, py: (v) => "paddingTop:" + v + ",paddingBottom:" + v, pt: (v) => "paddingTop:" + v, pb: (v) => "paddingBottom:" + v, pl: (v) => "paddingLeft:" + v, pr: (v) => "paddingRight:" + v, m: (v) => "margin:" + v, mx: (v) => "marginLeft:" + v + ",marginRight:" + v, my: (v) => "marginTop:" + v + ",marginBottom:" + v, mt: (v) => "marginTop:" + v, mb: (v) => "marginBottom:" + v, ml: (v) => "marginLeft:" + v, mr: (v) => "marginRight:" + v, radius: (v) => "borderRadius:" + v, w: (v) => "width:" + v, h: (v) => "height:" + v, "min-w": (v) => "minWidth:" + v, "max-w": (v) => "maxWidth:" + v, "min-h": (v) => "minHeight:" + v, "max-h": (v) => "maxHeight:" + v, gap: (v) => "gap:" + v, "col-gap": (v) => "columnGap:" + v, "row-gap": (v) => "rowGap:" + v, text: (v) => "fontSize:" + v, font: (v) => "fontFamily:" + v, weight: (v) => "fontWeight:" + v, tracking: (v) => "letterSpacing:" + v, leading: (v) => "lineHeight:" + v, shadow: (v) => "boxShadow:" + v, opacity: (v) => "opacity:" + v, border: (v) => "border:" + v, outline: (v) => "outline:" + v, transition: (v) => "transition:" + v, cursor: (v) => "cursor:" + v, overflow: (v) => "overflow:" + v, z: (v) => "zIndex:" + v, transform: (v) => "transform:" + v, direction: (v) => "flexDirection:" + v, align: (v) => "alignItems:" + v, justify: (v) => "justifyContent:" + v, "align-self": (v) => "alignSelf:" + v, "place-items": (v) => "placeItems:" + v, grow: (v) => "flexGrow:" + v, shrink: (v) => "flexShrink:" + v, basis: (v) => "flexBasis:" + v, cols: (v) => "gridTemplateColumns:" + v, rows: (v) => "gridTemplateRows:" + v, inset: (v) => "inset:" + v, top: (v) => "top:" + v, right: (v) => "right:" + v, bottom: (v) => "bottom:" + v, left: (v) => "left:" + v, "object-fit": (v) => "objectFit:" + v, "line-height": (v) => "lineHeight:" + v, "text-align": (v) => "textAlign:" + v, decoration: (v) => "textDecoration:" + v, clip: (v) => "clipPath:" + v, filter: (v) => "filter:" + v, backdrop: (v) => "backdropFilter:" + v, animation: (v) => "animation:" + v };
|
|
3209
3218
|
var JSX_STYLE_BOOL_PROPS = { flex: 'display:"flex"', grid: 'display:"grid"', block: 'display:"block"', "inline-flex": 'display:"inline-flex"', "inline-block": 'display:"inline-block"', bold: "fontWeight:700", italic: 'fontStyle:"italic"', underline: 'textDecoration:"underline"', pointer: 'cursor:"pointer"', hidden: 'display:"none"', relative: 'position:"relative"', absolute: 'position:"absolute"', fixed: 'position:"fixed"', sticky: 'position:"sticky"', "flex-col": 'flexDirection:"column"', "flex-row": 'flexDirection:"row"', "flex-wrap": 'flexWrap:"wrap"', "flex-1": "flex:1", "w-full": 'width:"100%"', "h-full": 'height:"100%"', center: 'textAlign:"center"', truncate: 'overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"', "select-none": 'userSelect:"none"', "no-wrap": 'whiteSpace:"nowrap"', "no-list": 'listStyle:"none"', "no-outline": 'outline:"none"', "no-border": 'border:"none"', "box-border": 'boxSizing:"border-box"' };
|
|
@@ -3279,7 +3288,7 @@ var require_jsx = __commonJS({
|
|
|
3279
3288
|
return false;
|
|
3280
3289
|
}
|
|
3281
3290
|
let i = this.pos - 1;
|
|
3282
|
-
while (i >= 0 && (this.src[i] == " " || this.src[i] == "
|
|
3291
|
+
while (i >= 0 && (this.src[i] == " " || this.src[i] == " ")) {
|
|
3283
3292
|
i = i - 1;
|
|
3284
3293
|
}
|
|
3285
3294
|
if (i < 0) {
|
|
@@ -3533,7 +3542,7 @@ var require_jsx = __commonJS({
|
|
|
3533
3542
|
}
|
|
3534
3543
|
}
|
|
3535
3544
|
skipWs() {
|
|
3536
|
-
while (this.pos < this.src.length && (this.src[this.pos] == " " || this.src[this.pos] == "
|
|
3545
|
+
while (this.pos < this.src.length && (this.src[this.pos] == " " || this.src[this.pos] == " ")) {
|
|
3537
3546
|
this.pos = this.pos + 1;
|
|
3538
3547
|
}
|
|
3539
3548
|
}
|
|
@@ -3552,9 +3561,9 @@ var require_jsx = __commonJS({
|
|
|
3552
3561
|
}
|
|
3553
3562
|
});
|
|
3554
3563
|
|
|
3555
|
-
//
|
|
3564
|
+
// src/checker.js
|
|
3556
3565
|
var require_checker = __commonJS({
|
|
3557
|
-
"
|
|
3566
|
+
"src/checker.js"(exports2, module2) {
|
|
3558
3567
|
"use strict";
|
|
3559
3568
|
var CheckError = class {
|
|
3560
3569
|
constructor(message, loc, hint, name, line, col) {
|
|
@@ -3843,9 +3852,10 @@ var require_checker = __commonJS({
|
|
|
3843
3852
|
}
|
|
3844
3853
|
});
|
|
3845
3854
|
|
|
3846
|
-
//
|
|
3855
|
+
// src/type-checker.js
|
|
3847
3856
|
var require_type_checker = __commonJS({
|
|
3848
|
-
"
|
|
3857
|
+
"src/type-checker.js"(exports2, module2) {
|
|
3858
|
+
"use strict";
|
|
3849
3859
|
var T_ANY = Object.freeze({ kind: "any" });
|
|
3850
3860
|
module2.exports.T_ANY = T_ANY;
|
|
3851
3861
|
var T_UNKNOWN = Object.freeze({ kind: "unknown" });
|
|
@@ -4891,9 +4901,9 @@ var require_type_checker = __commonJS({
|
|
|
4891
4901
|
}
|
|
4892
4902
|
});
|
|
4893
4903
|
|
|
4894
|
-
//
|
|
4904
|
+
// src/transpiler.js
|
|
4895
4905
|
var require_transpiler = __commonJS({
|
|
4896
|
-
"
|
|
4906
|
+
"src/transpiler.js"(exports2, module2) {
|
|
4897
4907
|
"use strict";
|
|
4898
4908
|
var { Lexer, lexerize, T } = require_lexer();
|
|
4899
4909
|
var { Parser, makeParser } = require_parser();
|
|
@@ -4987,9 +4997,9 @@ var require_transpiler = __commonJS({
|
|
|
4987
4997
|
}
|
|
4988
4998
|
});
|
|
4989
4999
|
|
|
4990
|
-
//
|
|
5000
|
+
// src/bundler.js
|
|
4991
5001
|
var require_bundler = __commonJS({
|
|
4992
|
-
"
|
|
5002
|
+
"src/bundler.js"(exports2, module2) {
|
|
4993
5003
|
"use strict";
|
|
4994
5004
|
var Fs2 = require("fs");
|
|
4995
5005
|
var Path2 = require("path");
|
|
@@ -5002,24 +5012,17 @@ var require_bundler = __commonJS({
|
|
|
5002
5012
|
}
|
|
5003
5013
|
function extractModuleInfo(ast, fromFile) {
|
|
5004
5014
|
const imports = [];
|
|
5005
|
-
const npmImports = [];
|
|
5006
5015
|
const exports3 = [];
|
|
5007
5016
|
const body = [];
|
|
5008
5017
|
const dir = Path2.dirname(fromFile);
|
|
5009
5018
|
for (const node of ast.body) {
|
|
5010
5019
|
if (node.type == "ImportDecl") {
|
|
5011
|
-
|
|
5012
|
-
if (src.
|
|
5013
|
-
|
|
5014
|
-
if (!resolved.endsWith(".flux")) {
|
|
5015
|
-
resolved = resolved + ".flux";
|
|
5016
|
-
}
|
|
5017
|
-
const absPath = Path2.resolve(dir, resolved);
|
|
5018
|
-
imports.push({ names: node.names, source: node.source, absPath });
|
|
5019
|
-
} else {
|
|
5020
|
-
npmImports.push({ names: node.names, source: src });
|
|
5021
|
-
body.push(node);
|
|
5020
|
+
let src = node.source;
|
|
5021
|
+
if (!src.endsWith(".flux")) {
|
|
5022
|
+
src = src + ".flux";
|
|
5022
5023
|
}
|
|
5024
|
+
const absPath = Path2.resolve(dir, src);
|
|
5025
|
+
imports.push({ names: node.names, source: node.source, absPath });
|
|
5023
5026
|
} else if (node.type == "ExportDecl") {
|
|
5024
5027
|
const inner = node.decl;
|
|
5025
5028
|
if (inner.type == "FnDecl") {
|
|
@@ -5036,7 +5039,7 @@ var require_bundler = __commonJS({
|
|
|
5036
5039
|
body.push(node);
|
|
5037
5040
|
}
|
|
5038
5041
|
}
|
|
5039
|
-
return { cleanAst: { type: "Program", body }, imports,
|
|
5042
|
+
return { cleanAst: { type: "Program", body }, imports, exports: exports3 };
|
|
5040
5043
|
}
|
|
5041
5044
|
function codegenModule(ast) {
|
|
5042
5045
|
const cg = makeCodeGen({ indent: " " });
|
|
@@ -5096,6 +5099,9 @@ var require_bundler = __commonJS({
|
|
|
5096
5099
|
lines.push('"use strict";');
|
|
5097
5100
|
lines.push("");
|
|
5098
5101
|
}
|
|
5102
|
+
lines.push("// flux_modules resolver");
|
|
5103
|
+
lines.push("(function(){var _p=require('path'),_fs=require('fs'),_M=require('module'),_d=_p.join(process.cwd(),'flux_modules','node_modules');if(_fs.existsSync(_d)){var _o=_M._resolveFilename.bind(_M);_M._resolveFilename=function(r,p,m,op){if(!r.startsWith('.')&&!r.startsWith('/')&&!r.startsWith('node:')){var _fp=_p.join(_d,r.split('/')[0]);if(_fs.existsSync(_fp)){try{return _o(_p.join(_d,r),p,m,op);}catch(_e){}}}return _o(r,p,m,op);};}})();");
|
|
5104
|
+
lines.push("");
|
|
5099
5105
|
lines.push("(function() {");
|
|
5100
5106
|
lines.push("");
|
|
5101
5107
|
for (const absPath of this.order) {
|
|
@@ -5164,9 +5170,10 @@ var require_bundler = __commonJS({
|
|
|
5164
5170
|
}
|
|
5165
5171
|
});
|
|
5166
5172
|
|
|
5167
|
-
//
|
|
5173
|
+
// src/formatter.js
|
|
5168
5174
|
var require_formatter = __commonJS({
|
|
5169
|
-
"
|
|
5175
|
+
"src/formatter.js"(exports2, module2) {
|
|
5176
|
+
"use strict";
|
|
5170
5177
|
function normalizeOperators(line) {
|
|
5171
5178
|
if ((line.match(/:/g) ?? []).length > 2) {
|
|
5172
5179
|
return line;
|
|
@@ -5273,9 +5280,10 @@ var require_formatter = __commonJS({
|
|
|
5273
5280
|
}
|
|
5274
5281
|
});
|
|
5275
5282
|
|
|
5276
|
-
//
|
|
5283
|
+
// src/linter.js
|
|
5277
5284
|
var require_linter = __commonJS({
|
|
5278
|
-
"
|
|
5285
|
+
"src/linter.js"(exports2, module2) {
|
|
5286
|
+
"use strict";
|
|
5279
5287
|
var { lexerize } = require_lexer();
|
|
5280
5288
|
var { makeParser } = require_parser();
|
|
5281
5289
|
var BUILTIN_NAMES = /* @__PURE__ */ new Set(["self", "this", "arguments", "exports", "module", "require", "__dirname", "__filename", "process", "console", "Math", "JSON", "Object", "Array", "String", "Number", "Boolean", "Promise", "Error", "Symbol", "Map", "Set", "WeakMap", "WeakSet", "Proxy", "Reflect", "undefined", "null", "true", "false", "NaN", "Infinity", "parseInt", "parseFloat", "isNaN", "isFinite", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "fetch", "globalThis", "print", "truncate", "range", "sum", "first", "last", "zip", "flatten", "groupBy", "unique", "sortBy", "chunk"]);
|
|
@@ -6037,9 +6045,10 @@ var require_linter = __commonJS({
|
|
|
6037
6045
|
}
|
|
6038
6046
|
});
|
|
6039
6047
|
|
|
6040
|
-
//
|
|
6048
|
+
// src/test-runner.js
|
|
6041
6049
|
var require_test_runner = __commonJS({
|
|
6042
|
-
"
|
|
6050
|
+
"src/test-runner.js"(exports2, module2) {
|
|
6051
|
+
"use strict";
|
|
6043
6052
|
var Fs2 = require("fs");
|
|
6044
6053
|
var Path2 = require("path");
|
|
6045
6054
|
var Os2 = require("os");
|
|
@@ -6204,28 +6213,16 @@ function __runTest(name, fn) {
|
|
|
6204
6213
|
}
|
|
6205
6214
|
});
|
|
6206
6215
|
|
|
6207
|
-
//
|
|
6216
|
+
// src/config.js
|
|
6208
6217
|
var require_config = __commonJS({
|
|
6209
|
-
"
|
|
6218
|
+
"src/config.js"(exports2, module2) {
|
|
6210
6219
|
"use strict";
|
|
6211
6220
|
var Fs2 = require("fs");
|
|
6212
6221
|
var Path2 = require("path");
|
|
6213
|
-
var DEFAULT_CONFIG = { entry: "src/main.flux", outDir: "dist", sourcemap: false, mangle: false, jsx: false, jsxTarget: "browser", typecheck: true, strict: false, watch: false, ignore: [], selfHosted: false, registry: "https://registry.
|
|
6222
|
+
var DEFAULT_CONFIG = { entry: "src/main.flux", outDir: "dist", sourcemap: false, mangle: false, jsx: false, jsxTarget: "browser", typecheck: true, strict: false, watch: false, ignore: [], selfHosted: false, registry: "https://registry.flux-lang.dev", pkg: { name: "", version: "1.0.0", description: "", author: "", license: "MIT", deps: {}, devDeps: {} } };
|
|
6214
6223
|
module2.exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
6215
6224
|
function loadConfig2(cwd_) {
|
|
6216
6225
|
const cwd = cwd_ ?? process.cwd();
|
|
6217
|
-
const pkgJsonPath = Path2.join(cwd, "package.json");
|
|
6218
|
-
if (Fs2.existsSync(pkgJsonPath)) {
|
|
6219
|
-
try {
|
|
6220
|
-
const raw = Fs2.readFileSync(pkgJsonPath, "utf8");
|
|
6221
|
-
const parsed = JSON.parse(raw);
|
|
6222
|
-
if (parsed.flux && typeof parsed.flux == "object") {
|
|
6223
|
-
return mergeConfig(DEFAULT_CONFIG, parsed.flux);
|
|
6224
|
-
}
|
|
6225
|
-
} catch (e) {
|
|
6226
|
-
throw new Error("Invalid package.json: " + e.message);
|
|
6227
|
-
}
|
|
6228
|
-
}
|
|
6229
6226
|
const jsonPath = Path2.join(cwd, "flux.json");
|
|
6230
6227
|
if (Fs2.existsSync(jsonPath)) {
|
|
6231
6228
|
try {
|
|
@@ -6236,6 +6233,15 @@ var require_config = __commonJS({
|
|
|
6236
6233
|
throw new Error("Invalid flux.json: " + e.message);
|
|
6237
6234
|
}
|
|
6238
6235
|
}
|
|
6236
|
+
const jsPath = Path2.join(cwd, "flux.config.js");
|
|
6237
|
+
if (Fs2.existsSync(jsPath)) {
|
|
6238
|
+
try {
|
|
6239
|
+
const loaded = require(jsPath);
|
|
6240
|
+
return mergeConfig(DEFAULT_CONFIG, loaded);
|
|
6241
|
+
} catch (e2) {
|
|
6242
|
+
throw new Error("Invalid flux.config.js: " + e2.message);
|
|
6243
|
+
}
|
|
6244
|
+
}
|
|
6239
6245
|
return { ...DEFAULT_CONFIG };
|
|
6240
6246
|
}
|
|
6241
6247
|
module2.exports.loadConfig = loadConfig2;
|
|
@@ -6255,17 +6261,9 @@ var require_config = __commonJS({
|
|
|
6255
6261
|
module2.exports.mergeConfig = mergeConfig;
|
|
6256
6262
|
function writeConfig(config, cwd_) {
|
|
6257
6263
|
const cwd = cwd_ ?? process.cwd();
|
|
6258
|
-
const
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
try {
|
|
6262
|
-
pkg = JSON.parse(Fs2.readFileSync(pkgPath, "utf8"));
|
|
6263
|
-
} catch (e) {
|
|
6264
|
-
pkg = {};
|
|
6265
|
-
}
|
|
6266
|
-
}
|
|
6267
|
-
pkg.flux = config;
|
|
6268
|
-
Fs2.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
|
|
6264
|
+
const jsonPath = Path2.join(cwd, "flux.json");
|
|
6265
|
+
const content = JSON.stringify(config, null, 2) + "\n";
|
|
6266
|
+
Fs2.writeFileSync(jsonPath, content, "utf8");
|
|
6269
6267
|
}
|
|
6270
6268
|
module2.exports.writeConfig = writeConfig;
|
|
6271
6269
|
function validateConfig(config) {
|
|
@@ -6281,18 +6279,18 @@ var require_config = __commonJS({
|
|
|
6281
6279
|
module2.exports.validateConfig = validateConfig;
|
|
6282
6280
|
function readPackage(cwd_) {
|
|
6283
6281
|
const cwd = cwd_ ?? process.cwd();
|
|
6284
|
-
const pkgJson = Path2.join(cwd, "package.json");
|
|
6285
6282
|
const fluxJson = Path2.join(cwd, "flux.json");
|
|
6286
|
-
|
|
6283
|
+
const pkgJson = Path2.join(cwd, "package.json");
|
|
6284
|
+
if (Fs2.existsSync(fluxJson)) {
|
|
6287
6285
|
try {
|
|
6288
|
-
return JSON.parse(Fs2.readFileSync(
|
|
6286
|
+
return JSON.parse(Fs2.readFileSync(fluxJson, "utf8"));
|
|
6289
6287
|
} catch (e) {
|
|
6290
6288
|
return null;
|
|
6291
6289
|
}
|
|
6292
6290
|
}
|
|
6293
|
-
if (Fs2.existsSync(
|
|
6291
|
+
if (Fs2.existsSync(pkgJson)) {
|
|
6294
6292
|
try {
|
|
6295
|
-
return JSON.parse(Fs2.readFileSync(
|
|
6293
|
+
return JSON.parse(Fs2.readFileSync(pkgJson, "utf8"));
|
|
6296
6294
|
} catch (e2) {
|
|
6297
6295
|
return null;
|
|
6298
6296
|
}
|
|
@@ -6303,18 +6301,19 @@ var require_config = __commonJS({
|
|
|
6303
6301
|
}
|
|
6304
6302
|
});
|
|
6305
6303
|
|
|
6306
|
-
//
|
|
6304
|
+
// src/pkg.js
|
|
6307
6305
|
var require_pkg = __commonJS({
|
|
6308
|
-
"
|
|
6306
|
+
"src/pkg.js"(exports2, module2) {
|
|
6309
6307
|
"use strict";
|
|
6310
6308
|
var Fs2 = require("fs");
|
|
6311
6309
|
var Path2 = require("path");
|
|
6312
6310
|
var Https = require("https");
|
|
6313
6311
|
var Http = require("http");
|
|
6314
6312
|
var Os2 = require("os");
|
|
6315
|
-
var { readPackage } = require_config();
|
|
6313
|
+
var { readPackage, writeConfig, loadConfig: loadConfig2 } = require_config();
|
|
6316
6314
|
var REGISTRY_URL = "https://registry.npmjs.org";
|
|
6317
|
-
var
|
|
6315
|
+
var PKG_FILE = "flux.json";
|
|
6316
|
+
var ESC = "\x1B";
|
|
6318
6317
|
var C2 = { reset: ESC + "[0m", bold: ESC + "[1m", dim: ESC + "[2m", red: ESC + "[31m", green: ESC + "[32m", yellow: ESC + "[33m", blue: ESC + "[34m", cyan: ESC + "[36m", gray: ESC + "[90m" };
|
|
6319
6318
|
function clr2(c, s) {
|
|
6320
6319
|
return c + s + C2.reset;
|
|
@@ -6336,7 +6335,7 @@ var require_pkg = __commonJS({
|
|
|
6336
6335
|
}
|
|
6337
6336
|
let frame = 0;
|
|
6338
6337
|
function tick() {
|
|
6339
|
-
stdout.write("
|
|
6338
|
+
stdout.write("\r" + clr2(C2.cyan, SPIN_FRAMES[frame % SPIN_FRAMES.length]) + " " + label + " ");
|
|
6340
6339
|
frame = frame + 1;
|
|
6341
6340
|
}
|
|
6342
6341
|
const timer = setInterval(tick, 80);
|
|
@@ -6347,7 +6346,7 @@ var require_pkg = __commonJS({
|
|
|
6347
6346
|
return;
|
|
6348
6347
|
}
|
|
6349
6348
|
clearInterval(timer);
|
|
6350
|
-
stdout.write("
|
|
6349
|
+
stdout.write("\r" + ESC + "[2K");
|
|
6351
6350
|
}
|
|
6352
6351
|
async function fetchJson(url) {
|
|
6353
6352
|
const mod = url.startsWith("https") ? Https : Http;
|
|
@@ -6371,6 +6370,21 @@ var require_pkg = __commonJS({
|
|
|
6371
6370
|
}
|
|
6372
6371
|
return new Promise(doRequest);
|
|
6373
6372
|
}
|
|
6373
|
+
function ensureFluxJson(cwd_) {
|
|
6374
|
+
const cwd = cwd_ ?? process.cwd();
|
|
6375
|
+
const file = Path2.join(cwd, PKG_FILE);
|
|
6376
|
+
if (!Fs2.existsSync(file)) {
|
|
6377
|
+
const pkg = { name: Path2.basename(cwd), version: "1.0.0", description: "", author: "", license: "MIT", scripts: { start: "flux run src/main.flux", build: "flux bundle src/main.flux -o dist/bundle.js", dev: "flux watch src/main.flux", check: "flux check src/main.flux" }, dependencies: {}, devDependencies: {} };
|
|
6378
|
+
Fs2.writeFileSync(file, JSON.stringify(pkg, null, 2) + "\n", "utf8");
|
|
6379
|
+
ok("Created flux.json");
|
|
6380
|
+
}
|
|
6381
|
+
return JSON.parse(Fs2.readFileSync(file, "utf8"));
|
|
6382
|
+
}
|
|
6383
|
+
function saveFluxJson(pkg, cwd_) {
|
|
6384
|
+
const cwd = cwd_ ?? process.cwd();
|
|
6385
|
+
const file = Path2.join(cwd, PKG_FILE);
|
|
6386
|
+
Fs2.writeFileSync(file, JSON.stringify(pkg, null, 2) + "\n", "utf8");
|
|
6387
|
+
}
|
|
6374
6388
|
function parsePackageSpec(spec) {
|
|
6375
6389
|
const atIdx = spec.lastIndexOf("@");
|
|
6376
6390
|
if (atIdx > 0) {
|
|
@@ -6379,58 +6393,116 @@ var require_pkg = __commonJS({
|
|
|
6379
6393
|
return { name: spec, version: "latest" };
|
|
6380
6394
|
}
|
|
6381
6395
|
async function cmdAdd2(specs, opts) {
|
|
6382
|
-
|
|
6396
|
+
var _a, _b;
|
|
6383
6397
|
const isDev = (opts == null ? void 0 : opts.dev) ?? false;
|
|
6384
6398
|
const cwd = process.cwd();
|
|
6399
|
+
const pkg = ensureFluxJson(cwd);
|
|
6385
6400
|
for (const spec of specs) {
|
|
6386
6401
|
const { name, version } = parsePackageSpec(spec);
|
|
6387
|
-
const spinner = startSpinner("
|
|
6402
|
+
const spinner = startSpinner("Fetching " + clr2(C2.bold, name) + clr2(C2.gray, "@" + version) + " ...");
|
|
6388
6403
|
try {
|
|
6389
|
-
const
|
|
6390
|
-
const
|
|
6404
|
+
const info_ = await fetchJson(REGISTRY_URL + "/" + name);
|
|
6405
|
+
const resolvedVersion = version == "latest" ? ((_a = info_["dist-tags"]) == null ? void 0 : _a.latest) ?? "1.0.0" : version;
|
|
6406
|
+
const versionInfo = (_b = info_.versions) == null ? void 0 : _b[resolvedVersion];
|
|
6391
6407
|
stopSpinner(spinner);
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6408
|
+
if (!versionInfo) {
|
|
6409
|
+
err("Version " + resolvedVersion + " not found for " + name);
|
|
6410
|
+
continue;
|
|
6411
|
+
}
|
|
6412
|
+
const depKey = isDev ? "devDependencies" : "dependencies";
|
|
6413
|
+
if (!pkg[depKey]) {
|
|
6414
|
+
pkg[depKey] = {};
|
|
6415
|
+
}
|
|
6416
|
+
pkg[depKey][name] = "^" + resolvedVersion;
|
|
6417
|
+
saveFluxJson(pkg, cwd);
|
|
6418
|
+
const desc = versionInfo.description ? clr2(C2.gray, " \u2014 " + versionInfo.description) : "";
|
|
6419
|
+
ok(name + clr2(C2.green, "@" + resolvedVersion) + desc);
|
|
6420
|
+
info("Added to " + (isDev ? "devDependencies" : "dependencies"));
|
|
6395
6421
|
} catch (e) {
|
|
6396
6422
|
stopSpinner(spinner);
|
|
6397
|
-
err("Failed to
|
|
6423
|
+
err("Failed to fetch " + name + ": " + e.message);
|
|
6398
6424
|
}
|
|
6399
6425
|
}
|
|
6400
6426
|
console.log();
|
|
6427
|
+
console.log(clr2(C2.gray, " Run ") + clr2(C2.yellow, "flux install") + clr2(C2.gray, " to install packages"));
|
|
6428
|
+
console.log();
|
|
6401
6429
|
}
|
|
6402
6430
|
module2.exports.cmdAdd = cmdAdd2;
|
|
6403
6431
|
function cmdRemove2(names, opts) {
|
|
6404
|
-
const { execSync } = require("child_process");
|
|
6405
6432
|
const cwd = process.cwd();
|
|
6433
|
+
const pkg = ensureFluxJson(cwd);
|
|
6434
|
+
let removed = 0;
|
|
6406
6435
|
for (const name of names) {
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6436
|
+
let found = false;
|
|
6437
|
+
if (pkg.dependencies && pkg.dependencies[name]) {
|
|
6438
|
+
delete pkg.dependencies[name];
|
|
6439
|
+
found = true;
|
|
6440
|
+
}
|
|
6441
|
+
if (pkg.devDependencies && pkg.devDependencies[name]) {
|
|
6442
|
+
delete pkg.devDependencies[name];
|
|
6443
|
+
found = true;
|
|
6444
|
+
}
|
|
6445
|
+
if (found) {
|
|
6410
6446
|
ok("Removed " + clr2(C2.bold, name));
|
|
6411
|
-
|
|
6412
|
-
|
|
6447
|
+
removed = removed + 1;
|
|
6448
|
+
} else {
|
|
6449
|
+
err(name + " not found in flux.json");
|
|
6413
6450
|
}
|
|
6414
6451
|
}
|
|
6452
|
+
if (removed > 0) {
|
|
6453
|
+
saveFluxJson(pkg, cwd);
|
|
6454
|
+
}
|
|
6415
6455
|
}
|
|
6416
6456
|
module2.exports.cmdRemove = cmdRemove2;
|
|
6417
6457
|
async function cmdInstall2(opts) {
|
|
6418
6458
|
const { execSync } = require("child_process");
|
|
6419
6459
|
const cwd = process.cwd();
|
|
6420
|
-
const
|
|
6421
|
-
|
|
6422
|
-
|
|
6460
|
+
const pkg = ensureFluxJson(cwd);
|
|
6461
|
+
const fluxModDir = Path2.join(cwd, "flux_modules");
|
|
6462
|
+
const deps = pkg.dependencies ?? {};
|
|
6463
|
+
const devDeps = pkg.devDependencies ?? {};
|
|
6464
|
+
const all = { ...deps, ...devDeps };
|
|
6465
|
+
const names = Object.keys(all);
|
|
6466
|
+
if (names.length == 0) {
|
|
6467
|
+
info("No dependencies found in flux.json");
|
|
6423
6468
|
return;
|
|
6424
6469
|
}
|
|
6425
|
-
console.log(clr2(C2.cyan, "\n Installing
|
|
6470
|
+
console.log(clr2(C2.cyan, "\n Installing ") + names.length + " package(s) into flux_modules/...\n");
|
|
6471
|
+
for (const name of names) {
|
|
6472
|
+
const spec = all[name];
|
|
6473
|
+
console.log(clr2(C2.gray, " \u25CB ") + name + clr2(C2.gray, "@" + spec));
|
|
6474
|
+
}
|
|
6475
|
+
console.log();
|
|
6476
|
+
if (!Fs2.existsSync(fluxModDir)) {
|
|
6477
|
+
Fs2.mkdirSync(fluxModDir, { recursive: true });
|
|
6478
|
+
}
|
|
6479
|
+
const fluxPkgFile = Path2.join(fluxModDir, "package.json");
|
|
6480
|
+
if (!Fs2.existsSync(fluxPkgFile)) {
|
|
6481
|
+
const fluxPkg = { name: pkg.name + "-flux-modules", version: "1.0.0", private: true };
|
|
6482
|
+
Fs2.writeFileSync(fluxPkgFile, JSON.stringify(fluxPkg, null, 2) + "\n", "utf8");
|
|
6483
|
+
}
|
|
6484
|
+
const prodNames = Object.keys(deps);
|
|
6485
|
+
const devNames = Object.keys(devDeps);
|
|
6426
6486
|
try {
|
|
6427
|
-
|
|
6487
|
+
if (prodNames.length > 0) {
|
|
6488
|
+
const prodPkgs = prodNames.map((n) => n + "@" + (deps[n] ?? "latest")).join(" ");
|
|
6489
|
+
const installCmd = "npm install --prefix " + fluxModDir + " " + prodPkgs;
|
|
6490
|
+
info("Running: " + installCmd);
|
|
6491
|
+
execSync(installCmd, { cwd, stdio: "inherit" });
|
|
6492
|
+
}
|
|
6493
|
+
if (devNames.length > 0) {
|
|
6494
|
+
const devPkgs = devNames.map((n) => n + "@" + (devDeps[n] ?? "latest")).join(" ");
|
|
6495
|
+
const devCmd = "npm install --prefix " + fluxModDir + " --save-dev " + devPkgs;
|
|
6496
|
+
info("Running: " + devCmd);
|
|
6497
|
+
execSync(devCmd, { cwd, stdio: "inherit" });
|
|
6498
|
+
}
|
|
6428
6499
|
console.log();
|
|
6429
|
-
ok("
|
|
6500
|
+
ok(names.length + " package(s) installed into flux_modules/node_modules/");
|
|
6501
|
+
info("Packages resolve automatically when using: flux run, flux bundle");
|
|
6430
6502
|
} catch (e) {
|
|
6431
6503
|
console.log();
|
|
6432
6504
|
err("Install failed: " + e.message);
|
|
6433
|
-
info("Try manually: npm install");
|
|
6505
|
+
info("Try manually: npm install --prefix ./flux_modules <package>");
|
|
6434
6506
|
}
|
|
6435
6507
|
console.log();
|
|
6436
6508
|
}
|
|
@@ -6439,7 +6511,7 @@ var require_pkg = __commonJS({
|
|
|
6439
6511
|
const cwd = process.cwd();
|
|
6440
6512
|
const pkg = readPackage(cwd);
|
|
6441
6513
|
if (!pkg) {
|
|
6442
|
-
err("No
|
|
6514
|
+
err("No flux.json found. Run: flux init");
|
|
6443
6515
|
return;
|
|
6444
6516
|
}
|
|
6445
6517
|
console.log();
|
|
@@ -6529,12 +6601,11 @@ var require_pkg = __commonJS({
|
|
|
6529
6601
|
module2.exports.cmdInfo = cmdInfo2;
|
|
6530
6602
|
async function cmdUpgrade(opts) {
|
|
6531
6603
|
var _a;
|
|
6532
|
-
const { execSync } = require("child_process");
|
|
6533
6604
|
const isCheck = (opts == null ? void 0 : opts.check) ?? false;
|
|
6534
6605
|
const cwd = process.cwd();
|
|
6535
6606
|
const pkg = readPackage(cwd);
|
|
6536
6607
|
if (!pkg) {
|
|
6537
|
-
err("No
|
|
6608
|
+
err("No flux.json found. Run: flux init");
|
|
6538
6609
|
return;
|
|
6539
6610
|
}
|
|
6540
6611
|
const deps = pkg.dependencies ?? {};
|
|
@@ -6572,9 +6643,11 @@ var require_pkg = __commonJS({
|
|
|
6572
6643
|
if (isCheck) {
|
|
6573
6644
|
console.log(" " + clr2(C2.yellow, "\u2191 ") + clr2(C2.bold, name) + clr2(C2.gray, " " + current + " \u2192 ") + clr2(C2.green, "^" + latest));
|
|
6574
6645
|
} else {
|
|
6646
|
+
const isDev = devDeps[name] != null;
|
|
6647
|
+
const depKey = isDev ? "devDependencies" : "dependencies";
|
|
6648
|
+
pkg[depKey][name] = "^" + latest;
|
|
6575
6649
|
updated = updated + 1;
|
|
6576
6650
|
console.log(" " + clr2(C2.green, "\u2713 ") + clr2(C2.bold, name) + clr2(C2.gray, " " + current + " \u2192 ") + clr2(C2.green, "^" + latest));
|
|
6577
|
-
execSync("npm install " + name + "@" + latest + " --save", { cwd, stdio: "pipe" });
|
|
6578
6651
|
}
|
|
6579
6652
|
}
|
|
6580
6653
|
} catch (e) {
|
|
@@ -6594,7 +6667,9 @@ var require_pkg = __commonJS({
|
|
|
6594
6667
|
if (updated == 0) {
|
|
6595
6668
|
ok("All packages are already up to date");
|
|
6596
6669
|
} else {
|
|
6597
|
-
|
|
6670
|
+
saveFluxJson(pkg, cwd);
|
|
6671
|
+
ok(updated + " package(s) updated in flux.json");
|
|
6672
|
+
console.log(clr2(C2.gray, " Run ") + clr2(C2.yellow, "flux install") + clr2(C2.gray, " to install updated versions"));
|
|
6598
6673
|
}
|
|
6599
6674
|
}
|
|
6600
6675
|
console.log();
|
|
@@ -6604,19 +6679,20 @@ var require_pkg = __commonJS({
|
|
|
6604
6679
|
const cwd = process.cwd();
|
|
6605
6680
|
const pkg = readPackage(cwd);
|
|
6606
6681
|
if (!pkg) {
|
|
6607
|
-
err("No
|
|
6682
|
+
err("No flux.json found. Run: flux init");
|
|
6608
6683
|
return;
|
|
6609
6684
|
}
|
|
6610
6685
|
console.log();
|
|
6611
6686
|
console.log(clr2(C2.cyan, " Publishing ") + clr2(C2.bold, pkg.name + "@" + pkg.version) + " ...");
|
|
6612
6687
|
console.log();
|
|
6613
|
-
info("
|
|
6688
|
+
info("Building package...");
|
|
6689
|
+
info("Checking flux.json...");
|
|
6614
6690
|
if (!pkg.name) {
|
|
6615
|
-
err("
|
|
6691
|
+
err("flux.json must have a name field");
|
|
6616
6692
|
return;
|
|
6617
6693
|
}
|
|
6618
6694
|
if (!pkg.version) {
|
|
6619
|
-
err("
|
|
6695
|
+
err("flux.json must have a version field");
|
|
6620
6696
|
return;
|
|
6621
6697
|
}
|
|
6622
6698
|
console.log();
|
|
@@ -6629,7 +6705,7 @@ var require_pkg = __commonJS({
|
|
|
6629
6705
|
}
|
|
6630
6706
|
});
|
|
6631
6707
|
|
|
6632
|
-
//
|
|
6708
|
+
// src/cli.js
|
|
6633
6709
|
var Fs = require("fs");
|
|
6634
6710
|
var Path = require("path");
|
|
6635
6711
|
var Os = require("os");
|
|
@@ -6681,20 +6757,32 @@ function showHelp() {
|
|
|
6681
6757
|
console.log(bold("USAGE:"));
|
|
6682
6758
|
console.log(" flux <command> [options]\n");
|
|
6683
6759
|
console.log(bold("COMPILER:"));
|
|
6684
|
-
const compilerCmds = [["compile <file.flux>", "Compile .flux \u2192 .js"], ["bundle <entry.flux>", "Bundle
|
|
6685
|
-
|
|
6760
|
+
const compilerCmds = [["compile <file.flux>", "Compile .flux \u2192 .js"], ["bundle <entry.flux>", "Bundle multiple files into one .js"], ["run <file.flux>", "Compile and run immediately"], ["watch <file.flux>", "Watch for changes, auto-compile"], ["check <file.flux>", "Type-check and static analysis"]];
|
|
6761
|
+
for (const __item__ of compilerCmds) {
|
|
6762
|
+
const [cmd, desc] = __item__;
|
|
6763
|
+
console.log(" " + green(("flux " + cmd).padEnd(36)) + " " + gray(desc));
|
|
6764
|
+
}
|
|
6686
6765
|
console.log();
|
|
6687
6766
|
console.log(bold("TOOLING:"));
|
|
6688
6767
|
const toolCmds = [["lint <file.flux>", "Full lint: types + style + immutability"], ["fmt <file.flux>", "Format source code in-place"], ["test [dir]", "Run *.test.flux files"], ["repl", "Interactive REPL mode"], ["tokens <file.flux>", "Show lexer token list"], ["ast <file.flux>", "Show Abstract Syntax Tree (JSON)"]];
|
|
6689
|
-
|
|
6768
|
+
for (const __item__ of toolCmds) {
|
|
6769
|
+
const [cmd, desc] = __item__;
|
|
6770
|
+
console.log(" " + green(("flux " + cmd).padEnd(36)) + " " + gray(desc));
|
|
6771
|
+
}
|
|
6690
6772
|
console.log();
|
|
6691
6773
|
console.log(bold("PACKAGE MANAGER:"));
|
|
6692
|
-
const pkgCmds = [["init [name]
|
|
6693
|
-
|
|
6774
|
+
const pkgCmds = [["init [name]", "Scaffold a new Flux project"], ["add <pkg[@version]>", "Add a dependency"], ["remove <pkg>", "Remove a dependency"], ["install", "Install all dependencies"], ["list", "List installed packages"], ["search <query>", "Search the package registry"], ["info <pkg>", "Show package details"], ["publish", "Publish package to registry"]];
|
|
6775
|
+
for (const __item__ of pkgCmds) {
|
|
6776
|
+
const [cmd, desc] = __item__;
|
|
6777
|
+
console.log(" " + cyan(("flux " + cmd).padEnd(36)) + " " + gray(desc));
|
|
6778
|
+
}
|
|
6694
6779
|
console.log();
|
|
6695
6780
|
console.log(bold("SELF-HOSTED:"));
|
|
6696
6781
|
const selfCmds = [["self-hosted", "Show self-hosted compiler status"], ["self-hosted build", "Bootstrap: compile compiler with itself"], ["self-hosted verify", "Verify self-hosted output matches stage-0"]];
|
|
6697
|
-
|
|
6782
|
+
for (const __item__ of selfCmds) {
|
|
6783
|
+
const [cmd, desc] = __item__;
|
|
6784
|
+
console.log(" " + yellow(("flux " + cmd).padEnd(36)) + " " + gray(desc));
|
|
6785
|
+
}
|
|
6698
6786
|
console.log();
|
|
6699
6787
|
console.log(bold("OPTIONS:"));
|
|
6700
6788
|
console.log(" " + yellow("--out, -o <file> ") + " Output file");
|
|
@@ -6704,12 +6792,11 @@ function showHelp() {
|
|
|
6704
6792
|
console.log(" " + yellow("--typecheck ") + " Enable type checking");
|
|
6705
6793
|
console.log(" " + yellow("--stdout ") + " Print to terminal");
|
|
6706
6794
|
console.log(" " + yellow("--no-color ") + " Disable colors");
|
|
6707
|
-
console.log(" " + yellow("--template ") + " Init template: script, server, webapp");
|
|
6708
6795
|
console.log();
|
|
6709
6796
|
}
|
|
6710
6797
|
function parseArgs(argv) {
|
|
6711
6798
|
const args = argv.slice(2);
|
|
6712
|
-
const opts = { out: null, sourcemap: false, mangle: false, typecheck: false, strict: false, stdout: false, watch: false, dev: false, verbose: false, jsx: false, jsxTarget: "browser"
|
|
6799
|
+
const opts = { out: null, sourcemap: false, mangle: false, typecheck: false, strict: false, stdout: false, watch: false, dev: false, verbose: false, jsx: false, jsxTarget: "browser" };
|
|
6713
6800
|
const positional = [];
|
|
6714
6801
|
let i = 0;
|
|
6715
6802
|
while (i < args.length) {
|
|
@@ -6738,9 +6825,6 @@ function parseArgs(argv) {
|
|
|
6738
6825
|
} else if (a == "--jsx-target") {
|
|
6739
6826
|
i = i + 1;
|
|
6740
6827
|
opts.jsxTarget = args[i];
|
|
6741
|
-
} else if (a == "--template" || a == "-t") {
|
|
6742
|
-
i = i + 1;
|
|
6743
|
-
opts.template = args[i];
|
|
6744
6828
|
} else if (!a.startsWith("--")) {
|
|
6745
6829
|
positional.push(a);
|
|
6746
6830
|
}
|
|
@@ -6808,21 +6892,6 @@ function printErrors(errors, source, filePath) {
|
|
|
6808
6892
|
}
|
|
6809
6893
|
console.error();
|
|
6810
6894
|
}
|
|
6811
|
-
function findFluxImports(source) {
|
|
6812
|
-
const found = [];
|
|
6813
|
-
const lines = source.split("\n");
|
|
6814
|
-
for (const line of lines) {
|
|
6815
|
-
const trimmed = line.trim();
|
|
6816
|
-
const m = trimmed.match(/^import\s+.+\s+from\s+["'](\.[^"']+)["']/);
|
|
6817
|
-
if (m) {
|
|
6818
|
-
const src = m[1];
|
|
6819
|
-
if (!src.endsWith(".js") && !src.endsWith(".json") && !src.endsWith(".node")) {
|
|
6820
|
-
found.push(src);
|
|
6821
|
-
}
|
|
6822
|
-
}
|
|
6823
|
-
}
|
|
6824
|
-
return found;
|
|
6825
|
-
}
|
|
6826
6895
|
function cmdCompile(filePath, opts) {
|
|
6827
6896
|
const { source, abs } = readFluxFile(filePath);
|
|
6828
6897
|
const cfg = loadConfig(Path.dirname(abs));
|
|
@@ -6856,21 +6925,6 @@ function cmdCompile(filePath, opts) {
|
|
|
6856
6925
|
}
|
|
6857
6926
|
function cmdRun(filePath, opts) {
|
|
6858
6927
|
const { source, abs } = readFluxFile(filePath);
|
|
6859
|
-
const fluxImports = findFluxImports(source);
|
|
6860
|
-
if (fluxImports.length > 0) {
|
|
6861
|
-
const example = fluxImports[0];
|
|
6862
|
-
const entryRel = Path.relative(process.cwd(), abs);
|
|
6863
|
-
const outFile = Path.basename(abs, ".flux") + ".js";
|
|
6864
|
-
console.error(red("\n\u2717 Cannot run a multi-file Flux project with `flux run`.\n"));
|
|
6865
|
-
console.error(" Found: " + yellow('import ... from "' + example + '"'));
|
|
6866
|
-
console.error();
|
|
6867
|
-
console.error(" Use " + cyan("flux bundle") + " to compile all files into one, then run it:\n");
|
|
6868
|
-
console.error(" " + yellow("flux bundle " + entryRel + " -o dist/" + outFile));
|
|
6869
|
-
console.error(" " + yellow("node dist/" + outFile));
|
|
6870
|
-
console.error();
|
|
6871
|
-
console.error(" Or use " + cyan("flux run") + " only for single-file scripts (no inter-file .flux imports).\n");
|
|
6872
|
-
process.exit(1);
|
|
6873
|
-
}
|
|
6874
6928
|
const result = transpile(source, { jsx: opts.jsx ?? false, jsxTarget: opts.jsxTarget ?? "browser", mangle: false });
|
|
6875
6929
|
if (!result.success) {
|
|
6876
6930
|
console.error(red("\n\u2717 Compile error"));
|
|
@@ -7031,10 +7085,6 @@ function cmdBundle(entryPath, opts) {
|
|
|
7031
7085
|
console.log(result.code);
|
|
7032
7086
|
return;
|
|
7033
7087
|
}
|
|
7034
|
-
const outDir = Path.dirname(Path.resolve(outFile));
|
|
7035
|
-
if (!Fs.existsSync(outDir)) {
|
|
7036
|
-
Fs.mkdirSync(outDir, { recursive: true });
|
|
7037
|
-
}
|
|
7038
7088
|
Fs.writeFileSync(outFile, result.code, "utf8");
|
|
7039
7089
|
const kb = (result.code.length / 1024).toFixed(1);
|
|
7040
7090
|
console.log(green("\u2713 Bundle done") + gray(" (" + elapsed + "ms) ") + Path.basename(abs) + gray(" + " + (result.modules - 1) + " module(s) \u2192 ") + cyan(Path.relative(process.cwd(), outFile)) + gray(" [" + kb + " KB]"));
|
|
@@ -7160,7 +7210,6 @@ function cmdRepl(opts) {
|
|
|
7160
7210
|
}
|
|
7161
7211
|
function cmdInit(name, opts) {
|
|
7162
7212
|
const projectName = name ?? "my-flux-app";
|
|
7163
|
-
const template = opts.template ?? "script";
|
|
7164
7213
|
const dir = Path.resolve(projectName);
|
|
7165
7214
|
if (Fs.existsSync(dir)) {
|
|
7166
7215
|
console.error(red("\u2717 Directory already exists: " + projectName));
|
|
@@ -7169,77 +7218,38 @@ function cmdInit(name, opts) {
|
|
|
7169
7218
|
Fs.mkdirSync(dir, { recursive: true });
|
|
7170
7219
|
Fs.mkdirSync(Path.join(dir, "src"), { recursive: true });
|
|
7171
7220
|
Fs.mkdirSync(Path.join(dir, "tests"), { recursive: true });
|
|
7172
|
-
const
|
|
7173
|
-
const
|
|
7174
|
-
if (
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
console.log("
|
|
7191
|
-
console.log();
|
|
7192
|
-
return;
|
|
7193
|
-
}
|
|
7194
|
-
if (template == "server") {
|
|
7195
|
-
const serverFlux = '// {projectName} \u2014 Flux HTTP server\n// Run: npm run dev\n// Build: npm run build && npm start\n\nimport Express from "express"\n\nval app = Express()\nval PORT = process.env.PORT or 3000\n\napp.use(Express.json())\n\napp.get("/", (req, res) ->\n res.json({ status: "ok", message: "Hello from Flux!", port: PORT })\n)\n\napp.listen(PORT, -> print("Server running at http://localhost:{PORT}"))';
|
|
7196
|
-
const pkgJson = { name: projectName, version: "1.0.0", description: "A Flux HTTP server", main: "dist/server.js", scripts: { dev: "flux run src/server.flux", build: "flux bundle src/server.flux -o dist/server.js", start: "node dist/server.js", test: "flux test tests/" }, flux: { entry: "src/server.flux", outDir: "dist", mangle: false, sourcemap: false }, dependencies: { "@xnoxs/flux-lang": "^" + VERSION, express: "^4.18.0" }, devDependencies: {} };
|
|
7197
|
-
Fs.writeFileSync(Path.join(dir, "src", "server.flux"), serverFlux, "utf8");
|
|
7198
|
-
Fs.writeFileSync(Path.join(dir, "tests", "main.test.flux"), testFlux, "utf8");
|
|
7199
|
-
Fs.writeFileSync(Path.join(dir, "package.json"), JSON.stringify(pkgJson, null, 2) + "\n", "utf8");
|
|
7200
|
-
Fs.writeFileSync(Path.join(dir, ".gitignore"), gitignore, "utf8");
|
|
7201
|
-
console.log();
|
|
7202
|
-
console.log(green("\u2713 Project ") + bold(projectName + "/") + green(" created with template ") + cyan("server"));
|
|
7203
|
-
console.log();
|
|
7204
|
-
console.log(bold(" Next steps:"));
|
|
7205
|
-
console.log(" " + yellow("cd " + projectName));
|
|
7206
|
-
console.log(" " + yellow("npm install"));
|
|
7207
|
-
console.log(" " + yellow("npm run dev"));
|
|
7208
|
-
console.log();
|
|
7209
|
-
console.log(gray(" Build for production:"));
|
|
7210
|
-
console.log(" " + yellow("npm run build && npm start"));
|
|
7211
|
-
console.log();
|
|
7212
|
-
return;
|
|
7213
|
-
}
|
|
7214
|
-
if (template == "webapp") {
|
|
7215
|
-
const utilsFlux = '// Utility functions\nexport fn formatDate(date):\n val d = new Date(date)\n return d.toISOString().split("T")[0]\n\nexport fn paginate(items, page, perPage):\n val start = (page - 1) * perPage\n return items.slice(start, start + perPage)';
|
|
7216
|
-
const routesFlux = '// Route handlers\nimport { formatDate, paginate } from "./utils" // inter-file .flux import\n\nval items = [\n { id: 1, name: "Item A", date: "2024-01-01" },\n { id: 2, name: "Item B", date: "2024-02-01" },\n { id: 3, name: "Item C", date: "2024-03-01" },\n]\n\nexport fn setupRoutes(app):\n app.get("/items", (req, res) ->\n val page = parseInt(req.query.page or "1")\n val perPage = parseInt(req.query.per_page or "10")\n val data = paginate(items, page, perPage)\n res.json({ data, page })\n )\n\n app.get("/items/:id", (req, res) ->\n val item = items.find(i -> i.id == parseInt(req.params.id))\n if item == null:\n res.status(404).json({ error: "Not found" })\n else:\n res.json({ data: item, date: formatDate(item.date) })\n )';
|
|
7217
|
-
const serverFlux = '// Entry point \u2014 MUST be compiled with: npm run build\n// Inter-file .flux imports only work via flux bundle, NOT flux run\nimport Express from "express"\nimport { setupRoutes } from "./routes" // inter-file .flux import\n\nval app = Express()\nval PORT = process.env.PORT or 3000\n\napp.use(Express.json())\nsetupRoutes(app)\n\napp.listen(PORT, -> print("{projectName} running at http://localhost:{PORT}"))';
|
|
7218
|
-
const pkgJson = { name: projectName, version: "1.0.0", description: "A Flux web app", main: "dist/server.js", scripts: { build: "flux bundle src/server.flux -o dist/server.js", start: "node dist/server.js", dev: "flux bundle src/server.flux -o dist/server.js && node dist/server.js", watch: "flux watch src/server.flux", test: "flux test tests/" }, flux: { entry: "src/server.flux", outDir: "dist", mangle: false, sourcemap: true }, dependencies: { "@xnoxs/flux-lang": "^" + VERSION, express: "^4.18.0" }, devDependencies: {} };
|
|
7219
|
-
Fs.writeFileSync(Path.join(dir, "src", "utils.flux"), utilsFlux, "utf8");
|
|
7220
|
-
Fs.writeFileSync(Path.join(dir, "src", "routes.flux"), routesFlux, "utf8");
|
|
7221
|
-
Fs.writeFileSync(Path.join(dir, "src", "server.flux"), serverFlux, "utf8");
|
|
7222
|
-
Fs.writeFileSync(Path.join(dir, "tests", "main.test.flux"), testFlux, "utf8");
|
|
7223
|
-
Fs.writeFileSync(Path.join(dir, "package.json"), JSON.stringify(pkgJson, null, 2) + "\n", "utf8");
|
|
7224
|
-
Fs.writeFileSync(Path.join(dir, ".gitignore"), gitignore, "utf8");
|
|
7225
|
-
console.log();
|
|
7226
|
-
console.log(green("\u2713 Project ") + bold(projectName + "/") + green(" created with template ") + cyan("webapp"));
|
|
7227
|
-
console.log();
|
|
7228
|
-
console.log(bold(" Next steps:"));
|
|
7229
|
-
console.log(" " + yellow("cd " + projectName));
|
|
7230
|
-
console.log(" " + yellow("npm install") + gray(" # install dependencies"));
|
|
7231
|
-
console.log(" " + yellow("npm run build") + gray(" # compile all .flux \u2192 dist/server.js"));
|
|
7232
|
-
console.log(" " + yellow("npm start") + gray(" # run the server"));
|
|
7233
|
-
console.log();
|
|
7234
|
-
console.log(yellow(" Note: ") + gray("This project uses multiple .flux files."));
|
|
7235
|
-
console.log(gray(" Always build with ") + yellow("npm run build") + gray(" (flux bundle) before running."));
|
|
7236
|
-
console.log(gray(" Do NOT use ") + red("flux run") + gray(" on files that import other .flux files."));
|
|
7237
|
-
console.log();
|
|
7238
|
-
return;
|
|
7221
|
+
const mainFlux = '// {projectName} \u2014 built with Flux Lang v{VERSION}\n// Run: flux run src/main.flux\n\n// \u2500\u2500 Algebraic Data Types + Pattern Matching \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ntype Shape = Circle(radius) | Rect(width, height) | Triangle(base, height)\n\nfn area(shape):\n match shape:\n when Circle(r): return Math.PI * r * r\n when Rect(w, h): return w * h\n when Triangle(b, h): return 0.5 * b * h\n\nfn describe(shape):\n match shape:\n when Circle(r): return "Circle(r={r:.2f})"\n when Rect(w, h): return "Rect({w:.1f}x{h:.1f})"\n when Triangle(b, h): return "Triangle(b={b:.1f}, h={h:.1f})"\n\n// \u2500\u2500 Result type \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ntype Result = Ok(value) | Err(message)\n\nfn safeDivide(a, b):\n if b == 0: return Err("division by zero")\n return Ok(a / b)\n\n// \u2500\u2500 Utility functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfn greet(name): return "Hello from Flux, {name}!"\n\nfn formatList(items):\n if items.length == 0: return "(empty)"\n return "[" + items.join(", ") + "]"\n\nfn clamp(value, lo, hi):\n if value < lo: return lo\n if value > hi: return hi\n return value\n\n// \u2500\u2500 Pipe operator + stdlib \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nval numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]\nval processed = numbers\n |> filter(n -> n > 3)\n |> map(n -> n * n)\n |> sort\n\n// \u2500\u2500 Main \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nprint(greet("{projectName}"))\nprint("Squares > 3: {formatList(processed)}")\nprint("clamp(12, 0, 10) = {clamp(12, 0, 10)}")\n\nval shapes = [Circle(5.0), Rect(8.0, 3.0), Triangle(6.0, 4.0)]\nfor shape in shapes:\n val a = area(shape)\n print("{describe(shape)} area={a:.2f}")\n\nmatch safeDivide(10.0, 3.0):\n when Ok(v): print("10 / 3 = {v:.4f}")\n when Err(e): print("Error: {e}")';
|
|
7222
|
+
const utilsFlux = '// Utility functions for {projectName}\n// Use with: flux bundle src/main.flux (bundles imports automatically)\n\nexport fn greet(name):\n return "Hello from Flux, {name}!"\n\nexport fn formatList(items):\n if items.length == 0: return "(empty)"\n return "[" + items.join(", ") + "]"\n\nexport fn clamp(value, lo, hi):\n if value < lo: return lo\n if value > hi: return hi\n return value\n\nexport fn sum(nums):\n return nums.reduce((acc, x) -> acc + x, 0)\n\nexport fn average(nums):\n if nums.length == 0: return 0\n return sum(nums) / nums.length';
|
|
7223
|
+
const testFlux = '// Tests for {projectName}\n// Run: flux test tests/\n\n// \u2500\u2500 Functions under test \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfn add(a, b):\n return a + b\n\nfn mul(a, b):\n return a * b\n\nfn clamp(value, lo, hi):\n if value < lo: return lo\n if value > hi: return hi\n return value\n\nfn average(nums):\n if nums.length == 0: return 0\n return nums.reduce((s, x) -> s + x, 0) / nums.length\n\ntype Result = Ok(value) | Err(message)\n\nfn safeDivide(a, b):\n if b == 0: return Err("div by zero")\n return Ok(a / b)\n\n// \u2500\u2500 Test functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfn test_add():\n assert(add(1, 2) == 3, "1+2=3")\n assert(add(0, 0) == 0, "0+0=0")\n assert(add(-1, 1) == 0, "-1+1=0")\n\nfn test_mul():\n assert(mul(3, 4) == 12, "3*4=12")\n assert(mul(0, 5) == 0, "0*5=0")\n\nfn test_clamp():\n assert(clamp(5, 0, 10) == 5, "within range")\n assert(clamp(-1, 0, 10) == 0, "below min")\n assert(clamp(15, 0, 10) == 10, "above max")\n\nfn test_average():\n assert(average([2, 4, 6]) == 4, "average of 2,4,6")\n assert(average([]) == 0, "empty list")\n\nfn test_safe_divide():\n val ok = safeDivide(10, 2)\n match ok:\n when Ok(v): assert(v == 5, "10/2=5")\n when Err(e): assert(false, "unexpected error")\n val err = safeDivide(10, 0)\n match err:\n when Ok(v): assert(false, "expected error")\n when Err(e): assert(e == "div by zero", "error message")\n\nfn test_pipe_operator():\n val result = [1, 2, 3, 4, 5] |> filter(n -> n > 2) |> map(n -> n * 2)\n assert(result.length == 3, "filter length")\n assert(result[0] == 6, "first element")\n assert(result[2] == 10, "last element")';
|
|
7224
|
+
const fluxJson = { name: projectName, version: "1.0.0", description: "A Flux Lang v" + VERSION + " project", author: "", license: "MIT", entry: "src/main.flux", outDir: "dist", sourcemap: false, typecheck: true, scripts: { start: "flux run src/main.flux", build: "flux bundle src/main.flux -o dist/bundle.js", dev: "flux watch src/main.flux", check: "flux check src/main.flux", test: "flux test tests/", fmt: "flux fmt src/", lint: "flux lint src/" }, dependencies: {}, devDependencies: { "@xnoxs/flux-lang": "^" + VERSION } };
|
|
7225
|
+
const gitignore = "node_modules/\ndist/\nflux_modules/\n*.js.map\n.DS_Store\n";
|
|
7226
|
+
const readme = "# {projectName}\n\nA project built with [Flux Lang](https://flux-lang.dev) v{VERSION} \u2014 the self-hosted compiler.\n\n## Quick Start\n\n```bash\nflux run src/main.flux\n```\n\n## Project Structure\n\n```\n{projectName}/\n\u251C\u2500\u2500 src/\n\u2502 \u251C\u2500\u2500 main.flux # Entry point\n\u2502 \u2514\u2500\u2500 utils.flux # Utility functions\n\u251C\u2500\u2500 tests/\n\u2502 \u2514\u2500\u2500 main.test.flux # Test suite\n\u251C\u2500\u2500 flux_modules/ # Packages installed by `flux install` (gitignored)\n\u251C\u2500\u2500 flux.json # Project config & dependencies\n\u2514\u2500\u2500 README.md\n```\n\n## Commands\n\n| Command | Description |\n|---|---|\n| `flux run src/main.flux` | Run the project |\n| `flux bundle src/main.flux -o dist/bundle.js` | Bundle to single file |\n| `flux watch src/main.flux` | Watch mode |\n| `flux check src/main.flux` | Type check + static analysis |\n| `flux test tests/` | Run all tests |\n| `flux fmt src/` | Format source code |\n| `flux lint src/` | Lint for issues |\n| `flux add <package>` | Add a dependency |";
|
|
7227
|
+
const allFiles = [projectName + "/src/main.flux", projectName + "/src/utils.flux", projectName + "/tests/main.test.flux", projectName + "/flux.json", projectName + "/.gitignore", projectName + "/README.md"];
|
|
7228
|
+
Fs.writeFileSync(Path.join(dir, "src", "main.flux"), mainFlux, "utf8");
|
|
7229
|
+
Fs.writeFileSync(Path.join(dir, "src", "utils.flux"), utilsFlux, "utf8");
|
|
7230
|
+
Fs.writeFileSync(Path.join(dir, "tests", "main.test.flux"), testFlux, "utf8");
|
|
7231
|
+
Fs.writeFileSync(Path.join(dir, "flux.json"), JSON.stringify(fluxJson, null, 2) + "\n", "utf8");
|
|
7232
|
+
Fs.writeFileSync(Path.join(dir, ".gitignore"), gitignore, "utf8");
|
|
7233
|
+
Fs.writeFileSync(Path.join(dir, "README.md"), readme, "utf8");
|
|
7234
|
+
console.log();
|
|
7235
|
+
console.log(green("\u2713 Created: ") + bold(projectName + "/"));
|
|
7236
|
+
console.log();
|
|
7237
|
+
console.log(gray(" Files:"));
|
|
7238
|
+
for (const f of allFiles) {
|
|
7239
|
+
console.log(" " + cyan(f));
|
|
7239
7240
|
}
|
|
7240
|
-
console.
|
|
7241
|
-
console.
|
|
7242
|
-
|
|
7241
|
+
console.log();
|
|
7242
|
+
console.log(bold(" Next steps:"));
|
|
7243
|
+
console.log(" " + yellow("cd " + projectName));
|
|
7244
|
+
console.log(" " + yellow("flux run src/main.flux"));
|
|
7245
|
+
console.log();
|
|
7246
|
+
console.log(gray(" Add packages (installed into flux_modules/):"));
|
|
7247
|
+
console.log(" " + yellow("flux add <package>"));
|
|
7248
|
+
console.log(" " + yellow("flux install"));
|
|
7249
|
+
console.log();
|
|
7250
|
+
console.log(gray(" Or run the test suite:"));
|
|
7251
|
+
console.log(" " + yellow("flux test tests/"));
|
|
7252
|
+
console.log();
|
|
7243
7253
|
}
|
|
7244
7254
|
function cmdSelfHosted(sub, opts) {
|
|
7245
7255
|
const SELF = Path.join(__dirname, ".");
|
|
@@ -7388,8 +7398,6 @@ function main() {
|
|
|
7388
7398
|
return cmdAst(positional[1], opts);
|
|
7389
7399
|
} else if (cmd === "repl") {
|
|
7390
7400
|
return cmdRepl(opts);
|
|
7391
|
-
} else if (cmd === "test") {
|
|
7392
|
-
return runTests(positional[1] ?? "tests/", (src) => transpile(src, {}));
|
|
7393
7401
|
} else if (cmd === "init") {
|
|
7394
7402
|
return cmdInit(positional[1], opts);
|
|
7395
7403
|
} else if (cmd === "add") {
|