@port-labs/jq-node-bindings 0.0.1
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/.editorconfig +5 -0
- package/.jshintignore +1 -0
- package/.jshintrc +23 -0
- package/binding.gyp +56 -0
- package/configure +26 -0
- package/deps/jq/.gitattributes +2 -0
- package/deps/jq/.travis.yml +53 -0
- package/deps/jq/AUTHORS +73 -0
- package/deps/jq/COPYING +70 -0
- package/deps/jq/ChangeLog +1349 -0
- package/deps/jq/Makefile.am +198 -0
- package/deps/jq/NEWS +88 -0
- package/deps/jq/README.md +64 -0
- package/deps/jq/builtin.c +1684 -0
- package/deps/jq/builtin.h +10 -0
- package/deps/jq/bytecode.c +161 -0
- package/deps/jq/bytecode.h +92 -0
- package/deps/jq/compile-ios.sh +102 -0
- package/deps/jq/compile.c +1210 -0
- package/deps/jq/compile.h +101 -0
- package/deps/jq/config/m4/check-math-func.m4 +4 -0
- package/deps/jq/config/m4/find-func-no-libs.m4 +8 -0
- package/deps/jq/config/m4/find-func-no-libs2.m4 +62 -0
- package/deps/jq/config/m4/find-func.m4 +9 -0
- package/deps/jq/config/m4/misc.m4 +3 -0
- package/deps/jq/configure.ac +221 -0
- package/deps/jq/docs/Gemfile +7 -0
- package/deps/jq/docs/Gemfile.lock +63 -0
- package/deps/jq/docs/README.md +25 -0
- package/deps/jq/docs/Rakefile +145 -0
- package/deps/jq/docs/content/1.tutorial/default.yml +327 -0
- package/deps/jq/docs/content/2.download/default.yml +117 -0
- package/deps/jq/docs/content/3.manual/manual.yml +2878 -0
- package/deps/jq/docs/content/3.manual/v1.3/manual.yml +1270 -0
- package/deps/jq/docs/content/3.manual/v1.4/manual.yml +1672 -0
- package/deps/jq/docs/content/index/index.yml +51 -0
- package/deps/jq/docs/default_manpage.md +22 -0
- package/deps/jq/docs/public/.htaccess +28 -0
- package/deps/jq/docs/public/bootstrap/css/bootstrap-responsive.css +1058 -0
- package/deps/jq/docs/public/bootstrap/css/bootstrap-responsive.min.css +9 -0
- package/deps/jq/docs/public/bootstrap/css/bootstrap.css +5224 -0
- package/deps/jq/docs/public/bootstrap/css/bootstrap.min.css +9 -0
- package/deps/jq/docs/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
- package/deps/jq/docs/public/bootstrap/img/glyphicons-halflings.png +0 -0
- package/deps/jq/docs/public/bootstrap/js/bootstrap.js +2027 -0
- package/deps/jq/docs/public/bootstrap/js/bootstrap.min.js +6 -0
- package/deps/jq/docs/public/css/base.scss +99 -0
- package/deps/jq/docs/public/jq.png +0 -0
- package/deps/jq/docs/public/robots.txt +2 -0
- package/deps/jq/docs/site.yml +18 -0
- package/deps/jq/docs/templates/default.liquid +34 -0
- package/deps/jq/docs/templates/index.liquid +60 -0
- package/deps/jq/docs/templates/manual.liquid +122 -0
- package/deps/jq/docs/templates/shared/_footer.liquid +5 -0
- package/deps/jq/docs/templates/shared/_head.liquid +12 -0
- package/deps/jq/docs/templates/shared/_header.liquid +26 -0
- package/deps/jq/exec_stack.h +112 -0
- package/deps/jq/execute.c +1155 -0
- package/deps/jq/inject_errors.c +112 -0
- package/deps/jq/jq.1.default +39 -0
- package/deps/jq/jq.1.prebuilt +3075 -0
- package/deps/jq/jq.h +60 -0
- package/deps/jq/jq.spec +70 -0
- package/deps/jq/jq_parser.h +9 -0
- package/deps/jq/jq_test.c +346 -0
- package/deps/jq/jv.c +1333 -0
- package/deps/jq/jv.h +240 -0
- package/deps/jq/jv_alloc.c +179 -0
- package/deps/jq/jv_alloc.h +27 -0
- package/deps/jq/jv_aux.c +619 -0
- package/deps/jq/jv_dtoa.c +4275 -0
- package/deps/jq/jv_dtoa.h +22 -0
- package/deps/jq/jv_file.c +49 -0
- package/deps/jq/jv_parse.c +852 -0
- package/deps/jq/jv_print.c +348 -0
- package/deps/jq/jv_unicode.c +96 -0
- package/deps/jq/jv_unicode.h +11 -0
- package/deps/jq/jv_utf8_tables.h +37 -0
- package/deps/jq/lexer.c +2442 -0
- package/deps/jq/lexer.h +362 -0
- package/deps/jq/lexer.l +184 -0
- package/deps/jq/libm.h +160 -0
- package/deps/jq/linker.c +393 -0
- package/deps/jq/linker.h +7 -0
- package/deps/jq/locfile.c +91 -0
- package/deps/jq/locfile.h +29 -0
- package/deps/jq/m4/ax_compare_version.m4 +177 -0
- package/deps/jq/m4/ax_prog_bison_version.m4 +68 -0
- package/deps/jq/main.c +566 -0
- package/deps/jq/opcode_list.h +44 -0
- package/deps/jq/parser.c +3914 -0
- package/deps/jq/parser.h +193 -0
- package/deps/jq/parser.y +923 -0
- package/deps/jq/scripts/crosscompile +42 -0
- package/deps/jq/scripts/gen_utf8_tables.py +32 -0
- package/deps/jq/scripts/version +5 -0
- package/deps/jq/setup.sh +33 -0
- package/deps/jq/tests/jq.test +1235 -0
- package/deps/jq/tests/jqtest +5 -0
- package/deps/jq/tests/mantest +7 -0
- package/deps/jq/tests/modules/.jq +5 -0
- package/deps/jq/tests/modules/a.jq +2 -0
- package/deps/jq/tests/modules/b/b.jq +2 -0
- package/deps/jq/tests/modules/c/c.jq +16 -0
- package/deps/jq/tests/modules/c/d.jq +1 -0
- package/deps/jq/tests/modules/data.json +4 -0
- package/deps/jq/tests/modules/lib/jq/e/e.jq +1 -0
- package/deps/jq/tests/modules/lib/jq/f.jq +1 -0
- package/deps/jq/tests/modules/syntaxerror/syntaxerror.jq +1 -0
- package/deps/jq/tests/modules/test_bind_order.jq +4 -0
- package/deps/jq/tests/modules/test_bind_order0.jq +1 -0
- package/deps/jq/tests/modules/test_bind_order1.jq +2 -0
- package/deps/jq/tests/modules/test_bind_order2.jq +2 -0
- package/deps/jq/tests/onig.supp +21 -0
- package/deps/jq/tests/onig.test +85 -0
- package/deps/jq/tests/onigtest +5 -0
- package/deps/jq/tests/setup +36 -0
- package/deps/jq/tests/shtest +205 -0
- package/deps/jq/tests/torture/input0.json +7 -0
- package/deps/jq/util.c +462 -0
- package/deps/jq/util.h +64 -0
- package/deps/jq.gyp +35 -0
- package/index.d.ts +3 -0
- package/jest.config.js +10 -0
- package/lib/index.js +14 -0
- package/package.json +48 -0
- package/reports/jest-port-api.xml +35 -0
- package/src/binding.cc +177 -0
- package/src/binding.h +13 -0
- package/test/santiy.test.js +122 -0
- package/util/configure.js +27 -0
package/deps/jq/parser.y
ADDED
|
@@ -0,0 +1,923 @@
|
|
|
1
|
+
%{
|
|
2
|
+
#include <assert.h>
|
|
3
|
+
#include <math.h>
|
|
4
|
+
#include <stdio.h>
|
|
5
|
+
#include <string.h>
|
|
6
|
+
#include "compile.h"
|
|
7
|
+
#include "jv_alloc.h"
|
|
8
|
+
#define YYMALLOC jv_mem_alloc
|
|
9
|
+
#define YYFREE jv_mem_free
|
|
10
|
+
%}
|
|
11
|
+
%code requires {
|
|
12
|
+
#include "locfile.h"
|
|
13
|
+
struct lexer_param;
|
|
14
|
+
|
|
15
|
+
#define YYLTYPE location
|
|
16
|
+
#define YYLLOC_DEFAULT(Loc, Rhs, N) \
|
|
17
|
+
do { \
|
|
18
|
+
if (N) { \
|
|
19
|
+
(Loc).start = YYRHSLOC(Rhs, 1).start; \
|
|
20
|
+
(Loc).end = YYRHSLOC(Rhs, N).end; \
|
|
21
|
+
} else { \
|
|
22
|
+
(Loc).start = YYRHSLOC(Rhs, 0).end; \
|
|
23
|
+
(Loc).end = YYRHSLOC(Rhs, 0).end; \
|
|
24
|
+
} \
|
|
25
|
+
} while (0)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
%locations
|
|
29
|
+
%error-verbose
|
|
30
|
+
%define api.pure
|
|
31
|
+
%union {
|
|
32
|
+
jv literal;
|
|
33
|
+
block blk;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
%destructor { jv_free($$); } <literal>
|
|
37
|
+
%destructor { block_free($$); } <blk>
|
|
38
|
+
|
|
39
|
+
%parse-param {block* answer}
|
|
40
|
+
%parse-param {int* errors}
|
|
41
|
+
%parse-param {struct locfile* locations}
|
|
42
|
+
%parse-param {struct lexer_param* lexer_param_ptr}
|
|
43
|
+
%lex-param {block* answer}
|
|
44
|
+
%lex-param {int* errors}
|
|
45
|
+
%lex-param {struct locfile* locations}
|
|
46
|
+
%lex-param {struct lexer_param* lexer_param_ptr}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
%token INVALID_CHARACTER
|
|
50
|
+
%token <literal> IDENT
|
|
51
|
+
%token <literal> FIELD
|
|
52
|
+
%token <literal> LITERAL
|
|
53
|
+
%token <literal> FORMAT
|
|
54
|
+
%token REC ".."
|
|
55
|
+
%token SETMOD "%="
|
|
56
|
+
%token EQ "=="
|
|
57
|
+
%token NEQ "!="
|
|
58
|
+
%token DEFINEDOR "//"
|
|
59
|
+
%token AS "as"
|
|
60
|
+
%token DEF "def"
|
|
61
|
+
%token MODULE "module"
|
|
62
|
+
%token IMPORT "import"
|
|
63
|
+
%token INCLUDE "include"
|
|
64
|
+
%token IF "if"
|
|
65
|
+
%token THEN "then"
|
|
66
|
+
%token ELSE "else"
|
|
67
|
+
%token ELSE_IF "elif"
|
|
68
|
+
%token REDUCE "reduce"
|
|
69
|
+
%token FOREACH "foreach"
|
|
70
|
+
%token END "end"
|
|
71
|
+
%token AND "and"
|
|
72
|
+
%token OR "or"
|
|
73
|
+
%token TRY "try"
|
|
74
|
+
%token CATCH "catch"
|
|
75
|
+
%token LABEL "label"
|
|
76
|
+
%token BREAK "break"
|
|
77
|
+
%token LOC "__loc__"
|
|
78
|
+
%token SETPIPE "|="
|
|
79
|
+
%token SETPLUS "+="
|
|
80
|
+
%token SETMINUS "-="
|
|
81
|
+
%token SETMULT "*="
|
|
82
|
+
%token SETDIV "/="
|
|
83
|
+
%token SETDEFINEDOR "//="
|
|
84
|
+
%token LESSEQ "<="
|
|
85
|
+
%token GREATEREQ ">="
|
|
86
|
+
|
|
87
|
+
%token QQSTRING_START
|
|
88
|
+
%token <literal> QQSTRING_TEXT
|
|
89
|
+
%token QQSTRING_INTERP_START
|
|
90
|
+
%token QQSTRING_INTERP_END
|
|
91
|
+
%token QQSTRING_END
|
|
92
|
+
|
|
93
|
+
/* Instead of raising this, find a way to use precedence to resolve
|
|
94
|
+
* shift-reduce conflicts. */
|
|
95
|
+
%expect 0
|
|
96
|
+
|
|
97
|
+
%precedence FUNCDEF
|
|
98
|
+
%right '|'
|
|
99
|
+
%left ','
|
|
100
|
+
%right "//"
|
|
101
|
+
%nonassoc '=' SETPIPE SETPLUS SETMINUS SETMULT SETDIV SETMOD SETDEFINEDOR
|
|
102
|
+
%left OR
|
|
103
|
+
%left AND
|
|
104
|
+
%nonassoc NEQ EQ '<' '>' LESSEQ GREATEREQ
|
|
105
|
+
%left '+' '-'
|
|
106
|
+
%left '*' '/' '%'
|
|
107
|
+
%precedence NONOPT /* non-optional; rules for which a specialized
|
|
108
|
+
'?' rule should be preferred over Exp '?' */
|
|
109
|
+
%precedence '?'
|
|
110
|
+
%precedence "try"
|
|
111
|
+
%precedence "catch"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
%type <blk> Exp Term MkDict MkDictPair ExpD ElseBody QQString
|
|
115
|
+
%type <blk> FuncDef FuncDefs String Import Imports Param Params
|
|
116
|
+
%type <blk> Arg Args Module Pattern ArrayPats ObjPats ObjPat
|
|
117
|
+
%type <literal> Keyword
|
|
118
|
+
%{
|
|
119
|
+
#include "lexer.h"
|
|
120
|
+
struct lexer_param {
|
|
121
|
+
yyscan_t lexer;
|
|
122
|
+
};
|
|
123
|
+
#define FAIL(loc, msg) \
|
|
124
|
+
do { \
|
|
125
|
+
location l = loc; \
|
|
126
|
+
yyerror(&l, answer, errors, locations, lexer_param_ptr, msg); \
|
|
127
|
+
/*YYERROR*/; \
|
|
128
|
+
} while (0)
|
|
129
|
+
|
|
130
|
+
void yyerror(YYLTYPE* loc, block* answer, int* errors,
|
|
131
|
+
struct locfile* locations, struct lexer_param* lexer_param_ptr, const char *s){
|
|
132
|
+
(*errors)++;
|
|
133
|
+
if (strstr(s, "unexpected")) {
|
|
134
|
+
#ifdef WIN32
|
|
135
|
+
locfile_locate(locations, *loc, "jq: error: %s (Windows cmd shell quoting issues?)", s);
|
|
136
|
+
#else
|
|
137
|
+
locfile_locate(locations, *loc, "jq: error: %s (Unix shell quoting issues?)", s);
|
|
138
|
+
#endif
|
|
139
|
+
} else {
|
|
140
|
+
locfile_locate(locations, *loc, "jq: error: %s", s);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, block* answer, int* errors,
|
|
145
|
+
struct locfile* locations, struct lexer_param* lexer_param_ptr) {
|
|
146
|
+
yyscan_t lexer = lexer_param_ptr->lexer;
|
|
147
|
+
int tok = jq_yylex(yylval, yylloc, lexer);
|
|
148
|
+
if ((tok == LITERAL || tok == QQSTRING_TEXT) && !jv_is_valid(yylval->literal)) {
|
|
149
|
+
jv msg = jv_invalid_get_msg(jv_copy(yylval->literal));
|
|
150
|
+
if (jv_get_kind(msg) == JV_KIND_STRING) {
|
|
151
|
+
FAIL(*yylloc, jv_string_value(msg));
|
|
152
|
+
} else {
|
|
153
|
+
FAIL(*yylloc, "Invalid literal");
|
|
154
|
+
}
|
|
155
|
+
jv_free(msg);
|
|
156
|
+
jv_free(yylval->literal);
|
|
157
|
+
yylval->literal = jv_null();
|
|
158
|
+
}
|
|
159
|
+
return tok;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static block gen_dictpair(block k, block v) {
|
|
163
|
+
return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
static block gen_index(block obj, block key) {
|
|
167
|
+
return BLOCK(gen_subexp(key), obj, gen_op_simple(INDEX));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
static block gen_index_opt(block obj, block key) {
|
|
171
|
+
return BLOCK(gen_subexp(key), obj, gen_op_simple(INDEX_OPT));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
static block gen_slice_index(block obj, block start, block end, opcode idx_op) {
|
|
175
|
+
block key = BLOCK(gen_subexp(gen_const(jv_object())),
|
|
176
|
+
gen_subexp(gen_const(jv_string("start"))),
|
|
177
|
+
gen_subexp(start),
|
|
178
|
+
gen_op_simple(INSERT),
|
|
179
|
+
gen_subexp(gen_const(jv_string("end"))),
|
|
180
|
+
gen_subexp(end),
|
|
181
|
+
gen_op_simple(INSERT));
|
|
182
|
+
return BLOCK(key, obj, gen_op_simple(idx_op));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
static block constant_fold(block a, block b, int op) {
|
|
186
|
+
if (!block_is_single(a) || !block_is_const(a) ||
|
|
187
|
+
!block_is_single(b) || !block_is_const(b))
|
|
188
|
+
return gen_noop();
|
|
189
|
+
if (block_const_kind(a) != block_const_kind(b))
|
|
190
|
+
return gen_noop();
|
|
191
|
+
|
|
192
|
+
jv res = jv_invalid();
|
|
193
|
+
|
|
194
|
+
if (block_const_kind(a) == JV_KIND_NUMBER) {
|
|
195
|
+
double na = jv_number_value(block_const(a));
|
|
196
|
+
double nb = jv_number_value(block_const(b));
|
|
197
|
+
switch (op) {
|
|
198
|
+
case '+': res = jv_number(na + nb); break;
|
|
199
|
+
case '-': res = jv_number(na - nb); break;
|
|
200
|
+
case '*': res = jv_number(na * nb); break;
|
|
201
|
+
case '/': res = jv_number(na / nb); break;
|
|
202
|
+
case EQ: res = (na == nb ? jv_true() : jv_false()); break;
|
|
203
|
+
case NEQ: res = (na != nb ? jv_true() : jv_false()); break;
|
|
204
|
+
case '<': res = (na < nb ? jv_true() : jv_false()); break;
|
|
205
|
+
case '>': res = (na > nb ? jv_true() : jv_false()); break;
|
|
206
|
+
case LESSEQ: res = (na <= nb ? jv_true() : jv_false()); break;
|
|
207
|
+
case GREATEREQ: res = (na >= nb ? jv_true() : jv_false()); break;
|
|
208
|
+
default: break;
|
|
209
|
+
}
|
|
210
|
+
} else if (op == '+' && block_const_kind(a) == JV_KIND_STRING) {
|
|
211
|
+
res = jv_string_concat(block_const(a), block_const(b));
|
|
212
|
+
} else {
|
|
213
|
+
return gen_noop();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (jv_get_kind(res) == JV_KIND_INVALID)
|
|
217
|
+
return gen_noop();
|
|
218
|
+
|
|
219
|
+
block_free(a);
|
|
220
|
+
block_free(b);
|
|
221
|
+
return gen_const(res);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
static block gen_binop(block a, block b, int op) {
|
|
225
|
+
block folded = constant_fold(a, b, op);
|
|
226
|
+
if (!block_is_noop(folded))
|
|
227
|
+
return folded;
|
|
228
|
+
|
|
229
|
+
const char* funcname = 0;
|
|
230
|
+
switch (op) {
|
|
231
|
+
case '+': funcname = "_plus"; break;
|
|
232
|
+
case '-': funcname = "_minus"; break;
|
|
233
|
+
case '*': funcname = "_multiply"; break;
|
|
234
|
+
case '/': funcname = "_divide"; break;
|
|
235
|
+
case '%': funcname = "_mod"; break;
|
|
236
|
+
case EQ: funcname = "_equal"; break;
|
|
237
|
+
case NEQ: funcname = "_notequal"; break;
|
|
238
|
+
case '<': funcname = "_less"; break;
|
|
239
|
+
case '>': funcname = "_greater"; break;
|
|
240
|
+
case LESSEQ: funcname = "_lesseq"; break;
|
|
241
|
+
case GREATEREQ: funcname = "_greatereq"; break;
|
|
242
|
+
}
|
|
243
|
+
assert(funcname);
|
|
244
|
+
|
|
245
|
+
return gen_call(funcname, BLOCK(gen_lambda(a), gen_lambda(b)));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
static block gen_format(block a, jv fmt) {
|
|
249
|
+
return BLOCK(a, gen_call("format", BLOCK(gen_lambda(gen_const(fmt)))));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
static block gen_definedor_assign(block object, block val) {
|
|
253
|
+
block tmp = gen_op_var_fresh(STOREV, "tmp");
|
|
254
|
+
return BLOCK(gen_op_simple(DUP),
|
|
255
|
+
val, tmp,
|
|
256
|
+
gen_call("_modify", BLOCK(gen_lambda(object),
|
|
257
|
+
gen_lambda(gen_definedor(gen_noop(),
|
|
258
|
+
gen_op_bound(LOADV, tmp))))));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
static block gen_update(block object, block val, int optype) {
|
|
262
|
+
block tmp = gen_op_var_fresh(STOREV, "tmp");
|
|
263
|
+
return BLOCK(gen_op_simple(DUP),
|
|
264
|
+
val,
|
|
265
|
+
tmp,
|
|
266
|
+
gen_call("_modify", BLOCK(gen_lambda(object),
|
|
267
|
+
gen_lambda(gen_binop(gen_noop(),
|
|
268
|
+
gen_op_bound(LOADV, tmp),
|
|
269
|
+
optype)))));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
%}
|
|
273
|
+
|
|
274
|
+
%%
|
|
275
|
+
TopLevel:
|
|
276
|
+
Module Imports Exp {
|
|
277
|
+
*answer = BLOCK($1, $2, gen_op_simple(TOP), $3);
|
|
278
|
+
} |
|
|
279
|
+
Module Imports FuncDefs {
|
|
280
|
+
*answer = BLOCK($1, $2, $3);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
Module:
|
|
284
|
+
%empty {
|
|
285
|
+
$$ = gen_noop();
|
|
286
|
+
} |
|
|
287
|
+
"module" Exp ';' {
|
|
288
|
+
if (!block_is_const($2)) {
|
|
289
|
+
FAIL(@$, "Module metadata must be constant.");
|
|
290
|
+
$$ = gen_noop();
|
|
291
|
+
} else {
|
|
292
|
+
$$ = gen_module($2);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
Imports:
|
|
297
|
+
%empty {
|
|
298
|
+
$$ = gen_noop();
|
|
299
|
+
} |
|
|
300
|
+
Import Imports {
|
|
301
|
+
$$ = BLOCK($1, $2);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
FuncDefs:
|
|
305
|
+
%empty {
|
|
306
|
+
$$ = gen_noop();
|
|
307
|
+
} |
|
|
308
|
+
FuncDef FuncDefs {
|
|
309
|
+
$$ = block_bind($1, $2, OP_IS_CALL_PSEUDO);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
Exp:
|
|
313
|
+
FuncDef Exp %prec FUNCDEF {
|
|
314
|
+
$$ = block_bind_referenced($1, $2, OP_IS_CALL_PSEUDO);
|
|
315
|
+
} |
|
|
316
|
+
|
|
317
|
+
Term "as" Pattern '|' Exp {
|
|
318
|
+
$$ = gen_destructure($1, $3, $5);
|
|
319
|
+
} |
|
|
320
|
+
|
|
321
|
+
"reduce" Term "as" Pattern '(' Exp ';' Exp ')' {
|
|
322
|
+
$$ = gen_reduce($2, $4, $6, $8);
|
|
323
|
+
} |
|
|
324
|
+
|
|
325
|
+
"foreach" Term "as" Pattern '(' Exp ';' Exp ';' Exp ')' {
|
|
326
|
+
$$ = gen_foreach($2, $4, $6, $8, $10);
|
|
327
|
+
} |
|
|
328
|
+
|
|
329
|
+
"foreach" Term "as" Pattern '(' Exp ';' Exp ')' {
|
|
330
|
+
$$ = gen_foreach($2, $4, $6, $8, gen_noop());
|
|
331
|
+
} |
|
|
332
|
+
|
|
333
|
+
"if" Exp "then" Exp ElseBody {
|
|
334
|
+
$$ = gen_cond($2, $4, $5);
|
|
335
|
+
} |
|
|
336
|
+
"if" Exp "then" error {
|
|
337
|
+
FAIL(@$, "Possibly unterminated 'if' statement");
|
|
338
|
+
$$ = $2;
|
|
339
|
+
} |
|
|
340
|
+
|
|
341
|
+
"try" Exp "catch" Exp {
|
|
342
|
+
//$$ = BLOCK(gen_op_target(FORK_OPT, $2), $2, $4);
|
|
343
|
+
$$ = gen_try($2, gen_try_handler($4));
|
|
344
|
+
} |
|
|
345
|
+
"try" Exp {
|
|
346
|
+
//$$ = BLOCK(gen_op_target(FORK_OPT, $2), $2, gen_op_simple(BACKTRACK));
|
|
347
|
+
$$ = gen_try($2, gen_op_simple(BACKTRACK));
|
|
348
|
+
} |
|
|
349
|
+
"try" Exp "catch" error {
|
|
350
|
+
FAIL(@$, "Possibly unterminated 'try' statement");
|
|
351
|
+
$$ = $2;
|
|
352
|
+
} |
|
|
353
|
+
|
|
354
|
+
"label" '$' IDENT '|' Exp {
|
|
355
|
+
jv v = jv_string_fmt("*label-%s", jv_string_value($3));
|
|
356
|
+
$$ = gen_location(@$, locations, gen_label(jv_string_value(v), $5));
|
|
357
|
+
jv_free($3);
|
|
358
|
+
jv_free(v);
|
|
359
|
+
} |
|
|
360
|
+
|
|
361
|
+
Exp '?' {
|
|
362
|
+
$$ = gen_try($1, gen_op_simple(BACKTRACK));
|
|
363
|
+
} |
|
|
364
|
+
|
|
365
|
+
Exp '=' Exp {
|
|
366
|
+
$$ = gen_call("_assign", BLOCK(gen_lambda($1), gen_lambda($3)));
|
|
367
|
+
} |
|
|
368
|
+
|
|
369
|
+
Exp "or" Exp {
|
|
370
|
+
$$ = gen_or($1, $3);
|
|
371
|
+
} |
|
|
372
|
+
|
|
373
|
+
Exp "and" Exp {
|
|
374
|
+
$$ = gen_and($1, $3);
|
|
375
|
+
} |
|
|
376
|
+
|
|
377
|
+
Exp "//" Exp {
|
|
378
|
+
$$ = gen_definedor($1, $3);
|
|
379
|
+
} |
|
|
380
|
+
|
|
381
|
+
Exp "//=" Exp {
|
|
382
|
+
$$ = gen_definedor_assign($1, $3);
|
|
383
|
+
} |
|
|
384
|
+
|
|
385
|
+
Exp "|=" Exp {
|
|
386
|
+
$$ = gen_call("_modify", BLOCK(gen_lambda($1), gen_lambda($3)));
|
|
387
|
+
} |
|
|
388
|
+
|
|
389
|
+
Exp '|' Exp {
|
|
390
|
+
$$ = block_join($1, $3);
|
|
391
|
+
} |
|
|
392
|
+
|
|
393
|
+
Exp ',' Exp {
|
|
394
|
+
$$ = gen_both($1, $3);
|
|
395
|
+
} |
|
|
396
|
+
|
|
397
|
+
Exp '+' Exp {
|
|
398
|
+
$$ = gen_binop($1, $3, '+');
|
|
399
|
+
} |
|
|
400
|
+
|
|
401
|
+
Exp "+=" Exp {
|
|
402
|
+
$$ = gen_update($1, $3, '+');
|
|
403
|
+
} |
|
|
404
|
+
|
|
405
|
+
'-' Exp {
|
|
406
|
+
$$ = BLOCK($2, gen_call("_negate", gen_noop()));
|
|
407
|
+
} |
|
|
408
|
+
|
|
409
|
+
Exp '-' Exp {
|
|
410
|
+
$$ = gen_binop($1, $3, '-');
|
|
411
|
+
} |
|
|
412
|
+
|
|
413
|
+
Exp "-=" Exp {
|
|
414
|
+
$$ = gen_update($1, $3, '-');
|
|
415
|
+
} |
|
|
416
|
+
|
|
417
|
+
Exp '*' Exp {
|
|
418
|
+
$$ = gen_binop($1, $3, '*');
|
|
419
|
+
} |
|
|
420
|
+
|
|
421
|
+
Exp "*=" Exp {
|
|
422
|
+
$$ = gen_update($1, $3, '*');
|
|
423
|
+
} |
|
|
424
|
+
|
|
425
|
+
Exp '/' Exp {
|
|
426
|
+
$$ = gen_binop($1, $3, '/');
|
|
427
|
+
if (block_is_const_inf($$))
|
|
428
|
+
FAIL(@$, "Division by zero?");
|
|
429
|
+
} |
|
|
430
|
+
|
|
431
|
+
Exp '%' Exp {
|
|
432
|
+
$$ = gen_binop($1, $3, '%');
|
|
433
|
+
if (block_is_const_inf($$))
|
|
434
|
+
FAIL(@$, "Remainder by zero?");
|
|
435
|
+
} |
|
|
436
|
+
|
|
437
|
+
Exp "/=" Exp {
|
|
438
|
+
$$ = gen_update($1, $3, '/');
|
|
439
|
+
} |
|
|
440
|
+
|
|
441
|
+
Exp SETMOD Exp {
|
|
442
|
+
$$ = gen_update($1, $3, '%');
|
|
443
|
+
} |
|
|
444
|
+
|
|
445
|
+
Exp "==" Exp {
|
|
446
|
+
$$ = gen_binop($1, $3, EQ);
|
|
447
|
+
} |
|
|
448
|
+
|
|
449
|
+
Exp "!=" Exp {
|
|
450
|
+
$$ = gen_binop($1, $3, NEQ);
|
|
451
|
+
} |
|
|
452
|
+
|
|
453
|
+
Exp '<' Exp {
|
|
454
|
+
$$ = gen_binop($1, $3, '<');
|
|
455
|
+
} |
|
|
456
|
+
|
|
457
|
+
Exp '>' Exp {
|
|
458
|
+
$$ = gen_binop($1, $3, '>');
|
|
459
|
+
} |
|
|
460
|
+
|
|
461
|
+
Exp "<=" Exp {
|
|
462
|
+
$$ = gen_binop($1, $3, LESSEQ);
|
|
463
|
+
} |
|
|
464
|
+
|
|
465
|
+
Exp ">=" Exp {
|
|
466
|
+
$$ = gen_binop($1, $3, GREATEREQ);
|
|
467
|
+
} |
|
|
468
|
+
|
|
469
|
+
Term {
|
|
470
|
+
$$ = $1;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
Import:
|
|
474
|
+
"import" String "as" '$' IDENT ';' {
|
|
475
|
+
jv v = block_const($2);
|
|
476
|
+
// XXX Make gen_import take only blocks and the int is_data so we
|
|
477
|
+
// don't have to free so much stuff here
|
|
478
|
+
$$ = gen_import(jv_string_value(v), gen_noop(), jv_string_value($5), 1);
|
|
479
|
+
block_free($2);
|
|
480
|
+
jv_free($5);
|
|
481
|
+
jv_free(v);
|
|
482
|
+
} |
|
|
483
|
+
"import" String "as" IDENT ';' {
|
|
484
|
+
jv v = block_const($2);
|
|
485
|
+
$$ = gen_import(jv_string_value(v), gen_noop(), jv_string_value($4), 0);
|
|
486
|
+
block_free($2);
|
|
487
|
+
jv_free($4);
|
|
488
|
+
jv_free(v);
|
|
489
|
+
} |
|
|
490
|
+
"include" String ';' {
|
|
491
|
+
jv v = block_const($2);
|
|
492
|
+
$$ = gen_import(jv_string_value(v), gen_noop(), NULL, 0);
|
|
493
|
+
block_free($2);
|
|
494
|
+
jv_free(v);
|
|
495
|
+
} |
|
|
496
|
+
"import" String "as" IDENT Exp ';' {
|
|
497
|
+
if (!block_is_const($5)) {
|
|
498
|
+
FAIL(@$, "Module metadata must be constant.");
|
|
499
|
+
$$ = gen_noop();
|
|
500
|
+
} else {
|
|
501
|
+
jv v = block_const($2);
|
|
502
|
+
$$ = gen_import(jv_string_value(v), $5, jv_string_value($4), 0);
|
|
503
|
+
jv_free(v);
|
|
504
|
+
}
|
|
505
|
+
block_free($2);
|
|
506
|
+
jv_free($4);
|
|
507
|
+
} |
|
|
508
|
+
"include" String Exp ';' {
|
|
509
|
+
if (!block_is_const($3)) {
|
|
510
|
+
FAIL(@$, "Module metadata must be constant.");
|
|
511
|
+
$$ = gen_noop();
|
|
512
|
+
} else {
|
|
513
|
+
jv v = block_const($2);
|
|
514
|
+
$$ = gen_import(jv_string_value(v), $3, NULL, 0);
|
|
515
|
+
jv_free(v);
|
|
516
|
+
}
|
|
517
|
+
block_free($2);
|
|
518
|
+
} |
|
|
519
|
+
"import" String "as" '$' IDENT Exp ';' {
|
|
520
|
+
if (!block_is_const($6)) {
|
|
521
|
+
FAIL(@$, "Module metadata must be constant.");
|
|
522
|
+
$$ = gen_noop();
|
|
523
|
+
} else {
|
|
524
|
+
jv v = block_const($2);
|
|
525
|
+
$$ = gen_import(jv_string_value(v), $6, jv_string_value($5), 1);
|
|
526
|
+
jv_free(v);
|
|
527
|
+
}
|
|
528
|
+
block_free($2);
|
|
529
|
+
jv_free($5);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
FuncDef:
|
|
533
|
+
"def" IDENT ':' Exp ';' {
|
|
534
|
+
$$ = gen_function(jv_string_value($2), gen_noop(), $4);
|
|
535
|
+
jv_free($2);
|
|
536
|
+
} |
|
|
537
|
+
|
|
538
|
+
"def" IDENT '(' Params ')' ':' Exp ';' {
|
|
539
|
+
$$ = gen_function(jv_string_value($2), $4, $7);
|
|
540
|
+
jv_free($2);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
Params:
|
|
544
|
+
Param {
|
|
545
|
+
$$ = $1;
|
|
546
|
+
} |
|
|
547
|
+
Params ';' Param {
|
|
548
|
+
$$ = BLOCK($1, $3);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
Param:
|
|
552
|
+
'$' IDENT {
|
|
553
|
+
$$ = gen_param_regular(jv_string_value($2));
|
|
554
|
+
jv_free($2);
|
|
555
|
+
} |
|
|
556
|
+
|
|
557
|
+
IDENT {
|
|
558
|
+
$$ = gen_param(jv_string_value($1));
|
|
559
|
+
jv_free($1);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
String:
|
|
564
|
+
QQSTRING_START { $<literal>$ = jv_string("text"); } QQString QQSTRING_END {
|
|
565
|
+
$$ = $3;
|
|
566
|
+
jv_free($<literal>2);
|
|
567
|
+
} |
|
|
568
|
+
FORMAT QQSTRING_START { $<literal>$ = $1; } QQString QQSTRING_END {
|
|
569
|
+
$$ = $4;
|
|
570
|
+
jv_free($<literal>3);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
QQString:
|
|
575
|
+
%empty {
|
|
576
|
+
$$ = gen_const(jv_string(""));
|
|
577
|
+
} |
|
|
578
|
+
QQString QQSTRING_TEXT {
|
|
579
|
+
$$ = gen_binop($1, gen_const($2), '+');
|
|
580
|
+
} |
|
|
581
|
+
QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END {
|
|
582
|
+
$$ = gen_binop($1, gen_format($3, jv_copy($<literal>0)), '+');
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
ElseBody:
|
|
587
|
+
"elif" Exp "then" Exp ElseBody {
|
|
588
|
+
$$ = gen_cond($2, $4, $5);
|
|
589
|
+
} |
|
|
590
|
+
"else" Exp "end" {
|
|
591
|
+
$$ = $2;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
ExpD:
|
|
595
|
+
ExpD '|' ExpD {
|
|
596
|
+
$$ = block_join($1, $3);
|
|
597
|
+
} |
|
|
598
|
+
'-' ExpD {
|
|
599
|
+
$$ = BLOCK($2, gen_call("_negate", gen_noop()));
|
|
600
|
+
} |
|
|
601
|
+
Term {
|
|
602
|
+
$$ = $1;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
Term:
|
|
607
|
+
'.' {
|
|
608
|
+
$$ = gen_noop();
|
|
609
|
+
} |
|
|
610
|
+
REC {
|
|
611
|
+
$$ = gen_call("recurse", gen_noop());
|
|
612
|
+
} |
|
|
613
|
+
BREAK '$' IDENT {
|
|
614
|
+
jv v = jv_string_fmt("*label-%s", jv_string_value($3)); // impossible symbol
|
|
615
|
+
$$ = gen_location(@$, locations,
|
|
616
|
+
BLOCK(gen_op_unbound(LOADV, jv_string_value(v)),
|
|
617
|
+
gen_call("error", gen_noop())));
|
|
618
|
+
jv_free(v);
|
|
619
|
+
jv_free($3);
|
|
620
|
+
} |
|
|
621
|
+
BREAK error {
|
|
622
|
+
FAIL(@$, "break requires a label to break to");
|
|
623
|
+
$$ = gen_noop();
|
|
624
|
+
} |
|
|
625
|
+
Term FIELD '?' {
|
|
626
|
+
$$ = gen_index_opt($1, gen_const($2));
|
|
627
|
+
} |
|
|
628
|
+
FIELD '?' {
|
|
629
|
+
$$ = gen_index_opt(gen_noop(), gen_const($1));
|
|
630
|
+
} |
|
|
631
|
+
Term '.' String '?' {
|
|
632
|
+
$$ = gen_index_opt($1, $3);
|
|
633
|
+
} |
|
|
634
|
+
'.' String '?' {
|
|
635
|
+
$$ = gen_index_opt(gen_noop(), $2);
|
|
636
|
+
} |
|
|
637
|
+
Term FIELD %prec NONOPT {
|
|
638
|
+
$$ = gen_index($1, gen_const($2));
|
|
639
|
+
} |
|
|
640
|
+
FIELD %prec NONOPT {
|
|
641
|
+
$$ = gen_index(gen_noop(), gen_const($1));
|
|
642
|
+
} |
|
|
643
|
+
Term '.' String %prec NONOPT {
|
|
644
|
+
$$ = gen_index($1, $3);
|
|
645
|
+
} |
|
|
646
|
+
'.' String %prec NONOPT {
|
|
647
|
+
$$ = gen_index(gen_noop(), $2);
|
|
648
|
+
} |
|
|
649
|
+
'.' error {
|
|
650
|
+
FAIL(@$, "try .[\"field\"] instead of .field for unusually named fields");
|
|
651
|
+
$$ = gen_noop();
|
|
652
|
+
} |
|
|
653
|
+
'.' IDENT error {
|
|
654
|
+
jv_free($2);
|
|
655
|
+
FAIL(@$, "try .[\"field\"] instead of .field for unusually named fields");
|
|
656
|
+
$$ = gen_noop();
|
|
657
|
+
} |
|
|
658
|
+
/* FIXME: string literals */
|
|
659
|
+
Term '[' Exp ']' '?' {
|
|
660
|
+
$$ = gen_index_opt($1, $3);
|
|
661
|
+
} |
|
|
662
|
+
Term '[' Exp ']' %prec NONOPT {
|
|
663
|
+
$$ = gen_index($1, $3);
|
|
664
|
+
} |
|
|
665
|
+
Term '[' ']' '?' {
|
|
666
|
+
$$ = block_join($1, gen_op_simple(EACH_OPT));
|
|
667
|
+
} |
|
|
668
|
+
Term '[' ']' %prec NONOPT {
|
|
669
|
+
$$ = block_join($1, gen_op_simple(EACH));
|
|
670
|
+
} |
|
|
671
|
+
Term '[' Exp ':' Exp ']' '?' {
|
|
672
|
+
$$ = gen_slice_index($1, $3, $5, INDEX_OPT);
|
|
673
|
+
} |
|
|
674
|
+
Term '[' Exp ':' ']' '?' {
|
|
675
|
+
$$ = gen_slice_index($1, $3, gen_const(jv_null()), INDEX_OPT);
|
|
676
|
+
} |
|
|
677
|
+
Term '[' ':' Exp ']' '?' {
|
|
678
|
+
$$ = gen_slice_index($1, gen_const(jv_null()), $4, INDEX_OPT);
|
|
679
|
+
} |
|
|
680
|
+
Term '[' Exp ':' Exp ']' %prec NONOPT {
|
|
681
|
+
$$ = gen_slice_index($1, $3, $5, INDEX);
|
|
682
|
+
} |
|
|
683
|
+
Term '[' Exp ':' ']' %prec NONOPT {
|
|
684
|
+
$$ = gen_slice_index($1, $3, gen_const(jv_null()), INDEX);
|
|
685
|
+
} |
|
|
686
|
+
Term '[' ':' Exp ']' %prec NONOPT {
|
|
687
|
+
$$ = gen_slice_index($1, gen_const(jv_null()), $4, INDEX);
|
|
688
|
+
} |
|
|
689
|
+
LITERAL {
|
|
690
|
+
$$ = gen_const($1);
|
|
691
|
+
} |
|
|
692
|
+
String {
|
|
693
|
+
$$ = $1;
|
|
694
|
+
} |
|
|
695
|
+
FORMAT {
|
|
696
|
+
$$ = gen_format(gen_noop(), $1);
|
|
697
|
+
} |
|
|
698
|
+
'(' Exp ')' {
|
|
699
|
+
$$ = $2;
|
|
700
|
+
} |
|
|
701
|
+
'[' Exp ']' {
|
|
702
|
+
$$ = gen_collect($2);
|
|
703
|
+
} |
|
|
704
|
+
'[' ']' {
|
|
705
|
+
$$ = gen_const(jv_array());
|
|
706
|
+
} |
|
|
707
|
+
'{' MkDict '}' {
|
|
708
|
+
block o = gen_const_object($2);
|
|
709
|
+
if (o.first != NULL)
|
|
710
|
+
$$ = o;
|
|
711
|
+
else
|
|
712
|
+
$$ = BLOCK(gen_subexp(gen_const(jv_object())), $2, gen_op_simple(POP));
|
|
713
|
+
} |
|
|
714
|
+
'$' LOC {
|
|
715
|
+
$$ = gen_const(JV_OBJECT(jv_string("file"), jv_copy(locations->fname),
|
|
716
|
+
jv_string("line"), jv_number(locfile_get_line(locations, @$.start) + 1)));
|
|
717
|
+
} |
|
|
718
|
+
'$' IDENT {
|
|
719
|
+
$$ = gen_location(@$, locations, gen_op_unbound(LOADV, jv_string_value($2)));
|
|
720
|
+
jv_free($2);
|
|
721
|
+
} |
|
|
722
|
+
IDENT {
|
|
723
|
+
const char *s = jv_string_value($1);
|
|
724
|
+
if (strcmp(s, "false") == 0)
|
|
725
|
+
$$ = gen_const(jv_false());
|
|
726
|
+
else if (strcmp(s, "true") == 0)
|
|
727
|
+
$$ = gen_const(jv_true());
|
|
728
|
+
else if (strcmp(s, "null") == 0)
|
|
729
|
+
$$ = gen_const(jv_null());
|
|
730
|
+
else
|
|
731
|
+
$$ = gen_location(@$, locations, gen_call(s, gen_noop()));
|
|
732
|
+
jv_free($1);
|
|
733
|
+
} |
|
|
734
|
+
IDENT '(' Args ')' {
|
|
735
|
+
$$ = gen_call(jv_string_value($1), $3);
|
|
736
|
+
$$ = gen_location(@1, locations, $$);
|
|
737
|
+
jv_free($1);
|
|
738
|
+
} |
|
|
739
|
+
'(' error ')' { $$ = gen_noop(); } |
|
|
740
|
+
'[' error ']' { $$ = gen_noop(); } |
|
|
741
|
+
Term '[' error ']' { $$ = $1; } |
|
|
742
|
+
'{' error '}' { $$ = gen_noop(); }
|
|
743
|
+
|
|
744
|
+
Args:
|
|
745
|
+
Arg {
|
|
746
|
+
$$ = $1;
|
|
747
|
+
} |
|
|
748
|
+
Args ';' Arg {
|
|
749
|
+
$$ = BLOCK($1, $3);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
Arg:
|
|
753
|
+
Exp {
|
|
754
|
+
$$ = gen_lambda($1);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
Pattern:
|
|
758
|
+
'$' IDENT {
|
|
759
|
+
$$ = gen_op_unbound(STOREV, jv_string_value($2));
|
|
760
|
+
jv_free($2);
|
|
761
|
+
} |
|
|
762
|
+
'[' ArrayPats ']' {
|
|
763
|
+
$$ = BLOCK($2, gen_op_simple(POP));
|
|
764
|
+
} |
|
|
765
|
+
'{' ObjPats '}' {
|
|
766
|
+
$$ = BLOCK($2, gen_op_simple(POP));
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
ArrayPats:
|
|
770
|
+
Pattern {
|
|
771
|
+
$$ = gen_array_matcher(gen_noop(), $1);
|
|
772
|
+
} |
|
|
773
|
+
ArrayPats ',' Pattern {
|
|
774
|
+
$$ = gen_array_matcher($1, $3);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
ObjPats:
|
|
778
|
+
ObjPat {
|
|
779
|
+
$$ = $1;
|
|
780
|
+
} |
|
|
781
|
+
ObjPats ',' ObjPat {
|
|
782
|
+
$$ = BLOCK($1, $3);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
ObjPat:
|
|
786
|
+
'$' IDENT {
|
|
787
|
+
$$ = gen_object_matcher(gen_const($2), gen_op_unbound(STOREV, jv_string_value($2)));
|
|
788
|
+
} |
|
|
789
|
+
IDENT ':' Pattern {
|
|
790
|
+
$$ = gen_object_matcher(gen_const($1), $3);
|
|
791
|
+
} |
|
|
792
|
+
Keyword ':' Pattern {
|
|
793
|
+
$$ = gen_object_matcher(gen_const($1), $3);
|
|
794
|
+
} |
|
|
795
|
+
String ':' Pattern {
|
|
796
|
+
$$ = gen_object_matcher($1, $3);
|
|
797
|
+
} |
|
|
798
|
+
'(' Exp ')' ':' Pattern {
|
|
799
|
+
$$ = gen_object_matcher($2, $5);
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
Keyword:
|
|
803
|
+
"as" {
|
|
804
|
+
$$ = jv_string("as");
|
|
805
|
+
} |
|
|
806
|
+
"def" {
|
|
807
|
+
$$ = jv_string("def");
|
|
808
|
+
} |
|
|
809
|
+
"module" {
|
|
810
|
+
$$ = jv_string("module");
|
|
811
|
+
} |
|
|
812
|
+
"import" {
|
|
813
|
+
$$ = jv_string("import");
|
|
814
|
+
} |
|
|
815
|
+
"include" {
|
|
816
|
+
$$ = jv_string("include");
|
|
817
|
+
} |
|
|
818
|
+
"if" {
|
|
819
|
+
$$ = jv_string("if");
|
|
820
|
+
} |
|
|
821
|
+
"then" {
|
|
822
|
+
$$ = jv_string("then");
|
|
823
|
+
} |
|
|
824
|
+
"else" {
|
|
825
|
+
$$ = jv_string("else");
|
|
826
|
+
} |
|
|
827
|
+
"elif" {
|
|
828
|
+
$$ = jv_string("elif");
|
|
829
|
+
} |
|
|
830
|
+
"reduce" {
|
|
831
|
+
$$ = jv_string("reduce");
|
|
832
|
+
} |
|
|
833
|
+
"foreach" {
|
|
834
|
+
$$ = jv_string("foreach");
|
|
835
|
+
} |
|
|
836
|
+
"end" {
|
|
837
|
+
$$ = jv_string("end");
|
|
838
|
+
} |
|
|
839
|
+
"and" {
|
|
840
|
+
$$ = jv_string("and");
|
|
841
|
+
} |
|
|
842
|
+
"or" {
|
|
843
|
+
$$ = jv_string("or");
|
|
844
|
+
} |
|
|
845
|
+
"try" {
|
|
846
|
+
$$ = jv_string("try");
|
|
847
|
+
} |
|
|
848
|
+
"catch" {
|
|
849
|
+
$$ = jv_string("catch");
|
|
850
|
+
} |
|
|
851
|
+
"label" {
|
|
852
|
+
$$ = jv_string("label");
|
|
853
|
+
} |
|
|
854
|
+
"break" {
|
|
855
|
+
$$ = jv_string("break");
|
|
856
|
+
} |
|
|
857
|
+
"__loc__" {
|
|
858
|
+
$$ = jv_string("__loc__");
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
MkDict:
|
|
862
|
+
%empty {
|
|
863
|
+
$$=gen_noop();
|
|
864
|
+
} |
|
|
865
|
+
MkDictPair { $$ = $1; }
|
|
866
|
+
| MkDictPair ',' MkDict { $$=block_join($1, $3); }
|
|
867
|
+
| error ',' MkDict { $$ = $3; }
|
|
868
|
+
|
|
869
|
+
MkDictPair:
|
|
870
|
+
IDENT ':' ExpD {
|
|
871
|
+
$$ = gen_dictpair(gen_const($1), $3);
|
|
872
|
+
}
|
|
873
|
+
| Keyword ':' ExpD {
|
|
874
|
+
$$ = gen_dictpair(gen_const($1), $3);
|
|
875
|
+
}
|
|
876
|
+
| String ':' ExpD {
|
|
877
|
+
$$ = gen_dictpair($1, $3);
|
|
878
|
+
}
|
|
879
|
+
| String {
|
|
880
|
+
$$ = gen_dictpair($1, BLOCK(gen_op_simple(POP), gen_op_simple(DUP2),
|
|
881
|
+
gen_op_simple(DUP2), gen_op_simple(INDEX)));
|
|
882
|
+
}
|
|
883
|
+
| '$' IDENT {
|
|
884
|
+
$$ = gen_dictpair(gen_const($2),
|
|
885
|
+
gen_location(@$, locations, gen_op_unbound(LOADV, jv_string_value($2))));
|
|
886
|
+
}
|
|
887
|
+
| IDENT {
|
|
888
|
+
$$ = gen_dictpair(gen_const(jv_copy($1)),
|
|
889
|
+
gen_index(gen_noop(), gen_const($1)));
|
|
890
|
+
}
|
|
891
|
+
| '(' Exp ')' ':' ExpD {
|
|
892
|
+
$$ = gen_dictpair($2, $5);
|
|
893
|
+
}
|
|
894
|
+
| '(' error ')' ':' ExpD { $$ = $5; }
|
|
895
|
+
%%
|
|
896
|
+
|
|
897
|
+
int jq_parse(struct locfile* locations, block* answer) {
|
|
898
|
+
struct lexer_param scanner;
|
|
899
|
+
YY_BUFFER_STATE buf;
|
|
900
|
+
jq_yylex_init_extra(0, &scanner.lexer);
|
|
901
|
+
buf = jq_yy_scan_bytes(locations->data, locations->length, scanner.lexer);
|
|
902
|
+
int errors = 0;
|
|
903
|
+
*answer = gen_noop();
|
|
904
|
+
yyparse(answer, &errors, locations, &scanner);
|
|
905
|
+
jq_yy_delete_buffer(buf, scanner.lexer);
|
|
906
|
+
jq_yylex_destroy(scanner.lexer);
|
|
907
|
+
if (errors > 0) {
|
|
908
|
+
block_free(*answer);
|
|
909
|
+
*answer = gen_noop();
|
|
910
|
+
}
|
|
911
|
+
return errors;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
int jq_parse_library(struct locfile* locations, block* answer) {
|
|
915
|
+
int errs = jq_parse(locations, answer);
|
|
916
|
+
if (errs) return errs;
|
|
917
|
+
if (block_has_main(*answer)) {
|
|
918
|
+
locfile_locate(locations, UNKNOWN_LOCATION, "jq: error: library should only have function definitions, not a main expression");
|
|
919
|
+
return 1;
|
|
920
|
+
}
|
|
921
|
+
assert(block_has_only_binders_and_imports(*answer, OP_IS_CALL_PSEUDO));
|
|
922
|
+
return 0;
|
|
923
|
+
}
|