porffor 0.41.3 → 0.41.4
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/compiler/codegen.js +92 -81
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -96,10 +96,8 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
96
96
|
return cacheAst(decl, generateChain(scope, decl));
|
97
97
|
|
98
98
|
case 'CallExpression':
|
99
|
-
return cacheAst(decl, generateCall(scope, decl, global, name, valueUnused));
|
100
|
-
|
101
99
|
case 'NewExpression':
|
102
|
-
return cacheAst(decl,
|
100
|
+
return cacheAst(decl, generateCall(scope, decl, global, name, valueUnused));
|
103
101
|
|
104
102
|
case 'ThisExpression':
|
105
103
|
return cacheAst(decl, generateThis(scope, decl));
|
@@ -189,6 +187,9 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
189
187
|
case 'TemplateLiteral':
|
190
188
|
return cacheAst(decl, generateTemplate(scope, decl));
|
191
189
|
|
190
|
+
case 'TaggedTemplateExpression':
|
191
|
+
return cacheAst(decl, generateTaggedTemplate(scope, decl, global, name));
|
192
|
+
|
192
193
|
case 'ExportNamedDeclaration':
|
193
194
|
if (!decl.declaration) return todo(scope, 'unsupported export declaration');
|
194
195
|
|
@@ -209,79 +210,6 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
209
210
|
|
210
211
|
return cacheAst(decl, []);
|
211
212
|
|
212
|
-
case 'TaggedTemplateExpression': {
|
213
|
-
const funcs = {
|
214
|
-
__Porffor_wasm: str => {
|
215
|
-
let out = [];
|
216
|
-
|
217
|
-
for (const line of str.split('\n')) {
|
218
|
-
const asm = line.trim().split(';;')[0].split(' ').filter(x => x);
|
219
|
-
if (!asm[0]) continue; // blank
|
220
|
-
|
221
|
-
if (asm[0] === 'local') {
|
222
|
-
const [ name, type ] = asm.slice(1);
|
223
|
-
scope.locals[name] = { idx: scope.localInd++, type: Valtype[type] };
|
224
|
-
continue;
|
225
|
-
}
|
226
|
-
|
227
|
-
if (asm[0] === 'returns') {
|
228
|
-
scope.returns = asm.slice(1).map(x => Valtype[x]);
|
229
|
-
continue;
|
230
|
-
}
|
231
|
-
|
232
|
-
let inst = Opcodes[asm[0].replace('.', '_')];
|
233
|
-
if (inst == null) throw new Error(`inline asm: inst ${asm[0]} not found`);
|
234
|
-
if (!Array.isArray(inst)) inst = [ inst ];
|
235
|
-
|
236
|
-
const immediates = asm.slice(1).map(x => {
|
237
|
-
const int = parseInt(x);
|
238
|
-
if (Number.isNaN(int)) {
|
239
|
-
if (builtinFuncs[x]) {
|
240
|
-
if (funcIndex[x] == null) includeBuiltin(scope, x);
|
241
|
-
return funcIndex[x];
|
242
|
-
}
|
243
|
-
|
244
|
-
return scope.locals[x]?.idx ?? globals[x].idx;
|
245
|
-
}
|
246
|
-
return int;
|
247
|
-
});
|
248
|
-
|
249
|
-
const encodeFunc = ({
|
250
|
-
[Opcodes.f64_const]: x => x,
|
251
|
-
[Opcodes.if]: unsignedLEB128,
|
252
|
-
[Opcodes.loop]: unsignedLEB128
|
253
|
-
})[inst[0]] ?? signedLEB128;
|
254
|
-
out.push([ ...inst, ...immediates.flatMap(x => encodeFunc(x)) ]);
|
255
|
-
}
|
256
|
-
|
257
|
-
return out;
|
258
|
-
},
|
259
|
-
|
260
|
-
__Porffor_bs: str => makeString(scope, str, global, name, true),
|
261
|
-
__Porffor_s: str => makeString(scope, str, global, name, false)
|
262
|
-
};
|
263
|
-
|
264
|
-
const func = decl.tag.name;
|
265
|
-
// hack for inline asm
|
266
|
-
if (!funcs[func]) return cacheAst(decl, todo(scope, 'tagged template expressions not implemented', true));
|
267
|
-
|
268
|
-
const { quasis, expressions } = decl.quasi;
|
269
|
-
let str = quasis[0].value.raw;
|
270
|
-
|
271
|
-
for (let i = 0; i < expressions.length; i++) {
|
272
|
-
const e = expressions[i];
|
273
|
-
if (!e.name) {
|
274
|
-
if (e.type === 'BinaryExpression' && e.operator === '+' && e.left.type === 'Identifier' && e.right.type === 'Literal') {
|
275
|
-
str += lookupName(scope, e.left.name)[0].idx + e.right.value;
|
276
|
-
} else todo(scope, 'unsupported expression in intrinsic');
|
277
|
-
} else str += lookupName(scope, e.name)[0].idx;
|
278
|
-
|
279
|
-
str += quasis[i + 1].value.raw;
|
280
|
-
}
|
281
|
-
|
282
|
-
return cacheAst(decl, funcs[func](str));
|
283
|
-
}
|
284
|
-
|
285
213
|
default:
|
286
214
|
// ignore typescript nodes
|
287
215
|
if (decl.type.startsWith('TS') ||
|
@@ -1823,6 +1751,8 @@ const createThisArg = (scope, decl) => {
|
|
1823
1751
|
};
|
1824
1752
|
|
1825
1753
|
const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
1754
|
+
if (decl.type === 'NewExpression') decl._new = true;
|
1755
|
+
|
1826
1756
|
let out = [];
|
1827
1757
|
let name = decl.callee.name;
|
1828
1758
|
|
@@ -2606,11 +2536,6 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2606
2536
|
return out;
|
2607
2537
|
};
|
2608
2538
|
|
2609
|
-
const generateNew = (scope, decl, _global, _name) => generateCall(scope, {
|
2610
|
-
...decl,
|
2611
|
-
_new: true
|
2612
|
-
}, _global, _name);
|
2613
|
-
|
2614
2539
|
const generateThis = (scope, decl) => {
|
2615
2540
|
if (!scope.constr) {
|
2616
2541
|
// this in a non-constructor context is a reference to globalThis
|
@@ -5908,6 +5833,92 @@ export const generateTemplate = (scope, decl) => {
|
|
5908
5833
|
return generate(scope, current);
|
5909
5834
|
};
|
5910
5835
|
|
5836
|
+
const generateTaggedTemplate = (scope, decl, global = false, name = undefined) => {
|
5837
|
+
const intrinsics = {
|
5838
|
+
__Porffor_wasm: str => {
|
5839
|
+
let out = [];
|
5840
|
+
|
5841
|
+
for (const line of str.split('\n')) {
|
5842
|
+
const asm = line.trim().split(';;')[0].split(' ').filter(x => x);
|
5843
|
+
if (!asm[0]) continue; // blank
|
5844
|
+
|
5845
|
+
if (asm[0] === 'local') {
|
5846
|
+
const [ name, type ] = asm.slice(1);
|
5847
|
+
scope.locals[name] = { idx: scope.localInd++, type: Valtype[type] };
|
5848
|
+
continue;
|
5849
|
+
}
|
5850
|
+
|
5851
|
+
if (asm[0] === 'returns') {
|
5852
|
+
scope.returns = asm.slice(1).map(x => Valtype[x]);
|
5853
|
+
continue;
|
5854
|
+
}
|
5855
|
+
|
5856
|
+
let inst = Opcodes[asm[0].replace('.', '_')];
|
5857
|
+
if (inst == null) throw new Error(`inline asm: inst ${asm[0]} not found`);
|
5858
|
+
if (!Array.isArray(inst)) inst = [ inst ];
|
5859
|
+
|
5860
|
+
const immediates = asm.slice(1).map(x => {
|
5861
|
+
const int = parseInt(x);
|
5862
|
+
if (Number.isNaN(int)) {
|
5863
|
+
if (builtinFuncs[x]) {
|
5864
|
+
if (funcIndex[x] == null) includeBuiltin(scope, x);
|
5865
|
+
return funcIndex[x];
|
5866
|
+
}
|
5867
|
+
|
5868
|
+
return scope.locals[x]?.idx ?? globals[x].idx;
|
5869
|
+
}
|
5870
|
+
return int;
|
5871
|
+
});
|
5872
|
+
|
5873
|
+
const encodeFunc = ({
|
5874
|
+
[Opcodes.f64_const]: x => x,
|
5875
|
+
[Opcodes.if]: unsignedLEB128,
|
5876
|
+
[Opcodes.loop]: unsignedLEB128
|
5877
|
+
})[inst[0]] ?? signedLEB128;
|
5878
|
+
out.push([ ...inst, ...immediates.flatMap(x => encodeFunc(x)) ]);
|
5879
|
+
}
|
5880
|
+
|
5881
|
+
return out;
|
5882
|
+
},
|
5883
|
+
|
5884
|
+
__Porffor_bs: str => makeString(scope, str, global, name, true),
|
5885
|
+
__Porffor_s: str => makeString(scope, str, global, name, false)
|
5886
|
+
};
|
5887
|
+
|
5888
|
+
const { quasis, expressions } = decl.quasi;
|
5889
|
+
if (intrinsics[decl.tag.name]) {
|
5890
|
+
let str = quasis[0].value.raw;
|
5891
|
+
|
5892
|
+
for (let i = 0; i < expressions.length; i++) {
|
5893
|
+
const e = expressions[i];
|
5894
|
+
if (!e.name) {
|
5895
|
+
if (e.type === 'BinaryExpression' && e.operator === '+' && e.left.type === 'Identifier' && e.right.type === 'Literal') {
|
5896
|
+
str += lookupName(scope, e.left.name)[0].idx + e.right.value;
|
5897
|
+
} else todo(scope, 'unsupported expression in intrinsic');
|
5898
|
+
} else str += lookupName(scope, e.name)[0].idx;
|
5899
|
+
|
5900
|
+
str += quasis[i + 1].value.raw;
|
5901
|
+
}
|
5902
|
+
|
5903
|
+
return cacheAst(decl, intrinsics[decl.tag.name](str));
|
5904
|
+
}
|
5905
|
+
|
5906
|
+
return generate(scope, {
|
5907
|
+
type: 'CallExpression',
|
5908
|
+
callee: decl.tag,
|
5909
|
+
arguments: [
|
5910
|
+
{ // strings
|
5911
|
+
type: 'ArrayExpression',
|
5912
|
+
elements: quasis.map(x => ({
|
5913
|
+
type: 'Literal',
|
5914
|
+
value: x.value.cooked
|
5915
|
+
}))
|
5916
|
+
},
|
5917
|
+
...expressions
|
5918
|
+
]
|
5919
|
+
});
|
5920
|
+
};
|
5921
|
+
|
5911
5922
|
globalThis._uniqId = 0;
|
5912
5923
|
const uniqId = () => '_' + globalThis._uniqId++;
|
5913
5924
|
|
package/package.json
CHANGED