lang: ast: initial implementation of msg handler and selector parsing

This commit is contained in:
2024-11-26 13:08:39 +00:00
parent 27792c43b3
commit 5f5efd8d35
9 changed files with 312 additions and 24 deletions

View File

@@ -14,6 +14,55 @@ struct class_parser_state {
int s_prev_token;
};
static enum ivy_status parse_dollar(struct ivy_parser *ctx, struct ivy_token *tok)
{
struct class_parser_state *state
= parser_get_state(ctx, struct class_parser_state);
if (state->s_current_area != AREA_BODY) {
return IVY_ERR_BAD_SYNTAX;
}
parser_push_state(ctx, IVY_AST_PROPERTY);
return IVY_OK;
}
static enum ivy_status parse_plus(struct ivy_parser *ctx, struct ivy_token *tok)
{
struct class_parser_state *state
= parser_get_state(ctx, struct class_parser_state);
if (state->s_current_area != AREA_BODY) {
return IVY_ERR_BAD_SYNTAX;
}
parser_push_state(ctx, IVY_AST_MSGH);
struct parser_state *msgh_state = parser_get_state_generic(ctx);
struct ivy_ast_msgh_node *msgh
= (struct ivy_ast_msgh_node *)msgh_state->s_node;
msgh->n_recipient = IVY_AST_MSGH_CLASS;
return IVY_OK;
}
static enum ivy_status parse_hyphen(struct ivy_parser *ctx, struct ivy_token *tok)
{
struct class_parser_state *state
= parser_get_state(ctx, struct class_parser_state);
if (state->s_current_area != AREA_BODY) {
return IVY_ERR_BAD_SYNTAX;
}
parser_push_state(ctx, IVY_AST_MSGH);
struct parser_state *msgh_state = parser_get_state_generic(ctx);
struct ivy_ast_msgh_node *msgh
= (struct ivy_ast_msgh_node *)msgh_state->s_node;
msgh->n_recipient = IVY_AST_MSGH_OBJECT;
return IVY_OK;
}
static enum ivy_status parse_ident(struct ivy_parser *ctx, struct ivy_token *tok)
{
struct class_parser_state *state
@@ -96,7 +145,7 @@ static void print(struct ivy_ast_node *node)
c->n_ident->t_str);
}
static void init_state(struct parser_state *sp)
static void init_state(struct ivy_parser *ctx, struct parser_state *sp)
{
struct class_parser_state *state = (struct class_parser_state *)sp;
state->s_prev_token = IVY_KW_CLASS;
@@ -109,6 +158,11 @@ struct ast_node_type class_node_ops = {
.n_init_state = init_state,
.n_state_size = sizeof(struct class_parser_state),
.n_node_size = sizeof(struct ivy_ast_class_node),
.n_symbol_parsers = {
[IVY_SYM_DOLLAR] = parse_dollar,
[IVY_SYM_HYPHEN] = parse_hyphen,
[IVY_SYM_PLUS] = parse_plus,
},
.n_token_parsers = {
[IVY_TOK_IDENT] = parse_ident,
[IVY_TOK_LINEFEED] = parse_linefeed,

View File

@@ -94,7 +94,7 @@ struct parser_state *parser_push_state(
state->s_node = ast_node_create_with_size(type, node_type->n_node_size);
if (node_type->n_init_state) {
node_type->n_init_state(state);
node_type->n_init_state(parser, state);
}
b_queue_push_back(&parser->p_state, &state->s_entry);
@@ -134,7 +134,7 @@ struct ivy_ast_node *ivy_parser_dequeue_node(struct ivy_parser *parser)
{
b_queue_entry *entry = b_queue_first(&parser->p_state);
struct parser_state *state = b_unbox(struct parser_state, entry, s_entry);
if (!state) {
return NULL;
}
@@ -146,10 +146,10 @@ struct ivy_ast_node *ivy_parser_dequeue_node(struct ivy_parser *parser)
struct ivy_ast_unit_node *unit = (struct ivy_ast_unit_node *)state->s_node;
entry = b_queue_pop_front(&unit->n_children);
if (!entry) {
return NULL;
}
return b_unbox(struct ivy_ast_node, entry, n_entry);
}
}

75
lang/ast/msgh.c Normal file
View File

@@ -0,0 +1,75 @@
#include "ctx.h"
#include "ivy/status.h"
#include "node.h"
#include <blue/object/string.h>
#include <ivy/lang/lex.h>
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 enum ivy_status parse_ident(struct ivy_parser *ctx, struct ivy_token *tok)
{
struct msgh_parser_state *state
= parser_get_state(ctx, struct msgh_parser_state);
struct ivy_ast_msgh_node *msgh
= (struct ivy_ast_msgh_node *)state->s_base.s_node;
if (state->s_current_area == AREA_BODY) {
/* TODO expression parsing */
return IVY_ERR_NOT_SUPPORTED;
}
if (state->s_prev == IVY_SYM_HYPHEN) {
/* message name */
return IVY_OK;
}
return IVY_OK;
}
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 IVY_OK;
}
b_queue_push_back(&msgh->n_body, &child->n_entry);
return IVY_OK;
}
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);
}
struct ast_node_type msgh_node_ops = {
.n_add_child = add_child,
.n_init_state = init_state,
.n_state_size = sizeof(struct msgh_parser_state),
.n_node_size = sizeof(struct ivy_ast_msgh_node),
.n_token_parsers = {
[IVY_TOK_IDENT] = parse_ident,
},
};

View File

@@ -16,8 +16,9 @@ struct ast_node_type {
enum ivy_status (*n_add_child)(
struct ivy_ast_node *, struct ivy_ast_node *);
void (*n_print)(struct ivy_ast_node *);
void (*n_init_state)(struct parser_state *);
void (*n_collect_children)(struct ivy_ast_node *, struct ivy_ast_node_iterator *);
void (*n_init_state)(struct ivy_parser *, struct parser_state *);
void (*n_collect_children)(
struct ivy_ast_node *, struct ivy_ast_node_iterator *);
size_t n_state_size;
size_t n_node_size;

0
lang/ast/property.c Normal file
View File

147
lang/ast/selector.c Normal file
View File

@@ -0,0 +1,147 @@
#include "ctx.h"
#include "ivy/status.h"
#include "node.h"
#include <blue/object/string.h>
#include <ivy/lang/lex.h>
struct selector_parser_state {
struct parser_state s_base;
unsigned int s_prev;
};
static enum ivy_status parse_ident(struct ivy_parser *ctx, struct ivy_token *tok)
{
struct selector_parser_state *state
= parser_get_state(ctx, struct selector_parser_state);
struct ivy_ast_selector_node *sel
= (struct ivy_ast_selector_node *)state->s_base.s_node;
if (state->s_prev == 0) {
/* message name */
sel->n_msg_name = tok;
state->s_prev = IVY_TOK_IDENT;
return IVY_OK;
}
if (state->s_prev == IVY_TOK_LABEL) {
/* internal parameter name */
b_queue_push_back(&sel->n_arg_names, &tok->t_entry);
state->s_prev = IVY_TOK_IDENT;
return IVY_OK;
}
return IVY_ERR_BAD_SYNTAX;
}
static enum ivy_status parse_label(struct ivy_parser *ctx, struct ivy_token *tok)
{
struct selector_parser_state *state
= parser_get_state(ctx, struct selector_parser_state);
struct ivy_ast_selector_node *sel
= (struct ivy_ast_selector_node *)state->s_base.s_node;
if (state->s_prev != IVY_TOK_IDENT && state->s_prev != IVY_SYM_LEFT_PAREN) {
return IVY_ERR_BAD_SYNTAX;
}
b_queue_push_back(&sel->n_arg_labels, &tok->t_entry);
return IVY_OK;
}
static enum ivy_status parse_linefeed(struct ivy_parser *ctx, struct ivy_token *tok)
{
struct selector_parser_state *state
= parser_get_state(ctx, struct selector_parser_state);
struct ivy_ast_selector_node *sel
= (struct ivy_ast_selector_node *)state->s_base.s_node;
if (!b_queue_empty(&sel->n_arg_labels)
&& state->s_prev != IVY_SYM_RIGHT_PAREN) {
return IVY_ERR_BAD_SYNTAX;
}
if (state->s_prev != IVY_TOK_IDENT) {
return IVY_ERR_BAD_SYNTAX;
}
parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT);
return IVY_OK;
}
static enum ivy_status parse_left_paren(
struct ivy_parser *ctx, struct ivy_token *tok)
{
struct selector_parser_state *state
= parser_get_state(ctx, struct selector_parser_state);
struct ivy_ast_selector_node *sel
= (struct ivy_ast_selector_node *)state->s_base.s_node;
if (state->s_prev != IVY_TOK_IDENT || !b_queue_empty(&sel->n_arg_labels)) {
return IVY_ERR_BAD_SYNTAX;
}
return IVY_OK;
}
static enum ivy_status parse_right_paren(
struct ivy_parser *ctx, struct ivy_token *tok)
{
struct selector_parser_state *state
= parser_get_state(ctx, struct selector_parser_state);
struct ivy_ast_selector_node *sel
= (struct ivy_ast_selector_node *)state->s_base.s_node;
if (state->s_prev != IVY_TOK_IDENT || !b_queue_empty(&sel->n_arg_labels)) {
return IVY_ERR_BAD_SYNTAX;
}
return IVY_OK;
}
static enum ivy_status parse_pipe(struct ivy_parser *ctx, struct ivy_token *tok)
{
struct selector_parser_state *state
= parser_get_state(ctx, struct selector_parser_state);
struct ivy_ast_selector_node *sel
= (struct ivy_ast_selector_node *)state->s_base.s_node;
if (!b_queue_empty(&sel->n_arg_labels)
&& state->s_prev != IVY_SYM_RIGHT_PAREN) {
return IVY_ERR_BAD_SYNTAX;
}
if (state->s_prev != IVY_TOK_IDENT) {
return IVY_ERR_BAD_SYNTAX;
}
parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT);
return IVY_OK;
}
static void init_state(struct ivy_parser *ctx, struct parser_state *sp)
{
struct selector_parser_state *state = (struct selector_parser_state *)sp;
state->s_prev = 0;
}
struct ast_node_type msgh_node_ops = {
.n_init_state = init_state,
.n_state_size = sizeof(struct selector_parser_state),
.n_node_size = sizeof(struct ivy_ast_selector_node),
.n_token_parsers = {
[IVY_TOK_IDENT] = parse_ident,
[IVY_TOK_LABEL] = parse_label,
},
.n_symbol_parsers = {
[IVY_SYM_LEFT_PAREN] = parse_left_paren,
[IVY_SYM_RIGHT_PAREN] = parse_right_paren,
[IVY_SYM_PIPE] = parse_pipe,
},
};

View File

@@ -1,10 +1,10 @@
#include "ctx.h"
#include "node.h"
#include <blue/object/string.h>
#include <ivy/lang/lex.h>
#include <stdio.h>
#include "ctx.h"
#include "node.h"
struct unit_import_parser_state {
struct parser_state s_base;
int s_prev_token;
@@ -28,7 +28,8 @@ static enum ivy_status parse_ident(struct ivy_parser *ctx, struct ivy_token *tok
struct unit_import_parser_state *state
= parser_get_state(ctx, struct unit_import_parser_state);
struct ivy_ast_unit_import_node *node = (struct ivy_ast_unit_import_node *)(state->s_base.s_node);
struct ivy_ast_unit_import_node *node
= (struct ivy_ast_unit_import_node *)(state->s_base.s_node);
if (state->s_prev_token == IVY_TOK_IDENT) {
return IVY_ERR_BAD_SYNTAX;
@@ -61,12 +62,14 @@ static enum ivy_status add_child(
static void print(struct ivy_ast_node *node)
{
struct ivy_ast_unit_import_node *unit_import = (struct ivy_ast_unit_import_node *)node;
struct ivy_ast_unit_import_node *unit_import
= (struct ivy_ast_unit_import_node *)node;
b_string *str = b_string_create();
b_queue_iterator it = {0};
b_queue_foreach (&it, &unit_import->n_ident) {
struct ivy_token *tok = b_unbox(struct ivy_token, it.entry, t_entry);
struct ivy_token *tok
= b_unbox(struct ivy_token, it.entry, t_entry);
if (b_string_get_size(str, B_STRLEN_NORMAL) > 0) {
b_string_append_cstr(str, ".");
@@ -75,11 +78,12 @@ static void print(struct ivy_ast_node *node)
b_string_append_cstr(str, tok->t_str);
}
printf("%s(%s)\n", ivy_ast_node_type_to_string(node->n_type), b_string_ptr(str));
printf("%s(%s)\n", ivy_ast_node_type_to_string(node->n_type),
b_string_ptr(str));
b_string_release(str);
}
static void init_state(struct parser_state *sp)
static void init_state(struct ivy_parser *ctx, struct parser_state *sp)
{
struct unit_import_parser_state *state
= (struct unit_import_parser_state *)sp;

View File

@@ -1,10 +1,10 @@
#include "ctx.h"
#include "node.h"
#include <blue/object/string.h>
#include <ivy/lang/lex.h>
#include <stdio.h>
#include "ctx.h"
#include "node.h"
struct unit_package_parser_state {
struct parser_state s_base;
int s_prev_token;
@@ -28,7 +28,8 @@ static enum ivy_status parse_ident(struct ivy_parser *ctx, struct ivy_token *tok
struct unit_package_parser_state *state
= parser_get_state(ctx, struct unit_package_parser_state);
struct ivy_ast_unit_package_node *node = (struct ivy_ast_unit_package_node *)(state->s_base.s_node);
struct ivy_ast_unit_package_node *node
= (struct ivy_ast_unit_package_node *)(state->s_base.s_node);
if (state->s_prev_token == IVY_TOK_IDENT) {
return IVY_ERR_BAD_SYNTAX;
@@ -61,12 +62,14 @@ static enum ivy_status add_child(
static void print(struct ivy_ast_node *node)
{
struct ivy_ast_unit_package_node *unit_package = (struct ivy_ast_unit_package_node *)node;
struct ivy_ast_unit_package_node *unit_package
= (struct ivy_ast_unit_package_node *)node;
b_string *str = b_string_create();
b_queue_iterator it = {0};
b_queue_foreach (&it, &unit_package->n_ident) {
struct ivy_token *tok = b_unbox(struct ivy_token, it.entry, t_entry);
struct ivy_token *tok
= b_unbox(struct ivy_token, it.entry, t_entry);
if (b_string_get_size(str, B_STRLEN_NORMAL) > 0) {
b_string_append_cstr(str, ".");
@@ -75,11 +78,12 @@ static void print(struct ivy_ast_node *node)
b_string_append_cstr(str, tok->t_str);
}
printf("%s(%s)\n", ivy_ast_node_type_to_string(node->n_type), b_string_ptr(str));
printf("%s(%s)\n", ivy_ast_node_type_to_string(node->n_type),
b_string_ptr(str));
b_string_release(str);
}
static void init_state(struct parser_state *sp)
static void init_state(struct ivy_parser *ctx, struct parser_state *sp)
{
struct unit_package_parser_state *state
= (struct unit_package_parser_state *)sp;