nirguna 0.1.0
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 +846 -0
- package/README.md +140 -0
- package/bin/ishvara.js +174 -0
- package/lib/ishvara.js +29 -0
- package/package.json +111 -0
- package/packages/compiler-fasm/compiler.js +75 -0
- package/packages/compiler-wasm/compiler.js +62 -0
- package/packages/operator-wasm/index.js +55 -0
- package/packages/optimizer-fasm/optimizer.js +15 -0
- package/packages/optimizer-wasm/optimizer.js +13 -0
- package/packages/printer-fasm/printer/printer.js +30 -0
- package/packages/printer-fasm/printer/visitors/assignment-expression.js +47 -0
- package/packages/printer-fasm/printer/visitors/block-statement.js +7 -0
- package/packages/printer-fasm/printer/visitors/call-expression.js +56 -0
- package/packages/printer-fasm/printer/visitors/expression-statement/expression-statement.js +34 -0
- package/packages/printer-fasm/printer/visitors/expression-statement/print-in-out.js +37 -0
- package/packages/printer-fasm/printer/visitors/expression-statement/print-jmp-far.js +30 -0
- package/packages/printer-fasm/printer/visitors/labeled-statement.js +14 -0
- package/packages/printer-fasm/printer/visitors/member-expression.js +5 -0
- package/packages/printer-fasm/printer/visitors/sequence-expression.js +17 -0
- package/packages/printer-fasm/printer/visitors/string-literal.js +55 -0
- package/packages/printer-fasm/printer/visitors/tagged-template-expression.js +4 -0
- package/packages/printer-fasm/printer.js +7 -0
- package/packages/printer-wasm/printer/maybe-type-annotation.js +15 -0
- package/packages/printer-wasm/printer/params.js +72 -0
- package/packages/printer-wasm/printer/printer.js +32 -0
- package/packages/printer-wasm/printer/visitors/block-statement.js +33 -0
- package/packages/printer-wasm/printer/visitors/call-expression/call-expression.js +53 -0
- package/packages/printer-wasm/printer/visitors/call-expression/is-wasm-type.js +6 -0
- package/packages/printer-wasm/printer/visitors/export-named-declaration.js +3 -0
- package/packages/printer-wasm/printer/visitors/expression-statement/expression-statement.js +38 -0
- package/packages/printer-wasm/printer/visitors/expression-statement/print-wasm-import.js +81 -0
- package/packages/printer-wasm/printer/visitors/expression-statement/print-wasm-memory.js +31 -0
- package/packages/printer-wasm/printer/visitors/function-declaration.js +91 -0
- package/packages/printer-wasm/printer/visitors/identifier.js +11 -0
- package/packages/printer-wasm/printer/visitors/if-statement.js +128 -0
- package/packages/printer-wasm/printer/visitors/program.js +26 -0
- package/packages/printer-wasm/printer/visitors/return.js +16 -0
- package/packages/printer-wasm/printer.js +10 -0
- package/packages/test-wasm/test.js +45 -0
- package/packages/transformer-fasm/transformer.js +70 -0
- package/packages/transformer-wasm/transformer.js +20 -0
- package/packages/translator-fasm/dump.js +68 -0
- package/packages/translator-fasm/translator.js +15 -0
- package/packages/translator-wasm/translator.js +51 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {visitors} from '@putout/printer';
|
|
2
|
+
import {types} from '@putout/babel';
|
|
3
|
+
|
|
4
|
+
const {isMemberExpression} = types;
|
|
5
|
+
|
|
6
|
+
export const AssignmentExpression = (path, printer, semantics) => {
|
|
7
|
+
const left = path.get('left');
|
|
8
|
+
const right = path.get('right');
|
|
9
|
+
|
|
10
|
+
if (isMemberExpression(left) && left.node.computed) {
|
|
11
|
+
const {write, traverse} = printer;
|
|
12
|
+
const object = path.get('left.object');
|
|
13
|
+
const property = path.get('left.property');
|
|
14
|
+
|
|
15
|
+
write('mov ');
|
|
16
|
+
write('[');
|
|
17
|
+
traverse(object);
|
|
18
|
+
write(':');
|
|
19
|
+
traverse(property);
|
|
20
|
+
write(']');
|
|
21
|
+
write(',');
|
|
22
|
+
write.space();
|
|
23
|
+
traverse(right);
|
|
24
|
+
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (isMemberExpression(right) && right.node.computed) {
|
|
29
|
+
const {write, traverse} = printer;
|
|
30
|
+
const object = path.get('right.object');
|
|
31
|
+
const property = path.get('right.property');
|
|
32
|
+
|
|
33
|
+
write('mov ');
|
|
34
|
+
traverse(left);
|
|
35
|
+
write(',');
|
|
36
|
+
write.space();
|
|
37
|
+
write('[');
|
|
38
|
+
traverse(object);
|
|
39
|
+
write(':');
|
|
40
|
+
traverse(property);
|
|
41
|
+
write(']');
|
|
42
|
+
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return visitors.AssignmentExpression(path, printer, semantics);
|
|
47
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const {isArray} = Array;
|
|
2
|
+
|
|
3
|
+
const parseArgs = (path) => {
|
|
4
|
+
const argsPath = path.get('arguments');
|
|
5
|
+
|
|
6
|
+
if (!isArray(argsPath))
|
|
7
|
+
return [];
|
|
8
|
+
|
|
9
|
+
return argsPath;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function CallExpression(path, {indent, print, maybe, traverse}) {
|
|
13
|
+
const args = parseArgs(path);
|
|
14
|
+
const isParentCall = tooLong(args) && path.parentPath.isCallExpression();
|
|
15
|
+
|
|
16
|
+
const callee = path.get('callee');
|
|
17
|
+
|
|
18
|
+
traverse(callee);
|
|
19
|
+
|
|
20
|
+
maybe.print.space(args.length);
|
|
21
|
+
|
|
22
|
+
const n = args.length - 1;
|
|
23
|
+
|
|
24
|
+
maybe.indent.inc(isParentCall);
|
|
25
|
+
|
|
26
|
+
for (const [i, arg] of args.entries()) {
|
|
27
|
+
const isObject = arg.isObjectExpression();
|
|
28
|
+
|
|
29
|
+
if (isParentCall && !isObject && n)
|
|
30
|
+
print.breakline();
|
|
31
|
+
|
|
32
|
+
print(arg);
|
|
33
|
+
|
|
34
|
+
if (isParentCall && n) {
|
|
35
|
+
print(',');
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (i < n)
|
|
40
|
+
print(', ');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (isParentCall) {
|
|
44
|
+
indent.dec();
|
|
45
|
+
maybe.print.breakline(n);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function tooLong(args) {
|
|
50
|
+
for (const arg of args) {
|
|
51
|
+
if (arg.isIdentifier() && arg.node.name.length > 10)
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {isNext, exists} from '@putout/printer/is';
|
|
2
|
+
import {isJmpFar, printJmpFar} from './print-jmp-far.js';
|
|
3
|
+
import {isInOut, printInOut} from './print-in-out.js';
|
|
4
|
+
|
|
5
|
+
export const ExpressionStatement = (path, printer) => {
|
|
6
|
+
const {
|
|
7
|
+
maybe,
|
|
8
|
+
print,
|
|
9
|
+
indent,
|
|
10
|
+
traverse,
|
|
11
|
+
} = printer;
|
|
12
|
+
|
|
13
|
+
const expression = path.get('expression');
|
|
14
|
+
|
|
15
|
+
if (isJmpFar(expression)) {
|
|
16
|
+
printJmpFar(expression, printer);
|
|
17
|
+
maybe.print.breakline(isNext(path));
|
|
18
|
+
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (isInOut(expression)) {
|
|
23
|
+
printInOut(expression, printer);
|
|
24
|
+
print.breakline();
|
|
25
|
+
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
indent();
|
|
30
|
+
traverse(expression);
|
|
31
|
+
|
|
32
|
+
const next = path.getNextSibling();
|
|
33
|
+
maybe.print.newline(exists(next));
|
|
34
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {types} from '@putout/babel';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
isCallExpression,
|
|
5
|
+
isMemberExpression,
|
|
6
|
+
} = types;
|
|
7
|
+
|
|
8
|
+
export const isInOut = (expression) => {
|
|
9
|
+
if (!isCallExpression(expression))
|
|
10
|
+
return false;
|
|
11
|
+
|
|
12
|
+
const {callee} = expression.node;
|
|
13
|
+
|
|
14
|
+
if (!isMemberExpression(callee))
|
|
15
|
+
return false;
|
|
16
|
+
|
|
17
|
+
const {object, property} = callee;
|
|
18
|
+
|
|
19
|
+
if (object.name !== 'io')
|
|
20
|
+
return false;
|
|
21
|
+
|
|
22
|
+
return /^(in|out)$/.test(property.name);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function printInOut(path, printer) {
|
|
26
|
+
const {print} = printer;
|
|
27
|
+
const callee = path.get('callee');
|
|
28
|
+
const property = callee.get('property');
|
|
29
|
+
|
|
30
|
+
print(property);
|
|
31
|
+
print(' ');
|
|
32
|
+
const [arg1, arg2] = path.get('arguments');
|
|
33
|
+
|
|
34
|
+
print(arg1);
|
|
35
|
+
print(', ');
|
|
36
|
+
print(arg2);
|
|
37
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {types} from '@putout/babel';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
isCallExpression,
|
|
5
|
+
isMemberExpression,
|
|
6
|
+
} = types;
|
|
7
|
+
|
|
8
|
+
export const isJmpFar = (expression) => {
|
|
9
|
+
if (!isCallExpression(expression))
|
|
10
|
+
return false;
|
|
11
|
+
|
|
12
|
+
const {callee} = expression.node;
|
|
13
|
+
|
|
14
|
+
if (!isMemberExpression(callee))
|
|
15
|
+
return false;
|
|
16
|
+
|
|
17
|
+
const {object, property} = callee;
|
|
18
|
+
|
|
19
|
+
return object.name === 'jmp' && property.name === 'far';
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function printJmpFar(path, printer) {
|
|
23
|
+
const {print} = printer;
|
|
24
|
+
const callee = path.get('callee');
|
|
25
|
+
const [first] = path.node.arguments;
|
|
26
|
+
|
|
27
|
+
print(callee);
|
|
28
|
+
print(' ');
|
|
29
|
+
print(first.value);
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {exists} from '@putout/printer/is';
|
|
2
|
+
|
|
3
|
+
export const LabeledStatement = (path, {print, maybe}) => {
|
|
4
|
+
const prev = path.getPrevSibling();
|
|
5
|
+
const next = path.getNextSibling();
|
|
6
|
+
|
|
7
|
+
maybe.print.breakline(exists(prev));
|
|
8
|
+
|
|
9
|
+
print('__label');
|
|
10
|
+
print(':');
|
|
11
|
+
print.breakline();
|
|
12
|
+
print('__body');
|
|
13
|
+
maybe.print.breakline(exists(next));
|
|
14
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {types} from '@putout/babel';
|
|
2
|
+
|
|
3
|
+
const {isMemberExpression} = types;
|
|
4
|
+
|
|
5
|
+
export const SequenceExpression = (path, {traverse, maybe, write}) => {
|
|
6
|
+
const expressions = path.get('expressions');
|
|
7
|
+
const n = expressions.length - 1;
|
|
8
|
+
|
|
9
|
+
for (const [i, expression] of expressions.entries()) {
|
|
10
|
+
traverse(expression);
|
|
11
|
+
|
|
12
|
+
if (isMemberExpression(expression) || n > 1 && i < n)
|
|
13
|
+
write(',');
|
|
14
|
+
|
|
15
|
+
maybe.write(i < n, ' ');
|
|
16
|
+
}
|
|
17
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export const StringLiteral = (path, {write}, semantics) => {
|
|
2
|
+
const {value, raw = `'${value}'`} = path.node;
|
|
3
|
+
|
|
4
|
+
if (path.parentPath.isJSXAttribute()) {
|
|
5
|
+
write(`"${value}"`);
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const newValue = raw.slice(1, -1);
|
|
10
|
+
write.quote();
|
|
11
|
+
write(maybeEscape(newValue, semantics));
|
|
12
|
+
write.quote();
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const maybeEscape = (value, {escapeDoubleQuote, escapeSingleQuote}) => {
|
|
16
|
+
const list = value.split('');
|
|
17
|
+
const slash = '\\';
|
|
18
|
+
|
|
19
|
+
if (escapeSingleQuote)
|
|
20
|
+
return escape(list, {
|
|
21
|
+
slash,
|
|
22
|
+
quote: `'`,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (escapeDoubleQuote)
|
|
26
|
+
return escape(list, {
|
|
27
|
+
slash,
|
|
28
|
+
quote: `"`,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return value;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const escape = (list, {slash, quote}) => {
|
|
35
|
+
const result = [];
|
|
36
|
+
|
|
37
|
+
for (const [index, char] of list.entries()) {
|
|
38
|
+
const prev = list[index - 1];
|
|
39
|
+
const next = list[index + 1];
|
|
40
|
+
|
|
41
|
+
if (char === slash && next === quote) {
|
|
42
|
+
result.push(quote);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (char === quote && prev !== slash) {
|
|
47
|
+
result.push(`${slash}${char}`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
result.push(char);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return result.join('');
|
|
55
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const maybeTypeAnnotation = (visit) => (path, printer, semantics) => {
|
|
2
|
+
visit(path, printer, semantics);
|
|
3
|
+
|
|
4
|
+
maybePrintTypeAnnotation(path, printer);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export function maybePrintTypeAnnotation(path, printer) {
|
|
8
|
+
const {typeAnnotation} = path.node;
|
|
9
|
+
const {write, traverse} = printer;
|
|
10
|
+
|
|
11
|
+
if (typeAnnotation) {
|
|
12
|
+
write.space();
|
|
13
|
+
traverse(path.get('typeAnnotation'));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const parseParams = (path) => path.get('params');
|
|
2
|
+
|
|
3
|
+
export const printParams = (path, printer, semantics, customization = {}) => {
|
|
4
|
+
const {extra, typeParameters} = path.node;
|
|
5
|
+
const {
|
|
6
|
+
print,
|
|
7
|
+
maybe,
|
|
8
|
+
traverse,
|
|
9
|
+
} = printer;
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
params = parseParams(path),
|
|
13
|
+
braceOpen = '(',
|
|
14
|
+
braceClose = ')',
|
|
15
|
+
printSpace = print.space,
|
|
16
|
+
} = customization;
|
|
17
|
+
|
|
18
|
+
if (typeParameters)
|
|
19
|
+
traverse(path.get('typeParameters'));
|
|
20
|
+
|
|
21
|
+
const n = params.length - 1;
|
|
22
|
+
|
|
23
|
+
for (let i = 0; i <= n; i++) {
|
|
24
|
+
printBraceOpen(path, {
|
|
25
|
+
print,
|
|
26
|
+
braceOpen,
|
|
27
|
+
}, semantics);
|
|
28
|
+
|
|
29
|
+
const isLast = i === n;
|
|
30
|
+
const current = params[i];
|
|
31
|
+
|
|
32
|
+
print('$');
|
|
33
|
+
traverse(current);
|
|
34
|
+
|
|
35
|
+
printBraceClose(path, {
|
|
36
|
+
print,
|
|
37
|
+
braceClose,
|
|
38
|
+
}, semantics);
|
|
39
|
+
|
|
40
|
+
if (!isLast)
|
|
41
|
+
printSpace();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
maybe.print(extra?.trailingComma, ',');
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function printBraceOpen(path, {print, braceOpen}, semantics) {
|
|
48
|
+
if (isOneArgArrow(path) && !semantics.roundBraces.arrow)
|
|
49
|
+
return;
|
|
50
|
+
|
|
51
|
+
return print(braceOpen);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function printBraceClose(path, {print, braceClose}, semantics) {
|
|
55
|
+
if (isOneArgArrow(path) && !semantics.roundBraces.arrow)
|
|
56
|
+
return;
|
|
57
|
+
|
|
58
|
+
print(braceClose);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isOneArgArrow(path) {
|
|
62
|
+
if (path.type !== 'ArrowFunctionExpression')
|
|
63
|
+
return false;
|
|
64
|
+
|
|
65
|
+
const {params} = path.node;
|
|
66
|
+
const [param] = params;
|
|
67
|
+
|
|
68
|
+
if (params.length !== 1)
|
|
69
|
+
return false;
|
|
70
|
+
|
|
71
|
+
return param.type === 'Identifier';
|
|
72
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {print as putoutPrint} from '@putout/printer';
|
|
2
|
+
import {CallExpression} from './visitors/call-expression/call-expression.js';
|
|
3
|
+
import {BlockStatement} from './visitors/block-statement.js';
|
|
4
|
+
import {ExpressionStatement} from './visitors/expression-statement/expression-statement.js';
|
|
5
|
+
import {ExportNamedDeclaration} from './visitors/export-named-declaration.js';
|
|
6
|
+
import {FunctionDeclaration} from './visitors/function-declaration.js';
|
|
7
|
+
import {Program} from './visitors/program.js';
|
|
8
|
+
import {Identifier} from './visitors/identifier.js';
|
|
9
|
+
import {ReturnStatement} from './visitors/return.js';
|
|
10
|
+
import {IfStatement} from './visitors/if-statement.js';
|
|
11
|
+
|
|
12
|
+
export const print = (ast) => {
|
|
13
|
+
return putoutPrint(ast, {
|
|
14
|
+
format: {
|
|
15
|
+
quote: '"',
|
|
16
|
+
},
|
|
17
|
+
semantics: {
|
|
18
|
+
comments: false,
|
|
19
|
+
},
|
|
20
|
+
visitors: {
|
|
21
|
+
ReturnStatement,
|
|
22
|
+
CallExpression,
|
|
23
|
+
BlockStatement,
|
|
24
|
+
IfStatement,
|
|
25
|
+
ExpressionStatement,
|
|
26
|
+
ExportNamedDeclaration,
|
|
27
|
+
FunctionDeclaration,
|
|
28
|
+
Program,
|
|
29
|
+
Identifier,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const isFirstStatement = (path) => path.node.body[0];
|
|
2
|
+
const isFirstDirective = (path) => path.node.directives?.[0];
|
|
3
|
+
|
|
4
|
+
export const BlockStatement = {
|
|
5
|
+
print(path, printer) {
|
|
6
|
+
const {
|
|
7
|
+
indent,
|
|
8
|
+
maybe,
|
|
9
|
+
write,
|
|
10
|
+
traverse,
|
|
11
|
+
} = printer;
|
|
12
|
+
|
|
13
|
+
const body = path.get('body');
|
|
14
|
+
|
|
15
|
+
if (path.parentPath.isBlockStatement())
|
|
16
|
+
indent();
|
|
17
|
+
|
|
18
|
+
indent.inc();
|
|
19
|
+
|
|
20
|
+
if (isFirstStatement(path) || isFirstDirective(path))
|
|
21
|
+
write.newline();
|
|
22
|
+
|
|
23
|
+
for (const element of body) {
|
|
24
|
+
traverse(element);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
indent.dec();
|
|
28
|
+
maybe.indent(body.length);
|
|
29
|
+
|
|
30
|
+
if (path.parentPath.isObjectMethod())
|
|
31
|
+
write(',');
|
|
32
|
+
},
|
|
33
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {types} from '@putout/babel';
|
|
2
|
+
import {isWasmType} from './is-wasm-type.js';
|
|
3
|
+
|
|
4
|
+
const {isIdentifier} = types;
|
|
5
|
+
const {isArray} = Array;
|
|
6
|
+
|
|
7
|
+
const parseArgs = (path) => {
|
|
8
|
+
const argsPath = path.get('arguments');
|
|
9
|
+
|
|
10
|
+
if (!isArray(argsPath))
|
|
11
|
+
return [];
|
|
12
|
+
|
|
13
|
+
return argsPath;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function CallExpression(path, {indent, print, maybe, traverse}) {
|
|
17
|
+
const args = parseArgs(path);
|
|
18
|
+
const n = args.length - 1;
|
|
19
|
+
const isParentCall = path.parentPath.isCallExpression();
|
|
20
|
+
const callee = path.get('callee');
|
|
21
|
+
|
|
22
|
+
print('(');
|
|
23
|
+
|
|
24
|
+
traverse(callee);
|
|
25
|
+
|
|
26
|
+
maybe.print.space(args.length);
|
|
27
|
+
maybe.indent.inc(isParentCall);
|
|
28
|
+
|
|
29
|
+
for (const [i, arg] of args.entries()) {
|
|
30
|
+
const isObject = arg.isObjectExpression();
|
|
31
|
+
|
|
32
|
+
if (isParentCall && !isObject && n)
|
|
33
|
+
print.breakline();
|
|
34
|
+
|
|
35
|
+
if (isIdentifier(arg) && !isWasmType(arg.node.name))
|
|
36
|
+
print('$');
|
|
37
|
+
|
|
38
|
+
print(arg);
|
|
39
|
+
|
|
40
|
+
if (isParentCall && n)
|
|
41
|
+
continue;
|
|
42
|
+
|
|
43
|
+
if (i < n)
|
|
44
|
+
print(' ');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (isParentCall) {
|
|
48
|
+
indent.dec();
|
|
49
|
+
maybe.print.breakline(n);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
print(')');
|
|
53
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {isNext, isPrev} from '@putout/printer/is';
|
|
2
|
+
import {types} from 'putout';
|
|
3
|
+
import {
|
|
4
|
+
isWastImport,
|
|
5
|
+
printWasmImport,
|
|
6
|
+
} from './print-wasm-import.js';
|
|
7
|
+
import {
|
|
8
|
+
isWastMemory,
|
|
9
|
+
printWasmMemory,
|
|
10
|
+
} from './print-wasm-memory.js';
|
|
11
|
+
|
|
12
|
+
const {isFunction} = types;
|
|
13
|
+
|
|
14
|
+
export const ExpressionStatement = (path, printer) => {
|
|
15
|
+
const {print, maybe} = printer;
|
|
16
|
+
|
|
17
|
+
const expression = path.get('expression');
|
|
18
|
+
|
|
19
|
+
if (isWastImport(expression)) {
|
|
20
|
+
printWasmImport(expression, printer);
|
|
21
|
+
maybe.print.breakline(isNext(path));
|
|
22
|
+
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (isWastMemory(expression)) {
|
|
27
|
+
printWasmMemory(expression, printer);
|
|
28
|
+
maybe.print.newline(isNext(path));
|
|
29
|
+
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const surrounded = isNext(path) || isFunction(path.parentPath.parentPath);
|
|
34
|
+
|
|
35
|
+
maybe.indent(surrounded || isPrev(path));
|
|
36
|
+
print('__expression');
|
|
37
|
+
maybe.print.newline(surrounded);
|
|
38
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {types} from '@putout/babel';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
isCallExpression,
|
|
5
|
+
isReturnStatement,
|
|
6
|
+
} = types;
|
|
7
|
+
|
|
8
|
+
export const isWastImport = (expression) => {
|
|
9
|
+
if (!isCallExpression(expression))
|
|
10
|
+
return;
|
|
11
|
+
|
|
12
|
+
const {name} = expression.node.callee;
|
|
13
|
+
|
|
14
|
+
return name === '__ishvara_wasm_import';
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function printWasmImport(path, printer) {
|
|
18
|
+
const {print, maybe} = printer;
|
|
19
|
+
|
|
20
|
+
const [first, second, func] = path.get('arguments');
|
|
21
|
+
|
|
22
|
+
print('(import ');
|
|
23
|
+
|
|
24
|
+
print(first);
|
|
25
|
+
print(' ');
|
|
26
|
+
print(second);
|
|
27
|
+
print(' ');
|
|
28
|
+
print('(func ');
|
|
29
|
+
|
|
30
|
+
const {name: funcName} = func.node.id;
|
|
31
|
+
const funcArgs = func.get('params');
|
|
32
|
+
const returnType = getReturnType(func);
|
|
33
|
+
|
|
34
|
+
print(`$${funcName} `);
|
|
35
|
+
|
|
36
|
+
const n = funcArgs.length - 1;
|
|
37
|
+
|
|
38
|
+
for (const [i, funcArg] of funcArgs.entries()) {
|
|
39
|
+
printParam(funcArg, printer);
|
|
40
|
+
maybe.print.space(i < n);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (returnType) {
|
|
44
|
+
maybe.print.space(funcArgs.length);
|
|
45
|
+
print('(result ');
|
|
46
|
+
print(returnType);
|
|
47
|
+
print(')');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
print(')');
|
|
51
|
+
print(')');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getReturnType(func) {
|
|
55
|
+
const [first] = func.get('body.body');
|
|
56
|
+
|
|
57
|
+
if (!first)
|
|
58
|
+
return null;
|
|
59
|
+
|
|
60
|
+
if (isReturnStatement(first))
|
|
61
|
+
return first.get('argument');
|
|
62
|
+
|
|
63
|
+
return first.get('expression');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function printParam(funcArg, {print}) {
|
|
67
|
+
const {name, typeAnnotation} = funcArg.node;
|
|
68
|
+
|
|
69
|
+
if (!typeAnnotation) {
|
|
70
|
+
print(`(param `);
|
|
71
|
+
print(name);
|
|
72
|
+
print(`)`);
|
|
73
|
+
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
print(`(param `);
|
|
78
|
+
print(`$${name} `);
|
|
79
|
+
print(funcArg.get('typeAnnotation.typeAnnotation'));
|
|
80
|
+
print(`)`);
|
|
81
|
+
}
|