Skip to content

Commit

Permalink
Allow map reference variable to be initialized with a nested struct v…
Browse files Browse the repository at this point in the history
…ariable
  • Loading branch information
positively-charged committed May 18, 2017
1 parent 48d58c1 commit 5c7e346
Showing 1 changed file with 39 additions and 9 deletions.
48 changes: 39 additions & 9 deletions src/semantic/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ static void test_subscript( struct semantic* semantic, struct expr_test* test,
static void test_subscript_array( struct semantic* semantic,
struct expr_test* test, struct result* result, struct result* lside,
struct subscript* subscript );
static void warn_bounds_violation( struct semantic* semantic,
static bool warn_bounds_violation( struct semantic* semantic,
struct subscript* subscript, const char* subject, int upper_bound );
static void test_subscript_str( struct semantic* semantic,
struct expr_test* test, struct result* result, struct result* lside,
Expand Down Expand Up @@ -1610,21 +1610,17 @@ static void test_subscript_array( struct semantic* semantic,
s_bail( semantic );
}
// Out-of-bounds warning for a constant index.
bool out_of_bounds = false;
if ( lside->dim && lside->dim->length && subscript->index->folded ) {
warn_bounds_violation( semantic, subscript, "dimension-length",
lside->dim->length );
out_of_bounds = warn_bounds_violation( semantic, subscript,
"dimension-length", lside->dim->length );
}
enum subscript_result element = s_subscript_array_ref( semantic,
&lside->type, &result->type );
switch ( element ) {
case SUBSCRIPTRESULT_SUBARRAY:
result->data_origin = lside->data_origin;
if ( lside->dim ) {
if ( subscript->index->folded ) {
result->value = lside->value +
lside->dim->element_size * subscript->index->value;
result->folded = true;
}
result->dim = lside->dim->next;
}
break;
Expand All @@ -1640,18 +1636,40 @@ static void test_subscript_array( struct semantic* semantic,
if ( lside->type.ref->nullable ) {
semantic->lib->uses_nullable_refs = true;
}
// Compile-time evaluation.
switch ( element ) {
case SUBSCRIPTRESULT_SUBARRAY:
case SUBSCRIPTRESULT_STRUCT:
if ( lside->folded && subscript->index->folded && ! out_of_bounds ) {
result->value = lside->value +
lside->dim->element_size * subscript->index->value;
result->folded = true;
}
break;
case SUBSCRIPTRESULT_REF:
case SUBSCRIPTRESULT_PRIMITIVE:
break;
default:
UNREACHABLE();
s_bail( semantic );
}
}

static void warn_bounds_violation( struct semantic* semantic,
static bool warn_bounds_violation( struct semantic* semantic,
struct subscript* subscript, const char* subject, int upper_bound ) {
if ( subscript->index->value < 0 ) {
s_diag( semantic, DIAG_WARN | DIAG_POS, &subscript->index->pos,
"index out-of-bounds: index (%d) < 0", subscript->index->value );
return true;
}
else if ( subscript->index->value >= upper_bound ) {
s_diag( semantic, DIAG_WARN | DIAG_POS, &subscript->index->pos,
"index out-of-bounds: index (%d) >= %s (%d)",
subscript->index->value, subject, upper_bound );
return true;
}
else {
return false;
}
}

Expand Down Expand Up @@ -2814,6 +2832,18 @@ static void select_structure_member( struct semantic* semantic,
}
result->complete = true;
result->usable = true;
// Compile-time evaluation.
switch ( s_describe_type( &result->type ) ) {
case TYPEDESC_ARRAYREF:
case TYPEDESC_STRUCTREF:
if ( lside->folded ) {
result->value = lside->value + member->offset;
result->folded = true;
}
break;
default:
break;
}
}

static void select_func( struct semantic* semantic, struct result* result,
Expand Down

0 comments on commit 5c7e346

Please sign in to comment.