@xnoxs/flux-lang 3.4.0 → 3.4.2
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 +13 -0
- package/README.md +459 -1
- package/dist/flux-cli.js +234 -112
- package/dist/flux.cjs.js +1 -1
- package/dist/flux.esm.js +1 -1
- package/dist/flux.min.js +1 -1
- package/package.json +1 -1
- package/src/self/cli.flux +169 -50
- package/src/self/cli.js +1 -818
package/src/self/cli.flux
CHANGED
|
@@ -588,54 +588,153 @@ fn cmdInit(name, opts):
|
|
|
588
588
|
Fs.mkdirSync(Path.join(dir, "src"), { recursive: true })
|
|
589
589
|
Fs.mkdirSync(Path.join(dir, "tests"), { recursive: true })
|
|
590
590
|
|
|
591
|
-
val mainFlux = `// {projectName} —
|
|
591
|
+
val mainFlux = `// {projectName} — built with Flux Lang v{VERSION}
|
|
592
|
+
// Run: flux run src/main.flux
|
|
592
593
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
| Rect(width: Float, height: Float)
|
|
596
|
-
| Triangle(base: Float, height: Float)
|
|
594
|
+
// ── Algebraic Data Types + Pattern Matching ───────────────────
|
|
595
|
+
type Shape = Circle(radius) | Rect(width, height) | Triangle(base, height)
|
|
597
596
|
|
|
598
|
-
fn area(shape
|
|
597
|
+
fn area(shape):
|
|
599
598
|
match shape:
|
|
600
|
-
when Circle(r):
|
|
601
|
-
when Rect(w, h):
|
|
602
|
-
when Triangle(b, h):
|
|
599
|
+
when Circle(r): return Math.PI * r * r
|
|
600
|
+
when Rect(w, h): return w * h
|
|
601
|
+
when Triangle(b, h): return 0.5 * b * h
|
|
603
602
|
|
|
604
|
-
fn
|
|
605
|
-
|
|
603
|
+
fn describe(shape):
|
|
604
|
+
match shape:
|
|
605
|
+
when Circle(r): return "Circle(r={r:.2f})"
|
|
606
|
+
when Rect(w, h): return "Rect({w:.1f}x{h:.1f})"
|
|
607
|
+
when Triangle(b, h): return "Triangle(b={b:.1f}, h={h:.1f})"
|
|
608
|
+
|
|
609
|
+
// ── Result type ───────────────────────────────────────────────
|
|
610
|
+
type Result = Ok(value) | Err(message)
|
|
611
|
+
|
|
612
|
+
fn safeDivide(a, b):
|
|
613
|
+
if b == 0: return Err("division by zero")
|
|
614
|
+
return Ok(a / b)
|
|
615
|
+
|
|
616
|
+
// ── Utility functions ─────────────────────────────────────────
|
|
617
|
+
fn greet(name): return "Hello from Flux, {name}!"
|
|
618
|
+
|
|
619
|
+
fn formatList(items):
|
|
620
|
+
if items.length == 0: return "(empty)"
|
|
621
|
+
return "[" + items.join(", ") + "]"
|
|
606
622
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
]
|
|
623
|
+
fn clamp(value, lo, hi):
|
|
624
|
+
if value < lo: return lo
|
|
625
|
+
if value > hi: return hi
|
|
626
|
+
return value
|
|
612
627
|
|
|
628
|
+
// ── Pipe operator + stdlib ────────────────────────────────────
|
|
629
|
+
val numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
|
|
630
|
+
val processed = numbers
|
|
631
|
+
|> filter(n -> n > 3)
|
|
632
|
+
|> map(n -> n * n)
|
|
633
|
+
|> sort
|
|
634
|
+
|
|
635
|
+
// ── Main ──────────────────────────────────────────────────────
|
|
636
|
+
print(greet("{projectName}"))
|
|
637
|
+
print("Squares > 3: {formatList(processed)}")
|
|
638
|
+
print("clamp(12, 0, 10) = {clamp(12, 0, 10)}")
|
|
639
|
+
|
|
640
|
+
val shapes = [Circle(5.0), Rect(8.0, 3.0), Triangle(6.0, 4.0)]
|
|
613
641
|
for shape in shapes:
|
|
614
642
|
val a = area(shape)
|
|
615
|
-
print("
|
|
643
|
+
print("{describe(shape)} area={a:.2f}")
|
|
616
644
|
|
|
617
|
-
|
|
645
|
+
match safeDivide(10.0, 3.0):
|
|
646
|
+
when Ok(v): print("10 / 3 = {v:.4f}")
|
|
647
|
+
when Err(e): print("Error: {e}")
|
|
618
648
|
`
|
|
619
649
|
|
|
620
|
-
val
|
|
650
|
+
val utilsFlux = `// Utility functions for {projectName}
|
|
651
|
+
// Use with: flux bundle src/main.flux (bundles imports automatically)
|
|
652
|
+
|
|
653
|
+
export fn greet(name):
|
|
654
|
+
return "Hello from Flux, {name}!"
|
|
621
655
|
|
|
622
|
-
fn
|
|
623
|
-
|
|
656
|
+
export fn formatList(items):
|
|
657
|
+
if items.length == 0: return "(empty)"
|
|
658
|
+
return "[" + items.join(", ") + "]"
|
|
624
659
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
660
|
+
export fn clamp(value, lo, hi):
|
|
661
|
+
if value < lo: return lo
|
|
662
|
+
if value > hi: return hi
|
|
663
|
+
return value
|
|
629
664
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
665
|
+
export fn sum(nums):
|
|
666
|
+
return nums.reduce((acc, x) -> acc + x, 0)
|
|
667
|
+
|
|
668
|
+
export fn average(nums):
|
|
669
|
+
if nums.length == 0: return 0
|
|
670
|
+
return sum(nums) / nums.length
|
|
671
|
+
`
|
|
672
|
+
|
|
673
|
+
val testFlux = `// Tests for {projectName}
|
|
674
|
+
// Run: flux test tests/
|
|
675
|
+
|
|
676
|
+
// ── Functions under test ──────────────────────────────────────
|
|
677
|
+
fn add(a, b):
|
|
678
|
+
return a + b
|
|
679
|
+
|
|
680
|
+
fn mul(a, b):
|
|
681
|
+
return a * b
|
|
682
|
+
|
|
683
|
+
fn clamp(value, lo, hi):
|
|
684
|
+
if value < lo: return lo
|
|
685
|
+
if value > hi: return hi
|
|
686
|
+
return value
|
|
687
|
+
|
|
688
|
+
fn average(nums):
|
|
689
|
+
if nums.length == 0: return 0
|
|
690
|
+
return nums.reduce((s, x) -> s + x, 0) / nums.length
|
|
691
|
+
|
|
692
|
+
type Result = Ok(value) | Err(message)
|
|
693
|
+
|
|
694
|
+
fn safeDivide(a, b):
|
|
695
|
+
if b == 0: return Err("div by zero")
|
|
696
|
+
return Ok(a / b)
|
|
697
|
+
|
|
698
|
+
// ── Test functions ────────────────────────────────────────────
|
|
699
|
+
fn test_add():
|
|
700
|
+
assert(add(1, 2) == 3, "1+2=3")
|
|
701
|
+
assert(add(0, 0) == 0, "0+0=0")
|
|
702
|
+
assert(add(-1, 1) == 0, "-1+1=0")
|
|
703
|
+
|
|
704
|
+
fn test_mul():
|
|
705
|
+
assert(mul(3, 4) == 12, "3*4=12")
|
|
706
|
+
assert(mul(0, 5) == 0, "0*5=0")
|
|
707
|
+
|
|
708
|
+
fn test_clamp():
|
|
709
|
+
assert(clamp(5, 0, 10) == 5, "within range")
|
|
710
|
+
assert(clamp(-1, 0, 10) == 0, "below min")
|
|
711
|
+
assert(clamp(15, 0, 10) == 10, "above max")
|
|
712
|
+
|
|
713
|
+
fn test_average():
|
|
714
|
+
assert(average([2, 4, 6]) == 4, "average of 2,4,6")
|
|
715
|
+
assert(average([]) == 0, "empty list")
|
|
716
|
+
|
|
717
|
+
fn test_safe_divide():
|
|
718
|
+
val ok = safeDivide(10, 2)
|
|
719
|
+
match ok:
|
|
720
|
+
when Ok(v): assert(v == 5, "10/2=5")
|
|
721
|
+
when Err(e): assert(false, "unexpected error")
|
|
722
|
+
val err = safeDivide(10, 0)
|
|
723
|
+
match err:
|
|
724
|
+
when Ok(v): assert(false, "expected error")
|
|
725
|
+
when Err(e): assert(e == "div by zero", "error message")
|
|
726
|
+
|
|
727
|
+
fn test_pipe_operator():
|
|
728
|
+
val result = [1, 2, 3, 4, 5] |> filter(n -> n > 2) |> map(n -> n * 2)
|
|
729
|
+
assert(result.length == 3, "filter length")
|
|
730
|
+
assert(result[0] == 6, "first element")
|
|
731
|
+
assert(result[2] == 10, "last element")
|
|
633
732
|
`
|
|
634
733
|
|
|
635
734
|
val fluxJson = {
|
|
636
735
|
name: projectName,
|
|
637
736
|
version: "1.0.0",
|
|
638
|
-
description: "A Flux Lang project",
|
|
737
|
+
description: "A Flux Lang v" + VERSION + " project",
|
|
639
738
|
author: "",
|
|
640
739
|
license: "MIT",
|
|
641
740
|
entry: "src/main.flux",
|
|
@@ -652,40 +751,60 @@ test "mul works":
|
|
|
652
751
|
lint: "flux lint src/",
|
|
653
752
|
},
|
|
654
753
|
dependencies: {},
|
|
655
|
-
devDependencies: {},
|
|
754
|
+
devDependencies: { "@xnoxs/flux-lang": "^" + VERSION },
|
|
656
755
|
}
|
|
657
756
|
|
|
658
|
-
val gitignore =
|
|
659
|
-
dist/
|
|
660
|
-
flux_modules/
|
|
661
|
-
*.js.map
|
|
662
|
-
.DS_Store
|
|
663
|
-
`
|
|
757
|
+
val gitignore = "node_modules/\ndist/\nflux_modules/\n*.js.map\n.DS_Store\n"
|
|
664
758
|
|
|
665
759
|
val readme = `# {projectName}
|
|
666
760
|
|
|
667
|
-
A project built with [Flux Lang](https://flux-lang.dev) v{VERSION}.
|
|
761
|
+
A project built with [Flux Lang](https://flux-lang.dev) v{VERSION} — the self-hosted compiler.
|
|
668
762
|
|
|
669
|
-
##
|
|
763
|
+
## Quick Start
|
|
670
764
|
|
|
671
765
|
\`\`\`bash
|
|
672
766
|
flux run src/main.flux
|
|
673
767
|
\`\`\`
|
|
674
768
|
|
|
769
|
+
## Project Structure
|
|
770
|
+
|
|
771
|
+
\`\`\`
|
|
772
|
+
{projectName}/
|
|
773
|
+
├── src/
|
|
774
|
+
│ ├── main.flux # Entry point
|
|
775
|
+
│ └── utils.flux # Utility functions
|
|
776
|
+
├── tests/
|
|
777
|
+
│ └── main.test.flux # Test suite
|
|
778
|
+
├── flux.json # Project config
|
|
779
|
+
└── README.md
|
|
780
|
+
\`\`\`
|
|
781
|
+
|
|
675
782
|
## Commands
|
|
676
783
|
|
|
677
784
|
| Command | Description |
|
|
678
785
|
|---|---|
|
|
679
|
-
| \`flux run src/main.flux\` | Run
|
|
680
|
-
| \`flux
|
|
786
|
+
| \`flux run src/main.flux\` | Run the project |
|
|
787
|
+
| \`flux bundle src/main.flux -o dist/bundle.js\` | Bundle to single file |
|
|
681
788
|
| \`flux watch src/main.flux\` | Watch mode |
|
|
682
|
-
| \`flux check src/main.flux\` | Type check |
|
|
683
|
-
| \`flux test tests/\` | Run tests |
|
|
684
|
-
| \`flux fmt src/\` | Format code |
|
|
789
|
+
| \`flux check src/main.flux\` | Type check + static analysis |
|
|
790
|
+
| \`flux test tests/\` | Run all tests |
|
|
791
|
+
| \`flux fmt src/\` | Format source code |
|
|
792
|
+
| \`flux lint src/\` | Lint for issues |
|
|
793
|
+
| \`flux add <package>\` | Add a dependency |
|
|
685
794
|
`
|
|
686
795
|
|
|
687
|
-
|
|
688
|
-
|
|
796
|
+
val allFiles = [
|
|
797
|
+
projectName + "/src/main.flux",
|
|
798
|
+
projectName + "/src/utils.flux",
|
|
799
|
+
projectName + "/tests/main.test.flux",
|
|
800
|
+
projectName + "/flux.json",
|
|
801
|
+
projectName + "/.gitignore",
|
|
802
|
+
projectName + "/README.md",
|
|
803
|
+
]
|
|
804
|
+
|
|
805
|
+
Fs.writeFileSync(Path.join(dir, "src", "main.flux"), mainFlux, "utf8")
|
|
806
|
+
Fs.writeFileSync(Path.join(dir, "src", "utils.flux"), utilsFlux, "utf8")
|
|
807
|
+
Fs.writeFileSync(Path.join(dir, "tests", "main.test.flux"), testFlux, "utf8")
|
|
689
808
|
Fs.writeFileSync(Path.join(dir, "flux.json"), JSON.stringify(fluxJson, null, 2) + "\n", "utf8")
|
|
690
809
|
Fs.writeFileSync(Path.join(dir, ".gitignore"), gitignore, "utf8")
|
|
691
810
|
Fs.writeFileSync(Path.join(dir, "README.md"), readme, "utf8")
|
|
@@ -694,16 +813,16 @@ flux run src/main.flux
|
|
|
694
813
|
console.log(green("✓ Created: ") + bold(projectName + "/"))
|
|
695
814
|
console.log()
|
|
696
815
|
console.log(gray(" Files:"))
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
console.log(" " + cyan(projectName + "/flux.json"))
|
|
700
|
-
console.log(" " + cyan(projectName + "/.gitignore"))
|
|
701
|
-
console.log(" " + cyan(projectName + "/README.md"))
|
|
816
|
+
for f in allFiles:
|
|
817
|
+
console.log(" " + cyan(f))
|
|
702
818
|
console.log()
|
|
703
819
|
console.log(bold(" Next steps:"))
|
|
704
820
|
console.log(" " + yellow("cd " + projectName))
|
|
705
821
|
console.log(" " + yellow("flux run src/main.flux"))
|
|
706
822
|
console.log()
|
|
823
|
+
console.log(gray(" Or run the test suite:"))
|
|
824
|
+
console.log(" " + yellow("flux test tests/"))
|
|
825
|
+
console.log()
|
|
707
826
|
|
|
708
827
|
// ── flux self-hosted ──────────────────────────────────────────
|
|
709
828
|
fn cmdSelfHosted(sub, opts):
|