mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-25 00:48:56 +00:00
disallow indexed reads of localvars declared non-map
This commit is contained in:
parent
127c949d49
commit
5a3466aebf
5 changed files with 82 additions and 44 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue