diff --git a/c/containers/mlr_dsl_ast.c b/c/containers/mlr_dsl_ast.c index 2288e9b53..10c3c439d 100644 --- a/c/containers/mlr_dsl_ast.c +++ b/c/containers/mlr_dsl_ast.c @@ -79,6 +79,19 @@ mlr_dsl_ast_node_t* mlr_dsl_ast_node_alloc_ternary(char* text, mlr_dsl_ast_node_ return pnode; } +// ---------------------------------------------------------------- +mlr_dsl_ast_node_t* mlr_dsl_ast_node_alloc_quaternary(char* text, mlr_dsl_ast_node_type_t type, + mlr_dsl_ast_node_t* pa, mlr_dsl_ast_node_t* pb, mlr_dsl_ast_node_t* pc, mlr_dsl_ast_node_t* pd) +{ + mlr_dsl_ast_node_t* pnode = mlr_dsl_ast_node_alloc(text, type); + pnode->pchildren = sllv_alloc(); + sllv_append(pnode->pchildren, pa); + sllv_append(pnode->pchildren, pb); + sllv_append(pnode->pchildren, pc); + sllv_append(pnode->pchildren, pd); + return pnode; +} + // ---------------------------------------------------------------- mlr_dsl_ast_node_t* mlr_dsl_ast_node_prepend_arg( mlr_dsl_ast_node_t* pa, mlr_dsl_ast_node_t* pb) @@ -200,6 +213,7 @@ char* mlr_dsl_ast_node_describe_type(mlr_dsl_ast_node_type_t type) { case MD_AST_NODE_TYPE_FOR_SREC: return "for_srec"; break; case MD_AST_NODE_TYPE_FOR_OOSVAR: return "for_oosvar"; break; case MD_AST_NODE_TYPE_FOR_VARIABLES: return "for_variables"; break; + case MD_AST_NODE_TYPE_TRIPLE_FOR: return "triple_for"; break; case MD_AST_NODE_TYPE_BOUND_VARIABLE: return "bound_variable"; break; case MD_AST_NODE_TYPE_IN: return "in"; break; case MD_AST_NODE_TYPE_BREAK: return "break"; break; diff --git a/c/containers/mlr_dsl_ast.h b/c/containers/mlr_dsl_ast.h index 822a47b70..bf7c888cc 100644 --- a/c/containers/mlr_dsl_ast.h +++ b/c/containers/mlr_dsl_ast.h @@ -65,6 +65,7 @@ typedef enum _mlr_dsl_ast_node_type_t { MD_AST_NODE_TYPE_FOR_SREC, MD_AST_NODE_TYPE_FOR_OOSVAR, MD_AST_NODE_TYPE_FOR_VARIABLES, + MD_AST_NODE_TYPE_TRIPLE_FOR, MD_AST_NODE_TYPE_BOUND_VARIABLE, MD_AST_NODE_TYPE_IN, MD_AST_NODE_TYPE_BREAK, @@ -98,6 +99,9 @@ mlr_dsl_ast_node_t* mlr_dsl_ast_node_alloc_binary(char* text, mlr_dsl_ast_node_t mlr_dsl_ast_node_t* mlr_dsl_ast_node_alloc_ternary(char* text, mlr_dsl_ast_node_type_t type, mlr_dsl_ast_node_t* pa, mlr_dsl_ast_node_t* pb, mlr_dsl_ast_node_t* pc); +mlr_dsl_ast_node_t* mlr_dsl_ast_node_alloc_quaternary(char* text, mlr_dsl_ast_node_type_t type, + mlr_dsl_ast_node_t* pa, mlr_dsl_ast_node_t* pb, mlr_dsl_ast_node_t* pc, mlr_dsl_ast_node_t* pd); + mlr_dsl_ast_node_t* mlr_dsl_ast_node_copy(mlr_dsl_ast_node_t* pother); // These are so the parser can expand '$x += 1' to '$x = $x + 1', etc. mlr_dsl_ast_node_t* mlr_dsl_ast_tree_copy(mlr_dsl_ast_node_t* pother); diff --git a/c/dsls/mlr_dsl_parse.y b/c/dsls/mlr_dsl_parse.y index 3431fa535..eb03c5fb1 100644 --- a/c/dsls/mlr_dsl_parse.y +++ b/c/dsls/mlr_dsl_parse.y @@ -134,6 +134,7 @@ md_statement_braced_end(A) ::= md_while_block(B). { A = B; } md_statement_braced_end(A) ::= md_for_loop_full_srec(B). { A = B; } md_statement_braced_end(A) ::= md_for_loop_full_oosvar(B). { A = B; } md_statement_braced_end(A) ::= md_for_loop_oosvar(B). { A = B; } +md_statement_braced_end(A) ::= md_triple_for(B). { A = B; } md_statement_braced_end(A) ::= md_if_chain(B). { A = B; } md_statement_not_braced_end(A) ::= MD_TOKEN_SUBR_CALL md_fcn_or_subr_call(B). { @@ -420,6 +421,31 @@ md_for_oosvar_keylist(A) ::= md_for_oosvar_keylist(L) MD_TOKEN_COMMA MD_TOKEN_NO A = mlr_dsl_ast_node_append_arg(L, K); } +// ---------------------------------------------------------------- +md_triple_for(A) ::= + MD_TOKEN_FOR(F) MD_TOKEN_LPAREN + md_triple_for_start(S) MD_TOKEN_SEMICOLON + md_triple_for_condition(C) MD_TOKEN_SEMICOLON + md_triple_for_update(U) + MD_TOKEN_RPAREN + MD_TOKEN_LBRACE + md_statement_list(L) + MD_TOKEN_RBRACE. +{ + A = mlr_dsl_ast_node_alloc_quaternary(F->text, MD_AST_NODE_TYPE_TRIPLE_FOR, S, C, U, L); +} + +// xxx temp +md_triple_for_start(A) ::= md_rhs(B). { + A = B; +} +md_triple_for_condition(A) ::= md_rhs(B). { + A = B; +} +md_triple_for_update(A) ::= md_rhs(B). { + A = B; +} + // ---------------------------------------------------------------- // Cases: // if elif* diff --git a/c/mapping/mlr_dsl_cst.c b/c/mapping/mlr_dsl_cst.c index 52bf03856..510d62a7e 100644 --- a/c/mapping/mlr_dsl_cst.c +++ b/c/mapping/mlr_dsl_cst.c @@ -56,6 +56,7 @@ static cst_statement_allocator_t alloc_while; static cst_statement_allocator_t alloc_do_while; static cst_statement_allocator_t alloc_for_srec; static cst_statement_allocator_t alloc_for_oosvar; +static cst_statement_allocator_t alloc_triple_for; static cst_statement_allocator_t alloc_break; static cst_statement_allocator_t alloc_continue; static cst_statement_allocator_t alloc_filter; @@ -138,6 +139,7 @@ static cst_statement_handler_t handle_while; static cst_statement_handler_t handle_do_while; static cst_statement_handler_t handle_for_srec; static cst_statement_handler_t handle_for_oosvar; +static cst_statement_handler_t handle_triple_for; static cst_statement_handler_t handle_break; static cst_statement_handler_t handle_continue; static cst_statement_handler_t handle_if_head; @@ -631,6 +633,9 @@ mlr_dsl_cst_statement_t* mlr_dsl_cst_alloc_statement(mlr_dsl_cst_t* pcst, mlr_ds case MD_AST_NODE_TYPE_FOR_OOSVAR: return alloc_for_oosvar(pcst, pnode, type_inferencing, context_flags | IN_BREAKABLE); break; + case MD_AST_NODE_TYPE_TRIPLE_FOR: + return alloc_triple_for(pcst, pnode, type_inferencing, context_flags | IN_BREAKABLE); + break; case MD_AST_NODE_TYPE_BREAK: if (!(context_flags & IN_BREAKABLE)) { @@ -1369,6 +1374,72 @@ static mlr_dsl_cst_statement_t* alloc_for_oosvar(mlr_dsl_cst_t* pcst, mlr_dsl_as return pstatement; } +static mlr_dsl_cst_statement_t* alloc_triple_for(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, + int type_inferencing, int context_flags) +{ + mlr_dsl_cst_statement_t* pstatement = alloc_blank(); + +// // Left child node is list of bound variables. +// // Left subnode is namelist for key boundvars. +// // Right subnode is name for value boundvar. +// // Middle child node is keylist for basepoint in the oosvar mlhmmv. +// // Right child node is the list of statements in the body. +// mlr_dsl_ast_node_t* pleft = pnode->pchildren->phead->pvvalue; +// mlr_dsl_ast_node_t* psubleft = pleft->pchildren->phead->pvvalue; +// mlr_dsl_ast_node_t* psubright = pleft->pchildren->phead->pnext->pvvalue; +// mlr_dsl_ast_node_t* pmiddle = pnode->pchildren->phead->pnext->pvvalue; +// mlr_dsl_ast_node_t* pright = pnode->pchildren->phead->pnext->pnext->pvvalue; +// +// pstatement->pfor_oosvar_k_names = slls_alloc(); +// int ok = TRUE; +// hss_t* pnameset = hss_alloc(); +// for (sllve_t* pe = psubleft->pchildren->phead; pe != NULL; pe = pe->pnext) { +// mlr_dsl_ast_node_t* pnamenode = pe->pvvalue; +// slls_append_with_free(pstatement->pfor_oosvar_k_names, mlr_strdup_or_die(pnamenode->text)); +// if (hss_has(pnameset, pnamenode->text)) { +// fprintf(stderr, "%s: duplicate for-loop boundvar \"%s\".\n", +// MLR_GLOBALS.bargv0, pnamenode->text); +// ok = FALSE; +// } +// hss_add(pnameset, pnamenode->text); +// } +// pstatement->for_v_name = psubright->text; +// if (hss_has(pnameset, psubright->text)) { +// fprintf(stderr, "%s: duplicate for-loop boundvar \"%s\".\n", +// MLR_GLOBALS.bargv0, psubright->text); +// ok = FALSE; +// } +// hss_add(pnameset, psubright->text); +// if (!ok) { +// fprintf(stderr, "Boundvars: "); +// for (sllve_t* pe = psubleft->pchildren->phead; pe != NULL; pe = pe->pnext) { +// mlr_dsl_ast_node_t* pnamenode = pe->pvvalue; +// fprintf(stderr, "\"%s\", ", pnamenode->text); +// } +// fprintf(stderr, "\"%s\".\n", psubright->text); +// exit(1); +// } +// +// hss_free(pnameset); +// +// pstatement->poosvar_lhs_keylist_evaluators = allocate_keylist_evaluators_from_oosvar_node( +// pcst, pmiddle, type_inferencing, context_flags); +// + sllv_t* pblock_statements = sllv_alloc(); +// for (sllve_t* pe = pright->pchildren->phead; pe != NULL; pe = pe->pnext) { +// mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue; +// sllv_append(pblock_statements, mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node, +// type_inferencing, context_flags)); +// } + pstatement->pblock_statements = pblock_statements; + pstatement->pframe = bind_stack_frame_alloc_unfenced(); + + pstatement->pnode_handler = handle_triple_for; + pstatement->pblock_handler = handle_statement_list_with_break_continue; + + return pstatement; +} + static mlr_dsl_cst_statement_t* alloc_break(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, int type_inferencing, int context_flags) { @@ -2690,6 +2761,21 @@ static void handle_for_oosvar_aux( } } +// ---------------------------------------------------------------- +static void handle_triple_for( + mlr_dsl_cst_statement_t* pstatement, + variables_t* pvars, + cst_outputs_t* pcst_outputs) +{ + bind_stack_push(pvars->pbind_stack, bind_stack_frame_enter(pstatement->pframe)); + loop_stack_push(pvars->ploop_stack); + + printf("HANDLE_TRIPLE_FOR STUB\n"); + + loop_stack_pop(pvars->ploop_stack); + bind_stack_frame_exit(bind_stack_pop(pvars->pbind_stack)); +} + // ---------------------------------------------------------------- static void handle_break( mlr_dsl_cst_statement_t* pstatement,