diff --git a/c/mapping/Makefile.am b/c/mapping/Makefile.am index 48594a27a..ab1975e86 100644 --- a/c/mapping/Makefile.am +++ b/c/mapping/Makefile.am @@ -49,7 +49,9 @@ libmapping_la_SOURCES= \ mappers.h \ mlr_dsl_cst.h \ mlr_dsl_cst.c \ - mlr_dsl_cst_analyze.c \ + mlr_dsl_cst_stack_allocate.c \ + mlr_dsl_blocked_ast.c \ + mlr_dsl_blocked_ast.h \ mlr_dsl_cst_func_subr.c \ mlr_dsl_cst_keywords.c \ mlr_dsl_cst_statements.c \ diff --git a/c/mapping/mlr_dsl_cst.c b/c/mapping/mlr_dsl_cst.c index 641d27cab..531c1c61b 100644 --- a/c/mapping/mlr_dsl_cst.c +++ b/c/mapping/mlr_dsl_cst.c @@ -71,11 +71,11 @@ mlr_dsl_cst_t* mlr_dsl_cst_alloc(mlr_dsl_ast_t* past, int print_ast, int type_in mlr_dsl_cst_t* pcst = mlr_malloc_or_die(sizeof(mlr_dsl_cst_t)); - pcst->paast = analyzed_ast_alloc(past); + pcst->paast = blocked_ast_alloc(past); // xxx temp if (print_ast && getenv("MLR_BIND_STACK_ALLOC_DEV")) { - analyzed_ast_allocate_locals(pcst->paast); + blocked_ast_allocate_locals(pcst->paast); } pcst->pbegin_blocks = sllv_alloc(); @@ -232,7 +232,7 @@ void mlr_dsl_cst_free(mlr_dsl_cst_t* pcst) { lhmsv_free(pcst->psubr_defsites); } - analyzed_ast_free(pcst->paast); + blocked_ast_free(pcst->paast); free(pcst); } diff --git a/c/mapping/mlr_dsl_cst.h b/c/mapping/mlr_dsl_cst.h index 0a7a32f8f..291c7cf94 100644 --- a/c/mapping/mlr_dsl_cst.h +++ b/c/mapping/mlr_dsl_cst.h @@ -6,6 +6,7 @@ #include "containers/lhmsmv.h" #include "containers/bind_stack.h" #include "containers/loop_stack.h" +#include "mapping/mlr_dsl_blocked_ast.h" #include "mapping/rval_evaluators.h" #include "mapping/function_manager.h" #include "output/multi_out.h" @@ -52,20 +53,8 @@ // ---------------------------------------------------------------- // xxx comment -typedef struct _analyzed_ast_t { - sllv_t* pfunc_defs; - sllv_t* psubr_defs; - sllv_t* pbegin_blocks; - mlr_dsl_ast_node_t* pmain_block; - sllv_t* pend_blocks; -} analyzed_ast_t; - -// This strips nodes off the raw AST and transfers them to the analyzed AST. -analyzed_ast_t* analyzed_ast_alloc(mlr_dsl_ast_t* past); -void analyzed_ast_free(analyzed_ast_t* paast); - -// xxx comment -void analyzed_ast_allocate_locals(analyzed_ast_t* paast); +// xxx move to own source&header +void blocked_ast_allocate_locals(blocked_ast_t* paast); // ---------------------------------------------------------------- // Forward references for virtual-function prototypes @@ -239,7 +228,7 @@ typedef struct _mlr_dsl_cst_t { // The CST object retains the AST pointer (in order to reuse its strings etc. with minimal copying) // and will free the AST in the CST destructor. - analyzed_ast_t* paast; + blocked_ast_t* paast; } mlr_dsl_cst_t; // ---------------------------------------------------------------- diff --git a/c/mapping/mlr_dsl_cst_analyze.c b/c/mapping/mlr_dsl_stack_allocate.c similarity index 51% rename from c/mapping/mlr_dsl_cst_analyze.c rename to c/mapping/mlr_dsl_stack_allocate.c index 23b19a63f..93504b1fa 100644 --- a/c/mapping/mlr_dsl_cst_analyze.c +++ b/c/mapping/mlr_dsl_stack_allocate.c @@ -1,76 +1,86 @@ #include #include "lib/mlr_globals.h" #include "lib/mlrutil.h" -#include "mlr_dsl_cst.h" -#include "context_flags.h" +#include "containers/free_flags.h" +#include "containers/lhmsi.h" +#include "mapping/mlr_dsl_blocked_ast.h" +#include "mapping/context_flags.h" +// ================================================================ // xxx make a summary comment here +// ================================================================ // ---------------------------------------------------------------- -// xxx have ast freed back where it was (for callsite-balance) but w/ has-been-exfoliated comment -analyzed_ast_t* analyzed_ast_alloc(mlr_dsl_ast_t* past) { - analyzed_ast_t* paast = mlr_malloc_or_die(sizeof(analyzed_ast_t)); +// xxx to do: - paast->pfunc_defs = sllv_alloc(); - paast->psubr_defs = sllv_alloc(); - paast->pbegin_blocks = sllv_alloc(); - paast->pmain_block = mlr_dsl_ast_node_alloc_zary("main_block", MD_AST_NODE_TYPE_STATEMENT_BLOCK); - paast->pend_blocks = sllv_alloc(); +// xxx put 'pass_1' and 'pass_2' in the function names - if (past->proot->type != MD_AST_NODE_TYPE_STATEMENT_BLOCK) { - fprintf(stderr, "%s: internal coding error detected in file %s at line %d:\n", - MLR_GLOBALS.bargv0, __FILE__, __LINE__); - fprintf(stderr, - "expected root node type %s but found %s.\n", - mlr_dsl_ast_node_describe_type(MD_AST_NODE_TYPE_STATEMENT_BLOCK), - mlr_dsl_ast_node_describe_type(past->proot->type)); - exit(1); - } +// * maybe move ast from containers to mapping? - sllv_t* pnodelist = past->proot->pchildren; - while (pnodelist->phead) { - mlr_dsl_ast_node_t* pnode = sllv_pop(pnodelist); - switch (pnode->type) { - case MD_AST_NODE_TYPE_FUNC_DEF: - sllv_append(paast->pfunc_defs, pnode); - break; - case MD_AST_NODE_TYPE_SUBR_DEF: - sllv_append(paast->psubr_defs, pnode); - break; - case MD_AST_NODE_TYPE_BEGIN: - sllv_append(paast->pbegin_blocks, pnode); - break; - case MD_AST_NODE_TYPE_END: - sllv_append(paast->pend_blocks, pnode); - break; - default: - sllv_append(paast->pmain_block->pchildren, pnode); - break; - } - } +// * make a separate file for tree-reorg part into top-level blocks - return paast; -} +// * 'semantic analysis': use this to describe CST-build-time checks +// * 'object binding': use this to describe linking func/subr defs and callsites +// * separate verbosity for allocator? and invoke it in UT cases specific to this? +// -> (note allocation marks in the AST will be printed regardless) + +// * nodestash: +// @ localvar: fridx & upcount; then frgridx +// @ statement block: frct; then maxdepth (default #def NONESUCH @ ctor; respect @ ast-node printer) + +// pass 1: +// @localvar put fridx & upcount +// @exit from statement block put frct + +// pass 2: +// @localvar map fridx & upcount to relidx (>=0 for in-frame, <0 for upframe) +// @base put maxdepth + +// 1 frame_relative_index +// 1 upstack_frame_count +// 2 frame_var_count +// 2 recursive_max_var_count +// 2 absolute_index + +// ================================================================ +typedef struct _stkalc_frame_t { + long long index_count; + lhmsi_t* pnames_to_indices; +} stkalc_frame_t; + +static stkalc_frame_t* stkalc_frame_alloc(); +static void stkalc_frame_free(stkalc_frame_t* pframe); +static int stkalc_frame_has(stkalc_frame_t* pframe, char* name); +static int stkalc_frame_get(stkalc_frame_t* pframe, char* name); +static void stkalc_frame_add(stkalc_frame_t* pframe, char* desc, char* name, int depth, int verbose); // ---------------------------------------------------------------- -void analyzed_ast_free(analyzed_ast_t* paast) { - for (sllve_t* pe = paast->pfunc_defs->phead; pe != NULL; pe = pe->pnext) - mlr_dsl_ast_node_free(pe->pvvalue); - for (sllve_t* pe = paast->psubr_defs->phead; pe != NULL; pe = pe->pnext) - mlr_dsl_ast_node_free(pe->pvvalue); - for (sllve_t* pe = paast->pbegin_blocks->phead; pe != NULL; pe = pe->pnext) - mlr_dsl_ast_node_free(pe->pvvalue); - mlr_dsl_ast_node_free(paast->pmain_block); - for (sllve_t* pe = paast->pend_blocks->phead; pe != NULL; pe = pe->pnext) - mlr_dsl_ast_node_free(pe->pvvalue); +typedef struct _stkalc_frame_group_t { + sllv_t* plist; +} stkalc_frame_group_t; - sllv_free(paast->pfunc_defs); - sllv_free(paast->psubr_defs); - sllv_free(paast->pbegin_blocks); - sllv_free(paast->pend_blocks); - free(paast); +static stkalc_frame_group_t* stkalc_frame_group_alloc(stkalc_frame_t* pframe); +static void stkalc_frame_group_free(stkalc_frame_group_t* pframe_group); +static void stkalc_frame_group_push(stkalc_frame_group_t* pframe_group, stkalc_frame_t* pframe); +static stkalc_frame_t* stkalc_frame_group_pop(stkalc_frame_group_t* pframe_group); -} +static void stkalc_frame_group_mark_for_define(stkalc_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, + char* desc, int verbose); + +static void stkalc_frame_group_mark_for_write(stkalc_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, + char* desc, int verbose); + +static void stkalc_frame_group_mark_for_read(stkalc_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, + char* desc, int verbose); + +// ---------------------------------------------------------------- +static void blocked_ast_allocate_locals_for_func_subr_block(mlr_dsl_ast_node_t* pnode); +static void blocked_ast_allocate_locals_for_begin_end_block(mlr_dsl_ast_node_t* pnode); +static void blocked_ast_allocate_locals_for_main_block(mlr_dsl_ast_node_t* pnode); +static void blocked_ast_allocate_locals_for_statement_block(mlr_dsl_ast_node_t* pnode, + stkalc_frame_group_t* pframe_group); +static void blocked_ast_allocate_locals_for_node(mlr_dsl_ast_node_t* pnode, + stkalc_frame_group_t* pframe_group); // ================================================================ // xxx under construction @@ -157,169 +167,291 @@ void analyzed_ast_free(analyzed_ast_t* paast) { // nothing to do here. // ---------------------------------------------------------------- -// func f(a,b) { -// return a+b; -// } -// subr s(n) { -// print n; -// } -// begin { -// local x = 1; -// } -// end { -// local z = 3; -// } -// local y = 2; +// ---------------------------------------------------------------- +// xxx rename +void blocked_ast_allocate_locals(blocked_ast_t* paast) { + printf("\n"); // xxx temp + for (sllve_t* pe = paast->pfunc_defs->phead; pe != NULL; pe = pe->pnext) { + blocked_ast_allocate_locals_for_func_subr_block(pe->pvvalue); + } + for (sllve_t* pe = paast->psubr_defs->phead; pe != NULL; pe = pe->pnext) { + blocked_ast_allocate_locals_for_func_subr_block(pe->pvvalue); + } + for (sllve_t* pe = paast->pbegin_blocks->phead; pe != NULL; pe = pe->pnext) { + blocked_ast_allocate_locals_for_begin_end_block(pe->pvvalue); + } + blocked_ast_allocate_locals_for_main_block(paast->pmain_block); + for (sllve_t* pe = paast->pend_blocks->phead; pe != NULL; pe = pe->pnext) { + blocked_ast_allocate_locals_for_begin_end_block(pe->pvvalue); + } +} -// ANALYZED AST: -// -// FUNCTION DEFINITION: -// text="f", type=FUNC_DEF: -// text="f", type=NON_SIGIL_NAME: -// text="a", type=NON_SIGIL_NAME. -// text="b", type=NON_SIGIL_NAME. -// text="list", type=STATEMENT_BLOCK: -// text="return_value", type=RETURN_VALUE: -// text="+", type=OPERATOR: -// text="a", type=BOUND_VARIABLE. -// text="b", type=BOUND_VARIABLE. -// -// SUBROUTINE DEFINITION: -// text="s", type=SUBR_DEF: -// text="s", type=NON_SIGIL_NAME: -// text="n", type=NON_SIGIL_NAME. -// text="list", type=STATEMENT_BLOCK: -// text="print", type=PRINT: -// text="n", type=BOUND_VARIABLE. -// text=">", type=FILE_WRITE: -// text="stdout", type=STDOUT: -// -// BEGIN-BLOCK: -// text="begin", type=BEGIN: -// text="list", type=STATEMENT_BLOCK: -// text="local", type=LOCAL: -// text="x", type=BOUND_VARIABLE. -// text="1", type=STRNUM_LITERAL. -// -// END-BLOCK: -// text="end", type=END: -// text="list", type=STATEMENT_BLOCK: -// text="local", type=LOCAL: -// text="z", type=BOUND_VARIABLE. -// text="3", type=STRNUM_LITERAL. -// -// MAIN BLOCK: -// text="main_block", type=STATEMENT_BLOCK: -// text="local", type=LOCAL: -// text="y", type=BOUND_VARIABLE. -// text="2", type=STRNUM_LITERAL. +// ---------------------------------------------------------------- +static void blocked_ast_allocate_locals_for_func_subr_block(mlr_dsl_ast_node_t* pnode) { + // xxx make a keystroke-saver, use it here, & use it from the cst builder as well + if (pnode->type != MD_AST_NODE_TYPE_SUBR_DEF && pnode->type != MD_AST_NODE_TYPE_FUNC_DEF) { + fprintf(stderr, + "%s: internal coding error detected in file %s at line %d.\n", + MLR_GLOBALS.bargv0, __FILE__, __LINE__); + exit(1); + } + // xxx assert two children of desired type + stkalc_frame_t* pframe = stkalc_frame_alloc(); + stkalc_frame_group_t* pframe_group = stkalc_frame_group_alloc(pframe); + + printf("\n"); + printf("ALLOCATING LOCALS FOR DEFINITION BLOCK [%s]\n", pnode->text); + mlr_dsl_ast_node_t* pdef_name_node = pnode->pchildren->phead->pvvalue; + mlr_dsl_ast_node_t* plist_node = pnode->pchildren->phead->pnext->pvvalue; + for (sllve_t* pe = pdef_name_node->pchildren->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_ast_node_t* pparameter_node = pe->pvvalue; + stkalc_frame_group_mark_for_define(pframe_group, pparameter_node, "PARAMETER", TRUE/*xxx temp*/); + } + blocked_ast_allocate_locals_for_statement_block(plist_node, pframe_group); + pnode->frame_var_count = pframe->index_count; + printf("BLK %s frct=%d\n", pnode->text, pnode->frame_var_count); + + stkalc_frame_free(stkalc_frame_group_pop(pframe_group)); + stkalc_frame_group_free(pframe_group); +} + +// ---------------------------------------------------------------- +static void blocked_ast_allocate_locals_for_begin_end_block(mlr_dsl_ast_node_t* pnode) { + if (pnode->type != MD_AST_NODE_TYPE_BEGIN && pnode->type != MD_AST_NODE_TYPE_END) { + fprintf(stderr, + "%s: internal coding error detected in file %s at line %d.\n", + MLR_GLOBALS.bargv0, __FILE__, __LINE__); + exit(1); + } + + printf("\n"); + printf("ALLOCATING LOCALS FOR %s BLOCK\n", pnode->text); + + stkalc_frame_t* pframe = stkalc_frame_alloc(); + stkalc_frame_group_t* pframe_group = stkalc_frame_group_alloc(pframe); + + blocked_ast_allocate_locals_for_statement_block(pnode->pchildren->phead->pvvalue, pframe_group); + pnode->frame_var_count = pframe->index_count; + printf("BLK %s frct=%d\n", pnode->text, pnode->frame_var_count); // xxx fix name + + stkalc_frame_free(stkalc_frame_group_pop(pframe_group)); + stkalc_frame_group_free(pframe_group); +} + +// ---------------------------------------------------------------- +static void blocked_ast_allocate_locals_for_main_block(mlr_dsl_ast_node_t* pnode) { +// xxx assert node type + + printf("\n"); + printf("ALLOCATING LOCALS FOR MAIN BLOCK\n"); + + // xxx make this a one-liner + stkalc_frame_t* pframe = stkalc_frame_alloc(); + stkalc_frame_group_t* pframe_group = stkalc_frame_group_alloc(pframe); + + blocked_ast_allocate_locals_for_statement_block(pnode, pframe_group); + pnode->frame_var_count = pframe->index_count; + printf("BLK %s frct=%d\n", pnode->text, pnode->frame_var_count); // xxx fix name + + stkalc_frame_free(stkalc_frame_group_pop(pframe_group)); + stkalc_frame_group_free(pframe_group); +} + +// ---------------------------------------------------------------- +static void blocked_ast_allocate_locals_for_statement_block(mlr_dsl_ast_node_t* pnode, + stkalc_frame_group_t* pframe_group) +{ + if (pnode->type != MD_AST_NODE_TYPE_STATEMENT_BLOCK) { + fprintf(stderr, + "%s: internal coding error detected in file %s at line %d.\n", + MLR_GLOBALS.bargv0, __FILE__, __LINE__); + exit(1); + } + for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_ast_node_t* pchild = pe->pvvalue; + blocked_ast_allocate_locals_for_node(pchild, pframe_group); + } +} + +// ---------------------------------------------------------------- +static void blocked_ast_allocate_locals_for_node(mlr_dsl_ast_node_t* pnode, + stkalc_frame_group_t* pframe_group) +{ + // xxx make separate functions + + if (pnode->type == MD_AST_NODE_TYPE_FOR_SREC) { // xxx comment + + for (int i = 0; i < pframe_group->plist->length; i++) // xxx temp + printf(":: "); + printf("PUSH FRAME %s\n", pnode->text); + stkalc_frame_t* pnext_frame = stkalc_frame_alloc(); + stkalc_frame_group_push(pframe_group, pnext_frame); + + mlr_dsl_ast_node_t* pvarsnode = pnode->pchildren->phead->pvvalue; + mlr_dsl_ast_node_t* pblocknode = pnode->pchildren->phead->pnext->pvvalue; + + mlr_dsl_ast_node_t* pknode = pvarsnode->pchildren->phead->pvvalue; + mlr_dsl_ast_node_t* pvnode = pvarsnode->pchildren->phead->pnext->pvvalue; + stkalc_frame_group_mark_for_define(pframe_group, pknode, "FOR-BIND", TRUE/*xxx temp*/); + stkalc_frame_group_mark_for_define(pframe_group, pvnode, "FOR-BIND", TRUE/*xxx temp*/); + + blocked_ast_allocate_locals_for_statement_block(pblocknode, pframe_group); + pblocknode->frame_var_count = pnext_frame->index_count; + + stkalc_frame_free(stkalc_frame_group_pop(pframe_group)); + + for (int i = 0; i < pframe_group->plist->length; i++) + printf(":: "); + printf("POP FRAME %s frct=%d\n", pnode->text, pblocknode->frame_var_count); + + } else if (pnode->type == MD_AST_NODE_TYPE_FOR_OOSVAR) { // xxx comment + + mlr_dsl_ast_node_t* pvarsnode = pnode->pchildren->phead->pvvalue; + mlr_dsl_ast_node_t* pkeylistnode = pnode->pchildren->phead->pnext->pvvalue; + mlr_dsl_ast_node_t* pblocknode = pnode->pchildren->phead->pnext->pnext->pvvalue; + + mlr_dsl_ast_node_t* pkeysnode = pvarsnode->pchildren->phead->pvvalue; + mlr_dsl_ast_node_t* pvalnode = pvarsnode->pchildren->phead->pnext->pvvalue; + + // xxx note keylistnode is outside the block binding. in particular if there are any localvar reads + // in there they shouldn't read from forloop boundvars. + for (sllve_t* pe = pkeylistnode->pchildren->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_ast_node_t* pchild = pe->pvvalue; + blocked_ast_allocate_locals_for_node(pchild, pframe_group); + } + + for (int i = 0; i < pframe_group->plist->length; i++) // xxx temp + printf(":: "); + printf("PUSH FRAME %s\n", pnode->text); + stkalc_frame_t* pnext_frame = stkalc_frame_alloc(); + stkalc_frame_group_push(pframe_group, pnext_frame); + + for (sllve_t* pe = pkeysnode->pchildren->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_ast_node_t* pkeynode = pe->pvvalue; + stkalc_frame_group_mark_for_define(pframe_group, pkeynode, "FOR-BIND", TRUE/*xxx temp*/); + } + stkalc_frame_group_mark_for_define(pframe_group, pvalnode, "FOR-BIND", TRUE/*xxx temp*/); + blocked_ast_allocate_locals_for_statement_block(pblocknode, pframe_group); + // xxx make accessor ... + pblocknode->frame_var_count = pnext_frame->index_count; + + stkalc_frame_free(stkalc_frame_group_pop(pframe_group)); + for (int i = 0; i < pframe_group->plist->length; i++) + printf(":: "); + printf("POP FRAME %s frct=%d\n", pnode->text, pblocknode->frame_var_count); + + } else if (pnode->type == MD_AST_NODE_TYPE_LOCAL_DEFINITION) { + // xxx decide on preorder vs. postorder + mlr_dsl_ast_node_t* pnamenode = pnode->pchildren->phead->pvvalue; + + stkalc_frame_group_mark_for_define(pframe_group, pnamenode, "DEFINE", TRUE/*xxx temp*/); + mlr_dsl_ast_node_t* pvaluenode = pnode->pchildren->phead->pnext->pvvalue; + blocked_ast_allocate_locals_for_node(pvaluenode, pframe_group); + + } else if (pnode->type == MD_AST_NODE_TYPE_LOCAL_ASSIGNMENT) { // xxx rename + mlr_dsl_ast_node_t* pnamenode = pnode->pchildren->phead->pvvalue; + stkalc_frame_group_mark_for_write(pframe_group, pnamenode, "WRITE", TRUE/*xxx temp*/); + mlr_dsl_ast_node_t* pvaluenode = pnode->pchildren->phead->pnext->pvvalue; + blocked_ast_allocate_locals_for_node(pvaluenode, pframe_group); + + } else if (pnode->type == MD_AST_NODE_TYPE_BOUND_VARIABLE) { + stkalc_frame_group_mark_for_read(pframe_group, pnode, "READ", TRUE/*xxx temp*/); + + } else if (pnode->pchildren != NULL) { + for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_ast_node_t* pchild = pe->pvvalue; + + if (pchild->type == MD_AST_NODE_TYPE_STATEMENT_BLOCK) { + + for (int i = 0; i < pframe_group->plist->length; i++) // xxx temp + printf(":: "); + printf("PUSH FRAME %s\n", pchild->text); + + stkalc_frame_t* pnext_frame = stkalc_frame_alloc(); + stkalc_frame_group_push(pframe_group, pnext_frame); + + blocked_ast_allocate_locals_for_statement_block(pchild, pframe_group); + pchild->frame_var_count = pnext_frame->index_count; + + stkalc_frame_free(stkalc_frame_group_pop(pframe_group)); + + for (int i = 0; i < pframe_group->plist->length; i++) + printf(":: "); + printf("POP FRAME %s frct=%d\n", pnode->text, pchild->frame_var_count); + + } else { + blocked_ast_allocate_locals_for_node(pchild, pframe_group); + } + } + } +} // ================================================================ -// xxx move to separate file - -// xxx analysis -> stack_allocation; saf & safg acronyms -// xxx put 'pass_1' and 'pass_2' in the function names - -// ================================================================ -typedef struct _analysis_frame_t { - long long index_count; - lhmsi_t* pnames_to_indices; -} analysis_frame_t; - -static analysis_frame_t* analysis_frame_alloc(); - -static void analysis_frame_free(analysis_frame_t* pframe); - -static int analysis_frame_has(analysis_frame_t* pframe, char* name); - -static int analysis_frame_get(analysis_frame_t* pframe, char* name); - -static void analysis_frame_add(analysis_frame_t* pframe, char* desc, char* name, int depth, int verbose); - -static analysis_frame_t* analysis_frame_alloc() { - analysis_frame_t* pframe = mlr_malloc_or_die(sizeof(analysis_frame_t)); +static stkalc_frame_t* stkalc_frame_alloc() { + stkalc_frame_t* pframe = mlr_malloc_or_die(sizeof(stkalc_frame_t)); pframe->index_count = 0; pframe->pnames_to_indices = lhmsi_alloc(); return pframe; } -static void analysis_frame_free(analysis_frame_t* pframe) { +static void stkalc_frame_free(stkalc_frame_t* pframe) { if (pframe == NULL) return; lhmsi_free(pframe->pnames_to_indices); free(pframe); } -static int analysis_frame_has(analysis_frame_t* pframe, char* name) { +static int stkalc_frame_has(stkalc_frame_t* pframe, char* name) { return lhmsi_has_key(pframe->pnames_to_indices, name); } -static int analysis_frame_get(analysis_frame_t* pframe, char* name) { +static int stkalc_frame_get(stkalc_frame_t* pframe, char* name) { return lhmsi_get(pframe->pnames_to_indices, name); } -static void analysis_frame_add(analysis_frame_t* pframe, char* desc, char* name, int depth, int verbose) { +static void stkalc_frame_add(stkalc_frame_t* pframe, char* desc, char* name, int depth, int verbose) { lhmsi_put(pframe->pnames_to_indices, name, pframe->index_count, NO_FREE); pframe->index_count++; } // ================================================================ -typedef struct _analysis_frame_group_t { - sllv_t* plist; -} analysis_frame_group_t; - -static analysis_frame_group_t* analysis_frame_group_alloc(analysis_frame_t* pframe); -static void analysis_frame_group_free(analysis_frame_group_t* pframe_group); -static void analysis_frame_group_push(analysis_frame_group_t* pframe_group, analysis_frame_t* pframe); -static analysis_frame_t* analysis_frame_group_pop(analysis_frame_group_t* pframe_group); - -// xxx shorten names by a lot -- e.g. "af_" and "afg_". -static void analysis_frame_group_mark_for_define(analysis_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, - char* desc, int verbose); - -static void analysis_frame_group_mark_for_write(analysis_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, - char* desc, int verbose); - -static void analysis_frame_group_mark_for_read(analysis_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, - char* desc, int verbose); - -static analysis_frame_group_t* analysis_frame_group_alloc(analysis_frame_t* pframe) { - analysis_frame_group_t* pframe_group = mlr_malloc_or_die(sizeof(analysis_frame_group_t)); +static stkalc_frame_group_t* stkalc_frame_group_alloc(stkalc_frame_t* pframe) { + stkalc_frame_group_t* pframe_group = mlr_malloc_or_die(sizeof(stkalc_frame_group_t)); pframe_group->plist = sllv_alloc(); sllv_prepend(pframe_group->plist, pframe); return pframe_group; } -static void analysis_frame_group_free(analysis_frame_group_t* pframe_group) { +static void stkalc_frame_group_free(stkalc_frame_group_t* pframe_group) { if (pframe_group == NULL) return; while (pframe_group->plist->phead != NULL) { - analysis_frame_free(sllv_pop(pframe_group->plist)); + stkalc_frame_free(sllv_pop(pframe_group->plist)); } sllv_free(pframe_group->plist); free(pframe_group); } -static void analysis_frame_group_push(analysis_frame_group_t* pframe_group, analysis_frame_t* pframe) { +static void stkalc_frame_group_push(stkalc_frame_group_t* pframe_group, stkalc_frame_t* pframe) { sllv_prepend(pframe_group->plist, pframe); } -static analysis_frame_t* analysis_frame_group_pop(analysis_frame_group_t* pframe_group) { +static stkalc_frame_t* stkalc_frame_group_pop(stkalc_frame_group_t* pframe_group) { return sllv_pop(pframe_group->plist); } -static void analysis_frame_group_mark_for_define(analysis_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, +static void stkalc_frame_group_mark_for_define(stkalc_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, char* desc, int verbose) { char* op = "REUSE"; - analysis_frame_t* pframe = pframe_group->plist->phead->pvvalue; - if (!analysis_frame_has(pframe, pnode->text)) { - analysis_frame_add(pframe, desc, pnode->text, pframe_group->plist->length, verbose); + stkalc_frame_t* pframe = pframe_group->plist->phead->pvvalue; + if (!stkalc_frame_has(pframe, pnode->text)) { + stkalc_frame_add(pframe, desc, pnode->text, pframe_group->plist->length, verbose); op = "ADD"; } pnode->upstack_frame_count = 0; - pnode->frame_relative_index = analysis_frame_get(pframe, pnode->text); + pnode->frame_relative_index = stkalc_frame_get(pframe, pnode->text); if (verbose) { for (int i = 1; i < pframe_group->plist->length; i++) { printf(":: "); @@ -329,7 +461,7 @@ static void analysis_frame_group_mark_for_define(analysis_frame_group_t* pframe_ } } -static void analysis_frame_group_mark_for_write(analysis_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, +static void stkalc_frame_group_mark_for_write(stkalc_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, char* desc, int verbose) { char* op = "REUSE"; @@ -337,18 +469,18 @@ static void analysis_frame_group_mark_for_write(analysis_frame_group_t* pframe_g // xxx loop. if not found, fall back to top frame. pnode->upstack_frame_count = 0; for (sllve_t* pe = pframe_group->plist->phead; pe != NULL; pe = pe->pnext, pnode->upstack_frame_count++) { - analysis_frame_t* pframe = pe->pvvalue; - if (analysis_frame_has(pframe, pnode->text)) { + stkalc_frame_t* pframe = pe->pvvalue; + if (stkalc_frame_has(pframe, pnode->text)) { found = TRUE; // xxx dup - pnode->frame_relative_index = analysis_frame_get(pframe, pnode->text); + pnode->frame_relative_index = stkalc_frame_get(pframe, pnode->text); break; } } if (!found) { pnode->upstack_frame_count = 0; - analysis_frame_t* pframe = pframe_group->plist->phead->pvvalue; - analysis_frame_add(pframe, desc, pnode->text, pnode->upstack_frame_count, verbose); + stkalc_frame_t* pframe = pframe_group->plist->phead->pvvalue; + stkalc_frame_add(pframe, desc, pnode->text, pnode->upstack_frame_count, verbose); // xxx temp pnode->frame_relative_index = pframe->index_count; op = "ADD"; @@ -363,17 +495,17 @@ static void analysis_frame_group_mark_for_write(analysis_frame_group_t* pframe_g } } -static void analysis_frame_group_mark_for_read(analysis_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, +static void stkalc_frame_group_mark_for_read(stkalc_frame_group_t* pframe_group, mlr_dsl_ast_node_t* pnode, char* desc, int verbose) { int found = FALSE; // xxx loop. if not found, fall back to top frame. pnode->upstack_frame_count = 0; for (sllve_t* pe = pframe_group->plist->phead; pe != NULL; pe = pe->pnext, pnode->upstack_frame_count++) { - analysis_frame_t* pframe = pe->pvvalue; - if (analysis_frame_has(pframe, pnode->text)) { + stkalc_frame_t* pframe = pe->pvvalue; + if (stkalc_frame_has(pframe, pnode->text)) { found = TRUE; // xxx dup - pnode->frame_relative_index = analysis_frame_get(pframe, pnode->text); + pnode->frame_relative_index = stkalc_frame_get(pframe, pnode->text); break; } } @@ -394,248 +526,3 @@ static void analysis_frame_group_mark_for_read(analysis_frame_group_t* pframe_gr } } } - -// ================================================================ -static void analyzed_ast_allocate_locals_for_func_subr_block(mlr_dsl_ast_node_t* pnode); -static void analyzed_ast_allocate_locals_for_begin_end_block(mlr_dsl_ast_node_t* pnode); -static void analyzed_ast_allocate_locals_for_main_block(mlr_dsl_ast_node_t* pnode); -static void analyzed_ast_allocate_locals_for_statement_block(mlr_dsl_ast_node_t* pnode, - analysis_frame_group_t* pframe_group); -static void analyzed_ast_allocate_locals_for_node(mlr_dsl_ast_node_t* pnode, - analysis_frame_group_t* pframe_group); - -// ---------------------------------------------------------------- -void analyzed_ast_allocate_locals(analyzed_ast_t* paast) { - printf("\n"); // xxx temp - for (sllve_t* pe = paast->pfunc_defs->phead; pe != NULL; pe = pe->pnext) { - analyzed_ast_allocate_locals_for_func_subr_block(pe->pvvalue); - } - for (sllve_t* pe = paast->psubr_defs->phead; pe != NULL; pe = pe->pnext) { - analyzed_ast_allocate_locals_for_func_subr_block(pe->pvvalue); - } - for (sllve_t* pe = paast->pbegin_blocks->phead; pe != NULL; pe = pe->pnext) { - analyzed_ast_allocate_locals_for_begin_end_block(pe->pvvalue); - } - analyzed_ast_allocate_locals_for_main_block(paast->pmain_block); - for (sllve_t* pe = paast->pend_blocks->phead; pe != NULL; pe = pe->pnext) { - analyzed_ast_allocate_locals_for_begin_end_block(pe->pvvalue); - } -} - -// ---------------------------------------------------------------- -static void analyzed_ast_allocate_locals_for_func_subr_block(mlr_dsl_ast_node_t* pnode) { - // xxx make a keystroke-saver, use it here, & use it from the cst builder as well - if (pnode->type != MD_AST_NODE_TYPE_SUBR_DEF && pnode->type != MD_AST_NODE_TYPE_FUNC_DEF) { - fprintf(stderr, - "%s: internal coding error detected in file %s at line %d.\n", - MLR_GLOBALS.bargv0, __FILE__, __LINE__); - exit(1); - } - // xxx assert two children of desired type - - analysis_frame_t* pframe = analysis_frame_alloc(); - analysis_frame_group_t* pframe_group = analysis_frame_group_alloc(pframe); - - printf("\n"); - printf("ALLOCATING LOCALS FOR DEFINITION BLOCK [%s]\n", pnode->text); - mlr_dsl_ast_node_t* pdef_name_node = pnode->pchildren->phead->pvvalue; - mlr_dsl_ast_node_t* plist_node = pnode->pchildren->phead->pnext->pvvalue; - for (sllve_t* pe = pdef_name_node->pchildren->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_ast_node_t* pparameter_node = pe->pvvalue; - analysis_frame_group_mark_for_define(pframe_group, pparameter_node, "PARAMETER", TRUE/*xxx temp*/); - } - analyzed_ast_allocate_locals_for_statement_block(plist_node, pframe_group); - - analysis_frame_free(analysis_frame_group_pop(pframe_group)); - analysis_frame_group_free(pframe_group); -} - -// ---------------------------------------------------------------- -static void analyzed_ast_allocate_locals_for_begin_end_block(mlr_dsl_ast_node_t* pnode) { - if (pnode->type != MD_AST_NODE_TYPE_BEGIN && pnode->type != MD_AST_NODE_TYPE_END) { - fprintf(stderr, - "%s: internal coding error detected in file %s at line %d.\n", - MLR_GLOBALS.bargv0, __FILE__, __LINE__); - exit(1); - } - - printf("\n"); - printf("ALLOCATING LOCALS FOR %s BLOCK\n", pnode->text); - - analysis_frame_t* pframe = analysis_frame_alloc(); - analysis_frame_group_t* pframe_group = analysis_frame_group_alloc(pframe); - - analyzed_ast_allocate_locals_for_statement_block(pnode->pchildren->phead->pvvalue, pframe_group); - - analysis_frame_free(analysis_frame_group_pop(pframe_group)); - analysis_frame_group_free(pframe_group); -} - -// ---------------------------------------------------------------- -static void analyzed_ast_allocate_locals_for_main_block(mlr_dsl_ast_node_t* pnode) { -// xxx assert node type - - printf("\n"); - printf("ALLOCATING LOCALS FOR MAIN BLOCK\n"); - - // xxx make this a one-liner - analysis_frame_t* pframe = analysis_frame_alloc(); - analysis_frame_group_t* pframe_group = analysis_frame_group_alloc(pframe); - - analyzed_ast_allocate_locals_for_statement_block(pnode, pframe_group); - - analysis_frame_free(analysis_frame_group_pop(pframe_group)); - analysis_frame_group_free(pframe_group); -} - -// ---------------------------------------------------------------- -static void analyzed_ast_allocate_locals_for_statement_block(mlr_dsl_ast_node_t* pnode, - analysis_frame_group_t* pframe_group) -{ - if (pnode->type != MD_AST_NODE_TYPE_STATEMENT_BLOCK) { - fprintf(stderr, - "%s: internal coding error detected in file %s at line %d.\n", - MLR_GLOBALS.bargv0, __FILE__, __LINE__); - exit(1); - } - for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_ast_node_t* pchild = pe->pvvalue; - analyzed_ast_allocate_locals_for_node(pchild, pframe_group); - } -} - -static void analyzed_ast_allocate_locals_for_node(mlr_dsl_ast_node_t* pnode, - analysis_frame_group_t* pframe_group) -{ - // xxx make separate functions - - if (pnode->type == MD_AST_NODE_TYPE_FOR_SREC) { // xxx comment - - for (int i = 0; i < pframe_group->plist->length; i++) // xxx temp - printf(":: "); - printf("PUSH FRAME %s\n", pnode->text); - analysis_frame_t* pnext_frame = analysis_frame_alloc(); - analysis_frame_group_push(pframe_group, pnext_frame); - - mlr_dsl_ast_node_t* pvarsnode = pnode->pchildren->phead->pvvalue; - mlr_dsl_ast_node_t* pblocknode = pnode->pchildren->phead->pnext->pvvalue; - - mlr_dsl_ast_node_t* pknode = pvarsnode->pchildren->phead->pvvalue; - mlr_dsl_ast_node_t* pvnode = pvarsnode->pchildren->phead->pnext->pvvalue; - analysis_frame_group_mark_for_define(pframe_group, pknode, "FOR-BIND", TRUE/*xxx temp*/); - analysis_frame_group_mark_for_define(pframe_group, pvnode, "FOR-BIND", TRUE/*xxx temp*/); - - analyzed_ast_allocate_locals_for_statement_block(pblocknode, pframe_group); - - analysis_frame_free(analysis_frame_group_pop(pframe_group)); - for (int i = 0; i < pframe_group->plist->length; i++) - printf(":: "); - printf("POP FRAME %s\n", pnode->text); - - } else if (pnode->type == MD_AST_NODE_TYPE_FOR_OOSVAR) { // xxx comment - - mlr_dsl_ast_node_t* pvarsnode = pnode->pchildren->phead->pvvalue; - mlr_dsl_ast_node_t* pkeylistnode = pnode->pchildren->phead->pnext->pvvalue; - mlr_dsl_ast_node_t* pblocknode = pnode->pchildren->phead->pnext->pnext->pvvalue; - - mlr_dsl_ast_node_t* pkeysnode = pvarsnode->pchildren->phead->pvvalue; - mlr_dsl_ast_node_t* pvalnode = pvarsnode->pchildren->phead->pnext->pvvalue; - - // xxx note keylistnode is outside the block binding. in particular if there are any localvar reads - // in there they shouldn't read from forloop boundvars. - for (sllve_t* pe = pkeylistnode->pchildren->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_ast_node_t* pchild = pe->pvvalue; - analyzed_ast_allocate_locals_for_node(pchild, pframe_group); - } - - for (int i = 0; i < pframe_group->plist->length; i++) // xxx temp - printf(":: "); - printf("PUSH FRAME %s\n", pnode->text); - analysis_frame_t* pnext_frame = analysis_frame_alloc(); - analysis_frame_group_push(pframe_group, pnext_frame); - - for (sllve_t* pe = pkeysnode->pchildren->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_ast_node_t* pkeynode = pe->pvvalue; - analysis_frame_group_mark_for_define(pframe_group, pkeynode, "FOR-BIND", TRUE/*xxx temp*/); - } - analysis_frame_group_mark_for_define(pframe_group, pvalnode, "FOR-BIND", TRUE/*xxx temp*/); - analyzed_ast_allocate_locals_for_statement_block(pblocknode, pframe_group); - - analysis_frame_free(analysis_frame_group_pop(pframe_group)); - for (int i = 0; i < pframe_group->plist->length; i++) - printf(":: "); - printf("POP FRAME %s\n", pnode->text); - - } else if (pnode->type == MD_AST_NODE_TYPE_LOCAL_DEFINITION) { - // xxx decide on preorder vs. postorder - mlr_dsl_ast_node_t* pnamenode = pnode->pchildren->phead->pvvalue; - - analysis_frame_group_mark_for_define(pframe_group, pnamenode, "DEFINE", TRUE/*xxx temp*/); - mlr_dsl_ast_node_t* pvaluenode = pnode->pchildren->phead->pnext->pvvalue; - analyzed_ast_allocate_locals_for_node(pvaluenode, pframe_group); - - } else if (pnode->type == MD_AST_NODE_TYPE_LOCAL_ASSIGNMENT) { // xxx rename - mlr_dsl_ast_node_t* pnamenode = pnode->pchildren->phead->pvvalue; - analysis_frame_group_mark_for_write(pframe_group, pnamenode, "WRITE", TRUE/*xxx temp*/); - mlr_dsl_ast_node_t* pvaluenode = pnode->pchildren->phead->pnext->pvvalue; - analyzed_ast_allocate_locals_for_node(pvaluenode, pframe_group); - - } else if (pnode->type == MD_AST_NODE_TYPE_BOUND_VARIABLE) { - analysis_frame_group_mark_for_read(pframe_group, pnode, "READ", TRUE/*xxx temp*/); - - } else if (pnode->pchildren != NULL) { - for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_ast_node_t* pchild = pe->pvvalue; - - if (pchild->type == MD_AST_NODE_TYPE_STATEMENT_BLOCK) { - - for (int i = 0; i < pframe_group->plist->length; i++) // xxx temp - printf(":: "); - printf("PUSH FRAME %s\n", pchild->text); - - analysis_frame_t* pnext_frame = analysis_frame_alloc(); - analysis_frame_group_push(pframe_group, pnext_frame); - - analyzed_ast_allocate_locals_for_statement_block(pchild, pframe_group); - - analysis_frame_free(analysis_frame_group_pop(pframe_group)); - - for (int i = 0; i < pframe_group->plist->length; i++) - printf(":: "); - printf("POP FRAME %s\n", pchild->text); - - } else { - analyzed_ast_allocate_locals_for_node(pchild, pframe_group); - } - } - } -} - -// xxx to do: - -// * make a separate file for tree-reorg part into top-level blocks - -// * rename entire file; also 'analysis' & its acronyms -// ->maybe blocked_asts? vs. raw_ast? -// * 'semantic analysis': use this to describe CST-build-time checks -// * 'object binding': use this to describe linking func/subr defs and callsites -// * separate verbosity for allocator? and invoke it in UT cases specific to this? -// -> (note allocation marks in the AST will be printed regardless) - -// * nodestash: -// @ localvar: fridx & upcount; then frgridx -// @ statement block: frct; then maxdepth (default #def NONESUCH @ ctor; respect @ ast-node printer) - -// pass 1: -// @localvar put fridx & upcount -// @exit from statement block put frct - -// pass 2: -// @localvar map fridx & upcount to relidx (>=0 for in-frame, <0 for upframe) -// @base put maxdepth - -// 1 frame_relative_index -// 1 upstack_frame_count -// 2 frame_var_count -// 2 recursive_max_var_count -// 2 absolute_index diff --git a/doc/manpage.html b/doc/manpage.html index 7afdafd0d..b9c5b0261 100644 --- a/doc/manpage.html +++ b/doc/manpage.html @@ -1871,7 +1871,7 @@ SEE ALSO - 2016-10-05 MILLER(1) + 2016-10-07 MILLER(1)

diff --git a/doc/manpage.txt b/doc/manpage.txt index 18207ecab..5c1513058 100644 --- a/doc/manpage.txt +++ b/doc/manpage.txt @@ -1724,4 +1724,4 @@ SEE ALSO - 2016-10-05 MILLER(1) + 2016-10-07 MILLER(1) diff --git a/doc/mlr.1 b/doc/mlr.1 index bf005e0fb..7617dba27 100644 --- a/doc/mlr.1 +++ b/doc/mlr.1 @@ -2,12 +2,12 @@ .\" Title: mlr .\" Author: [see the "AUTHOR" section] .\" Generator: ./mkman.rb -.\" Date: 2016-10-05 +.\" Date: 2016-10-07 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MILLER" "1" "2016-10-05" "\ \&" "\ \&" +.TH "MILLER" "1" "2016-10-07" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Portability definitions .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~