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.
Files changed (45) hide show
  1. package/ChangeLog +846 -0
  2. package/README.md +140 -0
  3. package/bin/ishvara.js +174 -0
  4. package/lib/ishvara.js +29 -0
  5. package/package.json +111 -0
  6. package/packages/compiler-fasm/compiler.js +75 -0
  7. package/packages/compiler-wasm/compiler.js +62 -0
  8. package/packages/operator-wasm/index.js +55 -0
  9. package/packages/optimizer-fasm/optimizer.js +15 -0
  10. package/packages/optimizer-wasm/optimizer.js +13 -0
  11. package/packages/printer-fasm/printer/printer.js +30 -0
  12. package/packages/printer-fasm/printer/visitors/assignment-expression.js +47 -0
  13. package/packages/printer-fasm/printer/visitors/block-statement.js +7 -0
  14. package/packages/printer-fasm/printer/visitors/call-expression.js +56 -0
  15. package/packages/printer-fasm/printer/visitors/expression-statement/expression-statement.js +34 -0
  16. package/packages/printer-fasm/printer/visitors/expression-statement/print-in-out.js +37 -0
  17. package/packages/printer-fasm/printer/visitors/expression-statement/print-jmp-far.js +30 -0
  18. package/packages/printer-fasm/printer/visitors/labeled-statement.js +14 -0
  19. package/packages/printer-fasm/printer/visitors/member-expression.js +5 -0
  20. package/packages/printer-fasm/printer/visitors/sequence-expression.js +17 -0
  21. package/packages/printer-fasm/printer/visitors/string-literal.js +55 -0
  22. package/packages/printer-fasm/printer/visitors/tagged-template-expression.js +4 -0
  23. package/packages/printer-fasm/printer.js +7 -0
  24. package/packages/printer-wasm/printer/maybe-type-annotation.js +15 -0
  25. package/packages/printer-wasm/printer/params.js +72 -0
  26. package/packages/printer-wasm/printer/printer.js +32 -0
  27. package/packages/printer-wasm/printer/visitors/block-statement.js +33 -0
  28. package/packages/printer-wasm/printer/visitors/call-expression/call-expression.js +53 -0
  29. package/packages/printer-wasm/printer/visitors/call-expression/is-wasm-type.js +6 -0
  30. package/packages/printer-wasm/printer/visitors/export-named-declaration.js +3 -0
  31. package/packages/printer-wasm/printer/visitors/expression-statement/expression-statement.js +38 -0
  32. package/packages/printer-wasm/printer/visitors/expression-statement/print-wasm-import.js +81 -0
  33. package/packages/printer-wasm/printer/visitors/expression-statement/print-wasm-memory.js +31 -0
  34. package/packages/printer-wasm/printer/visitors/function-declaration.js +91 -0
  35. package/packages/printer-wasm/printer/visitors/identifier.js +11 -0
  36. package/packages/printer-wasm/printer/visitors/if-statement.js +128 -0
  37. package/packages/printer-wasm/printer/visitors/program.js +26 -0
  38. package/packages/printer-wasm/printer/visitors/return.js +16 -0
  39. package/packages/printer-wasm/printer.js +10 -0
  40. package/packages/test-wasm/test.js +45 -0
  41. package/packages/transformer-fasm/transformer.js +70 -0
  42. package/packages/transformer-wasm/transformer.js +20 -0
  43. package/packages/translator-fasm/dump.js +68 -0
  44. package/packages/translator-fasm/translator.js +15 -0
  45. 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,7 @@
1
+ export const BlockStatement = (path, {traverse}) => {
2
+ const body = path.get('body');
3
+
4
+ for (const element of body) {
5
+ traverse(element);
6
+ }
7
+ };
@@ -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,5 @@
1
+ export const MemberExpression = (path, {print}) => {
2
+ print('__object');
3
+ print(' ');
4
+ print('__property');
5
+ };
@@ -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,4 @@
1
+ export const TaggedTemplateExpression = (path, {write}) => {
2
+ const {value} = path.node.quasi.quasis[0];
3
+ write(value.cooked.trim());
4
+ };
@@ -0,0 +1,7 @@
1
+ import {parse} from 'putout';
2
+ import * as printer from './printer/printer.js';
3
+
4
+ export const print = (source) => {
5
+ const ast = parse(source);
6
+ return printer.print(ast);
7
+ };
@@ -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,6 @@
1
+ const types = [
2
+ 'i32',
3
+ 'i64',
4
+ ];
5
+
6
+ export const isWasmType = (name) => types.includes(name);
@@ -0,0 +1,3 @@
1
+ export const ExportNamedDeclaration = (path, {print}) => {
2
+ print('__declaration');
3
+ };
@@ -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
+ }