Add def f($arg): syntax (fix #524)
This commit is contained in:
1 parent
fc52e78ed4
commit
32c08d48f3
6 files changed
+44
-77
No files matched your search
@@ -451,8 +451,14 @@ block gen_import(const char* name, const char* as, const char* search) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
block gen_function(const char* name, block formals, block body) {
|
block gen_function(const char* name, block formals, block body) {
|
||||||
block_bind_each(formals, body, OP_IS_CALL_PSEUDO);
|
|
||||||
inst* i = inst_new(CLOSURE_CREATE);
|
inst* i = inst_new(CLOSURE_CREATE);
|
||||||
|
for (inst* i = formals.last; i; i = i->prev) {
|
||||||
|
if (i->op == CLOSURE_PARAM_REGULAR) {
|
||||||
|
i->op = CLOSURE_PARAM;
|
||||||
|
body = gen_var_binding(gen_call(i->symbol, gen_noop()), i->symbol, body);
|
||||||
|
}
|
||||||
|
block_bind_subblock(inst_block(i), body, OP_IS_CALL_PSEUDO | OP_HAS_BINDING);
|
||||||
|
}
|
||||||
i->subfn = body;
|
i->subfn = body;
|
||||||
i->symbol = strdup(name);
|
i->symbol = strdup(name);
|
||||||
i->arglist = formals;
|
i->arglist = formals;
|
||||||
@@ -461,6 +467,10 @@ block gen_function(const char* name, block formals, block body) {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block gen_param_regular(const char* name) {
|
||||||
|
return gen_op_unbound(CLOSURE_PARAM_REGULAR, name);
|
||||||
|
}
|
||||||
|
|
||||||
block gen_param(const char* name) {
|
block gen_param(const char* name) {
|
||||||
return gen_op_unbound(CLOSURE_PARAM, name);
|
return gen_op_unbound(CLOSURE_PARAM, name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ block gen_op_var_fresh(opcode op, const char* name);
|
|||||||
|
|
||||||
block gen_import(const char* name, const char *as, const char *search);
|
block gen_import(const char* name, const char *as, const char *search);
|
||||||
block gen_function(const char* name, block formals, block body);
|
block gen_function(const char* name, block formals, block body);
|
||||||
|
block gen_param_regular(const char* name);
|
||||||
block gen_param(const char* name);
|
block gen_param(const char* name);
|
||||||
block gen_lambda(block body);
|
block gen_lambda(block body);
|
||||||
block gen_call(const char* name, block body);
|
block gen_call(const char* name, block body);
|
||||||
|
|||||||
@@ -1931,9 +1931,13 @@ sections:
|
|||||||
If you want the value-argument behaviour for defining simple
|
If you want the value-argument behaviour for defining simple
|
||||||
functions, you can just use a variable:
|
functions, you can just use a variable:
|
||||||
|
|
||||||
def addvalue(f): f as $value | map(. + $value);
|
def addvalue(f): f as $f | map(. + $f);
|
||||||
|
|
||||||
With that definition, `addvalue(.foo)` will add the current
|
Or use the short-hand:
|
||||||
|
|
||||||
|
def addvalue($f): ...;
|
||||||
|
|
||||||
|
With either definition, `addvalue(.foo)` will add the current
|
||||||
input's `.foo` field to each element of the array.
|
input's `.foo` field to each element of the array.
|
||||||
|
|
||||||
Multiple definitions using the same function name are allowed.
|
Multiple definitions using the same function name are allowed.
|
||||||
|
|||||||
@@ -36,4 +36,5 @@ OP(CLOSURE_CREATE, DEFINITION, 0, 0)
|
|||||||
OP(CLOSURE_CREATE_C, DEFINITION, 0, 0)
|
OP(CLOSURE_CREATE_C, DEFINITION, 0, 0)
|
||||||
|
|
||||||
OP(TOP, NONE, 0, 0)
|
OP(TOP, NONE, 0, 0)
|
||||||
|
OP(CLOSURE_PARAM_REGULAR, DEFINITION, 0, 0)
|
||||||
OP(DEPS, CONSTANT, 0, 0)
|
OP(DEPS, CONSTANT, 0, 0)
|
||||||
@@ -102,7 +102,7 @@ struct lexer_param;
|
|||||||
%precedence "catch"
|
%precedence "catch"
|
||||||
|
|
||||||
|
|
||||||
%type <blk> Exp Term MkDict MkDictPair ExpD ElseBody QQString FuncDef FuncDefs String Import Imports
|
%type <blk> Exp Term MkDict MkDictPair ExpD ElseBody QQString FuncDef FuncDefs String Import Imports Param Params
|
||||||
%{
|
%{
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
struct lexer_param {
|
struct lexer_param {
|
||||||
@@ -471,82 +471,28 @@ FuncDef:
|
|||||||
jv_free($2);
|
jv_free($2);
|
||||||
} |
|
} |
|
||||||
|
|
||||||
"def" IDENT '(' IDENT ')' ':' Exp ';' {
|
"def" IDENT '(' Params ')' ':' Exp ';' {
|
||||||
$$ = gen_function(jv_string_value($2),
|
$$ = gen_function(jv_string_value($2), $4, $7);
|
||||||
gen_param(jv_string_value($4)),
|
jv_free($2);
|
||||||
$7);
|
}
|
||||||
|
|
||||||
|
Params:
|
||||||
|
Param {
|
||||||
|
$$ = $1;
|
||||||
|
} |
|
||||||
|
Params ';' Param {
|
||||||
|
$$ = BLOCK($1, $3);
|
||||||
|
}
|
||||||
|
|
||||||
|
Param:
|
||||||
|
'$' IDENT {
|
||||||
|
$$ = gen_param_regular(jv_string_value($2));
|
||||||
jv_free($2);
|
jv_free($2);
|
||||||
jv_free($4);
|
|
||||||
} |
|
} |
|
||||||
|
|
||||||
"def" IDENT '(' IDENT ';' IDENT ')' ':' Exp ';' {
|
IDENT {
|
||||||
$$ = gen_function(jv_string_value($2),
|
$$ = gen_param(jv_string_value($1));
|
||||||
BLOCK(gen_param(jv_string_value($4)),
|
jv_free($1);
|
||||||
gen_param(jv_string_value($6))),
|
|
||||||
$9);
|
|
||||||
jv_free($2);
|
|
||||||
jv_free($4);
|
|
||||||
jv_free($6);
|
|
||||||
} |
|
|
||||||
|
|
||||||
"def" IDENT '(' IDENT ';' IDENT ';' IDENT ')' ':' Exp ';' {
|
|
||||||
$$ = gen_function(jv_string_value($2),
|
|
||||||
BLOCK(gen_param(jv_string_value($4)),
|
|
||||||
gen_param(jv_string_value($6)),
|
|
||||||
gen_param(jv_string_value($8))),
|
|
||||||
$11);
|
|
||||||
jv_free($2);
|
|
||||||
jv_free($4);
|
|
||||||
jv_free($6);
|
|
||||||
jv_free($8);
|
|
||||||
} |
|
|
||||||
|
|
||||||
"def" IDENT '(' IDENT ';' IDENT ';' IDENT ';' IDENT ')' ':' Exp ';' {
|
|
||||||
$$ = gen_function(jv_string_value($2),
|
|
||||||
BLOCK(gen_param(jv_string_value($4)),
|
|
||||||
gen_param(jv_string_value($6)),
|
|
||||||
gen_param(jv_string_value($8)),
|
|
||||||
gen_param(jv_string_value($10))),
|
|
||||||
$13);
|
|
||||||
jv_free($2);
|
|
||||||
jv_free($4);
|
|
||||||
jv_free($6);
|
|
||||||
jv_free($8);
|
|
||||||
jv_free($10);
|
|
||||||
} |
|
|
||||||
|
|
||||||
"def" IDENT '(' IDENT ';' IDENT ';' IDENT ';' IDENT ';' IDENT ')' ':' Exp ';' {
|
|
||||||
$$ = gen_function(jv_string_value($2),
|
|
||||||
BLOCK(gen_param(jv_string_value($4)),
|
|
||||||
gen_param(jv_string_value($6)),
|
|
||||||
gen_param(jv_string_value($8)),
|
|
||||||
gen_param(jv_string_value($10)),
|
|
||||||
gen_param(jv_string_value($12))),
|
|
||||||
$15);
|
|
||||||
jv_free($2);
|
|
||||||
jv_free($4);
|
|
||||||
jv_free($6);
|
|
||||||
jv_free($8);
|
|
||||||
jv_free($10);
|
|
||||||
jv_free($12);
|
|
||||||
} |
|
|
||||||
|
|
||||||
"def" IDENT '(' IDENT ';' IDENT ';' IDENT ';' IDENT ';' IDENT ';' IDENT ')' ':' Exp ';' {
|
|
||||||
$$ = gen_function(jv_string_value($2),
|
|
||||||
BLOCK(gen_param(jv_string_value($4)),
|
|
||||||
gen_param(jv_string_value($6)),
|
|
||||||
gen_param(jv_string_value($8)),
|
|
||||||
gen_param(jv_string_value($10)),
|
|
||||||
gen_param(jv_string_value($12)),
|
|
||||||
gen_param(jv_string_value($14))),
|
|
||||||
$17);
|
|
||||||
jv_free($2);
|
|
||||||
jv_free($4);
|
|
||||||
jv_free($6);
|
|
||||||
jv_free($8);
|
|
||||||
jv_free($10);
|
|
||||||
jv_free($12);
|
|
||||||
jv_free($14);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -538,6 +538,11 @@ def id(x):x; 2000 as $x | def f(x):1 as $x | id([$x, x, x]); def g(x): 100 as $x
|
|||||||
"more testing"
|
"more testing"
|
||||||
[1,100,2100.0,100,2100.0]
|
[1,100,2100.0,100,2100.0]
|
||||||
|
|
||||||
|
# test def f($a) syntax
|
||||||
|
def x(a;b): a as $a | b as $b | $a + $b; def y($a;$b): $a + $b; def check(a;b): [x(a;b)] == [y(a;b)]; check(.[];.[]*2)
|
||||||
|
[1,2,3]
|
||||||
|
true
|
||||||
|
|
||||||
# test backtracking through function calls and returns
|
# test backtracking through function calls and returns
|
||||||
# this test is *evil*
|
# this test is *evil*
|
||||||
[[20,10][1,0] as $x | def f: (100,200) as $y | def g: [$x + $y, .]; . + $x | g; f[0] | [f][0][1] | f]
|
[[20,10][1,0] as $x | def f: (100,200) as $y | def g: [$x + $y, .]; . + $x | g; f[0] | [f][0][1] | f]
|
||||||
|
|||||||
Reference in new issue
Block a user