2024-11-27 22:29:01 +00:00
|
|
|
#include <ivy/lang/lex.h>
|
2024-11-27 22:45:34 +00:00
|
|
|
#include <ivy/lang/operator.h>
|
2024-11-27 22:29:01 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
|
|
2024-12-01 13:19:01 +00:00
|
|
|
#define OP(id, p, a, l, u) \
|
|
|
|
|
[IVY_OP_##id] = { \
|
2024-11-28 16:54:45 +00:00
|
|
|
.op_id = (IVY_OP_##id), \
|
|
|
|
|
.op_precedence = (IVY_PRECEDENCE_##p), \
|
|
|
|
|
.op_associativity = (IVY_ASSOCIATIVITY_##a), \
|
|
|
|
|
.op_location = (IVY_OP_##l), \
|
|
|
|
|
.op_arity = (IVY_OP_##u), \
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-01 13:19:01 +00:00
|
|
|
#define TOK_OP(id, tok) \
|
|
|
|
|
[IVY_TOK_##tok - __IVY_TOK_INDEX_BASE] = &operators[IVY_OP_##id]
|
|
|
|
|
#define SYM_OP(id, sym) \
|
|
|
|
|
[IVY_SYM_##sym - __IVY_SYM_INDEX_BASE] = &operators[IVY_OP_##id]
|
|
|
|
|
#define KW_OP(id, kw) \
|
|
|
|
|
[IVY_KW_##kw - __IVY_KW_INDEX_BASE] = &operators[IVY_OP_##id]
|
2024-11-27 22:29:01 +00:00
|
|
|
|
2024-11-27 22:45:34 +00:00
|
|
|
/* clang-format off */
|
2024-11-27 22:29:01 +00:00
|
|
|
static const struct ivy_operator operators[] = {
|
2024-12-01 13:19:01 +00:00
|
|
|
OP(ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(ADD, ADDITION, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(SUBTRACT, ADDITION, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(MULTIPLY, MULTIPLICATION, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(DIVIDE, MULTIPLICATION, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(MODULO, MULTIPLICATION, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(LEFT_SHIFT, BITSHIFT, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(RIGHT_SHIFT, BITSHIFT, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(BINARY_AND, BITWISE_AND, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(BINARY_OR, BITWISE_OR, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(BINARY_XOR, BITWISE_XOR, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(LESS_THAN, COMPARISON, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(GREATER_THAN, COMPARISON, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(CASCADE, CASCADE, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(EQUAL, EQUALITY, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(NOT_EQUAL, EQUALITY, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(LESS_EQUAL, COMPARISON, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(GREATER_EQUAL, COMPARISON, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(ADD_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(SUBTRACT_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(MULTIPLY_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(DIVIDE_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(MODULO_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(LEFT_SHIFT_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(RIGHT_SHIFT_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(BINARY_AND_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(BINARY_OR_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(BINARY_XOR_ASSIGN, ASSIGN, RIGHT, INFIX, BINARY),
|
|
|
|
|
OP(AND, LOGICAL_AND, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(OR, LOGICAL_OR, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(IS, IS, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(NOT, NOT, LEFT, PREFIX, UNARY),
|
|
|
|
|
OP(UNDERSTANDS, IS, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(SELF_ACCESS, SUBSCRIPT, LEFT, INFIX, BINARY),
|
|
|
|
|
OP(PKG_ACCESS, SUBSCRIPT, LEFT, INFIX, BINARY),
|
2024-11-28 22:01:31 +00:00
|
|
|
|
|
|
|
|
/* parser-internal pseudo-operators. */
|
2024-12-01 13:19:01 +00:00
|
|
|
OP(MSG, UNARY_MSG, LEFT, POSTFIX, UNARY),
|
|
|
|
|
OP(LEFT_PAREN, PARENTHESIS, LEFT, INFIX, UNARY),
|
2024-11-27 22:29:01 +00:00
|
|
|
};
|
|
|
|
|
static const size_t nr_operators = sizeof operators / sizeof operators[0];
|
2024-12-01 13:19:01 +00:00
|
|
|
|
|
|
|
|
static const struct ivy_operator *operator_symbols[] = {
|
|
|
|
|
SYM_OP(ASSIGN, EQUAL),
|
|
|
|
|
SYM_OP(ADD, PLUS),
|
|
|
|
|
SYM_OP(SUBTRACT, HYPHEN),
|
|
|
|
|
SYM_OP(MULTIPLY, ASTERISK),
|
|
|
|
|
SYM_OP(DIVIDE, FORWARD_SLASH),
|
|
|
|
|
SYM_OP(MODULO, PERCENT),
|
|
|
|
|
SYM_OP(LEFT_SHIFT, DOUBLE_LEFT_ANGLE),
|
|
|
|
|
SYM_OP(RIGHT_SHIFT, DOUBLE_RIGHT_ANGLE),
|
|
|
|
|
SYM_OP(BINARY_AND, AMPERSAND),
|
|
|
|
|
SYM_OP(BINARY_OR, PIPE),
|
|
|
|
|
SYM_OP(BINARY_XOR, CARET),
|
|
|
|
|
SYM_OP(LESS_THAN, LEFT_ANGLE),
|
|
|
|
|
SYM_OP(GREATER_THAN, RIGHT_ANGLE),
|
|
|
|
|
SYM_OP(CASCADE, SEMICOLON),
|
|
|
|
|
SYM_OP(EQUAL, DOUBLE_EQUAL),
|
|
|
|
|
SYM_OP(NOT_EQUAL, BANG_EQUAL),
|
|
|
|
|
SYM_OP(LESS_EQUAL, LEFT_ANGLE_EQUAL),
|
|
|
|
|
SYM_OP(GREATER_EQUAL, RIGHT_ANGLE_EQUAL),
|
|
|
|
|
SYM_OP(ADD_ASSIGN, PLUS_EQUAL),
|
|
|
|
|
SYM_OP(SUBTRACT_ASSIGN, HYPHEN_EQUAL),
|
|
|
|
|
SYM_OP(MULTIPLY_ASSIGN, ASTERISK_EQUAL),
|
|
|
|
|
SYM_OP(DIVIDE_ASSIGN, FORWARD_SLASH_EQUAL),
|
|
|
|
|
SYM_OP(MODULO_ASSIGN, PERCENT_EQUAL),
|
|
|
|
|
SYM_OP(LEFT_SHIFT_ASSIGN, DOUBLE_LEFT_ANGLE_EQUAL),
|
|
|
|
|
SYM_OP(RIGHT_SHIFT_ASSIGN, DOUBLE_RIGHT_ANGLE_EQUAL),
|
|
|
|
|
SYM_OP(BINARY_AND_ASSIGN, AMPERSAND_EQUAL),
|
|
|
|
|
SYM_OP(BINARY_OR_ASSIGN, PIPE_EQUAL),
|
|
|
|
|
SYM_OP(BINARY_XOR_ASSIGN, CARET_EQUAL),
|
|
|
|
|
SYM_OP(SELF_ACCESS, DOUBLE_COLON),
|
|
|
|
|
SYM_OP(PKG_ACCESS, HYPHEN_RIGHT_ANGLE),
|
|
|
|
|
|
|
|
|
|
/* parser-internal pseudo-operators. */
|
|
|
|
|
SYM_OP(LEFT_PAREN, LEFT_PAREN),
|
|
|
|
|
};
|
|
|
|
|
static const size_t nr_operator_symbols = sizeof operator_symbols / sizeof operator_symbols[0];
|
|
|
|
|
|
|
|
|
|
static const struct ivy_operator *operator_keywords[] = {
|
|
|
|
|
KW_OP(AND, AND),
|
|
|
|
|
KW_OP(OR, OR),
|
|
|
|
|
KW_OP(IS, IS),
|
|
|
|
|
KW_OP(NOT, NOT),
|
|
|
|
|
KW_OP(UNDERSTANDS, UNDERSTANDS),
|
|
|
|
|
};
|
|
|
|
|
static const size_t nr_operator_keywords = sizeof operator_keywords / sizeof operator_keywords[0];
|
|
|
|
|
|
|
|
|
|
static const struct ivy_operator *operator_tokens[] = {
|
|
|
|
|
/* parser-internal pseudo-operators. */
|
|
|
|
|
TOK_OP(MSG, IDENT),
|
|
|
|
|
};
|
|
|
|
|
static const size_t nr_operator_tokens = sizeof operator_keywords / sizeof operator_keywords[0];
|
2024-11-27 22:45:34 +00:00
|
|
|
/* clang-format on */
|
2024-11-27 22:29:01 +00:00
|
|
|
|
2024-12-01 13:19:01 +00:00
|
|
|
const struct ivy_operator *ivy_operator_get_by_token(unsigned int token)
|
|
|
|
|
{
|
|
|
|
|
const struct ivy_operator **op_list = NULL;
|
|
|
|
|
size_t base = 0;
|
|
|
|
|
size_t op_list_size = 0;
|
|
|
|
|
|
|
|
|
|
if (token > __IVY_TOK_INDEX_BASE && token < __IVY_TOK_INDEX_LIMIT) {
|
|
|
|
|
op_list = operator_tokens;
|
|
|
|
|
base = __IVY_TOK_INDEX_BASE;
|
|
|
|
|
op_list_size = nr_operator_tokens;
|
|
|
|
|
} else if (token > __IVY_KW_INDEX_BASE && token < __IVY_KW_INDEX_LIMIT) {
|
|
|
|
|
op_list = operator_keywords;
|
|
|
|
|
base = __IVY_KW_INDEX_BASE;
|
|
|
|
|
op_list_size = nr_operator_keywords;
|
|
|
|
|
} else if (token > __IVY_SYM_INDEX_BASE && token < __IVY_SYM_INDEX_LIMIT) {
|
|
|
|
|
op_list = operator_symbols;
|
|
|
|
|
base = __IVY_SYM_INDEX_BASE;
|
|
|
|
|
op_list_size = nr_operator_symbols;
|
|
|
|
|
} else {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (token - base >= op_list_size) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return op_list[token - base];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct ivy_operator *ivy_operator_get_by_id(enum ivy_operator_id id)
|
2024-11-27 22:29:01 +00:00
|
|
|
{
|
2024-12-01 13:19:01 +00:00
|
|
|
if (id >= nr_operators) {
|
2024-11-27 22:29:01 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-01 13:19:01 +00:00
|
|
|
const struct ivy_operator *op = &operators[id];
|
|
|
|
|
if (op->op_id != id) {
|
2024-11-27 22:29:01 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return op;
|
2024-11-27 22:45:34 +00:00
|
|
|
}
|
2024-11-28 22:01:31 +00:00
|
|
|
|
|
|
|
|
#define ENUM_STR(x) \
|
|
|
|
|
case x: \
|
|
|
|
|
return #x
|
|
|
|
|
|
|
|
|
|
const char *ivy_operator_id_to_string(enum ivy_operator_id op)
|
|
|
|
|
{
|
|
|
|
|
switch (op) {
|
|
|
|
|
ENUM_STR(IVY_OP_NONE);
|
|
|
|
|
ENUM_STR(IVY_OP_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_ADD);
|
|
|
|
|
ENUM_STR(IVY_OP_SUBTRACT);
|
|
|
|
|
ENUM_STR(IVY_OP_MULTIPLY);
|
|
|
|
|
ENUM_STR(IVY_OP_DIVIDE);
|
|
|
|
|
ENUM_STR(IVY_OP_MODULO);
|
|
|
|
|
ENUM_STR(IVY_OP_LEFT_SHIFT);
|
|
|
|
|
ENUM_STR(IVY_OP_RIGHT_SHIFT);
|
|
|
|
|
ENUM_STR(IVY_OP_BINARY_AND);
|
|
|
|
|
ENUM_STR(IVY_OP_BINARY_OR);
|
|
|
|
|
ENUM_STR(IVY_OP_BINARY_XOR);
|
|
|
|
|
ENUM_STR(IVY_OP_LESS_THAN);
|
|
|
|
|
ENUM_STR(IVY_OP_GREATER_THAN);
|
|
|
|
|
ENUM_STR(IVY_OP_CASCADE);
|
|
|
|
|
ENUM_STR(IVY_OP_EQUAL);
|
|
|
|
|
ENUM_STR(IVY_OP_NOT_EQUAL);
|
|
|
|
|
ENUM_STR(IVY_OP_LESS_EQUAL);
|
|
|
|
|
ENUM_STR(IVY_OP_GREATER_EQUAL);
|
|
|
|
|
ENUM_STR(IVY_OP_ADD_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_SUBTRACT_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_MULTIPLY_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_DIVIDE_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_MODULO_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_LEFT_SHIFT_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_RIGHT_SHIFT_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_BINARY_AND_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_BINARY_OR_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_BINARY_XOR_ASSIGN);
|
|
|
|
|
ENUM_STR(IVY_OP_AND);
|
|
|
|
|
ENUM_STR(IVY_OP_OR);
|
|
|
|
|
ENUM_STR(IVY_OP_IS);
|
|
|
|
|
ENUM_STR(IVY_OP_NOT);
|
|
|
|
|
ENUM_STR(IVY_OP_UNDERSTANDS);
|
|
|
|
|
ENUM_STR(IVY_OP_SELF_ACCESS);
|
|
|
|
|
ENUM_STR(IVY_OP_PKG_ACCESS);
|
|
|
|
|
ENUM_STR(IVY_OP_MSG);
|
|
|
|
|
ENUM_STR(IVY_OP_LEFT_PAREN);
|
|
|
|
|
default:
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|