epoxylang 0.1.10 → 0.1.12
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/epoxy-vs-code/epoxy-language-0.1.0.vsix +0 -0
- package/epoxy-vs-code/language-configuration.json +86 -0
- package/epoxy-vs-code/package.json +28 -0
- package/epoxy-vs-code/syntaxes/epoxy.tmLanguage.json +280 -0
- package/examples/hybrid.epx +19 -11
- package/examples/method_test.epx +48 -0
- package/examples/square.epx +4 -0
- package/package.json +1 -1
- package/src/generator/jsgenerator.js +137 -1
- package/src/lexer/lexer.js +6 -1
- package/src/lexer/tokens.js +7 -0
- package/src/parser/ast.js +21 -1
- package/src/parser/parser.js +106 -3
- package/src/runtime/runner.js +13 -23
- package/src/test.js +6 -21
|
Binary file
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comments": {
|
|
3
|
+
"lineComment": "$"
|
|
4
|
+
},
|
|
5
|
+
"brackets": [
|
|
6
|
+
[
|
|
7
|
+
"{",
|
|
8
|
+
"}"
|
|
9
|
+
],
|
|
10
|
+
[
|
|
11
|
+
"[",
|
|
12
|
+
"]"
|
|
13
|
+
],
|
|
14
|
+
[
|
|
15
|
+
"(",
|
|
16
|
+
")"
|
|
17
|
+
]
|
|
18
|
+
],
|
|
19
|
+
"autoClosingPairs": [
|
|
20
|
+
{
|
|
21
|
+
"open": "{",
|
|
22
|
+
"close": "}"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"open": "[",
|
|
26
|
+
"close": "]"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"open": "(",
|
|
30
|
+
"close": ")"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"open": "\"",
|
|
34
|
+
"close": "\""
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"open": "'",
|
|
38
|
+
"close": "'"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"open": "`",
|
|
42
|
+
"close": "`"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"open": "@js :~",
|
|
46
|
+
"close": "~:"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"surroundingPairs": [
|
|
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
|
+
"folding": {
|
|
76
|
+
"markers": {
|
|
77
|
+
"start": "^\\s*\\{",
|
|
78
|
+
"end": "^\\s*\\}"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)",
|
|
82
|
+
"indentationRules": {
|
|
83
|
+
"increaseIndentPattern": "^.*\\{[^}]*$",
|
|
84
|
+
"decreaseIndentPattern": "^\\s*\\}"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "epoxy-language",
|
|
3
|
+
"displayName": "Epoxy Language",
|
|
4
|
+
"description": "Syntax highlighting for the Epoxy programming language",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"publisher": "iamsatyanchal",
|
|
7
|
+
"engines": {
|
|
8
|
+
"vscode": "^1.75.0"
|
|
9
|
+
},
|
|
10
|
+
"categories": ["Programming Languages"],
|
|
11
|
+
"contributes": {
|
|
12
|
+
"languages": [
|
|
13
|
+
{
|
|
14
|
+
"id": "epoxy",
|
|
15
|
+
"aliases": ["Epoxy", "epx"],
|
|
16
|
+
"extensions": [".epx"],
|
|
17
|
+
"configuration": "./language-configuration.json"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"grammars": [
|
|
21
|
+
{
|
|
22
|
+
"language": "epoxy",
|
|
23
|
+
"scopeName": "source.epoxy",
|
|
24
|
+
"path": "./syntaxes/epoxy.tmLanguage.json"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
|
3
|
+
"name": "Epoxy",
|
|
4
|
+
"scopeName": "source.epoxy",
|
|
5
|
+
"patterns": [
|
|
6
|
+
{ "include": "#comments" },
|
|
7
|
+
{ "include": "#raw-js-block" },
|
|
8
|
+
{ "include": "#keywords" },
|
|
9
|
+
{ "include": "#types" },
|
|
10
|
+
{ "include": "#constants" },
|
|
11
|
+
{ "include": "#strings" },
|
|
12
|
+
{ "include": "#numbers" },
|
|
13
|
+
{ "include": "#operators" },
|
|
14
|
+
{ "include": "#punctuation" },
|
|
15
|
+
{ "include": "#special-input" },
|
|
16
|
+
{ "include": "#function-declaration" },
|
|
17
|
+
{ "include": "#function-call" },
|
|
18
|
+
{ "include": "#identifiers" }
|
|
19
|
+
],
|
|
20
|
+
"repository": {
|
|
21
|
+
"comments": {
|
|
22
|
+
"patterns": [
|
|
23
|
+
{
|
|
24
|
+
"name": "comment.line.dollar.epoxy",
|
|
25
|
+
"match": "\\$.*$",
|
|
26
|
+
"captures": {
|
|
27
|
+
"0": { "name": "punctuation.definition.comment.epoxy" }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"raw-js-block": {
|
|
33
|
+
"patterns": [
|
|
34
|
+
{
|
|
35
|
+
"name": "meta.embedded.block.javascript",
|
|
36
|
+
"begin": "(@js)\\s*(:~)",
|
|
37
|
+
"end": "(~:)",
|
|
38
|
+
"beginCaptures": {
|
|
39
|
+
"1": { "name": "keyword.control.js.epoxy" },
|
|
40
|
+
"2": { "name": "punctuation.definition.js-block.begin.epoxy" }
|
|
41
|
+
},
|
|
42
|
+
"endCaptures": {
|
|
43
|
+
"1": { "name": "punctuation.definition.js-block.end.epoxy" }
|
|
44
|
+
},
|
|
45
|
+
"patterns": [
|
|
46
|
+
{ "include": "source.js" }
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
"keywords": {
|
|
52
|
+
"patterns": [
|
|
53
|
+
{
|
|
54
|
+
"name": "keyword.control.flow.epoxy",
|
|
55
|
+
"match": "\\b(check|alt|repeat|until|give)\\b"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "keyword.control.loop.epoxy",
|
|
59
|
+
"match": "\\b(in|to)\\b"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "keyword.declaration.epoxy",
|
|
63
|
+
"match": "\\b(assign|store|make|update)\\b"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "keyword.modifier.epoxy",
|
|
67
|
+
"match": "\\b(all|fix)\\b"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "keyword.other.epoxy",
|
|
71
|
+
"match": "\\b(call|show|as)\\b"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"name": "keyword.operator.logical.epoxy",
|
|
75
|
+
"match": "\\b(and|or)\\b"
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
"types": {
|
|
80
|
+
"patterns": [
|
|
81
|
+
{
|
|
82
|
+
"name": "storage.type.epoxy",
|
|
83
|
+
"match": "\\b(int|double|string|bool|array|object)\\b"
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
"constants": {
|
|
88
|
+
"patterns": [
|
|
89
|
+
{
|
|
90
|
+
"name": "constant.language.boolean.true.epoxy",
|
|
91
|
+
"match": "\\btrue\\b"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "constant.language.boolean.false.epoxy",
|
|
95
|
+
"match": "\\bfalse\\b"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"name": "constant.language.null.epoxy",
|
|
99
|
+
"match": "\\bnull\\b"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "constant.language.undefined.epoxy",
|
|
103
|
+
"match": "\\bundefined\\b"
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
"strings": {
|
|
108
|
+
"patterns": [
|
|
109
|
+
{
|
|
110
|
+
"name": "string.quoted.backtick.epoxy",
|
|
111
|
+
"begin": "`",
|
|
112
|
+
"end": "`",
|
|
113
|
+
"patterns": [
|
|
114
|
+
{
|
|
115
|
+
"name": "meta.interpolation.epoxy",
|
|
116
|
+
"begin": "\\[",
|
|
117
|
+
"end": "\\]",
|
|
118
|
+
"beginCaptures": {
|
|
119
|
+
"0": { "name": "punctuation.definition.interpolation.begin.epoxy" }
|
|
120
|
+
},
|
|
121
|
+
"endCaptures": {
|
|
122
|
+
"0": { "name": "punctuation.definition.interpolation.end.epoxy" }
|
|
123
|
+
},
|
|
124
|
+
"patterns": [
|
|
125
|
+
{ "include": "#identifiers" },
|
|
126
|
+
{ "include": "#function-call" },
|
|
127
|
+
{ "include": "#array-access" },
|
|
128
|
+
{ "include": "#numbers" }
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"name": "constant.character.escape.epoxy",
|
|
133
|
+
"match": "\\\\."
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"name": "string.quoted.double.epoxy",
|
|
139
|
+
"begin": "\"",
|
|
140
|
+
"end": "\"",
|
|
141
|
+
"patterns": [
|
|
142
|
+
{
|
|
143
|
+
"name": "constant.character.escape.epoxy",
|
|
144
|
+
"match": "\\\\."
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "string.quoted.single.epoxy",
|
|
150
|
+
"begin": "'",
|
|
151
|
+
"end": "'",
|
|
152
|
+
"patterns": [
|
|
153
|
+
{
|
|
154
|
+
"name": "constant.character.escape.epoxy",
|
|
155
|
+
"match": "\\\\."
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
"numbers": {
|
|
162
|
+
"patterns": [
|
|
163
|
+
{
|
|
164
|
+
"name": "constant.numeric.decimal.epoxy",
|
|
165
|
+
"match": "\\b\\d+\\.\\d+\\b"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"name": "constant.numeric.integer.epoxy",
|
|
169
|
+
"match": "\\b\\d+\\b"
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
"operators": {
|
|
174
|
+
"patterns": [
|
|
175
|
+
{
|
|
176
|
+
"name": "keyword.operator.comparison.epoxy",
|
|
177
|
+
"match": "(===|!==|==|!=|>=|<=|>|<)"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"name": "keyword.operator.arithmetic.epoxy",
|
|
181
|
+
"match": "(\\+|\\-|\\*|\\/)"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"name": "keyword.operator.assignment.epoxy",
|
|
185
|
+
"match": "="
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
},
|
|
189
|
+
"punctuation": {
|
|
190
|
+
"patterns": [
|
|
191
|
+
{
|
|
192
|
+
"name": "punctuation.terminator.statement.epoxy",
|
|
193
|
+
"match": ";"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"name": "punctuation.separator.comma.epoxy",
|
|
197
|
+
"match": ","
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"name": "punctuation.section.block.begin.epoxy",
|
|
201
|
+
"match": "\\{"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"name": "punctuation.section.block.end.epoxy",
|
|
205
|
+
"match": "\\}"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"name": "punctuation.section.brackets.begin.epoxy",
|
|
209
|
+
"match": "\\["
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"name": "punctuation.section.brackets.end.epoxy",
|
|
213
|
+
"match": "\\]"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"name": "punctuation.section.parens.begin.epoxy",
|
|
217
|
+
"match": "\\("
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"name": "punctuation.section.parens.end.epoxy",
|
|
221
|
+
"match": "\\)"
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
"special-input": {
|
|
226
|
+
"patterns": [
|
|
227
|
+
{
|
|
228
|
+
"name": "variable.language.input.epoxy",
|
|
229
|
+
"match": ":input\\b"
|
|
230
|
+
}
|
|
231
|
+
]
|
|
232
|
+
},
|
|
233
|
+
"function-declaration": {
|
|
234
|
+
"patterns": [
|
|
235
|
+
{
|
|
236
|
+
"name": "meta.function.epoxy",
|
|
237
|
+
"match": "\\b(make)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*(\\[)",
|
|
238
|
+
"captures": {
|
|
239
|
+
"1": { "name": "keyword.declaration.epoxy" },
|
|
240
|
+
"2": { "name": "entity.name.function.epoxy" },
|
|
241
|
+
"3": { "name": "punctuation.section.brackets.begin.epoxy" }
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
},
|
|
246
|
+
"function-call": {
|
|
247
|
+
"patterns": [
|
|
248
|
+
{
|
|
249
|
+
"name": "meta.function-call.epoxy",
|
|
250
|
+
"match": "\\b(call)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*(\\[)",
|
|
251
|
+
"captures": {
|
|
252
|
+
"1": { "name": "keyword.other.epoxy" },
|
|
253
|
+
"2": { "name": "entity.name.function.epoxy" },
|
|
254
|
+
"3": { "name": "punctuation.section.brackets.begin.epoxy" }
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
]
|
|
258
|
+
},
|
|
259
|
+
"array-access": {
|
|
260
|
+
"patterns": [
|
|
261
|
+
{
|
|
262
|
+
"name": "meta.array-access.epoxy",
|
|
263
|
+
"match": "([a-zA-Z_][a-zA-Z0-9_]*)\\s*(\\{)",
|
|
264
|
+
"captures": {
|
|
265
|
+
"1": { "name": "variable.other.epoxy" },
|
|
266
|
+
"2": { "name": "punctuation.section.braces.begin.epoxy" }
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
},
|
|
271
|
+
"identifiers": {
|
|
272
|
+
"patterns": [
|
|
273
|
+
{
|
|
274
|
+
"name": "variable.other.epoxy",
|
|
275
|
+
"match": "\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
package/examples/hybrid.epx
CHANGED
|
@@ -3,16 +3,24 @@ assign numbers as array = {};
|
|
|
3
3
|
repeat[x in 0 to 4, 1]{
|
|
4
4
|
show "Enter a number: ";
|
|
5
5
|
assign num_insert = :input;
|
|
6
|
-
|
|
7
|
-
numbers.push(num_insert);
|
|
8
|
-
~:
|
|
6
|
+
method:array numbers.append[num_insert];
|
|
9
7
|
}
|
|
10
8
|
show "The numbers you entered are: " + numbers;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
$ make test[name]{
|
|
14
|
+
$ all assign ok as string = :input;
|
|
15
|
+
$ fix assign tes as int = 3.14159;
|
|
16
|
+
$ store bubu = `[ok] and tes is [tes]`;
|
|
17
|
+
$ give bubu;
|
|
18
|
+
$ }
|
|
19
|
+
$ repeat[i in numbers]{
|
|
20
|
+
$ assign n as int = numbers{i};
|
|
21
|
+
$ @js :~
|
|
22
|
+
$ if(n % 2 == 0){
|
|
23
|
+
$ console.log(n);
|
|
24
|
+
$ }
|
|
25
|
+
$ ~:
|
|
26
|
+
$ }
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
$ Test array methods
|
|
2
|
+
assign numbers as array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
3
|
+
show "Original array:";
|
|
4
|
+
show numbers;
|
|
5
|
+
|
|
6
|
+
$ Test filter with lambda and modulo
|
|
7
|
+
assign evens as array = method:array numbers.filter[call [x] -> x % 2 == 0];
|
|
8
|
+
show "Even numbers (filter):";
|
|
9
|
+
show evens;
|
|
10
|
+
|
|
11
|
+
$ Test map with lambda
|
|
12
|
+
assign doubled as array = method:array numbers.map[call [x] -> x * 2];
|
|
13
|
+
show "Doubled numbers (map):";
|
|
14
|
+
show doubled;
|
|
15
|
+
|
|
16
|
+
$ Test slice - reverse array (note: slice takes string literal)
|
|
17
|
+
assign reversed as array = method:array numbers.slice["::-1"];
|
|
18
|
+
show "Reversed array:";
|
|
19
|
+
show reversed;
|
|
20
|
+
|
|
21
|
+
$ Test slice - every 2nd element
|
|
22
|
+
assign everynd as array = method:array numbers.slice["::2"];
|
|
23
|
+
show "Every 2nd element:";
|
|
24
|
+
show everynd;
|
|
25
|
+
|
|
26
|
+
$ Test slice - range
|
|
27
|
+
assign range as array = method:array numbers.slice["2:5"];
|
|
28
|
+
show "Elements 2-4:";
|
|
29
|
+
show range;
|
|
30
|
+
|
|
31
|
+
$ Test string methods
|
|
32
|
+
assign message as string = "Hello World";
|
|
33
|
+
assign upper as string = method:string message.upper[];
|
|
34
|
+
show "Uppercase:";
|
|
35
|
+
show upper;
|
|
36
|
+
|
|
37
|
+
assign lower as string = method:string message.lower[];
|
|
38
|
+
show "Lowercase:";
|
|
39
|
+
show lower;
|
|
40
|
+
show method:string lower.size[];
|
|
41
|
+
show method:string lower.replace["world", "epoxy"];
|
|
42
|
+
|
|
43
|
+
$ Test modulo operator
|
|
44
|
+
assign remainder as int = 17 % 5;
|
|
45
|
+
assign okko as double = 3.14;
|
|
46
|
+
show okko;
|
|
47
|
+
show "17 % 5 =";
|
|
48
|
+
show remainder;
|
package/examples/square.epx
CHANGED
|
@@ -2,8 +2,12 @@ make square[n] {
|
|
|
2
2
|
give n * n;
|
|
3
3
|
}
|
|
4
4
|
assign nums as array = {2, 4, 6};
|
|
5
|
+
assign ok as string;
|
|
5
6
|
repeat[x in nums]{
|
|
6
7
|
assign result as int = call square[nums{x}]; $ yaha pe comment dal rhe hai bhaii..
|
|
8
|
+
$ assign add as int = call [x,y] -> give x +y
|
|
7
9
|
store msg = `square of [nums{x}] is [result]`;
|
|
8
10
|
show msg;
|
|
9
11
|
}
|
|
12
|
+
update ok = :input;
|
|
13
|
+
show ok;
|
package/package.json
CHANGED
|
@@ -35,6 +35,8 @@ class JSCodeGenerator {
|
|
|
35
35
|
case "RepeatUntil": return this.visitRepeatUntil(node);
|
|
36
36
|
case "ArrayLiteral": return this.visitArrayLiteral(node);
|
|
37
37
|
case "ArrayAccess": return this.visitArrayAccess(node);
|
|
38
|
+
case "MethodCall": return this.visitMethodCall(node);
|
|
39
|
+
case "LambdaExpression": return this.visitLambdaExpression(node);
|
|
38
40
|
default:
|
|
39
41
|
throw new Error("Unknown AST node: " + node.type);
|
|
40
42
|
}
|
|
@@ -91,7 +93,7 @@ class JSCodeGenerator {
|
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
visitInputExpression(node) {
|
|
94
|
-
return "
|
|
96
|
+
return "input_of_epoxy_lang_dont_use_this_name()";
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
convertInterpolation(text) {
|
|
@@ -243,6 +245,140 @@ ${body}
|
|
|
243
245
|
} while (!(${condition}));`.trim();
|
|
244
246
|
}
|
|
245
247
|
|
|
248
|
+
visitMethodCall(node) {
|
|
249
|
+
const target = node.target;
|
|
250
|
+
const methodName = node.methodName;
|
|
251
|
+
const args = node.args;
|
|
252
|
+
|
|
253
|
+
// Array methods
|
|
254
|
+
if (node.targetType === "array") {
|
|
255
|
+
switch (methodName) {
|
|
256
|
+
case "append":
|
|
257
|
+
// .append[value] -> .push(value)
|
|
258
|
+
if (args.length !== 1) {
|
|
259
|
+
throw new Error("append requires exactly 1 argument");
|
|
260
|
+
}
|
|
261
|
+
return `${target}.push(${this.visit(args[0])})`;
|
|
262
|
+
|
|
263
|
+
case "pop":
|
|
264
|
+
// .pop[] -> .pop()
|
|
265
|
+
return `${target}.pop()`;
|
|
266
|
+
|
|
267
|
+
case "includes":
|
|
268
|
+
// .includes[value] -> .includes(value)
|
|
269
|
+
if (args.length !== 1) {
|
|
270
|
+
throw new Error("includes requires exactly 1 argument");
|
|
271
|
+
}
|
|
272
|
+
return `${target}.includes(${this.visit(args[0])})`;
|
|
273
|
+
|
|
274
|
+
case "filter":
|
|
275
|
+
// .filter[call [x] -> x % 2 == 0] -> .filter((x) => x % 2 === 0)
|
|
276
|
+
if (args.length !== 1) {
|
|
277
|
+
throw new Error("filter requires exactly 1 argument (lambda function)");
|
|
278
|
+
}
|
|
279
|
+
return `${target}.filter(${this.visit(args[0])})`;
|
|
280
|
+
|
|
281
|
+
case "map":
|
|
282
|
+
// .map[call [x] -> x * 2] -> .map((x) => x * 2)
|
|
283
|
+
if (args.length !== 1) {
|
|
284
|
+
throw new Error("map requires exactly 1 argument (lambda function)");
|
|
285
|
+
}
|
|
286
|
+
return `${target}.map(${this.visit(args[0])})`;
|
|
287
|
+
|
|
288
|
+
case "join":
|
|
289
|
+
// .join[separator] -> .join(separator) or .join() for default
|
|
290
|
+
if (args.length === 0) {
|
|
291
|
+
return `${target}.join()`;
|
|
292
|
+
} else if (args.length === 1) {
|
|
293
|
+
return `${target}.join(${this.visit(args[0])})`;
|
|
294
|
+
} else {
|
|
295
|
+
throw new Error("join requires 0 or 1 argument");
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
case "slice":
|
|
299
|
+
// .slice[pythonSlice] -> .slice(start, end)
|
|
300
|
+
if (args.length !== 1) {
|
|
301
|
+
throw new Error("slice requires exactly 1 argument (slice notation)");
|
|
302
|
+
}
|
|
303
|
+
return this.convertPythonSlice(target, args[0]);
|
|
304
|
+
|
|
305
|
+
default:
|
|
306
|
+
throw new Error(`Unknown array method: ${methodName}`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// String methods
|
|
311
|
+
if (node.targetType === "string") {
|
|
312
|
+
switch (methodName) {
|
|
313
|
+
case "upper":
|
|
314
|
+
// .upper[] -> .toUpperCase()
|
|
315
|
+
return `${target}.toUpperCase()`;
|
|
316
|
+
|
|
317
|
+
case "lower":
|
|
318
|
+
// .lower[] -> .toLowerCase()
|
|
319
|
+
return `${target}.toLowerCase()`;
|
|
320
|
+
|
|
321
|
+
case "size":
|
|
322
|
+
// .size[] -> .length
|
|
323
|
+
return `${target}.length`;
|
|
324
|
+
|
|
325
|
+
case "includes":
|
|
326
|
+
// .includes[value] -> .includes(value)
|
|
327
|
+
if (args.length !== 1) {
|
|
328
|
+
throw new Error("includes requires exactly 1 argument");
|
|
329
|
+
}
|
|
330
|
+
return `${target}.includes(${this.visit(args[0])})`;
|
|
331
|
+
|
|
332
|
+
case "replace":
|
|
333
|
+
// .replace["old" with "new"] -> .replace("old", "new")
|
|
334
|
+
if (args.length !== 2) {
|
|
335
|
+
throw new Error("replace requires exactly 2 arguments (old, new)");
|
|
336
|
+
}
|
|
337
|
+
return `${target}.replace(${this.visit(args[0])}, ${this.visit(args[1])})`;
|
|
338
|
+
|
|
339
|
+
default:
|
|
340
|
+
throw new Error(`Unknown string method: ${methodName}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
throw new Error(`Unknown target type: ${node.targetType}`);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
visitLambdaExpression(node) {
|
|
348
|
+
// Convert lambda to arrow function: call [x] -> x % 2 == 0 => (x) => x % 2 === 0
|
|
349
|
+
const params = node.params.join(", ");
|
|
350
|
+
const body = this.visit(node.body);
|
|
351
|
+
return `(${params}) => ${body}`;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
convertPythonSlice(target, sliceExpr) {
|
|
355
|
+
// Handle Python-style slicing: ::2, 2:5, ::-1
|
|
356
|
+
// This is a simplified version - you'd need to parse the slice notation
|
|
357
|
+
// For now, let's assume sliceExpr is a string literal
|
|
358
|
+
|
|
359
|
+
if (sliceExpr.type === "Literal" && typeof sliceExpr.value === "string") {
|
|
360
|
+
const slice = sliceExpr.value;
|
|
361
|
+
|
|
362
|
+
// Parse slice notation
|
|
363
|
+
if (slice === "::-1") {
|
|
364
|
+
// Reverse array
|
|
365
|
+
return `${target}.slice().reverse();`;
|
|
366
|
+
} else if (slice.startsWith("::")) {
|
|
367
|
+
// Every nth element
|
|
368
|
+
const step = parseInt(slice.substring(2));
|
|
369
|
+
return `${target}.filter((_, i) => i % ${step} === 0);`;
|
|
370
|
+
} else if (slice.includes(":")) {
|
|
371
|
+
// Range slice
|
|
372
|
+
const parts = slice.split(":");
|
|
373
|
+
const start = parts[0] || "0";
|
|
374
|
+
const end = parts[1] || `${target}.length`;
|
|
375
|
+
return `${target}.slice(${start}, ${end});`;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
throw new Error("Invalid slice notation");
|
|
380
|
+
}
|
|
381
|
+
|
|
246
382
|
}
|
|
247
383
|
|
|
248
384
|
export { JSCodeGenerator };
|
package/src/lexer/lexer.js
CHANGED
|
@@ -170,6 +170,7 @@ class Lexer {
|
|
|
170
170
|
// Not :input, restore position
|
|
171
171
|
this.pos = saved;
|
|
172
172
|
this.current = this.input[this.pos];
|
|
173
|
+
// If not :input, fall through to handle : as COLON token
|
|
173
174
|
}
|
|
174
175
|
|
|
175
176
|
// double-char operators
|
|
@@ -178,6 +179,7 @@ class Lexer {
|
|
|
178
179
|
if (twoChar === "!=") { this.advance(); this.advance(); return new Token(TokenType.NOTEQ); }
|
|
179
180
|
if (twoChar === ">=") { this.advance(); this.advance(); return new Token(TokenType.GTE); }
|
|
180
181
|
if (twoChar === "<=") { this.advance(); this.advance(); return new Token(TokenType.LTE); }
|
|
182
|
+
if (twoChar === "->") { this.advance(); this.advance(); return new Token(TokenType.ARROW); }
|
|
181
183
|
|
|
182
184
|
// single-char
|
|
183
185
|
const single = {
|
|
@@ -186,6 +188,7 @@ class Lexer {
|
|
|
186
188
|
"-": TokenType.MINUS,
|
|
187
189
|
"*": TokenType.STAR,
|
|
188
190
|
"/": TokenType.SLASH,
|
|
191
|
+
"%": TokenType.MODULO,
|
|
189
192
|
">": TokenType.GT,
|
|
190
193
|
"<": TokenType.LT,
|
|
191
194
|
"{": TokenType.LBRACE,
|
|
@@ -195,7 +198,9 @@ class Lexer {
|
|
|
195
198
|
"(": TokenType.LPAREN,
|
|
196
199
|
")": TokenType.RPAREN,
|
|
197
200
|
";": TokenType.SEMICOLON,
|
|
198
|
-
",": TokenType.COMMA
|
|
201
|
+
",": TokenType.COMMA,
|
|
202
|
+
".": TokenType.DOT,
|
|
203
|
+
":": TokenType.COLON
|
|
199
204
|
};
|
|
200
205
|
|
|
201
206
|
if (single[this.current]) {
|
package/src/lexer/tokens.js
CHANGED
|
@@ -18,6 +18,7 @@ const TokenType = {
|
|
|
18
18
|
AND: "AND",
|
|
19
19
|
AS: "AS",
|
|
20
20
|
SHOW: "SHOW",
|
|
21
|
+
METHOD: "METHOD",
|
|
21
22
|
|
|
22
23
|
// datatypes
|
|
23
24
|
TYPE: "TYPE",
|
|
@@ -41,12 +42,14 @@ const TokenType = {
|
|
|
41
42
|
MINUS: "MINUS",
|
|
42
43
|
STAR: "STAR",
|
|
43
44
|
SLASH: "SLASH",
|
|
45
|
+
MODULO: "MODULO",
|
|
44
46
|
GT: "GT",
|
|
45
47
|
LT: "LT",
|
|
46
48
|
GTE: "GTE",
|
|
47
49
|
LTE: "LTE",
|
|
48
50
|
EQEQ: "EQEQ",
|
|
49
51
|
NOTEQ: "NOTEQ",
|
|
52
|
+
ARROW: "ARROW",
|
|
50
53
|
|
|
51
54
|
// symbols
|
|
52
55
|
LBRACE: "LBRACE",
|
|
@@ -57,6 +60,8 @@ const TokenType = {
|
|
|
57
60
|
RPAREN: "RPAREN",
|
|
58
61
|
SEMICOLON: "SEMICOLON",
|
|
59
62
|
COMMA: "COMMA",
|
|
63
|
+
DOT: "DOT",
|
|
64
|
+
COLON: "COLON",
|
|
60
65
|
|
|
61
66
|
EOF: "EOF"
|
|
62
67
|
};
|
|
@@ -88,6 +93,7 @@ const KEYWORDS = {
|
|
|
88
93
|
and: TokenType.AND,
|
|
89
94
|
as: TokenType.AS,
|
|
90
95
|
show: TokenType.SHOW,
|
|
96
|
+
method: TokenType.METHOD,
|
|
91
97
|
};
|
|
92
98
|
|
|
93
99
|
const TYPES = [
|
|
@@ -106,6 +112,7 @@ const OP_MAP = {
|
|
|
106
112
|
MINUS: "-",
|
|
107
113
|
STAR: "*",
|
|
108
114
|
SLASH: "/",
|
|
115
|
+
MODULO: "%",
|
|
109
116
|
GT: ">",
|
|
110
117
|
LT: "<",
|
|
111
118
|
GTE: ">=",
|
package/src/parser/ast.js
CHANGED
|
@@ -145,6 +145,24 @@ class InputExpression {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
class MethodCall {
|
|
149
|
+
constructor(targetType, target, methodName, args) {
|
|
150
|
+
this.type = "MethodCall";
|
|
151
|
+
this.targetType = targetType; // "array" or "string"
|
|
152
|
+
this.target = target; // variable name (Identifier or expression)
|
|
153
|
+
this.methodName = methodName; // method name like "append", "upper"
|
|
154
|
+
this.args = args; // array of argument expressions
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
class LambdaExpression {
|
|
159
|
+
constructor(params, body) {
|
|
160
|
+
this.type = "LambdaExpression";
|
|
161
|
+
this.params = params; // array of parameter names
|
|
162
|
+
this.body = body; // expression
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
148
166
|
export {
|
|
149
167
|
Program,
|
|
150
168
|
AssignStatement,
|
|
@@ -163,5 +181,7 @@ export {
|
|
|
163
181
|
ShowStatement,
|
|
164
182
|
RepeatFor,
|
|
165
183
|
RawJSBlock,
|
|
166
|
-
InputExpression
|
|
184
|
+
InputExpression,
|
|
185
|
+
MethodCall,
|
|
186
|
+
LambdaExpression
|
|
167
187
|
};
|
package/src/parser/parser.js
CHANGED
|
@@ -16,7 +16,9 @@ import {
|
|
|
16
16
|
ShowStatement,
|
|
17
17
|
RepeatFor,
|
|
18
18
|
RawJSBlock,
|
|
19
|
-
InputExpression
|
|
19
|
+
InputExpression,
|
|
20
|
+
MethodCall,
|
|
21
|
+
LambdaExpression
|
|
20
22
|
} from "./ast.js";
|
|
21
23
|
|
|
22
24
|
class Parser {
|
|
@@ -94,6 +96,7 @@ class Parser {
|
|
|
94
96
|
if (t === TokenType.REPEAT && this.peekType() === TokenType.LBRACKET) return this.parseRepeatFor();
|
|
95
97
|
if (t === TokenType.REPEAT) return this.parseRepeatUntil();
|
|
96
98
|
if (t === TokenType.SHOW) return this.parseShow();
|
|
99
|
+
if (t === TokenType.METHOD) return this.parseMethodCall();
|
|
97
100
|
|
|
98
101
|
throw new Error("Unknown statement: " + t);
|
|
99
102
|
}
|
|
@@ -279,10 +282,38 @@ class Parser {
|
|
|
279
282
|
return new InputExpression();
|
|
280
283
|
}
|
|
281
284
|
|
|
282
|
-
// call expression
|
|
285
|
+
// call expression or lambda
|
|
283
286
|
if (tok.type === TokenType.CALL) {
|
|
284
287
|
this.eat(TokenType.CALL);
|
|
285
288
|
|
|
289
|
+
// Check if this is a lambda: call [param] -> body
|
|
290
|
+
if (this.current().type === TokenType.LBRACKET) {
|
|
291
|
+
this.eat(TokenType.LBRACKET);
|
|
292
|
+
|
|
293
|
+
// Parse parameters
|
|
294
|
+
const params = [];
|
|
295
|
+
if (this.current().type !== TokenType.RBRACKET) {
|
|
296
|
+
params.push(this.current().value);
|
|
297
|
+
this.eat(TokenType.IDENTIFIER);
|
|
298
|
+
|
|
299
|
+
while (this.current().type === TokenType.COMMA) {
|
|
300
|
+
this.eat(TokenType.COMMA);
|
|
301
|
+
params.push(this.current().value);
|
|
302
|
+
this.eat(TokenType.IDENTIFIER);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
this.eat(TokenType.RBRACKET);
|
|
307
|
+
|
|
308
|
+
// Check for arrow
|
|
309
|
+
if (this.current().type === TokenType.ARROW) {
|
|
310
|
+
this.eat(TokenType.ARROW);
|
|
311
|
+
const body = this.parseExpression();
|
|
312
|
+
return new LambdaExpression(params, body);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Regular function call: call functionName[args]
|
|
286
317
|
const name = this.current().value;
|
|
287
318
|
this.eat(TokenType.IDENTIFIER);
|
|
288
319
|
|
|
@@ -337,6 +368,41 @@ class Parser {
|
|
|
337
368
|
return node;
|
|
338
369
|
}
|
|
339
370
|
|
|
371
|
+
// method call as expression
|
|
372
|
+
if (tok.type === TokenType.METHOD) {
|
|
373
|
+
this.eat(TokenType.METHOD);
|
|
374
|
+
this.eat(TokenType.COLON);
|
|
375
|
+
|
|
376
|
+
// Get the target type (array or string)
|
|
377
|
+
const targetType = this.current().value;
|
|
378
|
+
this.eat(TokenType.TYPE);
|
|
379
|
+
|
|
380
|
+
// Get the target variable
|
|
381
|
+
const target = this.current().value;
|
|
382
|
+
this.eat(TokenType.IDENTIFIER);
|
|
383
|
+
|
|
384
|
+
this.eat(TokenType.DOT);
|
|
385
|
+
|
|
386
|
+
// Get the method name
|
|
387
|
+
const methodName = this.current().value;
|
|
388
|
+
this.eat(TokenType.IDENTIFIER);
|
|
389
|
+
|
|
390
|
+
// Parse arguments in brackets
|
|
391
|
+
this.eat(TokenType.LBRACKET);
|
|
392
|
+
const args = [];
|
|
393
|
+
|
|
394
|
+
if (this.current().type !== TokenType.RBRACKET) {
|
|
395
|
+
args.push(this.parseExpression());
|
|
396
|
+
while (this.current().type === TokenType.COMMA) {
|
|
397
|
+
this.eat(TokenType.COMMA);
|
|
398
|
+
args.push(this.parseExpression());
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
this.eat(TokenType.RBRACKET);
|
|
403
|
+
|
|
404
|
+
return new MethodCall(targetType, target, methodName, args);
|
|
405
|
+
}
|
|
340
406
|
|
|
341
407
|
throw new Error("Invalid primary expression: " + tok.type);
|
|
342
408
|
}
|
|
@@ -346,7 +412,8 @@ class Parser {
|
|
|
346
412
|
|
|
347
413
|
while (
|
|
348
414
|
this.current().type === TokenType.STAR ||
|
|
349
|
-
this.current().type === TokenType.SLASH
|
|
415
|
+
this.current().type === TokenType.SLASH ||
|
|
416
|
+
this.current().type === TokenType.MODULO
|
|
350
417
|
) {
|
|
351
418
|
const op = this.current().type;
|
|
352
419
|
this.pos++;
|
|
@@ -601,6 +668,42 @@ class Parser {
|
|
|
601
668
|
return new ShowStatement(value);
|
|
602
669
|
}
|
|
603
670
|
|
|
671
|
+
parseMethodCall() {
|
|
672
|
+
this.eat(TokenType.METHOD);
|
|
673
|
+
this.eat(TokenType.COLON);
|
|
674
|
+
|
|
675
|
+
// Get the target type (array or string)
|
|
676
|
+
const targetType = this.current().value;
|
|
677
|
+
this.eat(TokenType.TYPE);
|
|
678
|
+
|
|
679
|
+
// Get the target variable
|
|
680
|
+
const target = this.current().value;
|
|
681
|
+
this.eat(TokenType.IDENTIFIER);
|
|
682
|
+
|
|
683
|
+
this.eat(TokenType.DOT);
|
|
684
|
+
|
|
685
|
+
// Get the method name
|
|
686
|
+
const methodName = this.current().value;
|
|
687
|
+
this.eat(TokenType.IDENTIFIER);
|
|
688
|
+
|
|
689
|
+
// Parse arguments in brackets
|
|
690
|
+
this.eat(TokenType.LBRACKET);
|
|
691
|
+
const args = [];
|
|
692
|
+
|
|
693
|
+
if (this.current().type !== TokenType.RBRACKET) {
|
|
694
|
+
args.push(this.parseExpression());
|
|
695
|
+
while (this.current().type === TokenType.COMMA) {
|
|
696
|
+
this.eat(TokenType.COMMA);
|
|
697
|
+
args.push(this.parseExpression());
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
this.eat(TokenType.RBRACKET);
|
|
702
|
+
this.eat(TokenType.SEMICOLON);
|
|
703
|
+
|
|
704
|
+
return new MethodCall(targetType, target, methodName, args);
|
|
705
|
+
}
|
|
706
|
+
|
|
604
707
|
}
|
|
605
708
|
|
|
606
709
|
export { Parser };
|
package/src/runtime/runner.js
CHANGED
|
@@ -2,6 +2,9 @@ import { Lexer } from "../lexer/lexer.js";
|
|
|
2
2
|
import { TokenType } from "../lexer/tokens.js";
|
|
3
3
|
import { Parser } from "../parser/parser.js";
|
|
4
4
|
import { JSCodeGenerator } from "../generator/jsgenerator.js";
|
|
5
|
+
import { createRequire } from "module";
|
|
6
|
+
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
5
8
|
|
|
6
9
|
function tokenizeAll(code) {
|
|
7
10
|
const lexer = new Lexer(code);
|
|
@@ -10,7 +13,6 @@ function tokenizeAll(code) {
|
|
|
10
13
|
do {
|
|
11
14
|
t = lexer.getNextToken();
|
|
12
15
|
tokens.push(t);
|
|
13
|
-
//console.log(t);
|
|
14
16
|
} while (t.type !== TokenType.EOF);
|
|
15
17
|
return tokens;
|
|
16
18
|
}
|
|
@@ -23,30 +25,18 @@ function compile(code) {
|
|
|
23
25
|
|
|
24
26
|
function run(code) {
|
|
25
27
|
const js = compile(code);
|
|
28
|
+
|
|
26
29
|
const finalcode_input = `
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
process.stdin.setEncoding("utf8");
|
|
30
|
-
process.stdin.on("data", chunk => {
|
|
31
|
-
buffer_of_epoxy_lang_dont_use_this_name += chunk;
|
|
32
|
-
while (buffer_of_epoxy_lang_dont_use_this_name.includes("\\n") && resolvers_of_epoxy_lang_dont_use_this_name.length > 0) {
|
|
33
|
-
const line = buffer_of_epoxy_lang_dont_use_this_name.slice(0, buffer_of_epoxy_lang_dont_use_this_name.indexOf("\\n")).trim();
|
|
34
|
-
buffer_of_epoxy_lang_dont_use_this_name = buffer_of_epoxy_lang_dont_use_this_name.slice(buffer_of_epoxy_lang_dont_use_this_name.indexOf("\\n") + 1);
|
|
35
|
-
const resolve_of_epoxy_lang_dont_use_this_name = resolvers_of_epoxy_lang_dont_use_this_name.shift();
|
|
36
|
-
resolve_of_epoxy_lang_dont_use_this_name(line);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
function input_of_epoxy_lang_dont_use_this_name() {
|
|
40
|
-
return new Promise(resolve => {
|
|
41
|
-
resolvers_of_epoxy_lang_dont_use_this_name.push(resolve);
|
|
42
|
-
})}
|
|
43
|
-
async function main_of_epoxy_lang_dont_use_this_name() {
|
|
30
|
+
const promptSync_of_epoxy_lang_dont_use_this_name = require("prompt-sync");
|
|
31
|
+
const input_of_epoxy_lang_dont_use_this_name = promptSync_of_epoxy_lang_dont_use_this_name();
|
|
44
32
|
${js}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
const thisisthecode = js.includes("input_of_epoxy_lang_dont_use_this_name()")
|
|
36
|
+
? finalcode_input
|
|
37
|
+
: js;
|
|
38
|
+
|
|
49
39
|
return eval(thisisthecode);
|
|
50
40
|
}
|
|
51
41
|
|
|
52
|
-
export { tokenizeAll, compile, run };
|
|
42
|
+
export { tokenizeAll, compile, run };
|
package/src/test.js
CHANGED
|
@@ -1,33 +1,18 @@
|
|
|
1
1
|
import { compile } from './index.js';
|
|
2
2
|
import { readFileSync } from 'fs';
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
3
5
|
console.log("=== Testing test.epx ===");
|
|
4
|
-
const inputfile = readFileSync('./examples/
|
|
6
|
+
const inputfile = readFileSync('./examples/hybrid.epx', 'utf-8');
|
|
5
7
|
console.log("Epoxy code:");
|
|
6
8
|
console.log(inputfile);
|
|
7
9
|
console.log("\nCompiled JavaScript:");
|
|
8
10
|
const epx_to_js_raw = compile(inputfile);
|
|
9
11
|
const finalcode_input = `
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
process.stdin.setEncoding("utf8");
|
|
13
|
-
process.stdin.on("data", chunk => {
|
|
14
|
-
buffer_of_epoxy_lang_dont_use_this_name += chunk;
|
|
15
|
-
while (buffer_of_epoxy_lang_dont_use_this_name.includes("\\n") && resolvers_of_epoxy_lang_dont_use_this_name.length > 0) {
|
|
16
|
-
const line = buffer_of_epoxy_lang_dont_use_this_name.slice(0, buffer_of_epoxy_lang_dont_use_this_name.indexOf("\\n")).trim();
|
|
17
|
-
buffer_of_epoxy_lang_dont_use_this_name = buffer_of_epoxy_lang_dont_use_this_name.slice(buffer_of_epoxy_lang_dont_use_this_name.indexOf("\\n") + 1);
|
|
18
|
-
const resolve_of_epoxy_lang_dont_use_this_name = resolvers_of_epoxy_lang_dont_use_this_name.shift();
|
|
19
|
-
resolve_of_epoxy_lang_dont_use_this_name(line);
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
function input_of_epoxy_lang_dont_use_this_name() {
|
|
23
|
-
return new Promise(resolve => {
|
|
24
|
-
resolvers_of_epoxy_lang_dont_use_this_name.push(resolve);
|
|
25
|
-
})}
|
|
26
|
-
async function main_of_epoxy_lang_dont_use_this_name() {
|
|
12
|
+
const promptSync_of_epoxy_lang_dont_use_this_name = require("prompt-sync");
|
|
13
|
+
const input_of_epoxy_lang_dont_use_this_name = promptSync_of_epoxy_lang_dont_use_this_name();
|
|
27
14
|
${epx_to_js_raw}
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
main_of_epoxy_lang_dont_use_this_name();`;
|
|
15
|
+
`;
|
|
31
16
|
const thisisthecode = epx_to_js_raw.includes("input_of_epoxy_lang_dont_use_this_name()") ? finalcode_input : epx_to_js_raw;
|
|
32
17
|
console.log(thisisthecode);
|
|
33
18
|
console.log("\nRunning JavaScript:");
|