Skip to content

Commit 5b29f0c

Browse files
committed
work on values: ordinal, scalar & al.
1 parent 80bb3e3 commit 5b29f0c

3 files changed

Lines changed: 156 additions & 82 deletions

File tree

include/ps_value.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,30 @@ extern "C"
3434
/** @brief Free allocated value */
3535
ps_value *ps_value_free(ps_value *value);
3636

37-
/** @brief Scalar is: Ordinal, Real, *FUTURE* Pointer */
38-
bool ps_value_is_scalar(const ps_value *value);
37+
/** @brief Check if value is valid */
38+
bool ps_value_is_valid(const ps_value *value);
3939
/** @brief Ordinal is: Integer, Unsigned, Integer or Unsigned subrange, Boolean, Char or Enum */
4040
bool ps_value_is_ordinal(const ps_value *value);
41+
/** @brief Scalar is: Ordinal, Real, *FUTURE* Pointer */
42+
bool ps_value_is_scalar(const ps_value *value);
4143
/** @brief Number is: Real, Integer, Unsigned, Integer or Unsigned subrange */
4244
bool ps_value_is_number(const ps_value *value);
43-
/** @brief is Real? */
45+
/** @brief Is Integer? */
46+
bool ps_value_is_integer(const ps_value *value);
47+
/** @brief Is Unsigned? */
48+
bool ps_value_is_unsigned(const ps_value *value);
49+
/** @brief Is Boolean? */
50+
bool ps_value_is_boolean(const ps_value *value);
51+
/** @brief Is Real? */
4452
bool ps_value_is_real(const ps_value *value);
4553
/** @brief Is String? */
4654
bool ps_value_is_string(const ps_value *value);
4755
/** @brief Is Array? */
4856
bool ps_value_is_array(const ps_value *value);
57+
/** @brief Is Enum? */
58+
bool ps_value_is_enum(const ps_value *value);
59+
/** @brief Is Subrange? */
60+
bool ps_value_is_subrange(const ps_value *value);
4961

5062
/** @brief Get type */
5163
/** @returns PS_TYPE_NONE if value is invalid */

src/ps_functions.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ ps_error ps_function_high(ps_interpreter *interpreter, ps_symbol *type, ps_value
354354
return ps_function_low_or_high(interpreter, type, result, false);
355355
}
356356

357-
ps_error ps_function_pred_scalar(const ps_interpreter *interpreter, const ps_value *value, ps_value *result)
357+
ps_error ps_function_pred_IUS(const ps_interpreter *interpreter, const ps_value *value, ps_value *result)
358358
{
359359
switch (ps_value_get_type(value))
360360
{
@@ -436,16 +436,18 @@ ps_error ps_function_pred_ordinal(const ps_interpreter *interpreter, const ps_va
436436
/** @brief PRED - Get previous value (predecessor) of scalar or ordinal value */
437437
ps_error ps_function_pred(ps_interpreter *interpreter, const ps_value *value, ps_value *result)
438438
{
439+
if (!ps_value_is_valid(value))
440+
return ps_function_return_error_with_message(interpreter, PS_ERROR_EXPECTED_VALUE, "Pred: Invalid value");
441+
if (ps_value_is_integer(value) || ps_value_is_unsigned(value) || ps_value_is_subrange(value))
442+
return ps_function_pred_IUS(interpreter, value, result);
439443
if (ps_value_is_ordinal(value))
440444
return ps_function_pred_ordinal(interpreter, value, result);
441-
if (ps_value_is_scalar(value) && !ps_value_is_real(value))
442-
return ps_function_pred_scalar(interpreter, value, result);
443445
return ps_function_return_error_with_message(interpreter, PS_ERROR_UNEXPECTED_TYPE,
444446
"Pred: Ordinal expected, got %s",
445447
ps_type_definition_get_name(value->type->value->data.t));
446448
}
447449

448-
ps_error ps_function_succ_scalar(const ps_interpreter *interpreter, const ps_value *value, ps_value *result)
450+
ps_error ps_function_succ_ius(const ps_interpreter *interpreter, const ps_value *value, ps_value *result)
449451
{
450452
switch (ps_value_get_type(value))
451453
{
@@ -495,7 +497,7 @@ ps_error ps_function_succ_scalar(const ps_interpreter *interpreter, const ps_val
495497
return PS_ERROR_NONE;
496498
}
497499

498-
ps_error ps_function_succ_ordinal(const ps_interpreter *interpreter, const ps_value *value, ps_value *result)
500+
ps_error ps_function_succ_CEB(const ps_interpreter *interpreter, const ps_value *value, ps_value *result)
499501
{
500502
result->type = value->type;
501503
switch (ps_value_get_type(value))
@@ -528,10 +530,12 @@ ps_error ps_function_succ_ordinal(const ps_interpreter *interpreter, const ps_va
528530
/** @brief SUCC - Get next value (successor) of ordinal value */
529531
ps_error ps_function_succ(ps_interpreter *interpreter, const ps_value *value, ps_value *result)
530532
{
531-
if (ps_value_is_scalar(value) && !ps_value_is_real(value))
532-
return ps_function_succ_scalar(interpreter, value, result);
533+
if (!ps_value_is_valid(value))
534+
return ps_function_return_error_with_message(interpreter, PS_ERROR_EXPECTED_VALUE, "Succ: Invalid value");
535+
if (ps_value_is_integer(value) || ps_value_is_unsigned(value) || ps_value_is_subrange(value))
536+
return ps_function_succ_ius(interpreter, value, result);
533537
if (ps_value_is_ordinal(value))
534-
return ps_function_succ_ordinal(interpreter, value, result);
538+
return ps_function_succ_CEB(interpreter, value, result);
535539
return ps_function_return_error_with_message(interpreter, PS_ERROR_UNEXPECTED_TYPE,
536540
"Pred: Ordinal expected, got %s",
537541
ps_type_definition_get_name(value->type->value->data.t));
@@ -876,9 +880,9 @@ ps_error ps_function_random(ps_interpreter *interpreter, const ps_value *value,
876880
else
877881
{
878882
// one argument, return random integer / unsigned
879-
if (!ps_value_is_scalar(value))
883+
if (!(ps_value_is_number(value) && !ps_value_is_real(value)))
880884
return ps_function_return_error_with_message(interpreter, PS_ERROR_EXPECTED_SCALAR,
881-
"Random: Scalar expected, got %s",
885+
"Random: Integer or Unsigned expected, got %s",
882886
ps_type_definition_get_name(value->type->value->data.t));
883887
switch (ps_value_get_base(value))
884888
{

src/ps_value.c

Lines changed: 127 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ ps_value *ps_value_free(ps_value *value)
3737
ps_value_type type = ps_value_get_type(value);
3838
switch (type)
3939
{
40-
// case PS_TYPE_STRING:
41-
// ps_string_free(value->data.s);
42-
// break;
4340
case PS_TYPE_ARRAY:
4441
ps_array_free_data(value->data.a);
4542
break;
@@ -56,15 +53,14 @@ ps_value *ps_value_free(ps_value *value)
5653
return NULL;
5754
}
5855

59-
bool ps_value_is_scalar(const ps_value *value)
56+
bool ps_value_is_valid(const ps_value *value)
6057
{
61-
return value != NULL && value->type != NULL && value->type->value != NULL && value->type->value->data.t != NULL &&
62-
(ps_value_is_ordinal(value) || ps_value_is_real(value));
58+
return value != NULL && value->type != NULL && value->type->value != NULL && value->type->value->data.t != NULL;
6359
}
6460

6561
bool ps_value_is_ordinal(const ps_value *value)
6662
{
67-
if (value != NULL && value->type != NULL && value->type->value != NULL && value->type->value->data.t != NULL)
63+
if (ps_value_is_valid(value))
6864
{
6965
ps_value_type type = value->type->value->data.t->type;
7066
ps_value_type base = value->type->value->data.t->base;
@@ -75,9 +71,14 @@ bool ps_value_is_ordinal(const ps_value *value)
7571
return false;
7672
}
7773

74+
bool ps_value_is_scalar(const ps_value *value)
75+
{
76+
return ps_value_is_ordinal(value) || ps_value_is_real(value);
77+
}
78+
7879
bool ps_value_is_number(const ps_value *value)
7980
{
80-
if (value != NULL && value->type != NULL && value->type->value != NULL && value->type->value->data.t != NULL)
81+
if (ps_value_is_valid(value))
8182
{
8283
ps_value_type type = value->type->value->data.t->type;
8384
ps_value_type base = value->type->value->data.t->base;
@@ -88,9 +89,41 @@ bool ps_value_is_number(const ps_value *value)
8889
return false;
8990
}
9091

92+
bool ps_value_is_integer(const ps_value *value)
93+
{
94+
if (ps_value_is_valid(value))
95+
{
96+
ps_value_type type = value->type->value->data.t->type;
97+
ps_value_type base = value->type->value->data.t->base;
98+
return (type == PS_TYPE_INTEGER || (type == PS_TYPE_SUBRANGE && base == PS_TYPE_INTEGER));
99+
}
100+
return false;
101+
}
102+
103+
bool ps_value_is_unsigned(const ps_value *value)
104+
{
105+
if (ps_value_is_valid(value))
106+
{
107+
ps_value_type type = value->type->value->data.t->type;
108+
ps_value_type base = value->type->value->data.t->base;
109+
return (type == PS_TYPE_UNSIGNED || (type == PS_TYPE_SUBRANGE && base == PS_TYPE_UNSIGNED));
110+
}
111+
return false;
112+
}
113+
114+
bool ps_value_is_boolean(const ps_value *value)
115+
{
116+
if (ps_value_is_valid(value))
117+
{
118+
ps_value_type type = value->type->value->data.t->type;
119+
return type == PS_TYPE_BOOLEAN;
120+
}
121+
return false;
122+
}
123+
91124
bool ps_value_is_real(const ps_value *value)
92125
{
93-
if (value != NULL && value->type != NULL && value->type->value != NULL && value->type->value->data.t != NULL)
126+
if (ps_value_is_valid(value))
94127
{
95128
ps_value_type type = value->type->value->data.t->type;
96129
ps_value_type base = value->type->value->data.t->base;
@@ -102,48 +135,115 @@ bool ps_value_is_real(const ps_value *value)
102135

103136
bool ps_value_is_string(const ps_value *value)
104137
{
105-
if (value != NULL && value->type != NULL && value->type->value != NULL && value->type->value->data.t != NULL)
138+
if (ps_value_is_valid(value))
106139
{
107140
ps_value_type type = value->type->value->data.t->type;
108-
ps_value_type base = value->type->value->data.t->base;
109-
if (type == PS_TYPE_STRING || base == PS_TYPE_STRING)
141+
if (type == PS_TYPE_STRING)
110142
return true;
111143
}
112144
return false;
113145
}
114146

115147
bool ps_value_is_array(const ps_value *value)
116148
{
117-
if (value != NULL && value->type != NULL && value->type->value != NULL && value->type->value->data.t != NULL)
149+
if (ps_value_is_valid(value))
118150
{
119151
ps_value_type type = value->type->value->data.t->type;
120-
ps_value_type base = value->type->value->data.t->base;
121-
if (type == PS_TYPE_ARRAY && base == PS_TYPE_ARRAY)
152+
if (type == PS_TYPE_ARRAY)
153+
return true;
154+
}
155+
return false;
156+
}
157+
158+
bool ps_value_is_enum(const ps_value *value)
159+
{
160+
if (ps_value_is_valid(value))
161+
{
162+
ps_value_type type = value->type->value->data.t->type;
163+
if (type == PS_TYPE_ENUM)
164+
return true;
165+
}
166+
return false;
167+
}
168+
169+
bool ps_value_is_subrange(const ps_value *value)
170+
{
171+
if (ps_value_is_valid(value))
172+
{
173+
ps_value_type type = value->type->value->data.t->type;
174+
if (type == PS_TYPE_SUBRANGE)
122175
return true;
123176
}
124177
return false;
125178
}
126179

127180
ps_value_type ps_value_get_type(const ps_value *value)
128181
{
129-
if (value == NULL || value->type == NULL || value->type->value == NULL || value->type->value->data.t == NULL)
182+
if (!ps_value_is_valid(value))
130183
return PS_TYPE_NONE;
131184
return value->type->value->data.t->type;
132185
}
133186

134187
ps_value_type ps_value_get_base(const ps_value *value)
135188
{
136-
if (value == NULL || value->type == NULL || value->type->value == NULL || value->type->value->data.t == NULL)
189+
if (!ps_value_is_valid(value))
137190
return PS_TYPE_NONE;
138191
return value->type->value->data.t->base;
139192
}
140193

194+
ps_error ps_value_copy_char(const ps_value *from, ps_value *to, bool range_check)
195+
{
196+
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
197+
(from->data.c < to->type->value->data.t->def.g.c.min || from->data.c > to->type->value->data.t->def.g.c.max))
198+
return PS_ERROR_OUT_OF_RANGE;
199+
to->data.c = from->data.c;
200+
return PS_ERROR_NONE;
201+
}
202+
203+
ps_error ps_value_copy_integer(const ps_value *from, ps_value *to, bool range_check)
204+
{
205+
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
206+
(from->data.i < to->type->value->data.t->def.g.i.min || from->data.i > to->type->value->data.t->def.g.i.max))
207+
return PS_ERROR_OUT_OF_RANGE;
208+
to->data.i = from->data.i;
209+
return PS_ERROR_NONE;
210+
}
211+
212+
ps_error ps_value_copy_unsigned(const ps_value *from, ps_value *to, bool range_check)
213+
{
214+
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
215+
(from->data.u < to->type->value->data.t->def.g.u.min || from->data.u > to->type->value->data.t->def.g.u.max))
216+
return PS_ERROR_OUT_OF_RANGE;
217+
to->data.u = from->data.u;
218+
return PS_ERROR_NONE;
219+
}
220+
221+
ps_error ps_value_copy_integer_to_unsigned(const ps_value *from, ps_value *to, bool range_check)
222+
{
223+
if (range_check && from->data.i < 0)
224+
return PS_ERROR_OUT_OF_RANGE;
225+
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
226+
((ps_unsigned)from->data.i < to->type->value->data.t->def.g.u.min ||
227+
(ps_unsigned)from->data.i > to->type->value->data.t->def.g.u.max))
228+
return PS_ERROR_OUT_OF_RANGE;
229+
to->data.u = (ps_unsigned)from->data.i;
230+
return PS_ERROR_NONE;
231+
}
232+
233+
ps_error ps_value_copy_unsigned_to_integer(const ps_value *from, ps_value *to, bool range_check)
234+
{
235+
if (range_check && from->data.u > PS_INTEGER_MAX)
236+
return PS_ERROR_OUT_OF_RANGE;
237+
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
238+
((ps_integer)from->data.u < to->type->value->data.t->def.g.i.min ||
239+
(ps_integer)from->data.u > to->type->value->data.t->def.g.i.max))
240+
return PS_ERROR_OUT_OF_RANGE;
241+
to->data.i = (ps_integer)from->data.u;
242+
return PS_ERROR_NONE;
243+
}
244+
141245
ps_error ps_value_copy(const ps_value *from, ps_value *to, bool range_check)
142246
{
143-
assert(NULL != from);
144-
assert(NULL != from->type);
145-
assert(NULL != to);
146-
assert(NULL != to->type);
147247
ps_value_type from_base = ps_value_get_base(from);
148248
ps_value_type to_base = ps_value_get_base(to);
149249
// If destination type is NONE, set it to source type
@@ -158,63 +258,22 @@ ps_error ps_value_copy(const ps_value *from, ps_value *to, bool range_check)
158258
}
159259
// Enum can only be copied to exact same enum type
160260
if (ps_value_get_type(from) == PS_TYPE_ENUM)
161-
{
162261
return PS_ERROR_TYPE_MISMATCH;
163-
}
164262
// Char => Char? (subrange)
165263
if (from_base == PS_TYPE_CHAR && to_base == PS_TYPE_CHAR)
166-
{
167-
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
168-
(from->data.c < to->type->value->data.t->def.g.c.min ||
169-
from->data.c > to->type->value->data.t->def.g.c.max))
170-
return PS_ERROR_OUT_OF_RANGE;
171-
to->data.c = from->data.c;
172-
return PS_ERROR_NONE;
173-
}
264+
return ps_value_copy_char(from, to, range_check);
174265
// Integer => Integer? (subrange)
175266
if (from_base == PS_TYPE_INTEGER && to_base == PS_TYPE_INTEGER)
176-
{
177-
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
178-
(from->data.i < to->type->value->data.t->def.g.i.min ||
179-
from->data.i > to->type->value->data.t->def.g.i.max))
180-
return PS_ERROR_OUT_OF_RANGE;
181-
to->data.i = from->data.i;
182-
return PS_ERROR_NONE;
183-
}
267+
return ps_value_copy_integer(from, to, range_check);
184268
// Unsigned => Unsigned? (subrange)
185269
if (from_base == PS_TYPE_UNSIGNED && to_base == PS_TYPE_UNSIGNED)
186-
{
187-
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
188-
(from->data.u < to->type->value->data.t->def.g.u.min ||
189-
from->data.u > to->type->value->data.t->def.g.u.max))
190-
return PS_ERROR_OUT_OF_RANGE;
191-
to->data.u = from->data.u;
192-
return PS_ERROR_NONE;
193-
}
270+
return ps_value_copy_unsigned(from, to, range_check);
194271
// Integer => Unsigned?
195272
if (from_base == PS_TYPE_INTEGER && to_base == PS_TYPE_UNSIGNED)
196-
{
197-
if (range_check && from->data.i < 0)
198-
return PS_ERROR_OUT_OF_RANGE;
199-
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
200-
((ps_unsigned)from->data.i < to->type->value->data.t->def.g.u.min ||
201-
(ps_unsigned)from->data.i > to->type->value->data.t->def.g.u.max))
202-
return PS_ERROR_OUT_OF_RANGE;
203-
to->data.u = (ps_unsigned)from->data.i;
204-
return PS_ERROR_NONE;
205-
}
273+
return ps_value_copy_integer_to_unsigned(from, to, range_check);
206274
// Unsigned => Integer?
207275
if (from_base == PS_TYPE_UNSIGNED && to_base == PS_TYPE_INTEGER)
208-
{
209-
if (range_check && from->data.u > PS_INTEGER_MAX)
210-
return PS_ERROR_OUT_OF_RANGE;
211-
if (range_check && ps_value_get_type(to) == PS_TYPE_SUBRANGE &&
212-
((ps_integer)from->data.u < to->type->value->data.t->def.g.i.min ||
213-
(ps_integer)from->data.u > to->type->value->data.t->def.g.i.max))
214-
return PS_ERROR_OUT_OF_RANGE;
215-
to->data.i = (ps_integer)from->data.u;
216-
return PS_ERROR_NONE;
217-
}
276+
return ps_value_copy_unsigned_to_integer(from, to, range_check);
218277
// Integer => Real? (no range check needed, as real can hold all integer values)
219278
if (from_base == PS_TYPE_INTEGER && to_base == PS_TYPE_REAL)
220279
{
@@ -271,8 +330,7 @@ ps_value *ps_value_set_char(ps_value *value, ps_char c)
271330

272331
char *ps_value_get_enum(const ps_value *value)
273332
{
274-
if (value == NULL || value->type == NULL || value->type->value == NULL || value->type->value->data.t == NULL ||
275-
value->type->value->data.t->type != PS_TYPE_ENUM)
333+
if (!ps_value_is_valid(value) || !ps_value_is_enum(value))
276334
return NULL;
277335
const ps_type_definition *type_def = value->type->value->data.t;
278336
ps_symbol **values = type_def->def.e.values;

0 commit comments

Comments
 (0)