summaryrefslogtreecommitdiff
path: root/src/lib/eolian/database_expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/eolian/database_expr.c')
-rw-r--r--src/lib/eolian/database_expr.c165
1 files changed, 130 insertions, 35 deletions
diff --git a/src/lib/eolian/database_expr.c b/src/lib/eolian/database_expr.c
index 1b0a6d10e3..a03c8208a0 100644
--- a/src/lib/eolian/database_expr.c
+++ b/src/lib/eolian/database_expr.c
@@ -7,11 +7,12 @@
#include <Eina.h>
#include "eolian_database.h"
#include "eolian_priv.h"
+#include "eo_lexer.h"
static Eina_Bool
node_error(const Eolian_Object *obj, const char *msg)
{
- _eolian_log_line(obj->file, obj->line, obj->column, "%s", msg);
+ eolian_state_log_obj(obj->unit->state, obj, "%s", msg);
return EINA_FALSE;
}
@@ -182,12 +183,14 @@ promote(Eolian_Expression *a, Eolian_Expression *b)
}
static Eina_Bool eval_exp(const Eolian_Unit *unit,
- const Eolian_Expression *expr,
- Eolian_Expression_Mask mask, Eolian_Expression *out);
+ Eolian_Expression *expr,
+ Eolian_Expression_Mask mask, Eolian_Expression *out,
+ Expr_Obj_Cb cb, void *data);
static Eina_Bool
-eval_unary(const Eolian_Unit *unit, const Eolian_Expression *expr,
- Eolian_Expression_Mask mask, Eolian_Expression *out)
+eval_unary(const Eolian_Unit *unit, Eolian_Expression *expr,
+ Eolian_Expression_Mask mask, Eolian_Expression *out,
+ Expr_Obj_Cb cb, void *data)
{
switch (expr->unop)
{
@@ -197,7 +200,7 @@ eval_unary(const Eolian_Unit *unit, const Eolian_Expression *expr,
if (!(mask & EOLIAN_MASK_SIGNED))
return expr_type_error(expr, EOLIAN_MASK_SIGNED, mask);
- return eval_exp(unit, expr->expr, EOLIAN_MASK_SIGNED, out);
+ return eval_exp(unit, expr->expr, EOLIAN_MASK_SIGNED, out, cb, data);
}
case EOLIAN_UNOP_UNM:
{
@@ -206,7 +209,7 @@ eval_unary(const Eolian_Unit *unit, const Eolian_Expression *expr,
if (!(mask & EOLIAN_MASK_SIGNED))
return expr_type_error(expr, EOLIAN_MASK_SIGNED, mask);
- if (!eval_exp(unit, expr->expr, EOLIAN_MASK_SIGNED, &exp))
+ if (!eval_exp(unit, expr->expr, EOLIAN_MASK_SIGNED, &exp, cb, data))
return EINA_FALSE;
switch (exp.type)
@@ -229,7 +232,7 @@ eval_unary(const Eolian_Unit *unit, const Eolian_Expression *expr,
if (!(mask & EOLIAN_MASK_BOOL))
return expr_type_error(expr, EOLIAN_MASK_BOOL, mask);
- if (!eval_exp(unit, expr->expr, EOLIAN_MASK_NUMBER | EOLIAN_MASK_BOOL, &exp))
+ if (!eval_exp(unit, expr->expr, EOLIAN_MASK_NUMBER | EOLIAN_MASK_BOOL, &exp, cb, data))
return EINA_FALSE;
exp.value.b = !(exp.value.ull);
@@ -245,7 +248,7 @@ eval_unary(const Eolian_Unit *unit, const Eolian_Expression *expr,
if (!(mask & EOLIAN_MASK_INT))
return expr_type_error(expr, EOLIAN_MASK_INT, mask);
- if (!eval_exp(unit, expr->expr, EOLIAN_MASK_INT, &exp))
+ if (!eval_exp(unit, expr->expr, EOLIAN_MASK_INT, &exp, cb, data))
return EINA_FALSE;
switch (exp.type)
@@ -272,19 +275,19 @@ eval_unary(const Eolian_Unit *unit, const Eolian_Expression *expr,
}
static Eina_Bool
-eval_promote_num(const Eolian_Unit *unit, const Eolian_Expression *expr,
+eval_promote_num(const Eolian_Unit *unit, Eolian_Expression *expr,
Eolian_Expression *lhs, Eolian_Expression *rhs, int mask,
- int emask)
+ int emask, Expr_Obj_Cb cb, void *data)
{
/* make sure the output can be a number */
if (!(mask & EOLIAN_MASK_NUMBER))
return expr_type_error(expr, EOLIAN_MASK_NUMBER, mask);
/* eval into primitive value */
- if (!eval_exp(unit, expr->lhs, emask, lhs))
+ if (!eval_exp(unit, expr->lhs, emask, lhs, cb, data))
return EINA_FALSE;
- if (!eval_exp(unit, expr->rhs, emask, rhs))
+ if (!eval_exp(unit, expr->rhs, emask, rhs, cb, data))
return EINA_FALSE;
/* promote so both sides are of the same type */
@@ -295,8 +298,9 @@ eval_promote_num(const Eolian_Unit *unit, const Eolian_Expression *expr,
}
static Eina_Bool
-eval_binary(const Eolian_Unit *unit, const Eolian_Expression *expr,
- Eolian_Expression_Mask mask, Eolian_Expression *out)
+eval_binary(const Eolian_Unit *unit, Eolian_Expression *expr,
+ Eolian_Expression_Mask mask, Eolian_Expression *out,
+ Expr_Obj_Cb cb, void *data)
{
#define APPLY_CASE(id, expr, lhs, rhs, fnm, op) \
case EOLIAN_EXPR_##id: \
@@ -341,7 +345,7 @@ eval_binary(const Eolian_Unit *unit, const Eolian_Expression *expr,
int emask = (mask & EOLIAN_MASK_FLOAT) \
? EOLIAN_MASK_NUMBER \
: EOLIAN_MASK_INT; \
- if (!eval_promote_num(unit, expr, &lhs, &rhs, mask, emask)) \
+ if (!eval_promote_num(unit, expr, &lhs, &rhs, mask, emask, cb, data)) \
return EINA_FALSE; \
APPLY_NUM(out, lhs, rhs, op) \
return EINA_TRUE; \
@@ -352,7 +356,7 @@ eval_binary(const Eolian_Unit *unit, const Eolian_Expression *expr,
{ \
Eolian_Expression lhs; \
Eolian_Expression rhs; \
- if (!eval_promote_num(unit, expr, &lhs, &rhs, mask, EOLIAN_MASK_INT)) \
+ if (!eval_promote_num(unit, expr, &lhs, &rhs, mask, EOLIAN_MASK_INT, cb, data)) \
return EINA_FALSE; \
APPLY_INT(out, lhs, rhs, op) \
return EINA_TRUE; \
@@ -365,9 +369,9 @@ eval_binary(const Eolian_Unit *unit, const Eolian_Expression *expr,
Eolian_Expression rhs; \
if (!(mask & EOLIAN_MASK_BOOL)) \
return expr_type_error(expr, EOLIAN_MASK_BOOL, mask); \
- if (!eval_exp(unit, expr->lhs, allowed, &lhs)) \
+ if (!eval_exp(unit, expr->lhs, allowed, &lhs, cb, data)) \
return EINA_FALSE; \
- if (!eval_exp(unit, expr->rhs, allowed, &rhs)) \
+ if (!eval_exp(unit, expr->rhs, allowed, &rhs, cb, data)) \
return EINA_FALSE; \
if (lhs.type >= EOLIAN_EXPR_STRING && rhs.type != lhs.type) \
return expr_type_mismatch_error(&lhs, &rhs); \
@@ -436,8 +440,9 @@ split_enum_name(const char *str, char **ename, char **memb)
}
static Eina_Bool
-eval_exp(const Eolian_Unit *unit, const Eolian_Expression *expr,
- Eolian_Expression_Mask mask, Eolian_Expression *out)
+eval_exp(const Eolian_Unit *unit, Eolian_Expression *expr,
+ Eolian_Expression_Mask mask, Eolian_Expression *out,
+ Expr_Obj_Cb cb, void *data)
{
switch (expr->type)
{
@@ -469,7 +474,7 @@ eval_exp(const Eolian_Unit *unit, const Eolian_Expression *expr,
}
case EOLIAN_EXPR_STRING:
{
- if (!(mask & EOLIAN_MASK_STRING))
+ if (!(mask & EOLIAN_MASK_STRING) && !(mask & EOLIAN_MASK_NULL))
return expr_type_error(expr, EOLIAN_MASK_STRING, mask);
*out = *expr;
return EINA_TRUE;
@@ -497,9 +502,16 @@ eval_exp(const Eolian_Unit *unit, const Eolian_Expression *expr,
}
case EOLIAN_EXPR_NAME:
{
- const Eolian_Variable *var = eolian_variable_constant_get_by_name
+ if (!unit)
+ {
+ if (!expr->expr)
+ return expr_error(expr, "undefined value");
+ return eval_exp(NULL, expr->expr, mask, out, cb, data);
+ }
+
+ const Eolian_Variable *var = eolian_unit_constant_by_name_get
(unit, expr->value.s);
- const Eolian_Expression *exp = NULL;
+ Eolian_Expression *exp = NULL;
if (!var)
{
@@ -516,16 +528,21 @@ eval_exp(const Eolian_Unit *unit, const Eolian_Expression *expr,
if (!(mask & EOLIAN_MASK_INT))
return expr_type_error(expr, EOLIAN_MASK_INT, mask);
- etpd = eolian_typedecl_alias_get_by_name(unit, fulln);
+ etpd = eolian_unit_alias_by_name_get(unit, fulln);
+ if (etpd && cb) cb((const Eolian_Object *)etpd, data);
while (etpd && etpd->type == EOLIAN_TYPEDECL_ALIAS)
{
const Eolian_Type *etp = eolian_typedecl_base_type_get(etpd);
if (!etp || etp->type != EOLIAN_TYPE_REGULAR)
break;
- etpd = eolian_type_typedecl_get(unit, etp);
+ etpd = database_type_decl_find(unit, etp);
}
- if (!etpd) etpd = eolian_typedecl_enum_get_by_name(unit, fulln);
+ if (!etpd)
+ {
+ etpd = eolian_unit_enum_by_name_get(unit, fulln);
+ if (etpd && cb) cb((const Eolian_Object *)etpd, data);
+ }
if (!etpd || etpd->type != EOLIAN_TYPEDECL_ENUM)
{
free(fulln);
@@ -533,24 +550,28 @@ eval_exp(const Eolian_Unit *unit, const Eolian_Expression *expr,
}
fl = eolian_typedecl_enum_field_get(etpd, memb);
- if (fl) exp = eolian_typedecl_enum_field_value_get(fl, EINA_TRUE);
+ if (fl) exp = (Eolian_Expression *)eolian_typedecl_enum_field_value_get(fl, EINA_TRUE);
free(fulln);
if (!exp)
return expr_error(expr, "invalid enum field");
}
else
- exp = var->value;
+ {
+ exp = (Eolian_Expression *)var->value;
+ if (cb) cb((const Eolian_Object *)var, data);
+ }
if (!exp)
return expr_error(expr, "undefined variable");
- return eval_exp(unit, exp, mask, out);
+ expr->expr = exp;
+ return eval_exp(unit, exp, mask, out, cb, data);
}
case EOLIAN_EXPR_UNARY:
- return eval_unary(unit, expr, mask, out);
+ return eval_unary(unit, expr, mask, out, cb, data);
case EOLIAN_EXPR_BINARY:
- return eval_binary(unit, expr, mask, out);
+ return eval_binary(unit, expr, mask, out, cb, data);
default:
assert(EINA_FALSE);
return EINA_FALSE;
@@ -560,21 +581,95 @@ eval_exp(const Eolian_Unit *unit, const Eolian_Expression *expr,
}
Eolian_Value
-database_expr_eval(const Eolian_Unit *unit, const Eolian_Expression *expr,
- Eolian_Expression_Mask mask)
+database_expr_eval(const Eolian_Unit *unit, Eolian_Expression *expr,
+ Eolian_Expression_Mask mask, Expr_Obj_Cb cb, void *data)
{
Eolian_Expression out;
Eolian_Value ret;
ret.type = EOLIAN_EXPR_UNKNOWN;
if (!mask)
return ret;
- if (!eval_exp(unit, expr, mask, &out))
+ if (!eval_exp(unit, expr, mask, &out, cb, data))
return ret;
ret.type = out.type;
ret.value = out.value;
return ret;
}
+Eolian_Value
+database_expr_eval_type(const Eolian_Unit *unit, Eolian_Expression *expr,
+ const Eolian_Type *type, Expr_Obj_Cb cb, void *data)
+{
+ Eolian_Value err;
+ err.type = EOLIAN_EXPR_UNKNOWN;
+ if (!type)
+ return err;
+ switch (type->type)
+ {
+ case EOLIAN_TYPE_CLASS:
+ return database_expr_eval(unit, expr, EOLIAN_MASK_NULL, cb, data);
+ case EOLIAN_TYPE_REGULAR:
+ {
+ if (database_type_is_ownable(unit, type, EINA_FALSE))
+ return database_expr_eval(unit, expr, EOLIAN_MASK_NULL, cb, data);
+ int kw = eo_lexer_keyword_str_to_id(type->base.name);
+ if (!kw || kw < KW_byte || kw >= KW_void)
+ {
+ const Eolian_Typedecl *base = database_type_decl_find(unit, type);
+ if (!base)
+ return err;
+ if (base->type == EOLIAN_TYPEDECL_ALIAS)
+ return database_expr_eval_type(unit, expr, eolian_typedecl_base_type_get(base), cb, data);
+ else if (base->type == EOLIAN_TYPEDECL_ENUM)
+ return database_expr_eval(unit, expr, EOLIAN_MASK_INT, cb, data);
+ return err;
+ }
+ switch (kw)
+ {
+ case KW_byte:
+ case KW_short:
+ case KW_int:
+ case KW_long:
+ case KW_llong:
+ case KW_int8:
+ case KW_int16:
+ case KW_int32:
+ case KW_int64:
+ case KW_int128:
+ case KW_ssize:
+ case KW_intptr:
+ case KW_ptrdiff:
+ return database_expr_eval(unit, expr, EOLIAN_MASK_SINT, cb, data);
+ case KW_ubyte:
+ case KW_ushort:
+ case KW_uint:
+ case KW_ulong:
+ case KW_ullong:
+ case KW_uint8:
+ case KW_uint16:
+ case KW_uint32:
+ case KW_uint64:
+ case KW_uint128:
+ case KW_size:
+ case KW_uintptr:
+ case KW_time:
+ return database_expr_eval(unit, expr, EOLIAN_MASK_UINT, cb, data);
+ case KW_float:
+ case KW_double:
+ return database_expr_eval(unit, expr, EOLIAN_MASK_FLOAT, cb, data);
+ case KW_bool:
+ return database_expr_eval(unit, expr, EOLIAN_MASK_BOOL, cb, data);
+ case KW_char:
+ return database_expr_eval(unit, expr, EOLIAN_MASK_CHAR, cb, data);
+ default:
+ return err;
+ }
+ }
+ default:
+ return err;
+ }
+}
+
void
database_expr_del(Eolian_Expression *expr)
{