index 4291f6c5f402d97b9e5c859056dd107099b31895..ab5419d7d444c39fc645df0c04704756cb0678fd 100644 (file)
--- a/src/oberon-type-compat.c
+++ b/src/oberon-type-compat.c
#include <stdbool.h>
#include <math.h>
-#include "../include/oberon.h"
-
-#include "oberon-common.h"
#include "oberon-internals.h"
#include "oberon-type-compat.h"
+#include "oberon-common.h"
bool
oberon_is_array_type(oberon_type_t * t)
return e -> result -> class == OBERON_TYPE_STRING && e -> is_item && e -> item.mode == MODE_STRING;
}
+bool
+oberon_is_string_of_one(oberon_expr_t * e)
+{
+ return oberon_is_const_string(e) && strlen(e -> item.string) == 1;
+}
+
bool
oberon_is_assignment_compatible_expressions(oberon_expr_t * e, oberon_type_t * Tv)
{
@@ -296,7 +300,7 @@ oberon_is_assignment_compatible_expressions(oberon_expr_t * e, oberon_type_t * T
/* совпадают с параметрами Tv. */
/* Доп: Tv - символ, е - строковая константа из одного символа */
- /* SYSTEM: переменным типа BYTE можно присваивать значения переменных типа CHAR или SHORTINT. */
+ /* SYSTEM: Ð\9fеременным типа BYTE можно присваивать значения переменных типа CHAR или SHORTINT. */
/* SYSTEM: Переменным типа PTR могут быть присвоены значения переменных-указателей любого типа. */
oberon_type_t * Te = e -> result;
@@ -308,7 +312,7 @@ oberon_is_assignment_compatible_expressions(oberon_expr_t * e, oberon_type_t * T
|| ((oberon_is_pointer_type(Tv) || oberon_is_procedure_type(Tv)) && oberon_is_nil_type(Te))
|| (oberon_is_array_of_char_type(Tv) && !oberon_is_open_array(Tv) && oberon_is_const_string(e) && (strlen(e -> item.string) < Tv -> size))
|| (oberon_is_procedure_type(Tv) && e -> is_item && e -> item.var -> class == OBERON_CLASS_PROC && oberon_is_some_procedure_signatures(Tv, e -> result))
- || (oberon_is_char_type(Tv) && oberon_is_const_string(e) && strlen(e -> item.string) == 1)
+ || (oberon_is_char_type(Tv) && oberon_is_string_of_one(e))
|| (oberon_is_system_byte_type(Tv) && (oberon_is_char_type(Te) || oberon_is_byte_type(Te)))
|| (oberon_is_system_ptr_type(Tv) && oberon_is_pointer_type(Te));
}
@@ -344,6 +348,27 @@ oberon_check_compatible_arrays(oberon_context_t * ctx, oberon_object_t * f, ober
}
}
+bool
+oberon_is_compatible_bin_expr(int token, oberon_expr_t * a, oberon_expr_t * b)
+{
+ if(token == EQUAL || token == NEQ || token == LESS || token == LEQ || token == GREAT || token == GEQ)
+ {
+ if((oberon_is_char_type(a -> result) || oberon_is_string_of_one(a))
+ && (oberon_is_char_type(b -> result) || oberon_is_string_of_one(b)))
+ {
+ return true;
+ }
+ else
+ {
+ return oberon_is_compatible_bin_expr_types(token, a -> result, b -> result);
+ }
+ }
+ else
+ {
+ return oberon_is_compatible_bin_expr_types(token, a -> result, b -> result);
+ }
+}
+
bool
oberon_is_compatible_bin_expr_types(int token, oberon_type_t * a, oberon_type_t * b)
{
{
return true;
}
- else if((oberon_is_nil_type(a) || oberon_is_pointer_to_record(a) || oberon_is_procedure_type(a))
- && (oberon_is_nil_type(b) || oberon_is_pointer_to_record(b) || oberon_is_procedure_type(b)))
+ else if((oberon_is_nil_type(a) || oberon_is_pointer_type(a) || oberon_is_procedure_type(a))
+ && (oberon_is_nil_type(b) || oberon_is_pointer_type(b) || oberon_is_procedure_type(b)))
{
return true;
}
/* фактический параметр может быть указателем любого типа. */
return oberon_is_some_types(Tf, Ta)
- || (oberon_is_record_type(Tf) && oberon_extension_of(Ta, Tf))
+ || (oberon_is_record_type(Tf) && oberon_extension_of(Tf, Ta))
+ || (oberon_is_system_byte_type(Tf) && (oberon_is_char_type(Ta) || oberon_is_byte_type(Ta)))
|| (oberon_is_array_of_system_byte_type(Tf))
|| (oberon_is_system_ptr_type(Tf));
}
}
void
-oberon_check_compatible_bin_expr_types(oberon_context_t * ctx, int token, oberon_type_t * a, oberon_type_t * b)
+oberon_check_compatible_bin_expr(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b)
{
- if(!oberon_is_compatible_bin_expr_types(token, a, b))
+ if(!oberon_is_compatible_bin_expr(token, a, b))
{
oberon_error(ctx, "incompatibe expression types");
}