fusion-lang 0.0.1.alpha2 → 0.0.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.
- checksums.yaml +4 -4
- data/.mutant.yml +24 -0
- data/.simplecov +11 -0
- data/CHANGELOG.md +42 -0
- data/README.md +11 -9
- data/Rakefile +8 -0
- data/docs/lang/design.md +289 -51
- data/docs/lang/implementation.md +279 -0
- data/docs/lang/roadmap.md +20 -36
- data/docs/user/explanation.md +5 -10
- data/docs/user/how-to-guides.md +145 -15
- data/docs/user/reference.md +365 -140
- data/docs/user/tutorial.md +22 -19
- data/examples/double.fsn +4 -1
- data/examples/factorial.fsn +6 -3
- data/examples/fizzbuzz.fsn +1 -4
- data/examples/gcd.fsn +9 -0
- data/examples/json_test.fsn +4 -0
- data/examples/matrix/OP.fsn +2 -0
- data/examples/matrix/average.fsn +2 -0
- data/examples/matrix/solve.fsn +2 -0
- data/examples/palindrome.fsn +1 -1
- data/exe/fusion +12 -12
- data/lib/fusion/ast.rb +76 -27
- data/lib/fusion/atom.rb +1 -1
- data/lib/fusion/cli/decoder.rb +13 -8
- data/lib/fusion/cli/encoder.rb +2 -2
- data/lib/fusion/cli/options.rb +134 -61
- data/lib/fusion/cli/parser.rb +4 -4
- data/lib/fusion/cli/repl.rb +32 -27
- data/lib/fusion/cli/serializer.rb +11 -11
- data/lib/fusion/cli.rb +120 -49
- data/lib/fusion/interpreter/builtins.rb +298 -160
- data/lib/fusion/interpreter/env.rb +42 -12
- data/lib/fusion/interpreter/error_val.rb +42 -20
- data/lib/fusion/interpreter/thunk.rb +53 -0
- data/lib/fusion/interpreter.rb +263 -98
- data/lib/fusion/lexer.rb +125 -37
- data/lib/fusion/parser.rb +245 -70
- data/lib/fusion/version.rb +3 -1
- data/lib/fusion.rb +0 -1
- data/stdlib/all.fsn +13 -0
- data/stdlib/any.fsn +12 -0
- data/stdlib/chars.fsn +5 -0
- data/stdlib/compact.fsn +5 -0
- data/stdlib/concat.fsn +6 -0
- data/stdlib/entries.fsn +6 -0
- data/stdlib/falsey.fsn +6 -0
- data/stdlib/filter.fsn +12 -0
- data/stdlib/flatten.fsn +7 -0
- data/stdlib/map.fsn +7 -4
- data/stdlib/matrix/Matrix.fsn +8 -0
- data/stdlib/matrix/OP.fsn +18 -0
- data/stdlib/matrix/add.fsn +7 -0
- data/stdlib/matrix/column.fsn +6 -0
- data/stdlib/matrix/determinant.fsn +16 -0
- data/stdlib/matrix/dimensions.fsn +5 -0
- data/stdlib/matrix/identity.fsn +6 -0
- data/stdlib/matrix/invert.fsn +26 -0
- data/stdlib/matrix/minor.fsn +15 -0
- data/stdlib/matrix/multiply.fsn +10 -0
- data/stdlib/matrix/negate.fsn +5 -0
- data/stdlib/matrix/product.fsn +11 -0
- data/stdlib/matrix/rotate.fsn +10 -0
- data/stdlib/matrix/row.fsn +6 -0
- data/stdlib/matrix/scale.fsn +6 -0
- data/stdlib/matrix/subtract.fsn +7 -0
- data/stdlib/matrix/sum.fsn +14 -0
- data/stdlib/matrix/transpose.fsn +5 -0
- data/stdlib/range.fsn +2 -2
- data/stdlib/reduce.fsn +8 -0
- data/stdlib/safe.fsn +7 -0
- data/stdlib/sanitize.fsn +2 -3
- data/stdlib/toObject.fsn +7 -0
- data/stdlib/truthy.fsn +7 -0
- data/stdlib/vector/Vector.fsn +7 -0
- data/stdlib/vector/add.fsn +6 -0
- data/stdlib/vector/cross.fsn +6 -0
- data/stdlib/vector/dot.fsn +6 -0
- data/stdlib/vector/norm.fsn +6 -0
- data/stdlib/vector/scale.fsn +5 -0
- data/stdlib/vector/subtract.fsn +6 -0
- data/stdlib/zip.fsn +6 -0
- metadata +50 -4
- data/lib/fusion/interpreter/file_thunk.rb +0 -39
- data/stdlib/mapValues.fsn +0 -5
- data/stdlib/math/square.fsn +0 -4
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# The n-by-n identity matrix for a positive integer n.
|
|
2
|
+
(
|
|
3
|
+
n ? (i ? @Integer => i > 0) =>
|
|
4
|
+
n | @range |: (r => n | @range |: (c => (r == c) | (true => 1, false => 0))),
|
|
5
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/identity", "status": 0, "input": x, "expected": ["_ ? (n ? @Integer => n > 0)"]}
|
|
6
|
+
)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Inverse of a square matrix with a non-zero determinant: the adjugate scaled
|
|
2
|
+
# by 1/determinant. Adjugate entry (i, j) is (-1)^(i+j) * determinant(minor(j, i)).
|
|
3
|
+
(
|
|
4
|
+
m ? (sq ? @Matrix => sq | @dimensions | (d => d.rows == d.columns)) =>
|
|
5
|
+
m | @determinant | (det => (det ?? 0) | (
|
|
6
|
+
0 => !{"kind": "math_error", "origin": "stdlib", "operation": "@matrix/invert", "status": 0, "input": m, "message": "singular matrix (determinant 0)"},
|
|
7
|
+
_ => m | (
|
|
8
|
+
[[a]] => [[a | @@OP.invert]],
|
|
9
|
+
_ =>
|
|
10
|
+
[
|
|
11
|
+
det | @@OP.invert,
|
|
12
|
+
m | @dimensions | (d =>
|
|
13
|
+
d.rows | @range |: (i =>
|
|
14
|
+
d.columns | @range |: (j =>
|
|
15
|
+
[
|
|
16
|
+
[-1, [i, j] | @@OP.sum] | @math.pow,
|
|
17
|
+
[m, j, i] | @minor | @determinant,
|
|
18
|
+
] | @@OP.product
|
|
19
|
+
)
|
|
20
|
+
)
|
|
21
|
+
),
|
|
22
|
+
] | @scale
|
|
23
|
+
)
|
|
24
|
+
)),
|
|
25
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/invert", "status": 0, "input": x, "expected": ["_ ? (sq ? @matrix/Matrix => sq | @matrix/dimensions | (d => d.rows == d.columns))"]}
|
|
26
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# The minor of a matrix: drop row r and column c. Input: [matrix, r, c]. The
|
|
2
|
+
# matrix must be at least 2 by 2, so the minor is a matrix again.
|
|
3
|
+
(
|
|
4
|
+
[m, r, c] ? ([x ? @Matrix, row ? @Integer, col ? @Integer] =>
|
|
5
|
+
x | @dimensions | (d =>
|
|
6
|
+
row >= 0 && row < d.rows &&
|
|
7
|
+
col >= 0 && col < d.columns &&
|
|
8
|
+
d.rows >= 2 && d.columns >= 2)) =>
|
|
9
|
+
m | @dimensions | (d =>
|
|
10
|
+
d.rows | @range |? (k => ~(k == r)) |: (k =>
|
|
11
|
+
d.columns | @range |? (l => ~(l == c)) |: (l => m[k][l])
|
|
12
|
+
)
|
|
13
|
+
),
|
|
14
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/minor", "status": 0, "input": x, "expected": ["_ ? ([m ? @matrix/Matrix, r ? @Integer, c ? @Integer] => m | @matrix/dimensions | (d => r >= 0 && r < d.rows && c >= 0 && c < d.columns && d.rows >= 2 && d.columns >= 2))"]}
|
|
15
|
+
)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Matrix multiplication of a pair [a, b]: a's column count must equal b's row
|
|
2
|
+
# count. Entry (i, j) is the dot product of a's row i and b's column j — the
|
|
3
|
+
# columns are the rows of the transposed b, computed once.
|
|
4
|
+
(
|
|
5
|
+
[a, b] ? ([x ? @Matrix, y ? @Matrix] => (x | @dimensions).columns == (y | @dimensions).rows) =>
|
|
6
|
+
b | @transpose | (columns =>
|
|
7
|
+
a |: (row => columns |: (column => [row, column] | @vector/dot))
|
|
8
|
+
),
|
|
9
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/multiply", "status": 0, "input": x, "expected": ["_ ? ([x ? @matrix/Matrix, y ? @matrix/Matrix] => (x | @matrix/dimensions).columns == (y | @matrix/dimensions).rows)"]}
|
|
10
|
+
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Product of a non-empty array of matrices, folded left through
|
|
2
|
+
# @matrix/multiply. A dimension mismatch surfaces as @matrix/multiply's error.
|
|
3
|
+
(
|
|
4
|
+
matrices ? (ms => [
|
|
5
|
+
ms | @Array,
|
|
6
|
+
ms | @size > 0,
|
|
7
|
+
{"c": ms, "f": @Matrix} | @all,
|
|
8
|
+
] | @OP.and | @safe) =>
|
|
9
|
+
matrices |+ @multiply,
|
|
10
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/product", "status": 0, "input": x, "expected": ["_ ? (ms => [ms | @Array, ms | @size > 0, {\"c\": ms, \"f\": @matrix/Matrix} | @all] | @OP.and | @safe)"]}
|
|
11
|
+
)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Rotate a 2x2 matrix by an angle in radians: the rotation matrix
|
|
2
|
+
# [[cos, -sin], [sin, cos]] multiplied onto it. Input: [angle, matrix].
|
|
3
|
+
(
|
|
4
|
+
[angle ? @Number, [[a ? @Number, b ? @Number], [c ? @Number, d ? @Number]]] =>
|
|
5
|
+
[
|
|
6
|
+
[[angle | @math.cos, angle | @math.sin | @@OP.negate], [angle | @math.sin, angle | @math.cos]],
|
|
7
|
+
[[a, b], [c, d]],
|
|
8
|
+
] | @multiply,
|
|
9
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/rotate", "status": 0, "input": x, "expected": ["[_ ? @Number, [[_ ? @Number, _ ? @Number], [_ ? @Number, _ ? @Number]]]"]}
|
|
10
|
+
)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Extract the i-th (0-based) row of a matrix as a vector. Input: [matrix, index].
|
|
2
|
+
(
|
|
3
|
+
[m, i] ? ([x ? @Matrix, n ? @Integer] => n >= 0 && n < (x | @dimensions).rows) =>
|
|
4
|
+
m[i],
|
|
5
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/row", "status": 0, "input": x, "expected": ["_ ? ([m ? @matrix/Matrix, i ? @Integer] => i >= 0 && i < (m | @matrix/dimensions).rows)"]}
|
|
6
|
+
)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Scale a matrix elementwise by a single number: each row scaled as a vector.
|
|
2
|
+
# Input: [number, matrix].
|
|
3
|
+
(
|
|
4
|
+
[s ? @Number, m ? @Matrix] => m |: (row => [s, row] | @vector/scale),
|
|
5
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/scale", "status": 0, "input": x, "expected": ["[_ ? @Number, _ ? @matrix/Matrix]"]}
|
|
6
|
+
)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Subtract the second matrix from the first, elementwise: a + (-1 * b).
|
|
2
|
+
# Input: [a, b].
|
|
3
|
+
(
|
|
4
|
+
[a, b] ? ([x ? @Matrix, y ? @Matrix] => [x, y] |: @dimensions | @OP.equal) =>
|
|
5
|
+
[a, [-1, b] | @scale] | @add,
|
|
6
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/subtract", "status": 0, "input": x, "expected": ["_ ? ([a ? @matrix/Matrix, b ? @matrix/Matrix] => [a, b] |: @matrix/dimensions | @OP.equal)"]}
|
|
7
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Elementwise sum of a non-empty array of equally sized matrices: a reduce
|
|
2
|
+
# over @matrix/add. The guard is a flat conditions array ending in @safe: a
|
|
3
|
+
# condition that errors (e.g. @dimensions of a non-matrix) collapses the array
|
|
4
|
+
# into that error, @safe turns it into false, and the clause just doesn't match.
|
|
5
|
+
(
|
|
6
|
+
matrices ? (ms => [
|
|
7
|
+
ms | @Array,
|
|
8
|
+
ms | @size > 0,
|
|
9
|
+
{"c": ms, "f": @Matrix} | @all,
|
|
10
|
+
ms |: @dimensions | @OP.equal,
|
|
11
|
+
] | @OP.and | @safe) =>
|
|
12
|
+
matrices |+ @add,
|
|
13
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/sum", "status": 0, "input": x, "expected": ["_ ? (ms => [ms | @Array, ms | @size > 0, {\"c\": ms, \"f\": @matrix/Matrix} | @all, ms |: @matrix/dimensions | @OP.equal] | @OP.and | @safe)"]}
|
|
14
|
+
)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Transpose a matrix: its columns become its rows.
|
|
2
|
+
(
|
|
3
|
+
m ? @Matrix => (m | @dimensions).columns | @range |: (j => [m, j] | @column),
|
|
4
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@matrix/transpose", "status": 0, "input": x, "expected": ["_ ? @matrix/Matrix"]}
|
|
5
|
+
)
|
data/stdlib/range.fsn
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
(
|
|
2
2
|
0 => [],
|
|
3
|
-
n ? (m ? @Integer => [
|
|
4
|
-
x => !{"kind": "
|
|
3
|
+
n ? (m ? @Integer => [m, 0] | @OP.compare | @OP.gt) => [...([n, -1] | @OP.sum | @), [n, -1] | @OP.sum],
|
|
4
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@range", "status": 0, "input": x, "expected": ["_ ? (m ? @Integer => [m, 0] | @OP.compare | @OP.gte)"]}
|
|
5
5
|
)
|
data/stdlib/reduce.fsn
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Left fold over a NON-EMPTY array with no seed: combine the first two elements
|
|
2
|
+
# with f, then fold that result with the rest. Input: {"f": binaryFn, "c": array}.
|
|
3
|
+
# `f` receives the pair [acc, element]. An empty list is an error.
|
|
4
|
+
(
|
|
5
|
+
{"f": _ ? @Function, "c": [x]} => x,
|
|
6
|
+
{"f": f ? @Function, "c": [x, y, ...rest]} => {"f": f, "c": [[x, y] | f, ...rest]} | @,
|
|
7
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@reduce", "status": 0, "input": x, "expected": ["{\"f\": _ ? @Function, \"c\": [_, ...]}"]}
|
|
8
|
+
)
|
data/stdlib/safe.fsn
ADDED
data/stdlib/sanitize.fsn
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
# returned unchanged.
|
|
6
6
|
(
|
|
7
7
|
v ? @Function => "<function>",
|
|
8
|
-
v ? @NonFinite => [
|
|
9
|
-
v ? @
|
|
10
|
-
v ? @Object => {"f": @sanitize, "object": v} | @mapValues,
|
|
8
|
+
v ? @NonFinite => ["<", v | @toString, ">"] | @concat,
|
|
9
|
+
v ? @Collection => v |: @,
|
|
11
10
|
v => v
|
|
12
11
|
)
|
data/stdlib/toObject.fsn
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Build an object from an array of [key, value] entries; later duplicate keys win.
|
|
2
|
+
# The inverse of @entries: folds the entries onto {} with the [=] setter.
|
|
3
|
+
(
|
|
4
|
+
entries ? (xs ? @Array => {"c": xs, "f": ([_ ? @String, _] => true)} | @all) =>
|
|
5
|
+
[{}, ...entries] |+ ([object, [key, value]] => object[key = value]),
|
|
6
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@toObject", "status": 0, "input": x, "expected": ["_ ? (xs ? @Array => {\"c\": xs, \"f\": ([_ ? @String, _] => true)} | @all)"]}
|
|
7
|
+
)
|
data/stdlib/truthy.fsn
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Add two equal-length vectors elementwise: zip and sum each pair.
|
|
2
|
+
(
|
|
3
|
+
[u, v] ? ([a ? @Vector, b ? @Vector] => [a, b] |: @size | @OP.equal) =>
|
|
4
|
+
[u, v] | @zip |: @OP.sum,
|
|
5
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@vector/add", "status": 0, "input": x, "expected": ["_ ? ([u ? @vector/Vector, v ? @vector/Vector] => [u, v] |: @size | @OP.equal)"]}
|
|
6
|
+
)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Cross product of two 3-dimensional vectors.
|
|
2
|
+
(
|
|
3
|
+
[[a ? @Number, b ? @Number, c ? @Number], [d ? @Number, e ? @Number, f ? @Number]] =>
|
|
4
|
+
[b * f - c * e, c * d - a * f, a * e - b * d],
|
|
5
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@vector/cross", "status": 0, "input": x, "expected": ["[[_ ? @Number, _ ? @Number, _ ? @Number], [_ ? @Number, _ ? @Number, _ ? @Number]]"]}
|
|
6
|
+
)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Dot product of two equal-length vectors: zip, multiply each pair, sum.
|
|
2
|
+
(
|
|
3
|
+
[u, v] ? ([a ? @Vector, b ? @Vector] => [a, b] |: @size | @OP.equal) =>
|
|
4
|
+
[u, v] | @zip |: @OP.product | @OP.sum,
|
|
5
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@vector/dot", "status": 0, "input": x, "expected": ["_ ? ([u ? @vector/Vector, v ? @vector/Vector] => [u, v] |: @size | @OP.equal)"]}
|
|
6
|
+
)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Euclidean norm (length) of a vector: the square root of the dot product with
|
|
2
|
+
# itself. Always a float.
|
|
3
|
+
(
|
|
4
|
+
v ? @Vector => [v, v] | @dot | @math.sqrt,
|
|
5
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@vector/norm", "status": 0, "input": x, "expected": ["_ ? @vector/Vector"]}
|
|
6
|
+
)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Scale a vector elementwise by a single number. Input: [number, vector].
|
|
2
|
+
(
|
|
3
|
+
[s ? @Number, v ? @Vector] => v |: (entry => s * entry),
|
|
4
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@vector/scale", "status": 0, "input": x, "expected": ["[_ ? @Number, _ ? @vector/Vector]"]}
|
|
5
|
+
)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Subtract the second vector from the first, elementwise: u + (-1 * v).
|
|
2
|
+
(
|
|
3
|
+
[u, v] ? ([a ? @Vector, b ? @Vector] => [a, b] |: @size | @OP.equal) =>
|
|
4
|
+
[u, [-1, v] | @scale] | @add,
|
|
5
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@vector/subtract", "status": 0, "input": x, "expected": ["_ ? ([u ? @vector/Vector, v ? @vector/Vector] => [u, v] |: @size | @OP.equal)"]}
|
|
6
|
+
)
|
data/stdlib/zip.fsn
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Zip a pair of equal-length arrays into an array of [left, right] pairs.
|
|
2
|
+
(
|
|
3
|
+
[xs, ys] ? ([a ? @Array, b ? @Array] => a | @size == b | @size) =>
|
|
4
|
+
xs | @size | @range |: (k => [xs[k], ys[k]]),
|
|
5
|
+
x => !{"kind": "argument_error", "origin": "stdlib", "operation": "@zip", "status": 0, "input": x, "expected": ["_ ? ([xs ? @Array, ys ? @Array] => xs | @size == ys | @size)"]}
|
|
6
|
+
)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fusion-lang
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Klaus Weidinger
|
|
@@ -17,11 +17,15 @@ executables:
|
|
|
17
17
|
extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
|
19
19
|
files:
|
|
20
|
+
- ".mutant.yml"
|
|
21
|
+
- ".simplecov"
|
|
22
|
+
- CHANGELOG.md
|
|
20
23
|
- LICENSE.txt
|
|
21
24
|
- README.md
|
|
22
25
|
- Rakefile
|
|
23
26
|
- docs/index.md
|
|
24
27
|
- docs/lang/design.md
|
|
28
|
+
- docs/lang/implementation.md
|
|
25
29
|
- docs/lang/roadmap.md
|
|
26
30
|
- docs/user/explanation.md
|
|
27
31
|
- docs/user/how-to-guides.md
|
|
@@ -32,6 +36,11 @@ files:
|
|
|
32
36
|
- examples/factorial.fsn
|
|
33
37
|
- examples/first.fsn
|
|
34
38
|
- examples/fizzbuzz.fsn
|
|
39
|
+
- examples/gcd.fsn
|
|
40
|
+
- examples/json_test.fsn
|
|
41
|
+
- examples/matrix/OP.fsn
|
|
42
|
+
- examples/matrix/average.fsn
|
|
43
|
+
- examples/matrix/solve.fsn
|
|
35
44
|
- examples/palindrome.fsn
|
|
36
45
|
- exe/fusion
|
|
37
46
|
- lib/fusion.rb
|
|
@@ -48,9 +57,9 @@ files:
|
|
|
48
57
|
- lib/fusion/interpreter/builtins.rb
|
|
49
58
|
- lib/fusion/interpreter/env.rb
|
|
50
59
|
- lib/fusion/interpreter/error_val.rb
|
|
51
|
-
- lib/fusion/interpreter/file_thunk.rb
|
|
52
60
|
- lib/fusion/interpreter/func.rb
|
|
53
61
|
- lib/fusion/interpreter/native_func.rb
|
|
62
|
+
- lib/fusion/interpreter/thunk.rb
|
|
54
63
|
- lib/fusion/lexer.rb
|
|
55
64
|
- lib/fusion/null.rb
|
|
56
65
|
- lib/fusion/parser.rb
|
|
@@ -58,11 +67,48 @@ files:
|
|
|
58
67
|
- lib/fusion/typed_data.rb
|
|
59
68
|
- lib/fusion/version.rb
|
|
60
69
|
- lib/fusion/wire_pair.rb
|
|
70
|
+
- stdlib/all.fsn
|
|
71
|
+
- stdlib/any.fsn
|
|
72
|
+
- stdlib/chars.fsn
|
|
73
|
+
- stdlib/compact.fsn
|
|
74
|
+
- stdlib/concat.fsn
|
|
75
|
+
- stdlib/entries.fsn
|
|
76
|
+
- stdlib/falsey.fsn
|
|
77
|
+
- stdlib/filter.fsn
|
|
78
|
+
- stdlib/flatten.fsn
|
|
61
79
|
- stdlib/map.fsn
|
|
62
|
-
- stdlib/
|
|
63
|
-
- stdlib/
|
|
80
|
+
- stdlib/matrix/Matrix.fsn
|
|
81
|
+
- stdlib/matrix/OP.fsn
|
|
82
|
+
- stdlib/matrix/add.fsn
|
|
83
|
+
- stdlib/matrix/column.fsn
|
|
84
|
+
- stdlib/matrix/determinant.fsn
|
|
85
|
+
- stdlib/matrix/dimensions.fsn
|
|
86
|
+
- stdlib/matrix/identity.fsn
|
|
87
|
+
- stdlib/matrix/invert.fsn
|
|
88
|
+
- stdlib/matrix/minor.fsn
|
|
89
|
+
- stdlib/matrix/multiply.fsn
|
|
90
|
+
- stdlib/matrix/negate.fsn
|
|
91
|
+
- stdlib/matrix/product.fsn
|
|
92
|
+
- stdlib/matrix/rotate.fsn
|
|
93
|
+
- stdlib/matrix/row.fsn
|
|
94
|
+
- stdlib/matrix/scale.fsn
|
|
95
|
+
- stdlib/matrix/subtract.fsn
|
|
96
|
+
- stdlib/matrix/sum.fsn
|
|
97
|
+
- stdlib/matrix/transpose.fsn
|
|
64
98
|
- stdlib/range.fsn
|
|
99
|
+
- stdlib/reduce.fsn
|
|
100
|
+
- stdlib/safe.fsn
|
|
65
101
|
- stdlib/sanitize.fsn
|
|
102
|
+
- stdlib/toObject.fsn
|
|
103
|
+
- stdlib/truthy.fsn
|
|
104
|
+
- stdlib/vector/Vector.fsn
|
|
105
|
+
- stdlib/vector/add.fsn
|
|
106
|
+
- stdlib/vector/cross.fsn
|
|
107
|
+
- stdlib/vector/dot.fsn
|
|
108
|
+
- stdlib/vector/norm.fsn
|
|
109
|
+
- stdlib/vector/scale.fsn
|
|
110
|
+
- stdlib/vector/subtract.fsn
|
|
111
|
+
- stdlib/zip.fsn
|
|
66
112
|
homepage: https://github.com/dunkelziffer/fusion
|
|
67
113
|
licenses:
|
|
68
114
|
- MIT
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# === Interpreter internals ===
|
|
4
|
-
#
|
|
5
|
-
# Lazy, memoized reference to a file's value (a "thunk" / promise).
|
|
6
|
-
|
|
7
|
-
module Fusion
|
|
8
|
-
class Interpreter
|
|
9
|
-
class FileThunk
|
|
10
|
-
def initialize(loader, abspath)
|
|
11
|
-
@loader = loader
|
|
12
|
-
@abspath = abspath
|
|
13
|
-
@state = :unforced # :unforced | :forcing | :done
|
|
14
|
-
@value = nil
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def force
|
|
18
|
-
case @state
|
|
19
|
-
when :done then @value
|
|
20
|
-
when :forcing
|
|
21
|
-
# We are already evaluating this file and were asked for it again
|
|
22
|
-
# without any intervening function boundary => non-productive data cycle.
|
|
23
|
-
ErrorVal.internal(
|
|
24
|
-
kind: "reference_error",
|
|
25
|
-
location: @loader.file_location(@abspath),
|
|
26
|
-
operation: "forcing a file reference",
|
|
27
|
-
input: @abspath,
|
|
28
|
-
message: "non-productive data cycle"
|
|
29
|
-
)
|
|
30
|
-
else
|
|
31
|
-
@state = :forcing
|
|
32
|
-
@value = @loader.evaluate_file(@abspath)
|
|
33
|
-
@state = :done
|
|
34
|
-
@value
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
data/stdlib/mapValues.fsn
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
# Apply f to each value of an object, keeping the keys. Input: {"f": fn, "object": obj}.
|
|
2
|
-
(
|
|
3
|
-
{"f": f, "object": obj ? @Object} => {"f": (k => [k, [obj, k] | @get | f]), "xs": obj | @keys} | @map | @toObject,
|
|
4
|
-
x => !{"kind": "argument_error", "location": "stdlib mapValues.fsn", "operation": "mapValues", "input": x | @sanitize, "message": "expected {\"f\": _, \"object\": _}"}
|
|
5
|
-
)
|
data/stdlib/math/square.fsn
DELETED