2024-11-27 12:56:10 +00:00
|
|
|
#include "ctx.h"
|
|
|
|
|
#include "node.h"
|
|
|
|
|
|
|
|
|
|
#include <blue/object/string.h>
|
|
|
|
|
#include <ivy/lang/lex.h>
|
2024-11-27 22:45:34 +00:00
|
|
|
#include <ivy/lang/operator.h>
|
2024-11-27 22:29:29 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
enum expr_end {
|
|
|
|
|
EXPR_END_NONE = 0,
|
|
|
|
|
/* arithmetic expressions, terminated with a dot (.) */
|
|
|
|
|
EXPR_END_DOT,
|
|
|
|
|
/* keyword expressions (if-else, while/for loops, match, etc), terminated with the end keyword. */
|
|
|
|
|
EXPR_END_KEYWORD,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum expr_part {
|
|
|
|
|
EXPR_NONE = 0,
|
|
|
|
|
EXPR_OPERATOR,
|
|
|
|
|
EXPR_OPERAND,
|
|
|
|
|
};
|
2024-11-27 12:56:10 +00:00
|
|
|
|
|
|
|
|
struct expr_parser_state {
|
|
|
|
|
struct parser_state s_base;
|
2024-11-27 22:29:29 +00:00
|
|
|
enum expr_end s_end;
|
|
|
|
|
enum ivy_keyword s_type;
|
|
|
|
|
unsigned int s_prev_tok;
|
|
|
|
|
enum expr_part s_prev_part;
|
|
|
|
|
b_queue s_operand_queue;
|
|
|
|
|
b_queue s_operator_stack;
|
2024-11-27 12:56:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static enum ivy_status add_child(
|
|
|
|
|
struct ivy_ast_node *parent, struct ivy_ast_node *child)
|
|
|
|
|
{
|
2024-11-27 22:29:29 +00:00
|
|
|
struct ivy_ast_expr_node *expr = (struct ivy_ast_expr_node *)parent;
|
2024-11-27 12:56:10 +00:00
|
|
|
|
2024-11-27 22:29:29 +00:00
|
|
|
if (!expr->n_child) {
|
|
|
|
|
expr->n_child = child;
|
2024-11-27 12:56:10 +00:00
|
|
|
return IVY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return IVY_ERR_NOT_SUPPORTED;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-27 22:29:29 +00:00
|
|
|
static void set_previous(struct expr_parser_state *state, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
switch (tok->t_type) {
|
|
|
|
|
case IVY_TOK_SYMBOL:
|
|
|
|
|
state->s_prev_tok = tok->t_symbol;
|
|
|
|
|
state->s_prev_part = EXPR_OPERATOR;
|
|
|
|
|
break;
|
|
|
|
|
case IVY_TOK_KEYWORD:
|
|
|
|
|
state->s_prev_tok = tok->t_keyword;
|
|
|
|
|
state->s_prev_part = EXPR_OPERATOR;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
state->s_prev_tok = tok->t_type;
|
|
|
|
|
state->s_prev_part = EXPR_OPERAND;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void print_token(struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
switch (tok->t_type) {
|
|
|
|
|
case IVY_TOK_IDENT:
|
|
|
|
|
printf("%s", tok->t_str);
|
|
|
|
|
break;
|
|
|
|
|
case IVY_TOK_INT:
|
|
|
|
|
printf("%llu", tok->t_int);
|
|
|
|
|
break;
|
|
|
|
|
case IVY_TOK_DOUBLE:
|
|
|
|
|
printf("%.2lf", tok->t_double);
|
|
|
|
|
break;
|
|
|
|
|
case IVY_TOK_SYMBOL:
|
|
|
|
|
printf("%s", ivy_symbol_to_string(tok->t_symbol));
|
|
|
|
|
break;
|
|
|
|
|
case IVY_TOK_KEYWORD:
|
|
|
|
|
printf("%s", ivy_keyword_to_string(tok->t_keyword));
|
|
|
|
|
break;
|
|
|
|
|
case IVY_TOK_STRING:
|
|
|
|
|
printf("\"%s\"", tok->t_str);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
printf("<token>");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static enum ivy_status finalise_expr(struct expr_parser_state *state)
|
|
|
|
|
{
|
|
|
|
|
b_queue_iterator it = {0};
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
b_queue_foreach (&it, &state->s_operand_queue) {
|
2024-11-27 22:45:34 +00:00
|
|
|
struct ivy_token *operand
|
|
|
|
|
= b_unbox(struct ivy_token, it.entry, t_entry);
|
2024-11-27 22:29:29 +00:00
|
|
|
|
|
|
|
|
if (i > 0) {
|
|
|
|
|
printf(" ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print_token(operand);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_queue_foreach (&it, &state->s_operator_stack) {
|
2024-11-27 22:45:34 +00:00
|
|
|
struct ivy_token *operator= b_unbox(
|
|
|
|
|
struct ivy_token, it.entry, t_entry);
|
2024-11-27 22:29:29 +00:00
|
|
|
|
|
|
|
|
if (i > 0) {
|
|
|
|
|
printf(" ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print_token(operator);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("\n");
|
2024-11-28 10:26:53 +00:00
|
|
|
printf("%zu\n", sizeof(struct ast_node_type));
|
2024-11-27 22:29:29 +00:00
|
|
|
return IVY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_ident(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end == EXPR_END_NONE) {
|
|
|
|
|
state->s_end = EXPR_END_DOT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_queue_push_back(&state->s_operand_queue, &tok->t_entry);
|
|
|
|
|
set_previous(state, tok);
|
|
|
|
|
|
|
|
|
|
return PARSE_RESULT(IVY_OK, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_atom(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end == EXPR_END_NONE) {
|
|
|
|
|
state->s_end = EXPR_END_DOT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_queue_push_back(&state->s_operand_queue, &tok->t_entry);
|
|
|
|
|
set_previous(state, tok);
|
|
|
|
|
|
|
|
|
|
return PARSE_RESULT(IVY_OK, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_string(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end == EXPR_END_NONE) {
|
|
|
|
|
state->s_end = EXPR_END_DOT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_queue_push_back(&state->s_operand_queue, &tok->t_entry);
|
|
|
|
|
set_previous(state, tok);
|
|
|
|
|
return PARSE_RESULT(IVY_OK, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_str_start(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_str_end(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_label(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_int(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end == EXPR_END_NONE) {
|
|
|
|
|
state->s_end = EXPR_END_DOT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_queue_push_back(&state->s_operand_queue, &tok->t_entry);
|
|
|
|
|
set_previous(state, tok);
|
|
|
|
|
|
|
|
|
|
return PARSE_RESULT(IVY_OK, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_double(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end == EXPR_END_NONE) {
|
|
|
|
|
state->s_end = EXPR_END_DOT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_queue_push_back(&state->s_operand_queue, &tok->t_entry);
|
|
|
|
|
set_previous(state, tok);
|
2024-11-27 22:45:34 +00:00
|
|
|
|
2024-11-27 22:29:29 +00:00
|
|
|
return PARSE_RESULT(IVY_OK, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-27 22:45:34 +00:00
|
|
|
static const struct ivy_operator *get_operator(struct ivy_token *tok)
|
2024-11-27 22:29:29 +00:00
|
|
|
{
|
|
|
|
|
switch (tok->t_type) {
|
|
|
|
|
case IVY_TOK_KEYWORD:
|
|
|
|
|
return ivy_operator_get(tok->t_keyword);
|
|
|
|
|
case IVY_TOK_SYMBOL:
|
|
|
|
|
return ivy_operator_get(tok->t_symbol);
|
|
|
|
|
default:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_symbol(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end != EXPR_END_DOT) {
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-27 22:45:34 +00:00
|
|
|
const struct ivy_operator *op = ivy_operator_get(tok->t_symbol);
|
2024-11-27 22:29:29 +00:00
|
|
|
if (!op) {
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
b_queue_entry *top_entry = b_queue_last(&state->s_operator_stack);
|
|
|
|
|
|
|
|
|
|
if (!top_entry) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-27 22:45:34 +00:00
|
|
|
struct ivy_token *top
|
|
|
|
|
= b_unbox(struct ivy_token, top_entry, t_entry);
|
2024-11-27 22:29:29 +00:00
|
|
|
if (ivy_token_is_symbol(top, IVY_SYM_LEFT_PAREN)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-27 22:45:34 +00:00
|
|
|
const struct ivy_operator *top_op = get_operator(top);
|
2024-11-27 22:29:29 +00:00
|
|
|
if (top_op->op_precedence < op->op_precedence) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-27 22:45:34 +00:00
|
|
|
if (top_op->op_precedence == op->op_precedence
|
|
|
|
|
&& op->op_associativity != IVY_ASSOCIATIVITY_LEFT) {
|
2024-11-27 22:29:29 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_queue_delete(&state->s_operator_stack, top_entry);
|
|
|
|
|
b_queue_push_back(&state->s_operand_queue, top_entry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_queue_push_back(&state->s_operator_stack, &tok->t_entry);
|
|
|
|
|
set_previous(state, tok);
|
|
|
|
|
|
|
|
|
|
return PARSE_RESULT(IVY_OK, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_left_paren(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end == EXPR_END_NONE) {
|
|
|
|
|
state->s_end = EXPR_END_DOT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_queue_push_back(&state->s_operator_stack, &tok->t_entry);
|
|
|
|
|
set_previous(state, tok);
|
2024-11-27 22:45:34 +00:00
|
|
|
|
2024-11-27 22:29:29 +00:00
|
|
|
return PARSE_RESULT(IVY_OK, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_right_paren(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_OK, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_if(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end == EXPR_END_NONE) {
|
|
|
|
|
state->s_end = EXPR_END_KEYWORD;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PARSE_RESULT(IVY_OK, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_else(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_end(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_while(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_for(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_match(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_try(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_catch(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_throw(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_understands(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_in(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_do(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_is(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_and(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_or(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_not(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_IO_FAILURE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_bang(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end != EXPR_END_DOT) {
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ivy_status status = finalise_expr(state);
|
|
|
|
|
|
|
|
|
|
parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT);
|
|
|
|
|
return PARSE_RESULT(status, PARSE_REPEAT_TOKEN);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct token_parse_result parse_dot(
|
|
|
|
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
|
|
|
|
{
|
|
|
|
|
struct expr_parser_state *state
|
|
|
|
|
= parser_get_state(ctx, struct expr_parser_state);
|
|
|
|
|
|
|
|
|
|
if (state->s_end != EXPR_END_DOT) {
|
|
|
|
|
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ivy_status status = finalise_expr(state);
|
|
|
|
|
|
|
|
|
|
parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT);
|
|
|
|
|
return PARSE_RESULT(status, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-27 12:56:10 +00:00
|
|
|
struct ast_node_type expr_node_ops = {
|
|
|
|
|
.n_add_child = add_child,
|
|
|
|
|
.n_state_size = sizeof(struct expr_parser_state),
|
|
|
|
|
.n_node_size = sizeof(struct ivy_ast_expr_node),
|
2024-11-27 22:29:29 +00:00
|
|
|
.n_token_parsers = {
|
|
|
|
|
[IVY_TOK_IDENT] = parse_ident,
|
|
|
|
|
[IVY_TOK_ATOM] = parse_atom,
|
|
|
|
|
[IVY_TOK_STRING] = parse_string,
|
|
|
|
|
[IVY_TOK_STR_START] = parse_str_start,
|
|
|
|
|
[IVY_TOK_STR_END] = parse_str_end,
|
|
|
|
|
[IVY_TOK_LABEL] = parse_label,
|
|
|
|
|
[IVY_TOK_INT] = parse_int,
|
|
|
|
|
[IVY_TOK_DOUBLE] = parse_double,
|
|
|
|
|
[IVY_TOK_SYMBOL] = parse_symbol,
|
|
|
|
|
},
|
|
|
|
|
.n_symbol_parsers = {
|
|
|
|
|
[IVY_SYM_BANG] = parse_bang,
|
|
|
|
|
[IVY_SYM_DOT] = parse_dot,
|
|
|
|
|
[IVY_SYM_LEFT_PAREN] = parse_left_paren,
|
|
|
|
|
[IVY_SYM_RIGHT_PAREN] = parse_right_paren,
|
|
|
|
|
},
|
|
|
|
|
.n_keyword_parsers = {
|
|
|
|
|
[IVY_KW_IF] = parse_if,
|
|
|
|
|
[IVY_KW_ELSE] = parse_else,
|
|
|
|
|
[IVY_KW_END] = parse_end,
|
|
|
|
|
[IVY_KW_WHILE] = parse_while,
|
|
|
|
|
[IVY_KW_FOR] = parse_for,
|
|
|
|
|
[IVY_KW_MATCH] = parse_match,
|
|
|
|
|
[IVY_KW_TRY] = parse_try,
|
|
|
|
|
[IVY_KW_CATCH] = parse_catch,
|
|
|
|
|
[IVY_KW_THROW] = parse_throw,
|
|
|
|
|
[IVY_KW_UNDERSTANDS] = parse_understands,
|
|
|
|
|
[IVY_KW_IN] = parse_in,
|
|
|
|
|
[IVY_KW_DO] = parse_do,
|
|
|
|
|
[IVY_KW_IS] = parse_is,
|
|
|
|
|
[IVY_KW_AND] = parse_and,
|
|
|
|
|
[IVY_KW_OR] = parse_or,
|
|
|
|
|
[IVY_KW_NOT] = parse_not,
|
|
|
|
|
},
|
2024-11-27 12:56:10 +00:00
|
|
|
};
|