goldstein 2.0.0 → 2.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 +7 -0
- package/README.md +21 -2
- package/package.json +1 -1
- package/packages/goldstein/index.js +4 -0
- package/packages/keyword-if/index.js +1 -0
- package/packages/keyword-should/index.js +91 -0
- package/packages/keyword-try/index.js +1 -0
- package/packages/string-interpolation/index.js +65 -0
package/ChangeLog
CHANGED
package/README.md
CHANGED
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
[CoverageURL]: https://coveralls.io/github/coderaiser/goldstein?branch=master
|
|
10
10
|
[CoverageIMGURL]: https://coveralls.io/repos/coderaiser/goldstein/badge.svg?branch=master&service=github
|
|
11
11
|
|
|
12
|
+

|
|
13
|
+
|
|
12
14
|
> *"You haven't a real appreciation of Newspeak, Winston," he said almost sadly. "Even when you write it you're still thinking in Oldspeak. I've read some of those pieces that you write in The Times occasionally. They're good enough, but they're translations. In your heart you'd prefer to stick to Oldspeak, with all its vagueness and its useless shades of meaning. You don't grasp the beauty of the destruction of words. Do you know that Newspeak is the only language in the world whose vocabulary gets smaller every year?"*
|
|
13
15
|
>
|
|
14
16
|
> *(c) “1984”, George Orwell*
|
|
15
17
|
|
|
16
|
-
JavaScript with no limits
|
|
18
|
+
JavaScript with no limits 🤫.
|
|
17
19
|
|
|
18
20
|
Language ruled by the users, [create an issue](https://github.com/coderaiser/goldstein/issues/new/choose) with ideas of a new language construction and what is look like in JavaScript, and most likely we implement it :).
|
|
19
21
|
|
|
@@ -49,7 +51,7 @@ import {compile} from 'goldstein';
|
|
|
49
51
|
|
|
50
52
|
compile(`
|
|
51
53
|
fn hello() {
|
|
52
|
-
guard
|
|
54
|
+
guard text !== "world" else {
|
|
53
55
|
return ""
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -147,6 +149,23 @@ import tryToCatch from 'try-catch';
|
|
|
147
149
|
const [error, result] = await tryToCatch(1, 2, 3);
|
|
148
150
|
```
|
|
149
151
|
|
|
152
|
+
### `should`
|
|
153
|
+
|
|
154
|
+
`should` can be used as an expression (just like [`try`](https://github.com/coderaiser/goldstein/edit/master/README.md#try)).
|
|
155
|
+
This keyword is useful if you want to prevent a function call (also async) to throw an error because you don't need to have any result and the real execution is just optional (so runs if supported).
|
|
156
|
+
|
|
157
|
+
```gs
|
|
158
|
+
should hello()
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Is the same as:
|
|
162
|
+
|
|
163
|
+
```gs
|
|
164
|
+
try hello();
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
> ☝️ *Warning: this feature can be helpful but also dangerous especially if you're debugging your application. In fact, this is made to be used as an optional function call (ex. should load content, but not necessary and knowing this feature is optional), if you call a function in this way while debugging, no error will be printed and the application will continue run as nothing happened.*
|
|
168
|
+
|
|
150
169
|
### `if`
|
|
151
170
|
|
|
152
171
|
You can omit parens. But you must use braces in this case.
|
package/package.json
CHANGED
|
@@ -5,12 +5,16 @@ import {extendParser} from '../parser/index.js';
|
|
|
5
5
|
import keywordFn from '../keyword-fn/index.js';
|
|
6
6
|
import keywordGuard from '../keyword-guard/index.js';
|
|
7
7
|
import keywordTry from '../keyword-try/index.js';
|
|
8
|
+
import keywordShould from '../keyword-should/index.js';
|
|
9
|
+
import stringInterpolation from '../string-interpolation/index.js';
|
|
8
10
|
|
|
9
11
|
export const compile = (source) => {
|
|
10
12
|
const {parse} = extendParser([
|
|
11
13
|
keywordFn,
|
|
12
14
|
keywordGuard,
|
|
13
15
|
keywordTry,
|
|
16
|
+
keywordShould,
|
|
17
|
+
stringInterpolation,
|
|
14
18
|
]);
|
|
15
19
|
|
|
16
20
|
const ast = parse(source);
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {types} from 'putout';
|
|
2
|
+
import {
|
|
3
|
+
addKeyword,
|
|
4
|
+
TokenType,
|
|
5
|
+
tokTypes as tt,
|
|
6
|
+
} from '../operator/index.js';
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
isCallExpression,
|
|
10
|
+
isAwaitExpression,
|
|
11
|
+
} = types;
|
|
12
|
+
|
|
13
|
+
export default function newSpeak(Parser) {
|
|
14
|
+
const {keywordTypes} = Parser.acorn;
|
|
15
|
+
keywordTypes.should = new TokenType('should', {
|
|
16
|
+
keyword: 'should',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return class extends Parser {
|
|
20
|
+
parse() {
|
|
21
|
+
this.keywords = addKeyword('should', this.keywords);
|
|
22
|
+
return super.parse();
|
|
23
|
+
}
|
|
24
|
+
parseStatement(context, topLevel, exports) {
|
|
25
|
+
if (this.type === keywordTypes.should) {
|
|
26
|
+
return this.parseShould();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return super.parseStatement(context, topLevel, exports);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
parseShould() {
|
|
33
|
+
this.next();
|
|
34
|
+
|
|
35
|
+
const node = super.startNode();
|
|
36
|
+
|
|
37
|
+
if (this.type === tt.braceL)
|
|
38
|
+
return this.raise(this.start, `After 'should' only 'await' and 'function call' can come, brakets are not supported`);
|
|
39
|
+
|
|
40
|
+
const expression = this.parseExpression();
|
|
41
|
+
|
|
42
|
+
if (isCallExpression(expression))
|
|
43
|
+
node.expression = {
|
|
44
|
+
type: 'TryStatement',
|
|
45
|
+
block: {
|
|
46
|
+
type: 'BlockStatement',
|
|
47
|
+
body: [{
|
|
48
|
+
type: 'ExpressionStatement',
|
|
49
|
+
expression: {
|
|
50
|
+
type: 'CallExpression',
|
|
51
|
+
callee: expression.callee,
|
|
52
|
+
arguments: expression.arguments.slice(),
|
|
53
|
+
},
|
|
54
|
+
}],
|
|
55
|
+
},
|
|
56
|
+
handler: {
|
|
57
|
+
type: 'CatchClause',
|
|
58
|
+
body: {
|
|
59
|
+
type: 'BlockStatement',
|
|
60
|
+
body: [],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
else if (isAwaitExpression(expression))
|
|
66
|
+
node.expression = {
|
|
67
|
+
type: 'TryStatement',
|
|
68
|
+
block: {
|
|
69
|
+
type: 'BlockStatement',
|
|
70
|
+
body: [{
|
|
71
|
+
type: 'ExpressionStatement',
|
|
72
|
+
expression,
|
|
73
|
+
}],
|
|
74
|
+
},
|
|
75
|
+
handler: {
|
|
76
|
+
type: 'CatchClause',
|
|
77
|
+
body: {
|
|
78
|
+
type: 'BlockStatement',
|
|
79
|
+
body: [],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
else
|
|
85
|
+
this.raise(this.start, `After 'should' only 'await' and 'function call' can come`);
|
|
86
|
+
|
|
87
|
+
return super.finishNode(node, 'ExpressionStatement');
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {template} from 'putout';
|
|
2
|
+
const {assign} = Object;
|
|
3
|
+
|
|
4
|
+
export default function stringInterpolation(Parser) {
|
|
5
|
+
return class extends Parser {
|
|
6
|
+
parseLiteral(value) {
|
|
7
|
+
const chars = value.split('');
|
|
8
|
+
|
|
9
|
+
let literalOpened = false;
|
|
10
|
+
let parenthesis = 0;
|
|
11
|
+
const out = [];
|
|
12
|
+
let isTemplateLiteral = false;
|
|
13
|
+
|
|
14
|
+
for (let [index, char] of chars.entries()) {
|
|
15
|
+
if (char === '(') {
|
|
16
|
+
// keep count of parenthesis
|
|
17
|
+
parenthesis++;
|
|
18
|
+
|
|
19
|
+
// check if previous token was "/" (only if literal is not opened yet)
|
|
20
|
+
const prev = index - 1;
|
|
21
|
+
|
|
22
|
+
if (chars[prev] === '/' && !literalOpened) {
|
|
23
|
+
// set previous char to "$"
|
|
24
|
+
out[prev] = '$';
|
|
25
|
+
// set current char to "{"
|
|
26
|
+
char = '{';
|
|
27
|
+
|
|
28
|
+
// set literalOpened to true
|
|
29
|
+
literalOpened = true;
|
|
30
|
+
// match TemplateLiteral instead of StringLiteral
|
|
31
|
+
isTemplateLiteral = true;
|
|
32
|
+
}
|
|
33
|
+
} else if (char === ')') {
|
|
34
|
+
parenthesis--;
|
|
35
|
+
|
|
36
|
+
if (parenthesis === 0 && literalOpened) {
|
|
37
|
+
char = '}';
|
|
38
|
+
|
|
39
|
+
// reset literalOpened to false
|
|
40
|
+
literalOpened = false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
out.push(char);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (isTemplateLiteral) {
|
|
48
|
+
const node = this.startNode();
|
|
49
|
+
this.next();
|
|
50
|
+
|
|
51
|
+
const {quasis, expressions} = template.ast('`' + out.join('') + '`');
|
|
52
|
+
|
|
53
|
+
assign(node, {
|
|
54
|
+
quasis,
|
|
55
|
+
expressions,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return this.finishNode(node, 'TemplateLiteral');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return super.parseLiteral(out.join(''));
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|