Files
ivy/lang/operator.c

144 lines
6.1 KiB
C

#include <ivy/lang/lex.h>
#include <ivy/lang/operator.h>
#include <stddef.h>
#define TOK_OP(id, t, p, a, l, u) \
[IVY_TOK_##t] = { \
.op_id = (IVY_OP_##id), \
.op_token = (IVY_TOK_##t), \
.op_precedence = (IVY_PRECEDENCE_##p), \
.op_associativity = (IVY_ASSOCIATIVITY_##a), \
.op_location = (IVY_OP_##l), \
.op_arity = (IVY_OP_##u), \
}
#define SYM_OP(id, t, p, a, l, u) \
[IVY_SYM_##t] = { \
.op_id = (IVY_OP_##id), \
.op_token = (IVY_SYM_##t), \
.op_precedence = (IVY_PRECEDENCE_##p), \
.op_associativity = (IVY_ASSOCIATIVITY_##a), \
.op_location = (IVY_OP_##l), \
.op_arity = (IVY_OP_##u), \
}
#define KW_OP(id, t, p, a, l, u) \
[IVY_KW_##t] = { \
.op_id = (IVY_OP_##id), \
.op_token = (IVY_KW_##t), \
.op_precedence = (IVY_PRECEDENCE_##p), \
.op_associativity = (IVY_ASSOCIATIVITY_##a), \
.op_associativity = (IVY_ASSOCIATIVITY_##a), \
.op_location = (IVY_OP_##l), \
.op_arity = (IVY_OP_##u), \
}
/* clang-format off */
static const struct ivy_operator operators[] = {
SYM_OP(ASSIGN, EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(ADD, PLUS, ADDITION, LEFT, INFIX, BINARY),
SYM_OP(SUBTRACT, HYPHEN, ADDITION, LEFT, INFIX, BINARY),
SYM_OP(MULTIPLY, ASTERISK, MULTIPLICATION, LEFT, INFIX, BINARY),
SYM_OP(DIVIDE, FORWARD_SLASH, MULTIPLICATION, LEFT, INFIX, BINARY),
SYM_OP(MODULO, PERCENT, MULTIPLICATION, LEFT, INFIX, BINARY),
SYM_OP(LEFT_SHIFT, DOUBLE_LEFT_ANGLE, BITSHIFT, LEFT, INFIX, BINARY),
SYM_OP(RIGHT_SHIFT, DOUBLE_RIGHT_ANGLE, BITSHIFT, LEFT, INFIX, BINARY),
SYM_OP(BINARY_AND, AMPERSAND, BITWISE_AND, LEFT, INFIX, BINARY),
SYM_OP(BINARY_OR, PIPE, BITWISE_OR, LEFT, INFIX, BINARY),
SYM_OP(BINARY_XOR, CARET, BITWISE_XOR, LEFT, INFIX, BINARY),
SYM_OP(LESS_THAN, LEFT_ANGLE, COMPARISON, LEFT, INFIX, BINARY),
SYM_OP(GREATER_THAN, RIGHT_ANGLE, COMPARISON, LEFT, INFIX, BINARY),
SYM_OP(CASCADE, SEMICOLON, CASCADE, LEFT, INFIX, BINARY),
SYM_OP(EQUAL, DOUBLE_EQUAL, EQUALITY, LEFT, INFIX, BINARY),
SYM_OP(NOT_EQUAL, BANG_EQUAL, EQUALITY, LEFT, INFIX, BINARY),
SYM_OP(LESS_EQUAL, LEFT_ANGLE_EQUAL, COMPARISON, LEFT, INFIX, BINARY),
SYM_OP(GREATER_EQUAL, RIGHT_ANGLE_EQUAL, COMPARISON, LEFT, INFIX, BINARY),
SYM_OP(ADD_ASSIGN, PLUS_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(SUBTRACT_ASSIGN, HYPHEN_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(MULTIPLY_ASSIGN, ASTERISK_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(DIVIDE_ASSIGN, FORWARD_SLASH_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(MODULO_ASSIGN, PERCENT_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(LEFT_SHIFT_ASSIGN, DOUBLE_LEFT_ANGLE_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(RIGHT_SHIFT_ASSIGN, DOUBLE_RIGHT_ANGLE_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(BINARY_AND_ASSIGN, AMPERSAND_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(BINARY_OR_ASSIGN, PIPE_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
SYM_OP(BINARY_XOR_ASSIGN, CARET_EQUAL, ASSIGN, RIGHT, INFIX, BINARY),
KW_OP(AND, AND, LOGICAL_AND, LEFT, INFIX, BINARY),
KW_OP(OR, OR, LOGICAL_OR, LEFT, INFIX, BINARY),
KW_OP(IS, IS, IS, LEFT, INFIX, BINARY),
KW_OP(NOT, NOT, NOT, LEFT, PREFIX, UNARY),
KW_OP(UNDERSTANDS, UNDERSTANDS, IS, LEFT, INFIX, BINARY),
SYM_OP(SELF_ACCESS, DOUBLE_COLON, SUBSCRIPT, LEFT, INFIX, BINARY),
SYM_OP(PKG_ACCESS, HYPHEN_RIGHT_ANGLE, SUBSCRIPT, LEFT, INFIX, BINARY),
/* parser-internal pseudo-operators. */
TOK_OP(MSG, IDENT, UNARY_MSG, LEFT, POSTFIX, UNARY),
SYM_OP(LEFT_PAREN, LEFT_PAREN, SUBSCRIPT, LEFT, INFIX, UNARY),
};
static const size_t nr_operators = sizeof operators / sizeof operators[0];
/* clang-format on */
const struct ivy_operator *ivy_operator_get(unsigned int token)
{
if (token >= nr_operators) {
return NULL;
}
const struct ivy_operator *op = &operators[token];
if (op->op_token != token) {
return NULL;
}
return op;
}
#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 "";
}
}