eolian: new APIs for expression analysis

This adds a few new APIs to retrieve the type of an expression, operators
for binary and unary expressions, lhs/rhs for binary expressions, expr for
unary expressions and value for other expressions.
This commit is contained in:
Daniel Kolesa 2014-09-02 13:32:47 +01:00
parent 1a58ad78ab
commit 0998f2af5c
3 changed files with 189 additions and 38 deletions

View File

@ -217,6 +217,44 @@ typedef struct _Eolian_Value
Eolian_Value_Union value;
} Eolian_Value;
typedef enum
{
EOLIAN_BINOP_INVALID = -1,
EOLIAN_BINOP_ADD, /* + int, float */
EOLIAN_BINOP_SUB, /* - int, float */
EOLIAN_BINOP_MUL, /* * int, float */
EOLIAN_BINOP_DIV, /* / int, float */
EOLIAN_BINOP_MOD, /* % int */
EOLIAN_BINOP_EQ, /* == all types */
EOLIAN_BINOP_NQ, /* != all types */
EOLIAN_BINOP_GT, /* > int, float */
EOLIAN_BINOP_LT, /* < int, float */
EOLIAN_BINOP_GE, /* >= int, float */
EOLIAN_BINOP_LE, /* <= int, float */
EOLIAN_BINOP_AND, /* && all types */
EOLIAN_BINOP_OR, /* || all types */
EOLIAN_BINOP_BAND, /* & int */
EOLIAN_BINOP_BOR, /* | int */
EOLIAN_BINOP_BXOR, /* ^ int */
EOLIAN_BINOP_LSH, /* << int */
EOLIAN_BINOP_RSH /* >> int */
} Eolian_Binary_Operator;
typedef enum
{
EOLIAN_UNOP_INVALID = -1,
EOLIAN_UNOP_UNM, /* - sint */
EOLIAN_UNOP_UNP, /* + sint */
EOLIAN_UNOP_NOT, /* ! int, float, bool */
EOLIAN_UNOP_BNOT, /* ~ int */
} Eolian_Unary_Operator;
/*
* @brief Parse a given .eo file and fill the database.
*
@ -1540,6 +1578,94 @@ EAPI Eina_Stringshare *eolian_expression_value_to_literal(const Eolian_Value *v)
*/
EAPI Eina_Stringshare *eolian_expression_serialize(const Eolian_Expression *expr);
/*
* @brief Get the type of an expression.
*
* @param[in] expr the expression.
* @return the expression type.
*
* @ingroup Eolian
*/
EAPI Eolian_Expression_Type eolian_expression_type_get(const Eolian_Expression *expr);
/*
* @brief Get the binary operator of an expression.
*
* @param[in] expr the expression.
* @return the binary operator, EOLIAN_BINOP_INVALID on failure.
*
* This only works on binary expressions, otherwise it returns
* EOLIAN_BINOP_INVALID.
*
* @ingroup Eolian
*/
EAPI Eolian_Binary_Operator eolian_expression_binary_operator_get(const Eolian_Expression *expr);
/*
* @brief Get the lhs (left hand side) of a binary expression.
*
* @param[in] expr the expression.
* @return the expression or NULL.
*
* This only works on binary expressions, otherwise it returns NULL.
*
* @ingroup Eolian
*/
EAPI const Eolian_Expression *eolian_expression_binary_lhs_get(const Eolian_Expression *expr);
/*
* @brief Get the rhs (right hand side) of a binary expression.
*
* @param[in] expr the expression.
* @return the expression or NULL.
*
* This only works on binary expressions, otherwise it returns NULL.
*
* @ingroup Eolian
*/
EAPI const Eolian_Expression *eolian_expression_binary_rhs_get(const Eolian_Expression *expr);
/*
* @brief Get the unary operator of an expression.
*
* @param[in] expr the expression.
* @return the unary operator, EOLIAN_UNOP_INVALID on failure.
*
* This only works on unary expressions, otherwise it returns
* EOLIAN_UNOP_INVALID.
*
* @ingroup Eolian
*/
EAPI Eolian_Unary_Operator eolian_expression_unary_operator_get(const Eolian_Expression *expr);
/*
* @brief Get the expression of an unary expression.
*
* @param[in] expr the expression.
* @return the expression or NULL.
*
* This only works on unary expressions, otherwise it returns NULL.
*
* @ingroup Eolian
*/
EAPI const Eolian_Expression *eolian_expression_unary_expression_get(const Eolian_Expression *expr);
/*
* @brief Get the value of an expression.
*
* @param[in] expr the expression.
* @return the value.
*
* Keep in mind that this doesn't evaluate anything. That's why it only works
* on expressions that actually hold values (not unknown, not binary, not
* unary). For some types of expressions (enum, name), this stores the actual
* name (in the value.s field). Resources for this are held by the database.
* Don't attempt to free the string or anything like that.
*
* @ingroup Eolian
*/
EAPI Eolian_Value eolian_expression_value_get(const Eolian_Expression *expr);
/*
* @brief Get a global variable by name. Supports namespaces.
*

View File

@ -285,3 +285,66 @@ eolian_expression_serialize(const Eolian_Expression *expr)
eina_strbuf_free(buf);
return ret;
}
EAPI Eolian_Expression_Type
eolian_expression_type_get(const Eolian_Expression *expr)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EOLIAN_EXPR_UNKNOWN);
return expr->type;
}
EAPI Eolian_Binary_Operator
eolian_expression_binary_operator_get(const Eolian_Expression *expr)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EOLIAN_BINOP_INVALID);
EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_BINARY,
EOLIAN_BINOP_INVALID);
return expr->binop;
}
EAPI const Eolian_Expression *
eolian_expression_binary_lhs_get(const Eolian_Expression *expr)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(expr, NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_BINARY, NULL);
return expr->lhs;
}
EAPI const Eolian_Expression *
eolian_expression_binary_rhs_get(const Eolian_Expression *expr)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(expr, NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_BINARY, NULL);
return expr->rhs;
}
EAPI Eolian_Unary_Operator
eolian_expression_unary_operator_get(const Eolian_Expression *expr)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EOLIAN_UNOP_INVALID);
EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_UNARY,
EOLIAN_UNOP_INVALID);
return expr->unop;
}
EAPI const Eolian_Expression *
eolian_expression_unary_expression_get(const Eolian_Expression *expr)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(expr, NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_UNARY, NULL);
return expr->expr;
}
EAPI Eolian_Value
eolian_expression_value_get(const Eolian_Expression *expr)
{
Eolian_Value v;
v.type = EOLIAN_EXPR_UNKNOWN;
EINA_SAFETY_ON_NULL_RETURN_VAL(expr, v);
EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type != EOLIAN_EXPR_UNKNOWN
&& expr->type != EOLIAN_EXPR_BINARY
&& expr->type != EOLIAN_EXPR_UNARY, v);
v.type = expr->type;
v.value = expr->value;
return v;
}

View File

@ -201,44 +201,6 @@ struct _Eolian_Enum_Type_Field
Eina_Stringshare *comment;
};
typedef enum
{
EOLIAN_BINOP_INVALID = -1,
EOLIAN_BINOP_ADD, /* + int, float */
EOLIAN_BINOP_SUB, /* - int, float */
EOLIAN_BINOP_MUL, /* * int, float */
EOLIAN_BINOP_DIV, /* / int, float */
EOLIAN_BINOP_MOD, /* % int */
EOLIAN_BINOP_EQ, /* == all types */
EOLIAN_BINOP_NQ, /* != all types */
EOLIAN_BINOP_GT, /* > int, float */
EOLIAN_BINOP_LT, /* < int, float */
EOLIAN_BINOP_GE, /* >= int, float */
EOLIAN_BINOP_LE, /* <= int, float */
EOLIAN_BINOP_AND, /* && all types */
EOLIAN_BINOP_OR, /* || all types */
EOLIAN_BINOP_BAND, /* & int */
EOLIAN_BINOP_BOR, /* | int */
EOLIAN_BINOP_BXOR, /* ^ int */
EOLIAN_BINOP_LSH, /* << int */
EOLIAN_BINOP_RSH /* >> int */
} Eolian_Binary_Operator;
typedef enum
{
EOLIAN_UNOP_INVALID = -1,
EOLIAN_UNOP_UNM, /* - sint */
EOLIAN_UNOP_UNP, /* + sint */
EOLIAN_UNOP_NOT, /* ! int, float, bool */
EOLIAN_UNOP_BNOT, /* ~ int */
} Eolian_Unary_Operator;
struct _Eolian_Expression
{
Eolian_Object base;