exprforge 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +199 -16
- package/ast.js +22 -1
- package/emitters/cobol.js +410 -0
- package/emitters/fortran.js +169 -0
- package/emitters/julia.js +67 -0
- package/emitters/perl.js +95 -0
- package/emitters/php.js +79 -0
- package/emitters/registry.js +7 -0
- package/emitters/scheme.js +154 -0
- package/emitters/zig.js +126 -0
- package/index.js +7 -2
- package/math/index.js +113 -0
- package/package.json +9 -3
- package/samples/math-demo.js +48 -0
- package/samples/spline-frame.js +60 -42
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// exprforge/samples/math-demo.js
|
|
2
|
+
// Not a worked example -- a conformance-test fixture for math/index.js,
|
|
3
|
+
// same role samples/kitchen-sink.js plays for the core Math intrinsics:
|
|
4
|
+
// exercises every exprforge/math helper in one suite, purely so
|
|
5
|
+
// test/conformance.test.js can prove the generated code agrees across
|
|
6
|
+
// every target. Calls normalize3() twice (once per input vector) in the
|
|
7
|
+
// same function specifically to prove its internal gensym'd let-binding
|
|
8
|
+
// doesn't collide with itself -- see the comment on normalizeGensymCounter
|
|
9
|
+
// in math/index.js.
|
|
10
|
+
const { v, num, outputs } = require("../ast.js");
|
|
11
|
+
const { safeDiv, dot3, len3, cross3, normalize3, clamp } = require("../math/index.js");
|
|
12
|
+
|
|
13
|
+
// "byy", not "by": BY is a reserved COBOL keyword (BY REFERENCE/BY VALUE/
|
|
14
|
+
// BY CONTENT) -- confirmed against a real compiler ("syntax error,
|
|
15
|
+
// unexpected BY") that it can't be used as a data-item name there, same
|
|
16
|
+
// kind of unavoidable per-language collision as "len"/"mag" below.
|
|
17
|
+
const MATH_DEMO_PARAMS = ["ax", "ay", "az", "bx", "byy", "bz", "t", "lo", "hi"];
|
|
18
|
+
|
|
19
|
+
const cross = cross3(v("ax"), v("ay"), v("az"), v("bx"), v("byy"), v("bz"));
|
|
20
|
+
const normA = normalize3(v("ax"), v("ay"), v("az"));
|
|
21
|
+
const normB = normalize3(v("bx"), v("byy"), v("bz"));
|
|
22
|
+
|
|
23
|
+
const MathDemo = {
|
|
24
|
+
name: "MathDemo",
|
|
25
|
+
params: MATH_DEMO_PARAMS,
|
|
26
|
+
body: outputs({
|
|
27
|
+
dot: dot3(v("ax"), v("ay"), v("az"), v("bx"), v("byy"), v("bz")),
|
|
28
|
+
// "mag", not "len": LEN is a reserved QB64 builtin (string/array
|
|
29
|
+
// length) -- see test/conformance.test.js's normalizeXAst comment.
|
|
30
|
+
mag: len3(v("ax"), v("ay"), v("az")),
|
|
31
|
+
crossX: cross.x,
|
|
32
|
+
crossY: cross.y,
|
|
33
|
+
crossZ: cross.z,
|
|
34
|
+
normAX: normA.x,
|
|
35
|
+
normAY: normA.y,
|
|
36
|
+
normAZ: normA.z,
|
|
37
|
+
normBX: normB.x,
|
|
38
|
+
normBY: normB.y,
|
|
39
|
+
normBZ: normB.z,
|
|
40
|
+
clamped: clamp(v("t"), v("lo"), v("hi")),
|
|
41
|
+
// ax/bx as numerator/denominator: exercises both the safe path
|
|
42
|
+
// (bx away from zero) and the fallback (bx == 0, see
|
|
43
|
+
// test/conformance.test.js's math-demo input rows).
|
|
44
|
+
safeDivResult: safeDiv(v("ax"), v("bx"), num(-1)),
|
|
45
|
+
}),
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
module.exports = { mathDemoAst: MathDemo };
|
package/samples/spline-frame.js
CHANGED
|
@@ -15,7 +15,12 @@
|
|
|
15
15
|
// IMPORTANT for QB64: function/SUB names must be unique across the entire
|
|
16
16
|
// QB64 compilation unit. The SpEf prefix (SplineExprforge) exists to avoid
|
|
17
17
|
// collisions with hand-written code elsewhere in that project.
|
|
18
|
-
|
|
18
|
+
//
|
|
19
|
+
// mfLetChain/apLetChain/rfLetChain/SpEfCrWeights use letChain() (ast.js)
|
|
20
|
+
// instead of hand-nested letIn calls -- apLetChain was 14 levels deep
|
|
21
|
+
// before, all hand-balanced closing parens with no real hierarchy behind
|
|
22
|
+
// the nesting, exactly the kind of thing that's easy to miscount editing.
|
|
23
|
+
const { num, v, call, add, mul, sub, div, neg, letChain, select, cmp, outputs } = require("../ast.js");
|
|
19
24
|
|
|
20
25
|
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
21
26
|
const PI = num(3.141592653589793);
|
|
@@ -66,17 +71,20 @@ const MF_PARAMS = ["tx", "ty", "tz"];
|
|
|
66
71
|
const nearVert = cmp(call("abs", v("ty")), ">", num(0.98));
|
|
67
72
|
|
|
68
73
|
function mfLetChain(body) {
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
return letChain(
|
|
75
|
+
[
|
|
76
|
+
["wy", select(nearVert, num(0), num(1))],
|
|
77
|
+
["wz", select(nearVert, num(1), num(0))],
|
|
78
|
+
["crossX", sub(mul(v("ty"), v("wz")), mul(v("tz"), v("wy")))],
|
|
79
|
+
["crossY", neg(mul(v("tx"), v("wz")))],
|
|
80
|
+
["crossZ", mul(v("tx"), v("wy"))],
|
|
81
|
+
["rLen", len3(v("crossX"), v("crossY"), v("crossZ"))],
|
|
82
|
+
["rxN", safeDiv(v("crossX"), "rLen", num(0))],
|
|
83
|
+
["ryN", safeDiv(v("crossY"), "rLen", num(0))],
|
|
84
|
+
["rzN", safeDiv(v("crossZ"), "rLen", num(1))],
|
|
85
|
+
],
|
|
86
|
+
body,
|
|
87
|
+
);
|
|
80
88
|
}
|
|
81
89
|
|
|
82
90
|
// U = R × T (using normalized R) — a cyclic permutation, not one formula,
|
|
@@ -101,23 +109,26 @@ const SpEfMkFrame = {
|
|
|
101
109
|
const AP_PARAMS = ["wx", "wy_wire", "wz_wire", "tx", "ty", "tz", "prDeg", "so"];
|
|
102
110
|
|
|
103
111
|
function apLetChain(body) {
|
|
104
|
-
return
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
112
|
+
return letChain(
|
|
113
|
+
[
|
|
114
|
+
["wy", select(nearVert, num(0), num(1))],
|
|
115
|
+
["wz", select(nearVert, num(1), num(0))],
|
|
116
|
+
["crossX", sub(mul(v("ty"), v("wz")), mul(v("tz"), v("wy")))],
|
|
117
|
+
["crossY", neg(mul(v("tx"), v("wz")))],
|
|
118
|
+
["crossZ", mul(v("tx"), v("wy"))],
|
|
119
|
+
["rLen", len3(v("crossX"), v("crossY"), v("crossZ"))],
|
|
120
|
+
["rxN", safeDiv(v("crossX"), "rLen", num(0))],
|
|
121
|
+
["ryN", safeDiv(v("crossY"), "rLen", num(0))],
|
|
122
|
+
["rzN", safeDiv(v("crossZ"), "rLen", num(1))],
|
|
123
|
+
["ux", sub(mul(v("ryN"), v("tz")), mul(v("rzN"), v("ty")))],
|
|
124
|
+
["uy", sub(mul(v("rzN"), v("tx")), mul(v("rxN"), v("tz")))],
|
|
125
|
+
["uz", sub(mul(v("rxN"), v("ty")), mul(v("ryN"), v("tx")))],
|
|
126
|
+
["rad", degToRad(v("prDeg"))],
|
|
127
|
+
["c", call("cos", v("rad"))],
|
|
128
|
+
["s", call("sin", v("rad"))],
|
|
129
|
+
],
|
|
130
|
+
body,
|
|
131
|
+
);
|
|
121
132
|
}
|
|
122
133
|
|
|
123
134
|
const SpEfActualPos = {
|
|
@@ -139,10 +150,14 @@ const SpEfActualPos = {
|
|
|
139
150
|
const RF_PARAMS = ["ux", "uy", "uz", "rx", "ry", "rz", "crDeg"];
|
|
140
151
|
|
|
141
152
|
function rfLetChain(body) {
|
|
142
|
-
return
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
153
|
+
return letChain(
|
|
154
|
+
[
|
|
155
|
+
["rad", degToRad(v("crDeg"))],
|
|
156
|
+
["c", call("cos", v("rad"))],
|
|
157
|
+
["s", call("sin", v("rad"))],
|
|
158
|
+
],
|
|
159
|
+
body,
|
|
160
|
+
);
|
|
146
161
|
}
|
|
147
162
|
|
|
148
163
|
const SpEfRollFrame = {
|
|
@@ -167,15 +182,18 @@ const CRW_PARAMS = ["t"];
|
|
|
167
182
|
const SpEfCrWeights = {
|
|
168
183
|
name: "SpEfCrWeights",
|
|
169
184
|
params: CRW_PARAMS,
|
|
170
|
-
body:
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
185
|
+
body: letChain(
|
|
186
|
+
[
|
|
187
|
+
["t2", mul(v("t"), v("t"))],
|
|
188
|
+
["t3", mul(v("t2"), v("t"))],
|
|
189
|
+
],
|
|
190
|
+
outputs({
|
|
191
|
+
w0: mul(num(0.5), add(neg(v("t3")), mul(num(2), v("t2")), neg(v("t")))),
|
|
192
|
+
w1: mul(num(0.5), add(mul(num(3), v("t3")), mul(num(-5), v("t2")), num(2))),
|
|
193
|
+
w2: mul(num(0.5), add(mul(num(-3), v("t3")), mul(num(4), v("t2")), v("t"))),
|
|
194
|
+
w3: mul(num(0.5), add(v("t3"), neg(v("t2")))),
|
|
195
|
+
}),
|
|
196
|
+
),
|
|
179
197
|
};
|
|
180
198
|
|
|
181
199
|
// ── Exports ──────────────────────────────────────────────────────────────
|