lang: ast: fix incorrect return types; add function to determine expression tokens

This commit is contained in:
2024-11-27 12:56:10 +00:00
parent cd89c20beb
commit ad25b89af0
6 changed files with 127 additions and 21 deletions

28
lang/ast/expr.c Normal file
View File

@@ -0,0 +1,28 @@
#include "ctx.h"
#include "node.h"
#include <blue/object/string.h>
#include <ivy/lang/lex.h>
struct expr_parser_state {
struct parser_state s_base;
};
static enum ivy_status add_child(
struct ivy_ast_node *parent, struct ivy_ast_node *child)
{
struct ivy_ast_expr_node *c = (struct ivy_ast_expr_node *)parent;
if (!c->n_child) {
c->n_child = child;
return IVY_OK;
}
return IVY_ERR_NOT_SUPPORTED;
}
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),
};

View File

@@ -9,16 +9,12 @@ struct msgh_parser_state {
struct parser_state s_base;
bool s_oneline;
enum {
AREA_SELECTOR,
AREA_BODY,
} s_current_area;
unsigned int s_i;
unsigned int s_prev;
};
static struct token_parse_result parse_ident(struct ivy_parser *ctx, struct ivy_token *tok)
static struct token_parse_result parse_ident(
struct ivy_parser *ctx, struct ivy_token *tok)
{
struct msgh_parser_state *state
= parser_get_state(ctx, struct msgh_parser_state);
@@ -26,7 +22,7 @@ static struct token_parse_result parse_ident(struct ivy_parser *ctx, struct ivy_
struct ivy_ast_msgh_node *msgh
= (struct ivy_ast_msgh_node *)state->s_base.s_node;
if (state->s_current_area == AREA_BODY) {
if (msgh->n_sel) {
/* TODO expression parsing */
return PARSE_RESULT(IVY_ERR_NOT_SUPPORTED, 0);
}
@@ -39,18 +35,18 @@ static struct token_parse_result parse_ident(struct ivy_parser *ctx, struct ivy_
return PARSE_RESULT(IVY_OK, 0);
}
static struct token_parse_result add_child(
static enum ivy_status add_child(
struct ivy_ast_node *parent, struct ivy_ast_node *child)
{
struct ivy_ast_msgh_node *msgh = (struct ivy_ast_msgh_node *)parent;
if (child->n_type == IVY_AST_SELECTOR && !msgh->n_sel) {
msgh->n_sel = (struct ivy_ast_selector_node *)child;
return PARSE_RESULT(IVY_OK, 0);
return IVY_OK;
}
b_queue_push_back(&msgh->n_body, &child->n_entry);
return PARSE_RESULT(IVY_OK, 0);
return IVY_OK;
}
static void init_state(struct ivy_parser *ctx, struct parser_state *sp)
@@ -58,7 +54,6 @@ static void init_state(struct ivy_parser *ctx, struct parser_state *sp)
struct msgh_parser_state *state = (struct msgh_parser_state *)sp;
state->s_oneline = false;
state->s_i = 0;
state->s_current_area = AREA_SELECTOR;
state->s_prev = IVY_SYM_HYPHEN;
parser_push_state(ctx, IVY_AST_SELECTOR);

View File

@@ -17,11 +17,17 @@ static const struct ast_node_type *node_ops[] = {
[IVY_AST_UNIT_PACKAGE] = &unit_package_node_ops,
[IVY_AST_UNIT_IMPORT] = &unit_import_node_ops,
[IVY_AST_CLASS] = &class_node_ops,
[IVY_AST_MSGH] = &msgh_node_ops,
[IVY_AST_SELECTOR] = &selector_node_ops,
[IVY_AST_MSGH] = &msgh_node_ops,
[IVY_AST_SELECTOR] = &selector_node_ops,
};
static const size_t nr_node_ops = sizeof node_ops / sizeof node_ops[0];
enum tok_expr_type {
TOK_EXPR_NONE = 0,
TOK_EXPR_BEGIN,
TOK_EXPR_ANY,
};
const struct ast_node_type *get_ast_node_type(enum ivy_ast_node_type type)
{
if (type >= nr_node_ops) {
@@ -31,6 +37,73 @@ const struct ast_node_type *get_ast_node_type(enum ivy_ast_node_type type)
return node_ops[type];
}
static enum tok_expr_type get_tok_expr_type(struct ivy_token *tok)
{
switch (tok->t_type) {
case IVY_TOK_IDENT:
case IVY_TOK_INT:
case IVY_TOK_DOUBLE:
case IVY_TOK_STRING:
case IVY_TOK_STR_START:
case IVY_TOK_ATOM:
return TOK_EXPR_BEGIN;
case IVY_TOK_SYMBOL:
switch (tok->t_symbol) {
case IVY_SYM_LEFT_PAREN:
case IVY_SYM_CARET:
return TOK_EXPR_BEGIN;
case IVY_SYM_PLUS:
case IVY_SYM_HYPHEN:
case IVY_SYM_FORWARD_SLASH:
case IVY_SYM_ASTERISK:
case IVY_SYM_PIPE:
case IVY_SYM_COMMA:
case IVY_SYM_SEMICOLON:
case IVY_SYM_EQUAL:
case IVY_SYM_PLUS_EQUAL:
case IVY_SYM_HYPHEN_EQUAL:
case IVY_SYM_FORWARD_SLASH_EQUAL:
case IVY_SYM_ASTERISK_EQUAL:
case IVY_SYM_AMPERSAND_EQUAL:
case IVY_SYM_PIPE_EQUAL:
case IVY_SYM_PERCENT_EQUAL:
case IVY_SYM_CARET_EQUAL:
case IVY_SYM_PERCENT:
case IVY_SYM_AMPERSAND:
case IVY_SYM_DOUBLE_EQUAL:
case IVY_SYM_DOUBLE_LEFT_ANGLE:
case IVY_SYM_DOUBLE_RIGHT_ANGLE:
case IVY_SYM_DOUBLE_LEFT_ANGLE_EQUAL:
case IVY_SYM_DOUBLE_RIGHT_ANGLE_EQUAL:
case IVY_SYM_HYPHEN_RIGHT_ANGLE:
return TOK_EXPR_ANY;
default:
return TOK_EXPR_NONE;
}
case IVY_TOK_KEYWORD:
switch (tok->t_keyword) {
case IVY_KW_IF:
case IVY_KW_ELSE:
case IVY_KW_MATCH:
case IVY_KW_FOR:
case IVY_KW_WHILE:
case IVY_KW_TRY:
case IVY_KW_CATCH:
case IVY_KW_NOT:
case IVY_KW_THROW:
return TOK_EXPR_BEGIN;
case IVY_KW_IS:
case IVY_KW_AND:
case IVY_KW_OR:
return TOK_EXPR_ANY;
default:
return TOK_EXPR_NONE;
}
default:
return TOK_EXPR_NONE;
}
}
token_parse_function get_token_parser(
struct ivy_ast_node *context, struct ivy_token *tok)
{

View File

@@ -9,8 +9,8 @@
struct parser_state;
#define PARSE_RESULT(status, flags) \
((struct token_parse_result) {.r_status = (status), .r_flags = (flags) })
#define PARSE_RESULT(status, flags) \
((struct token_parse_result) {.r_status = (status), .r_flags = (flags)})
enum token_parse_flags {
PARSE_REPEAT_TOKEN = 0x01u,
@@ -38,6 +38,7 @@ struct ast_node_type {
token_parse_function n_token_parsers[IVY_TOK_TYPE_COUNT];
token_parse_function n_keyword_parsers[IVY_KW_TYPE_COUNT];
token_parse_function n_symbol_parsers[IVY_SYM_TYPE_COUNT];
token_parse_function n_expr_parser;
};
extern const struct ast_node_type *get_ast_node_type(enum ivy_ast_node_type type);

View File

@@ -1,7 +1,8 @@
#include <ivy/lang/ast.h>
#include "ctx.h"
#include "node.h"
#include "iterate.h"
#include "node.h"
#include <ivy/lang/ast.h>
static struct token_parse_result parse_package_keyword(
struct ivy_parser *ctx, struct ivy_token *tok)
@@ -24,20 +25,22 @@ static struct token_parse_result parse_class_keyword(
return PARSE_RESULT(IVY_OK, 0);
}
static struct token_parse_result add_child(
static enum ivy_status add_child(
struct ivy_ast_node *parent, struct ivy_ast_node *child)
{
struct ivy_ast_unit_node *unit = (struct ivy_ast_unit_node *)parent;
b_queue_push_back(&unit->n_children, &child->n_entry);
return PARSE_RESULT(IVY_OK, 0);
return IVY_OK;
}
static void collect_children(struct ivy_ast_node *node, struct ivy_ast_node_iterator *iterator)
static void collect_children(
struct ivy_ast_node *node, struct ivy_ast_node_iterator *iterator)
{
struct ivy_ast_unit_node *unit = (struct ivy_ast_unit_node *)node;
b_queue_iterator it = {0};
b_queue_foreach (&it, &unit->n_children) {
struct ivy_ast_node *child = b_unbox(struct ivy_ast_node, it.entry, n_entry);
struct ivy_ast_node *child
= b_unbox(struct ivy_ast_node, it.entry, n_entry);
ast_node_iterator_enqueue_node(iterator, node, child);
}
}

View File

@@ -20,6 +20,7 @@ enum ivy_ast_node_type {
IVY_AST_LAMBDA,
IVY_AST_UNIT_PACKAGE,
IVY_AST_UNIT_IMPORT,
IVY_AST_EXPR,
IVY_AST_INT,
IVY_AST_DOUBLE,
IVY_AST_STRING,
@@ -162,6 +163,11 @@ struct ivy_ast_unit_import_node {
b_queue n_ident;
};
struct ivy_ast_expr_node {
struct ivy_ast_node n_base;
struct ivy_ast_node *n_child;
};
struct ivy_ast_int_node {
struct ivy_ast_node n_base;
/* lex token of type IVY_TOK_INT. */