func-prohibits

This commit is contained in:
John Kerl 2016-09-12 05:15:00 -07:00
parent 30c7088ebd
commit d13da3b67f
6 changed files with 41 additions and 88 deletions

View file

@ -5,9 +5,10 @@
// there, and (b) because we get far better control over error messages here (vs. 'syntax error').
// The following flags are used as the CST is built from the AST for CST-build-time validation.
#define IN_BINDABLE 0x0100 // boundvars are only OK inside a bindable, e.g. (recursively) inside a for-loop
#define IN_BREAKABLE 0x0200 // break/continue are only OK (recursively) inside for/while/do-while
#define IN_BEGIN_OR_END 0x0400 // $stuff is not OK (recursively) inside begin/end
#define IN_MLR_FILTER 0x0800 // mlr filter takes only a single boolean; no @-vars; no looping; etc.
#define IN_BINDABLE 0x00000100 // boundvars are only OK inside a bindable, e.g. (recursively) inside a for-loop
#define IN_BREAKABLE 0x00000200 // break/continue are only OK (recursively) inside for/while/do-while
#define IN_BEGIN_OR_END 0x00000400 // $stuff is not OK (recursively) inside begin/end
#define IN_FUNC_DEF 0x00000800 // $stuff, @stuff is not OK inside user-defined functions
#define IN_MLR_FILTER 0x00004000 // mlr filter takes only a single boolean; no @-vars; no looping; etc.
#endif // CONTEXT_FLAGS_H

View file

@ -92,7 +92,7 @@ udf_defsite_state_t* mlr_dsl_cst_alloc_udf(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node
}
sllv_append(pcst_udf_state->pblock_statements,
mlr_dsl_cst_alloc_statement(pbody_ast_node, pcst->pfmgr, pcst->psubroutine_states,
type_inferencing, context_flags | IN_BINDABLE));
type_inferencing, context_flags | IN_BINDABLE | IN_FUNC_DEF));
}
// Callback struct for the function manager to invoke the new function:

View file

@ -23,12 +23,11 @@
rval_evaluator_t* rval_evaluator_alloc_from_ast(mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr,
int type_inferencing, int context_flags)
{
// xxx split out helper methods for outer if-statement.
// xxx convert innner if-elses to switches.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (pnode->pchildren == NULL) {
// leaf node
switch(pnode->type) {
case MD_AST_NODE_TYPE_FIELD_NAME:
if (context_flags & IN_BEGIN_OR_END) {
fprintf(stderr, "%s: statements involving $-variables are not valid within begin or end blocks.\n",
@ -37,6 +36,7 @@ rval_evaluator_t* rval_evaluator_alloc_from_ast(mlr_dsl_ast_node_t* pnode, fmgr_
}
return rval_evaluator_alloc_from_field_name(pnode->text, type_inferencing);
break;
case MD_AST_NODE_TYPE_STRNUM_LITERAL:
return rval_evaluator_alloc_from_strnum_literal(pnode->text, type_inferencing);
break;

View file

@ -75,88 +75,42 @@ run_mlr() {
num_passed=`expr $num_passed + 1`
}
mlr_expect_fail() {
# Use just "mlr" for info messages
echo mlr "$@"
echo mlr "$@" >> $outfile
# Use path to mlr for invoking the command
set +e
$path_to_mlr "$@" >> $outfile 2>&1
status=$?
if [ $status -ne 1 ]; then
echo "Exit status was $status; expected 1."
echo "Exit status was $status; expected 1." >> $outfile
fi
set -e
echo >> $outfile
test $status -eq 1
# since set -e
num_passed=`expr $num_passed + 1`
}
# ================================================================
announce GRAMMAR REORG
announce FUNC PROHIBITS
run_mlr -n put -v '$["x"]=3'
run_mlr -n put -v '@["x"]=3'
run_mlr -n put -v '$[$y]=$y'
run_mlr -n put -v '@[@y]=@y'
run_mlr -n put -v '@x=2; @x["y"]=3; @x["y"][$z]=4'
run_mlr -n put -v '@["x"]=2; @["x"]["y"]=3; @["x"]["y"][$z]=4'
run_mlr --from $indir/abixy put -q -v '@a=2; @b["y"]=3; @c["y"][$a]=4; emitp all'
run_mlr --from $indir/abixy put -q -v '@a=2; @b["y"]=3; @c["y"][$a]=4; emitp all'
run_mlr --from $indir/abixy put -q -v '@["a"]=2; @["b"]["y"]=3; @["c"]["y"][$a]=4; emitp all'
echo x=1|mlr put '$x=$x+1; for (k,v in $*) { $[v] = typeof(v)}'
# x=2,2=MT_INT
echo x=1|mlr put 'for (k,v in $*) { $[v] = typeof(v)}'
# x=1,1=MT_STRING
run_mlr put -v '@s = NR; $t = typeof(@s); $u= typeof(@["s"]); emitp all' $indir/abixy
run_mlr --opprint put -v '@s = NR; $t = @s; $u=@["s"]' $indir/abixy
run_mlr put -v '@t["u"] = NR; $tu = @["t"]["u"]; emitp all' $indir/abixy
run_mlr put -v '@["t"]["u"] = $y; emitp all' $indir/abixy
run_mlr --from $indir/abixy put -v '$sum = 0; for(k,v in $*) {if (k =~ "^[xy]$") {$sum += $[k]} }'
run_mlr --from $indir/abixy -n put -v '
$a = @s;
$b = @t[1];
$c = @u[1][2];
$d = @v[1][2][3];
$e = @["s"];
$f = @["t"][1];
$g = @["u"][1][2];
$h = @["v"][1][2][3];
'
run_mlr -n put -v 'emit @*'
run_mlr -n put -v 'emitp @*'
run_mlr -n put -v 'unset @*'
run_mlr --opprint --from $indir/abixy put -q -v '
for (k,v in $*) {
@logging1[NR][k] = v;
if (k == "x") {
break;
}
}
for (k,v in $*) {
if (k == "x") {
break;
}
@logging2[NR][k] = v;
}
for (k,v in $*) {
@logging3[NR][k] = v;
if (k == "x") {
continue;
}
}
for (k,v in $*) {
if (k == "x") {
continue;
}
@logging4[NR][k] = v;
}
end {
emitp @logging1, "NR", "k";
emitp @logging2, "NR", "k";
emitp @logging3, "NR", "k";
emitp @logging4, "NR", "k"
mlr_expect_fail --from $indir/abixy put '
func f(x,y,z) {
return $a # cannot reference srecs from functions
}
'
mlr_expect_fail --from $indir/abixy put '
func f(x,y,z) {
return $[x] # cannot reference srecs from functions
}
'
run_mlr -n put ''
# ================================================================
cat $outfile

View file

@ -4707,12 +4707,10 @@ run_mlr --opprint --from $indir/abixy filter -f $indir/filter-script-piece-1 -f
echo
echo ================================================================
echo "Differences between $expfile and $outfile:"
echo
diff -I '^mlr ' -C5 $expfile $outfile
echo "No differences found between $expfile and $outfile" # since set -e
echo ================================================================
echo
# ================================================================
echo ALL REGRESSION TESTS PASSED

View file

@ -24,8 +24,8 @@ UDFs:
- (lhs) no subr call
- (lhs) no srec assignment x 3, no oosvar assignment x 2, no filter, no unset
- (lhs) no tee, emitfx3; but allow print; ?dump?
- (rhs) no srec/oosvar references
* kw autodoc mods for func/subr/call/return; also add NR PI E etc. to keyword help.
* disallow func/subr redefines
* xxxes
* xxxes in reg_test/run
* valgrinds