diff --git a/c/containers/local_stack.c b/c/containers/local_stack.c index c0b1edd0e..bfd11032a 100644 --- a/c/containers/local_stack.c +++ b/c/containers/local_stack.c @@ -106,6 +106,10 @@ mv_t local_stack_frame_ref_terminal_from_indexed(local_stack_frame_t* pframe, local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index]; mlhmmv_xvalue_t* pbase_xval = &pentry->xvalue; + if (!(TYPE_MASK_MAP & pentry->type_mask)) { + local_stack_frame_throw_type_mismatch_for_read(pentry); + } + #ifdef LOCAL_STACK_TRACE_ENABLE // xxx needs an mlhmmv_xvalue_print if (pbase_xval == NULL) { @@ -146,8 +150,8 @@ mv_t local_stack_frame_ref_terminal_from_indexed(local_stack_frame_t* pframe, } // ---------------------------------------------------------------- -mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_indexed(local_stack_frame_t* pframe, - int vardef_frame_relative_index, sllmv_t* pmvkeys) +mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_nonindexed(local_stack_frame_t* pframe, + int vardef_frame_relative_index) { LOCAL_STACK_TRACE(printf("LOCAL STACK FRAME %p GET %d\n", pframe, vardef_frame_relative_index)); LOCAL_STACK_BOUNDS_CHECK(pframe, "GET", FALSE, vardef_frame_relative_index); @@ -172,14 +176,43 @@ mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_indexed(local_stack_frame_t } #endif - int error = 0; - // Maybe null - if (pmvkeys == NULL || pmvkeys->length == 0) { - return pmvalue; - } else { - return mlhmmv_level_look_up_and_ref_xvalue(pmvalue->pnext_level, pmvkeys, &error); + return pmvalue; +} + +// ---------------------------------------------------------------- +mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_indexed(local_stack_frame_t* pframe, + int vardef_frame_relative_index, sllmv_t* pmvkeys) +{ + LOCAL_STACK_TRACE(printf("LOCAL STACK FRAME %p GET %d\n", pframe, vardef_frame_relative_index)); + LOCAL_STACK_BOUNDS_CHECK(pframe, "GET", FALSE, vardef_frame_relative_index); + + local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index]; + mlhmmv_xvalue_t* pmvalue = &pentry->xvalue; + + if (!(TYPE_MASK_MAP & pentry->type_mask)) { + local_stack_frame_throw_type_mismatch_for_read(pentry); } +#ifdef LOCAL_STACK_TRACE_ENABLE + // xxx needs an mlhmmv_xvalue_print + if (pmvalue == NULL) { + printf("VALUE IS NULL\n"); + } else if (pmvalue->is_terminal) { + char* s = mv_alloc_format_val(&pmvalue->terminal_mlrval); + printf("VALUE IS %s\n", s); + free(s); + } else if (pmvalue->pnext_level == NULL) { + LOCAL_STACK_TRACE(printf("VALUE IS EMPTY\n")); + } else { + printf("VALUE IS:\n"); + printf("PTR IS %p\n", pmvalue->pnext_level); + mlhmmv_level_print_stacked(pmvalue->pnext_level, 0, TRUE, TRUE, "", stdout); + } +#endif + + int error = 0; + // Maybe null + return mlhmmv_level_look_up_and_ref_xvalue(pmvalue->pnext_level, pmvkeys, &error); } // ---------------------------------------------------------------- @@ -194,7 +227,7 @@ void local_stack_frame_define_terminal(local_stack_frame_t* pframe, char* variab pentry->type_mask = type_mask; if (!(type_mask_from_mv(&val) & pentry->type_mask)) { - local_stack_frame_throw_type_mismatch(pentry, &val); + local_stack_frame_throw_type_mismatch_for_write(pentry, &val); } mlhmmv_xvalue_free(&pentry->xvalue); @@ -219,11 +252,11 @@ void local_stack_frame_define_extended(local_stack_frame_t* pframe, char* variab if (xval.is_terminal) { if (!(type_mask_from_mv(&xval.terminal_mlrval) & pentry->type_mask)) { - local_stack_frame_throw_type_mismatch(pentry, &xval.terminal_mlrval); + local_stack_frame_throw_type_mismatch_for_write(pentry, &xval.terminal_mlrval); } } else { if (!(TYPE_MASK_MAP & pentry->type_mask)) { - local_stack_frame_throw_type_mismatch(pentry, &xval.terminal_mlrval); + local_stack_frame_throw_type_mismatch_for_write(pentry, &xval.terminal_mlrval); } } @@ -243,7 +276,7 @@ void local_stack_frame_assign_terminal_indexed(local_stack_frame_t* pframe, local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index]; if (!(TYPE_MASK_MAP & pentry->type_mask)) { - local_stack_frame_throw_type_mismatch(pentry, &terminal_value); + local_stack_frame_throw_type_mismatch_for_write(pentry, &terminal_value); } mlhmmv_xvalue_t* pmvalue = &pentry->xvalue; @@ -268,11 +301,11 @@ void local_stack_frame_assign_extended_nonindexed(local_stack_frame_t* pframe, if (xval.is_terminal) { if (!(type_mask_from_mv(&xval.terminal_mlrval) & pentry->type_mask)) { - local_stack_frame_throw_type_mismatch(pentry, &xval.terminal_mlrval); + local_stack_frame_throw_type_mismatch_for_write(pentry, &xval.terminal_mlrval); } } else { if (!(TYPE_MASK_MAP & pentry->type_mask)) { - local_stack_frame_throw_type_mismatch(pentry, &xval.terminal_mlrval); + local_stack_frame_throw_type_mismatch_for_write(pentry, &xval.terminal_mlrval); } } @@ -290,7 +323,7 @@ void local_stack_frame_assign_extended_indexed(local_stack_frame_t* pframe, local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index]; if (!(TYPE_MASK_MAP & pentry->type_mask)) { - local_stack_frame_throw_type_xmismatch(pentry, &new_value); + local_stack_frame_throw_type_xmismatch_for_write(pentry, &new_value); } mlhmmv_xvalue_t* pmvalue = &pentry->xvalue; @@ -331,7 +364,7 @@ void local_stack_bounds_check(local_stack_frame_t* pframe, char* op, int set, in } // ---------------------------------------------------------------- -void local_stack_frame_throw_type_mismatch(local_stack_frame_entry_t* pentry, mv_t* pval) { +void local_stack_frame_throw_type_mismatch_for_write(local_stack_frame_entry_t* pentry, mv_t* pval) { MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL); char* sval = mv_alloc_format_val_quoting_strings(pval); fprintf(stderr, "%s: %s type assertion for variable %s unmet by value %s with type %s.\n", @@ -341,7 +374,7 @@ void local_stack_frame_throw_type_mismatch(local_stack_frame_entry_t* pentry, mv exit(1); } -void local_stack_frame_throw_type_xmismatch(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval) { +void local_stack_frame_throw_type_xmismatch_for_write(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval) { MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL); char* sval = mv_alloc_format_val_quoting_strings(&pxval->terminal_mlrval); // xxx temp fprintf(stderr, "%s: %s type assertion for variable %s unmet by value %s with type %s.\n", @@ -350,3 +383,18 @@ void local_stack_frame_throw_type_xmismatch(local_stack_frame_entry_t* pentry, m free(sval); exit(1); } + +// ---------------------------------------------------------------- +void local_stack_frame_throw_type_mismatch_for_read(local_stack_frame_entry_t* pentry) { + MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL); + fprintf(stderr, "%s: %s type assertion for variable %s unmet on read.\n", + MLR_GLOBALS.bargv0, type_mask_to_desc(pentry->type_mask), pentry->name); + exit(1); +} + +void local_stack_frame_throw_type_xmismatch_for_read(local_stack_frame_entry_t* pentry) { + MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL); + fprintf(stderr, "%s: %s type assertion for variable %s unmet on read.\n", + MLR_GLOBALS.bargv0, type_mask_to_desc(pentry->type_mask), pentry->name); + exit(1); +} diff --git a/c/containers/local_stack.h b/c/containers/local_stack.h index e35949ad6..14219307d 100644 --- a/c/containers/local_stack.h +++ b/c/containers/local_stack.h @@ -82,8 +82,10 @@ void local_stack_bounds_check(local_stack_frame_t* pframe, char* op, int set, in local_stack_frame_t* local_stack_frame_enter(local_stack_frame_t* pframe); void local_stack_frame_exit(local_stack_frame_t* pframe); -void local_stack_frame_throw_type_mismatch(local_stack_frame_entry_t* pentry, mv_t* pval); -void local_stack_frame_throw_type_xmismatch(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval); +void local_stack_frame_throw_type_mismatch_for_write(local_stack_frame_entry_t* pentry, mv_t* pval); +void local_stack_frame_throw_type_xmismatch_for_write(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval); +void local_stack_frame_throw_type_mismatch_for_read(local_stack_frame_entry_t* pentry); +void local_stack_frame_throw_type_xmismatch_for_read(local_stack_frame_entry_t* pentry); // ---------------------------------------------------------------- static inline mv_t local_stack_frame_get_terminal_from_nonindexed(local_stack_frame_t* pframe, // move to reference semantics @@ -109,7 +111,7 @@ static inline void local_stack_frame_assign_terminal_nonindexed(local_stack_fram local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index]; if (!(type_mask_from_mv(&val) & pentry->type_mask)) { // xxx temp - local_stack_frame_throw_type_mismatch(pentry, &val); + local_stack_frame_throw_type_mismatch_for_write(pentry, &val); } mlhmmv_xvalue_free(&pentry->xvalue); @@ -120,6 +122,9 @@ static inline void local_stack_frame_assign_terminal_nonindexed(local_stack_fram mv_t local_stack_frame_ref_terminal_from_indexed(local_stack_frame_t* pframe, int vardef_frame_relative_index, sllmv_t* pmvkeys); +mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_nonindexed(local_stack_frame_t* pframe, + int vardef_frame_relative_index); + mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_indexed(local_stack_frame_t* pframe, int vardef_frame_relative_index, sllmv_t* pmvkeys); diff --git a/c/dsl/mlr_dsl_cst_func_subr.c b/c/dsl/mlr_dsl_cst_func_subr.c index 964c57bfd..a7e11138d 100644 --- a/c/dsl/mlr_dsl_cst_func_subr.c +++ b/c/dsl/mlr_dsl_cst_func_subr.c @@ -240,27 +240,6 @@ static void cst_udf_type_check_return_value(cst_udf_state_t* pstate, mlhmmv_xval } } -// xxx incorp -//void local_stack_frame_throw_type_mismatch(local_stack_frame_entry_t* pentry, mv_t* pval) { -// MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL); -// char* sval = mv_alloc_format_val_quoting_strings(pval); -// fprintf(stderr, "%s: %s type assertion for variable %s unmet by value %s with type %s.\n", -// MLR_GLOBALS.bargv0, type_mask_to_desc(pentry->type_mask), pentry->name, -// sval, mt_describe_type_simple(pval->type)); -// free(sval); -// exit(1); -//} -// -//void local_stack_frame_throw_type_xmismatch(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval) { -// MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL); -// char* sval = mv_alloc_format_val_quoting_strings(&pxval->terminal_mlrval); // xxx temp -// fprintf(stderr, "%s: %s type assertion for variable %s unmet by value %s with type %s.\n", -// MLR_GLOBALS.bargv0, type_mask_to_desc(pentry->type_mask), pentry->name, -// sval, mlhmmv_xvalue_describe_type_simple(pxval)); -// free(sval); -// exit(1); -//} - // ---------------------------------------------------------------- // Callback function for the function manager to invoke into here diff --git a/c/dsl/rxval_expr_evaluators.c b/c/dsl/rxval_expr_evaluators.c index 89066eb6c..1f92ca1b9 100644 --- a/c/dsl/rxval_expr_evaluators.c +++ b/c/dsl/rxval_expr_evaluators.c @@ -265,8 +265,8 @@ typedef struct _rxval_evaluator_from_nonindexed_local_variable_state_t { static boxed_xval_t rxval_evaluator_from_nonindexed_local_variable_func(void* pvstate, variables_t* pvars) { rxval_evaluator_from_nonindexed_local_variable_state_t* pstate = pvstate; local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); - mlhmmv_xvalue_t* pxval = local_stack_frame_ref_extended_from_indexed( - pframe, pstate->vardef_frame_relative_index, NULL); + mlhmmv_xvalue_t* pxval = local_stack_frame_ref_extended_from_nonindexed( + pframe, pstate->vardef_frame_relative_index); if (pxval == NULL) { return (boxed_xval_t) { .xval = mlhmmv_xvalue_wrap_terminal(mv_absent()), diff --git a/c/todo.txt b/c/todo.txt index 477c64d78..8f5d456a0 100644 --- a/c/todo.txt +++ b/c/todo.txt @@ -36,7 +36,8 @@ MAPVAR CHECKLIST: ! assert_map/assert_scalar/etc. -! this should throw an error: mlr --from s put 'int a=1;var b=a[2]' +! this should throw an error: + mlr --from ../c/s put 'int a=1;var b=a[2]' ! 'Local variables' 'Notes:' split into surprising and unsurprising @@ -171,6 +172,11 @@ k assign LHS full-srec from RHS func-retval alloc ephem & move ---------------------------------------------------------------- EXECUTION TRACE: +! missing operators + $ mlr --from ../c/s put -T 'int a=1;var b=a[2]' + TRACE (int a 1) + TRACE (var b (a 2)) + ! trace *assignments* (mutations of pvars state) * work through the grammar & neaten up pnode->text instances, now that these names are user-visible.