mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-25 17:04:01 +00:00
bind-stack allocation iterate: label statement blocks with frame-var count
This commit is contained in:
parent
25fcca6e24
commit
24ee024fc2
7 changed files with 326 additions and 448 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,76 +1,86 @@
|
|||
#include <stdlib.h>
|
||||
#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
|
||||
|
|
@ -1871,7 +1871,7 @@ SEE ALSO
|
|||
|
||||
|
||||
|
||||
2016-10-05 MILLER(1)
|
||||
2016-10-07 MILLER(1)
|
||||
</pre>
|
||||
</div>
|
||||
<p/>
|
||||
|
|
|
|||
|
|
@ -1724,4 +1724,4 @@ SEE ALSO
|
|||
|
||||
|
||||
|
||||
2016-10-05 MILLER(1)
|
||||
2016-10-07 MILLER(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
|
||||
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue