diff --git a/c/mapping/context_flags.h b/c/mapping/context_flags.h index 3aaf9a18b..581428479 100644 --- a/c/mapping/context_flags.h +++ b/c/mapping/context_flags.h @@ -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 diff --git a/c/mapping/mlr_dsl_cst_func_subr.c b/c/mapping/mlr_dsl_cst_func_subr.c index a5da3e1bd..0d36c4543 100644 --- a/c/mapping/mlr_dsl_cst_func_subr.c +++ b/c/mapping/mlr_dsl_cst_func_subr.c @@ -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: diff --git a/c/mapping/rval_expr_evaluators.c b/c/mapping/rval_expr_evaluators.c index 3aba50d2f..9c02f6746 100644 --- a/c/mapping/rval_expr_evaluators.c +++ b/c/mapping/rval_expr_evaluators.c @@ -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; diff --git a/c/reg_test/dev b/c/reg_test/dev index 907bd1372..279b0083b 100755 --- a/c/reg_test/dev +++ b/c/reg_test/dev @@ -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 diff --git a/c/reg_test/run b/c/reg_test/run index 862368ce0..4cecf6fe0 100755 --- a/c/reg_test/run +++ b/c/reg_test/run @@ -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 diff --git a/c/todo.txt b/c/todo.txt index 424727b54..272540fc7 100644 --- a/c/todo.txt +++ b/c/todo.txt @@ -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