lang: add operator precedence and associativity definitions

This commit is contained in:
2024-11-27 22:29:01 +00:00
parent c7e3cea9b9
commit 31de937a21
3 changed files with 139 additions and 19 deletions

View File

@@ -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,

View File

@@ -0,0 +1,80 @@
#ifndef IVY_LANG_OPERATOR_H_
#define IVY_LANG_OPERATOR_H_
#include <ivy/misc.h>
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

59
lang/operator.c Normal file
View File

@@ -0,0 +1,59 @@
#include <ivy/lang/operator.h>
#include <ivy/lang/lex.h>
#include <stddef.h>
#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;
}