Spaces:
Runtime error
Runtime error
File size: 2,481 Bytes
b5ea024 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# code-red
Experimental toolkit for writing x-to-JavaScript compilers. It is used in [Svelte](https://svelte.dev).
## API
The `code-red` package exposes three core functions — `b`, `x` and `print`.
`b` and `x` take a template literal and return an [ESTree](https://github.com/estree/estree) program body, or a single node:
```js
import { b, x } from 'code-red';
const expression = x`i + j`;
assert.equal(expression.type, 'AssignmentExpression');
assert.equal(expression.operator, '+');
assert.equal(expression.left.name, 'i');
assert.equal(expression.right.name, 'j');
const body = b`
const i = 1;
const j = 2;
const k = i + j;
`;
assert.equal(body.length, 3);
assert.equal(body[0].type, 'VariableDeclaration');
```
Expressions in template literals correspond to replacement nodes — so you could express the above like so:
```js
const i = x`i`;
const j = x`j`;
const expression = x`${i} + ${j}`;
const body = b`
const ${i} = 1;
const ${j} = 2;
const k = ${expression};
`;
```
The `print` function takes a node and turns it into a `{code, map}` object:
```js
const add = x`
function add(${i}, ${j}) {
return ${expression};
}
`;
print(add).code;
/*
function add(i, j) {
return i + j;
}
*/
i.name = 'foo';
j.name = 'bar';
print(add).code;
/*
function add(foo, bar) {
return foo + bar;
}
*/
```
## Prefixes
### `@`-prefixed names (replaceable globals)
So that you can use globals in your code. In Svelte, we use this to insert utility functions.
```js
// input
import { x } from 'code-red';
x`@foo(bar)`
// output
FOO(bar)
```
### `#`-prefixed names (automatically deconflicted names)
So that you can insert variables in your code without worrying if they clash with existing variable names.
`bar` used in user code and in inserted code gets a `$1` suffix:
```js
// input
import { x } from 'code-red';
x`
function foo(#bar) {
return #bar * bar;
}`;
// output
function foo(bar$1) {
return bar$1 * bar;
}
```
Without conflicts, no `$1` suffix:
```js
// input
import { b } from 'code-red';
b`const foo = #bar => #bar * 2`;
// output
const foo = bar => bar * 2;
```
## Optimiser
TODO add an optimiser that e.g. collapses consecutive identical if blocks
## Compiler
TODO add a `code-red/compiler` module that replaces template literals with the nodes they evaluate to, so that there's nothing to parse at runtime.
## Sourcemaps
TODO support source mappings for inserted nodes with location information.
## License
[MIT](LICENSE)
|