diff --git a/lang/include/ivy/lang/ast.h b/lang/include/ivy/lang/ast.h index a36b9c3..e38bbd1 100644 --- a/lang/include/ivy/lang/ast.h +++ b/lang/include/ivy/lang/ast.h @@ -36,25 +36,6 @@ enum ivy_ast_node_type { IVY_AST_TYPE_COUNT, }; -enum ivy_ast_op { - IVY_OP_NONE = 0, - IVY_OP_ASSIGN, - IVY_OP_ADD, - IVY_OP_SUBTRACT, - IVY_OP_MULTIPLY, - IVY_OP_DIVIDE, - IVY_OP_LESS_THAN, - IVY_OP_GREATER_THAN, - IVY_OP_EQUAL, - IVY_OP_NOT_EQUAL, - IVY_OP_LESS_EQUAL, - IVY_OP_GREATER_EQUAL, - IVY_OP_AND, - IVY_OP_OR, - IVY_OP_IS, - IVY_OP_NOT, -}; - enum ivy_ast_msgh_recipient_type { IVY_AST_MSGH_NONE = 0, IVY_AST_MSGH_OBJECT, diff --git a/lang/include/ivy/lang/operator.h b/lang/include/ivy/lang/operator.h new file mode 100644 index 0000000..22b8055 --- /dev/null +++ b/lang/include/ivy/lang/operator.h @@ -0,0 +1,80 @@ +#ifndef IVY_LANG_OPERATOR_H_ +#define IVY_LANG_OPERATOR_H_ + +#include + +enum ivy_operator_precedence { + IVY_PRECEDENCE_ASSIGN, + IVY_PRECEDENCE_KEYWORD_MSG, + IVY_PRECEDENCE_IF_ELSE, + IVY_PRECEDENCE_CASCADE, + IVY_PRECEDENCE_LOGICAL_OR, + IVY_PRECEDENCE_LOGICAL_AND, + IVY_PRECEDENCE_BITWISE_OR, + IVY_PRECEDENCE_BITWISE_XOR, + IVY_PRECEDENCE_BITWISE_AND, + IVY_PRECEDENCE_EQUALITY, + IVY_PRECEDENCE_COMPARISON, + IVY_PRECEDENCE_BITSHIFT, + IVY_PRECEDENCE_ADDITION, + IVY_PRECEDENCE_MULTIPLICATION, + IVY_PRECEDENCE_UNARY_MSG, + IVY_PRECEDENCE_IS, + IVY_PRECEDENCE_NOT, + IVY_PRECEDENCE_SUBSCRIPT, +}; + +enum ivy_operator_associativity { + IVY_ASSOCIATIVITY_LEFT, + IVY_ASSOCIATIVITY_RIGHT, +}; + +enum ivy_operator_id { + IVY_OP_NONE = 0, + IVY_OP_ASSIGN, + IVY_OP_ADD, + IVY_OP_SUBTRACT, + IVY_OP_MULTIPLY, + IVY_OP_DIVIDE, + IVY_OP_MODULO, + IVY_OP_LEFT_SHIFT, + IVY_OP_RIGHT_SHIFT, + IVY_OP_BINARY_AND, + IVY_OP_BINARY_OR, + IVY_OP_BINARY_XOR, + IVY_OP_LESS_THAN, + IVY_OP_GREATER_THAN, + IVY_OP_CASCADE, + IVY_OP_EQUAL, + IVY_OP_NOT_EQUAL, + IVY_OP_LESS_EQUAL, + IVY_OP_GREATER_EQUAL, + IVY_OP_ADD_ASSIGN, + IVY_OP_SUBTRACT_ASSIGN, + IVY_OP_MULTIPLY_ASSIGN, + IVY_OP_DIVIDE_ASSIGN, + IVY_OP_MODULO_ASSIGN, + IVY_OP_LEFT_SHIFT_ASSIGN, + IVY_OP_RIGHT_SHIFT_ASSIGN, + IVY_OP_BINARY_AND_ASSIGN, + IVY_OP_BINARY_OR_ASSIGN, + IVY_OP_BINARY_XOR_ASSIGN, + IVY_OP_AND, + IVY_OP_OR, + IVY_OP_IS, + IVY_OP_NOT, + IVY_OP_UNDERSTANDS, + IVY_OP_SELF_ACCESS, + IVY_OP_PKG_ACCESS, +}; + +struct ivy_operator { + enum ivy_operator_id op_id; + unsigned int op_token; + enum ivy_operator_precedence op_precedence; + enum ivy_operator_associativity op_associativity; +}; + +IVY_API const struct ivy_operator *ivy_operator_get(unsigned int token); + +#endif \ No newline at end of file diff --git a/lang/operator.c b/lang/operator.c new file mode 100644 index 0000000..d1216b5 --- /dev/null +++ b/lang/operator.c @@ -0,0 +1,59 @@ +#include +#include +#include + +#define SYM_OP(id, t, p, a) [IVY_SYM_ ## t] = { .op_id = (IVY_OP_ ## id), .op_token = (IVY_SYM_ ## t), .op_precedence = (IVY_PRECEDENCE_ ## p), .op_associativity = (IVY_ASSOCIATIVITY_ ## a) } +#define KW_OP(id, t, p, a) [IVY_KW_ ## t] = { .op_id = (IVY_OP_ ## id), .op_token = (IVY_KW_ ## t), .op_precedence = (IVY_PRECEDENCE_ ## p), .op_associativity = (IVY_ASSOCIATIVITY_ ## a) } + +static const struct ivy_operator operators[] = { + SYM_OP(ASSIGN, EQUAL, ASSIGN, RIGHT), + SYM_OP(ADD, PLUS, ADDITION, LEFT), + SYM_OP(SUBTRACT, HYPHEN, ADDITION, LEFT), + SYM_OP(MULTIPLY, ASTERISK, MULTIPLICATION, LEFT), + SYM_OP(DIVIDE, FORWARD_SLASH, MULTIPLICATION, LEFT), + SYM_OP(MODULO, PERCENT, MULTIPLICATION, LEFT), + SYM_OP(LEFT_SHIFT, DOUBLE_LEFT_ANGLE, BITSHIFT, LEFT), + SYM_OP(RIGHT_SHIFT, DOUBLE_RIGHT_ANGLE, BITSHIFT, LEFT), + SYM_OP(BINARY_AND, AMPERSAND, BITWISE_AND, LEFT), + SYM_OP(BINARY_OR, PIPE, BITWISE_OR, LEFT), + SYM_OP(BINARY_XOR, CARET, BITWISE_XOR, LEFT), + SYM_OP(LESS_THAN, LEFT_ANGLE, COMPARISON, LEFT), + SYM_OP(GREATER_THAN, RIGHT_ANGLE, COMPARISON, LEFT), + SYM_OP(CASCADE, SEMICOLON, CASCADE, LEFT), + SYM_OP(EQUAL, DOUBLE_EQUAL, EQUALITY, LEFT), + SYM_OP(NOT_EQUAL, BANG_EQUAL, EQUALITY, LEFT), + SYM_OP(LESS_EQUAL, LEFT_ANGLE_EQUAL, COMPARISON, LEFT), + SYM_OP(GREATER_EQUAL, RIGHT_ANGLE_EQUAL, COMPARISON, LEFT), + SYM_OP(ADD_ASSIGN, PLUS_EQUAL, ASSIGN, RIGHT), + SYM_OP(SUBTRACT_ASSIGN, HYPHEN_EQUAL, ASSIGN, RIGHT), + SYM_OP(MULTIPLY_ASSIGN, ASTERISK_EQUAL, ASSIGN, RIGHT), + SYM_OP(DIVIDE_ASSIGN, FORWARD_SLASH_EQUAL, ASSIGN, RIGHT), + SYM_OP(MODULO_ASSIGN, PERCENT_EQUAL, ASSIGN, RIGHT), + SYM_OP(LEFT_SHIFT_ASSIGN, DOUBLE_LEFT_ANGLE_EQUAL, ASSIGN, RIGHT), + SYM_OP(RIGHT_SHIFT_ASSIGN, DOUBLE_RIGHT_ANGLE_EQUAL, ASSIGN, RIGHT), + SYM_OP(BINARY_AND_ASSIGN, AMPERSAND_EQUAL, ASSIGN, RIGHT), + SYM_OP(BINARY_OR_ASSIGN, PIPE_EQUAL, ASSIGN, RIGHT), + SYM_OP(BINARY_XOR_ASSIGN, CARET_EQUAL, ASSIGN, RIGHT), + KW_OP(AND, AND, LOGICAL_AND, LEFT), + KW_OP(OR, OR, LOGICAL_OR, LEFT), + KW_OP(IS, IS, IS, LEFT), + KW_OP(NOT, NOT, NOT, LEFT), + KW_OP(UNDERSTANDS, UNDERSTANDS, IS, LEFT), + SYM_OP(SELF_ACCESS, DOUBLE_COLON, SUBSCRIPT, LEFT), + SYM_OP(PKG_ACCESS, HYPHEN_RIGHT_ANGLE, SUBSCRIPT, LEFT), +}; +static const size_t nr_operators = sizeof operators / sizeof operators[0]; + +const struct ivy_operator *ivy_operator_get(unsigned int token) +{ + if (token >= nr_operators) { + return NULL; + } + + struct ivy_operator *op = &operators[token]; + if (op->op_token != token) { + return NULL; + } + + return op; +} \ No newline at end of file