Skip to content

Commit 1037120

Browse files
committed
multi dimensional arrays WIP
1 parent bad6b6a commit 1037120

3 files changed

Lines changed: 121 additions & 119 deletions

File tree

include/ps_array.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ extern "C"
3333
int ps_array_get_dimensions(const ps_symbol *array_type);
3434
/** @brief Get array item type */
3535
ps_symbol *ps_array_get_item_type(const ps_symbol *array);
36-
/** @brief value := array[index] (allocating value if NULL) */
36+
/** @brief value := array[indicies] (allocating value if NULL) */
3737
ps_error ps_array_get_value(const ps_symbol *array, const ps_value *index, ps_value *value, bool range_check);
38-
/** @brief array[index] := value */
39-
ps_error ps_array_set_value(ps_symbol *array, const ps_value *index, const ps_value *value, bool range_check);
40-
38+
/** @brief array[indicies] := value */
39+
ps_error ps_array_set_value(ps_symbol *array_var, const ps_value **indicies, const ps_value *value,
40+
bool range_check);
41+
/** @brief Display (part of) array values */
4142
void ps_array_debug_values(FILE *out, ps_symbol *array_var);
4243

4344
#ifdef __cplusplus

src/ps_array.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ int ps_array_get_dimensions(const ps_symbol *array_type)
9797
ps_symbol_debug(stderr, "ps_array_get_dimensions, array_type: ", array_type);
9898
const ps_type_definition *type_def = ps_array_get_type_def(array_type);
9999
if (type_def == NULL)
100-
return NULL;
100+
return 0;
101101
return type_def->def.a.dimensions;
102102
}
103103

@@ -138,15 +138,15 @@ ps_error ps_array_set_value(ps_symbol *array_var, const ps_value **indicies, con
138138
if (ps_array_debug)
139139
{
140140
ps_symbol_debug(stderr, "PS_ARRAY_SET_VALUE, array_var: ", array_var);
141-
ps_value_debug(stderr, "PS_ARRAY_SET_VALUE, index: ", indicies);
141+
ps_value_debug(stderr, "PS_ARRAY_SET_VALUE, index: ", indicies[0]);
142142
}
143143
if (array_var == NULL || array_var->value == NULL || array_var->value->type == NULL ||
144144
array_var->value->data.a->values == NULL)
145145
return PS_ERROR_INVALID_PARAMETERS;
146-
const ps_symbol *subrange = ps_array_get_subrange(array_var->value->type);
146+
const ps_symbol **subranges = ps_array_get_subranges(array_var->value->type);
147147
// Get offset from index
148148
ps_array_debug = true;
149-
ps_unsigned offset = ps_type_definition_get_subrange_offset(subrange->value->data.t, indicies);
149+
ps_unsigned offset = ps_type_definition_get_subrange_offset(subranges[0]->value->data.t, indicies);
150150
if (offset >= array_var->value->data.a->count)
151151
return PS_ERROR_INVALID_SUBRANGE;
152152
ps_array_debug = false;

src/ps_visit_type.c

Lines changed: 112 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -444,139 +444,91 @@ bool ps_visit_type_reference_enum(ps_interpreter *interpreter, ps_interpreter_mo
444444
return false;
445445
}
446446

447-
bool ps_visit_type_reference_subrange_min_or_max(ps_interpreter *interpreter, ps_interpreter_mode mode, ps_value *value,
448-
ps_value_type *base, ps_type_definition_subrange_char *c,
449-
ps_type_definition_subrange_integer *i,
450-
ps_type_definition_subrange_unsigned *u,
451-
ps_type_definition_subrange_enum *e, bool is_for_min)
447+
bool ps_visit_type_reference_subrange_min(ps_interpreter *interpreter, ps_interpreter_mode mode, ps_value *min_value,
448+
ps_value_type *min_base, ps_type_definition_subrange *subrange)
452449
{
453450
VISIT_BEGIN("TYPE_REFERENCE_SUBRANGE", "")
454451

455-
*base = ps_value_get_type(value);
456-
if (*base == PS_TYPE_CHAR)
452+
if (!ps_visit_constant_expression(interpreter, mode, min_value))
453+
TRACE_ERROR("MIN")
454+
*min_base = ps_value_get_type(min_value);
455+
switch (*min_base)
457456
{
458-
if (ps_value_get_type(value) != PS_TYPE_CHAR)
457+
case PS_TYPE_CHAR:
458+
if (ps_value_get_type(min_value) != PS_TYPE_CHAR)
459459
RETURN_ERROR(PS_ERROR_EXPECTED_CHAR)
460-
if (is_for_min)
461-
c->min = value->data.c;
462-
else
463-
c->max = value->data.c;
464-
}
465-
else if (*base == PS_TYPE_INTEGER)
466-
{
467-
if (ps_value_get_type(value) != PS_TYPE_INTEGER)
460+
subrange->c.min = min_value->data.c;
461+
break;
462+
case PS_TYPE_INTEGER:
463+
if (ps_value_get_type(min_value) != PS_TYPE_INTEGER)
468464
RETURN_ERROR(PS_ERROR_EXPECTED_INTEGER)
469-
if (is_for_min)
470-
i->min = value->data.i;
471-
else
472-
i->max = value->data.i;
473-
}
474-
else if (*base == PS_TYPE_UNSIGNED)
475-
{
476-
if (ps_value_get_type(value) != PS_TYPE_UNSIGNED)
465+
subrange->i.min = min_value->data.i;
466+
break;
467+
case PS_TYPE_UNSIGNED:
468+
if (ps_value_get_type(min_value) != PS_TYPE_UNSIGNED)
477469
RETURN_ERROR(PS_ERROR_EXPECTED_UNSIGNED)
478-
if (is_for_min)
479-
u->min = value->data.u;
480-
else
481-
u->max = value->data.u;
482-
}
483-
else if (base == PS_TYPE_ENUM)
484-
{
485-
if (ps_value_get_type(value) != PS_TYPE_ENUM)
470+
subrange->u.min = min_value->data.u;
471+
break;
472+
case PS_TYPE_ENUM:
473+
if (ps_value_get_type(min_value) != PS_TYPE_ENUM)
486474
RETURN_ERROR(PS_ERROR_EXPECTED_ENUM)
487-
if (is_for_min)
488-
e->min = value->data.u;
489-
else
490-
e->max = value->data.u;
491-
}
492-
else
475+
subrange->e.min = min_value->data.u;
476+
break;
477+
default:
493478
RETURN_ERROR(PS_ERROR_UNEXPECTED_TOKEN)
479+
}
494480

495481
VISIT_END("OK")
496482
}
497483

498-
bool ps_visit_type_reference_subrange(ps_interpreter *interpreter, ps_interpreter_mode mode, ps_symbol **type_symbol,
499-
const char *type_name)
484+
bool ps_visit_type_reference_subrange_max(ps_interpreter *interpreter, ps_interpreter_mode mode, ps_value *max_value,
485+
ps_value_type *max_base, ps_type_definition_subrange *subrange)
500486
{
501-
// NOSONAR interpreter->debug = DEBUG_VERBOSE;
502487
VISIT_BEGIN("TYPE_REFERENCE_SUBRANGE", "")
503488

504-
ps_type_definition_subrange_char c = {0};
505-
ps_type_definition_subrange_integer i = {0};
506-
ps_type_definition_subrange_unsigned u = {0};
507-
ps_type_definition_subrange_enum e = {0};
508-
ps_value min_value = {0};
509-
ps_value tmp_value = {0};
510-
ps_value max_value = {0};
511-
ps_value_type min_base = PS_TYPE_NONE;
512-
ps_value_type max_base = PS_TYPE_NONE;
513-
514-
// Parse min value of subrange as a constant expression
515-
if (!ps_visit_constant_expression(interpreter, mode, &min_value))
516-
TRACE_ERROR("MIN1")
517-
if (!ps_visit_type_reference_subrange_min_or_max(interpreter, mode, &min_value, &min_base, &c, &i, &u, &e, true))
518-
TRACE_ERROR("MIN2")
519-
520-
// Parse '..'
521-
EXPECT_TOKEN(PS_TOKEN_RANGE)
522-
READ_NEXT_TOKEN
523-
524-
// Parse max value of subrange as a constant expression
525-
if (!ps_visit_constant_expression(interpreter, mode, &tmp_value))
526-
TRACE_ERROR("MAX1");
527-
if (!ps_visit_type_reference_subrange_min_or_max(interpreter, mode, &max_value, &max_base, &c, &i, &u, &e, false))
528-
TRACE_ERROR("MAX2")
529-
530-
max_value.type = min_value.type;
531-
if (!ps_interpreter_copy_value(interpreter, &tmp_value, &max_value))
532-
TRACE_ERROR("COPY")
533-
// ps_value_debug(stderr, "==> MAX_VALUE: ", &max_value);
534-
// fprintf(stderr, "======================================================================\n");
535-
max_base = ps_value_get_type(&max_value);
536-
if (max_base != min_base)
537-
{
538-
ps_interpreter_set_message(interpreter, "Min and max value of subrange type mismatch: %s %s",
539-
min_value.type->name, max_value.type->name);
540-
RETURN_ERROR(PS_ERROR_TYPE_MISMATCH)
541-
}
542-
if (max_base == PS_TYPE_CHAR)
489+
if (!ps_visit_constant_expression(interpreter, mode, max_value))
490+
TRACE_ERROR("MAX")
491+
*max_base = ps_value_get_type(max_value);
492+
switch (*max_base)
543493
{
544-
if (ps_value_get_type(&max_value) != PS_TYPE_CHAR)
494+
case PS_TYPE_CHAR:
495+
if (ps_value_get_type(max_value) != PS_TYPE_CHAR)
545496
RETURN_ERROR(PS_ERROR_EXPECTED_CHAR)
546-
c.max = max_value.data.c;
547-
if (c.max <= c.min)
548-
RETURN_ERROR(PS_ERROR_INVALID_SUBRANGE)
549-
}
550-
else if (max_base == PS_TYPE_INTEGER)
551-
{
552-
if (ps_value_get_type(&max_value) != PS_TYPE_INTEGER)
553-
RETURN_ERROR(PS_ERROR_EXPECTED_INTEGER)
554-
i.max = max_value.data.i;
555-
if (i.max <= i.min)
556-
RETURN_ERROR(PS_ERROR_INVALID_SUBRANGE)
557-
}
558-
else if (max_base == PS_TYPE_UNSIGNED)
559-
{
560-
if (ps_value_get_type(&max_value) != PS_TYPE_UNSIGNED)
561-
RETURN_ERROR(PS_ERROR_EXPECTED_INTEGER)
562-
u.max = max_value.data.u;
563-
if (u.max <= u.min)
564-
RETURN_ERROR(PS_ERROR_INVALID_SUBRANGE)
565-
}
566-
else if (max_base == PS_TYPE_ENUM)
567-
{
568-
if (ps_value_get_type(&max_value) != PS_TYPE_ENUM)
497+
subrange->c.max = max_value->data.c;
498+
break;
499+
case PS_TYPE_INTEGER:
500+
if (ps_value_get_type(max_value) != PS_TYPE_INTEGER)
569501
RETURN_ERROR(PS_ERROR_EXPECTED_INTEGER)
570-
u.max = max_value.data.u;
571-
if (u.max <= u.min)
572-
RETURN_ERROR(PS_ERROR_INVALID_SUBRANGE)
573-
}
574-
else
502+
subrange->i.max = max_value->data.i;
503+
break;
504+
case PS_TYPE_UNSIGNED:
505+
if (ps_value_get_type(max_value) != PS_TYPE_UNSIGNED)
506+
RETURN_ERROR(PS_ERROR_EXPECTED_UNSIGNED)
507+
subrange->u.max = max_value->data.u;
508+
break;
509+
case PS_TYPE_ENUM:
510+
if (ps_value_get_type(max_value) != PS_TYPE_ENUM)
511+
RETURN_ERROR(PS_ERROR_EXPECTED_ENUM)
512+
subrange->e.max = max_value->data.u;
513+
break;
514+
default:
575515
RETURN_ERROR(PS_ERROR_UNEXPECTED_TOKEN)
576-
// Create type definition for subrange
516+
}
517+
518+
VISIT_END("OK")
519+
}
520+
521+
bool ps_visit_type_reference_subrange_register_type_def(ps_interpreter *interpreter, ps_interpreter_mode mode,
522+
ps_value_type value_type, char *type_name,
523+
ps_symbol **type_symbol)
524+
{
525+
VISIT_BEGIN("TYPE_REFERENCE_SUBRANGE", "")
526+
577527
ps_type_definition *type_def = NULL;
578528
ps_identifier name = {0};
579-
switch (min_base)
529+
530+
// Create type definition for subrange
531+
switch (value_type)
580532
{
581533
case PS_TYPE_CHAR:
582534
type_def = ps_type_definition_create_subrange_char(c.min, c.max);
@@ -618,6 +570,55 @@ bool ps_visit_type_reference_subrange(ps_interpreter *interpreter, ps_interprete
618570
VISIT_END("OK")
619571
}
620572

573+
bool ps_visit_type_reference_subrange(ps_interpreter *interpreter, ps_interpreter_mode mode, ps_symbol **type_symbol,
574+
const char *type_name)
575+
{
576+
VISIT_BEGIN("TYPE_REFERENCE_SUBRANGE", "")
577+
578+
ps_type_definition_subrange subrange = {0};
579+
ps_value min_value = {0};
580+
ps_value tmp_value = {0};
581+
ps_value max_value = {0};
582+
ps_value_type min_base = PS_TYPE_NONE;
583+
ps_value_type max_base = PS_TYPE_NONE;
584+
585+
// Parse min value of subrange as a constant expression
586+
if (!ps_visit_type_reference_subrange_min(interpreter, mode, &min_value, &min_base, &subrange))
587+
TRACE_ERROR("MIN2")
588+
// Parse '..'
589+
EXPECT_TOKEN(PS_TOKEN_RANGE)
590+
READ_NEXT_TOKEN
591+
// Parse max value of subrange as a constant expression
592+
if (!ps_visit_type_reference_subrange_max(interpreter, mode, &tmp_value, &max_base, &subrange))
593+
TRACE_ERROR("MAX2")
594+
max_value.type = min_value.type;
595+
if (!ps_interpreter_copy_value(interpreter, &tmp_value, &max_value))
596+
{
597+
ps_interpreter_set_message(interpreter, "Min and max value of subrange type mismatch: %s %s",
598+
min_value.type->name, max_value.type->name);
599+
TRACE_ERROR("COPY")
600+
}
601+
// Check that subrange min is less than max
602+
if ((max_base == PS_TYPE_CHAR && subrange.c.max <= subrange.c.min) ||
603+
(max_base == PS_TYPE_INTEGER && subrange.i.max <= subrange.i.min) ||
604+
(max_base == PS_TYPE_UNSIGNED && subrange.u.max <= subrange.u.min))
605+
RETURN_ERROR(PS_ERROR_INVALID_SUBRANGE)
606+
else if (max_base == PS_TYPE_ENUM)
607+
{
608+
if (ps_value_get_type(&max_value) != PS_TYPE_ENUM)
609+
RETURN_ERROR(PS_ERROR_EXPECTED_INTEGER)
610+
if (subrange.u.max <= subrange.u.min)
611+
RETURN_ERROR(PS_ERROR_INVALID_SUBRANGE)
612+
}
613+
else
614+
RETURN_ERROR(PS_ERROR_UNEXPECTED_TYPE)
615+
// Register subrange
616+
if (!ps_visit_type_reference_subrange_register_type_def(interpreter, mode, min_base, type_name, type_symbol))
617+
TRACE_ERROR("TYPE_DEF")
618+
619+
VISIT_END("OK")
620+
}
621+
621622
/**
622623
* 'ARRAY' '[' SUBRANGE | IDENTIFIER [ ',' SUBRANGE | IDENTIFIER ]* ']' 'OF' TYPE_REFERENCE
623624
*/

0 commit comments

Comments
 (0)