write/append code-dedupe iterate

This commit is contained in:
John Kerl 2016-07-26 22:23:53 -04:00
parent 1e149c99aa
commit a7ff6de976
3 changed files with 64 additions and 93 deletions

View file

@ -607,7 +607,9 @@ md_tee_append(A) ::= MD_TOKEN_TEE(O) MD_TOKEN_BITWISE_RSH md_output_file(F) MD_T
// * On the "emit" we change the name to get "emit @a,@b,@c".
md_emitf(A) ::= MD_TOKEN_EMITF(O) md_emitf_args(B). {
A = mlr_dsl_ast_node_set_function_name(B, O->text);
B = mlr_dsl_ast_node_set_function_name(B, O->text);
A = mlr_dsl_ast_node_alloc_binary(O->text, MD_AST_NODE_TYPE_EMITF_WRITE, B,
mlr_dsl_ast_node_alloc_zary("stdout", MD_AST_NODE_TYPE_STDOUT));
}
// Need to invalidate "emit @a," -- use some non-empty-args expr.
md_emitf_args(A) ::= . {

View file

@ -34,8 +34,7 @@ static mlr_dsl_cst_statement_t* alloc_unset(mlr_dsl_ast_node_t* p, int t
static mlr_dsl_cst_statement_t* alloc_tee(mlr_dsl_ast_node_t* p, int ti, int cf, file_output_mode_t m);
static mlr_dsl_cst_statement_t* alloc_emitf(mlr_dsl_ast_node_t* p, int ti, int cf);
static mlr_dsl_cst_statement_t* alloc_emitf_to_file(mlr_dsl_ast_node_t* p, int ti, int cf, file_output_mode_t m);
static mlr_dsl_cst_statement_t* alloc_emitf(mlr_dsl_ast_node_t* p, int ti, int cf, file_output_mode_t m);
static mlr_dsl_cst_statement_t* alloc_emit(mlr_dsl_ast_node_t* p, int ti, int cf, int dfp);
static mlr_dsl_cst_statement_t* alloc_emit_to_file(mlr_dsl_ast_node_t* p, int ti, int cf, int dfp, file_output_mode_t m);
static mlr_dsl_cst_statement_t* alloc_emit_lashed(mlr_dsl_ast_node_t* p, int ti, int cf, int dfp);
@ -432,13 +431,13 @@ static mlr_dsl_cst_statement_t* alloc_cst_statement(mlr_dsl_ast_node_t* pnode, i
break;
case MD_AST_NODE_TYPE_EMITF:
return alloc_emitf(pnode, type_inferencing, context_flags);
return alloc_emitf(pnode, type_inferencing, context_flags, MODE_WRITE);
break;
case MD_AST_NODE_TYPE_EMITF_WRITE:
return alloc_emitf_to_file(pnode, type_inferencing, context_flags, MODE_WRITE);
return alloc_emitf(pnode, type_inferencing, context_flags, MODE_WRITE);
break;
case MD_AST_NODE_TYPE_EMITF_APPEND:
return alloc_emitf_to_file(pnode, type_inferencing, context_flags, MODE_APPEND);
return alloc_emitf(pnode, type_inferencing, context_flags, MODE_APPEND);
break;
case MD_AST_NODE_TYPE_EMITP:
return alloc_emit(pnode, type_inferencing, context_flags, TRUE);
@ -774,67 +773,12 @@ static mlr_dsl_cst_statement_t* alloc_tee(mlr_dsl_ast_node_t* pnode, int type_in
}
// ----------------------------------------------------------------
// Example AST:
// $ mlr -n put -v '@a=$x; @b=$y; emitf @a,@b'
// list (statement_list):
// = (oosvar_assignment):
// oosvar_keylist (oosvar_keylist):
// a (string_literal).
// x (field_name).
// = (oosvar_assignment):
// oosvar_keylist (oosvar_keylist):
// b (string_literal).
// y (field_name).
// emitf (emitf):
// oosvar_keylist (oosvar_keylist):
// a (string_literal).
// oosvar_keylist (oosvar_keylist):
// b (string_literal).
static mlr_dsl_cst_statement_t* alloc_emitf(mlr_dsl_ast_node_t* pnode, int type_inferencing,
int context_flags)
{
mlr_dsl_cst_statement_t* pstatement = alloc_blank();
// Loop over oosvar names to emit in e.g. 'emitf @a, @b, @c'.
pstatement->pvarargs = sllv_alloc();
for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) {
mlr_dsl_ast_node_t* pwalker = pe->pvvalue;
mlr_dsl_ast_node_t* pchild = pwalker->pchildren->phead->pvvalue;
// This could be enforced in the lemon parser but it's easier to do it here.
if (pwalker->pchildren->length != 1 || pchild->type != MD_AST_NODE_TYPE_STRING_LITERAL) {
fprintf(stderr,
"%s: emitf arguments must be all non-indexed, e.g. @a but not @[\"a\"] or @a[2].\n",
MLR_GLOBALS.bargv0);
fprintf(stderr, "Abstract syntax tree for the statement:\n");
mlr_dsl_ast_node_fprint(pnode, stderr);
exit(1);
}
sllv_append(pstatement->pvarargs, mlr_dsl_cst_statement_vararg_alloc(
pchild->text,
NULL,
rval_evaluator_alloc_from_ast(pwalker, type_inferencing, context_flags),
NULL));
}
pstatement->pnode_handler = handle_emitf;
return pstatement;
}
// 'emitf > "out", @a'
// text="emitf", type=emitf_write:
// text="emitf", type=emitf:
// text="oosvar_keylist", type=oosvar_keylist:
// text="a", type=string_literal.
// text="out", type=strnum_literal.
static mlr_dsl_cst_statement_t* alloc_emitf_to_file(mlr_dsl_ast_node_t* pnode, int type_inferencing,
int context_flags, file_output_mode_t file_output_mode)
{
mlr_dsl_cst_statement_t* pstatement = alloc_blank();
mlr_dsl_ast_node_t* pnamesnode = pnode->pchildren->phead->pvvalue;
mlr_dsl_ast_node_t* pfilenode = pnode->pchildren->phead->pnext->pvvalue;
// Loop over oosvar names to emit in e.g. 'emitf @a, @b, @c'.
pstatement->pvarargs = sllv_alloc();
@ -849,12 +793,23 @@ static mlr_dsl_cst_statement_t* alloc_emitf_to_file(mlr_dsl_ast_node_t* pnode, i
NULL));
}
pstatement->poutput_filename_evaluator = rval_evaluator_alloc_from_ast(pfilenode,
type_inferencing, context_flags);
pstatement->file_output_mode = file_output_mode;
pstatement->pmulti_lrec_writer = multi_lrec_writer_alloc();
mlr_dsl_ast_node_t* pfilename_node = pnode->pchildren->phead->pnext->pvvalue;
if (pfilename_node->type == MD_AST_NODE_TYPE_STDOUT) {
pstatement->pnode_handler = handle_emitf;
pstatement->stdfp = stdout;
} else if (pfilename_node->type == MD_AST_NODE_TYPE_STDERR) {
pstatement->pnode_handler = handle_emitf;
pstatement->stdfp = stderr;
} else {
pstatement->pnode_handler = handle_dump_to_file;
pstatement->poutput_filename_evaluator = rval_evaluator_alloc_from_ast(pfilename_node,
type_inferencing, context_flags);
pstatement->file_output_mode = file_output_mode;
pstatement->pmulti_lrec_writer = multi_lrec_writer_alloc();
pstatement->pnode_handler = handle_emitf_to_file;
}
pstatement->pnode_handler = handle_emitf_to_file;
return pstatement;
}

View file

@ -17476,15 +17476,21 @@ text="list", type=statement_list:
text="x", type=field_name.
text="end", type=end:
text="list", type=statement_list:
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="a", type=string_literal.
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="b", type=string_literal.
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="c", type=string_literal.
text="emitf", type=emitf_write:
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="a", type=string_literal.
text="stdout", type=stdout:
text="emitf", type=emitf_write:
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="b", type=string_literal.
text="stdout", type=stdout:
text="emitf", type=emitf_write:
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="c", type=string_literal.
text="stdout", type=stdout:
a=pan,b=pan,i=1,x=0.3467901443380824,y=0.7268028627434533
a=eks,b=pan,i=2,x=0.7586799647899636,y=0.5221511083334797
a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776
@ -17516,13 +17522,15 @@ text="list", type=statement_list:
text="x", type=field_name.
text="end", type=end:
text="list", type=statement_list:
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="a", type=string_literal.
text="oosvar_keylist", type=oosvar_keylist:
text="b", type=string_literal.
text="oosvar_keylist", type=oosvar_keylist:
text="c", type=string_literal.
text="emitf", type=emitf_write:
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="a", type=string_literal.
text="oosvar_keylist", type=oosvar_keylist:
text="b", type=string_literal.
text="oosvar_keylist", type=oosvar_keylist:
text="c", type=string_literal.
text="stdout", type=stdout:
a=pan,b=pan,i=1,x=0.3467901443380824,y=0.7268028627434533
a=eks,b=pan,i=2,x=0.7586799647899636,y=0.5221511083334797
a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776
@ -17572,9 +17580,11 @@ text="list", type=statement_list:
text="sum", type=string_literal.
text="oosvar_keylist", type=oosvar_keylist:
text="count", type=string_literal.
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="mean", type=string_literal.
text="emitf", type=emitf_write:
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="mean", type=string_literal.
text="stdout", type=stdout:
a b i x y
pan pan 1 0.3467901443380824 0.7268028627434533
eks pan 2 0.7586799647899636 0.5221511083334797
@ -17603,9 +17613,11 @@ text="list", type=statement_list:
text="sum", type=string_literal.
text="oosvar_keylist", type=oosvar_keylist:
text="count", type=string_literal.
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="mean", type=string_literal.
text="emitf", type=emitf_write:
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="mean", type=string_literal.
text="stdout", type=stdout:
text="begin", type=begin:
text="list", type=statement_list:
text="=", type=oosvar_assignment:
@ -18349,11 +18361,13 @@ text="list", type=statement_list:
text="u", type=strnum_literal.
text="5", type=field_name.
text="2", type=strnum_literal.
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="v", type=string_literal.
text="oosvar_keylist", type=oosvar_keylist:
text="w", type=string_literal.
text="emitf", type=emitf_write:
text="emitf", type=emitf:
text="oosvar_keylist", type=oosvar_keylist:
text="v", type=string_literal.
text="oosvar_keylist", type=oosvar_keylist:
text="w", type=string_literal.
text="stdout", type=stdout:
text="dump", type=dump:
text="stdout", type=stdout:
text="=", type=srec_assignment: