127 lines
2.5 KiB
C
127 lines
2.5 KiB
C
|
|
#include "ctx.h"
|
||
|
|
|
||
|
|
#include <ivy/lang/parse.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
enum ivy_status ivy_parser_create(struct ivy_parser **parser)
|
||
|
|
{
|
||
|
|
struct ivy_parser *out = malloc(sizeof *out);
|
||
|
|
if (!out) {
|
||
|
|
return IVY_ERR_NO_MEMORY;
|
||
|
|
}
|
||
|
|
|
||
|
|
memset(out, 0x0, sizeof *out);
|
||
|
|
|
||
|
|
*parser = out;
|
||
|
|
return IVY_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
void ivy_parser_destroy(struct ivy_parser *parser)
|
||
|
|
{
|
||
|
|
free(parser);
|
||
|
|
}
|
||
|
|
|
||
|
|
enum ivy_status ivy_parser_set_diag_ctx(
|
||
|
|
struct ivy_parser *parser, struct ivy_diag_ctx *ctx)
|
||
|
|
{
|
||
|
|
parser->p_diag = ctx;
|
||
|
|
return IVY_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
enum ivy_status ivy_parser_get_status(struct ivy_parser *parser)
|
||
|
|
{
|
||
|
|
return parser->p_status;
|
||
|
|
}
|
||
|
|
|
||
|
|
enum ivy_status ivy_parser_parse(
|
||
|
|
struct ivy_parser *parser, struct ivy_lexer *src, struct ivy_ast_node **out)
|
||
|
|
{
|
||
|
|
parser->p_src = src;
|
||
|
|
enum ivy_status status = parse_unit(parser, out);
|
||
|
|
if (status == IVY_ERR_EOF && *out != NULL) {
|
||
|
|
status = IVY_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
return status;
|
||
|
|
}
|
||
|
|
|
||
|
|
struct ivy_token *peek_token(struct ivy_parser *parser)
|
||
|
|
{
|
||
|
|
fx_queue_entry *entry = fx_queue_first(&parser->p_tokens);
|
||
|
|
if (!entry) {
|
||
|
|
return ivy_lexer_peek(parser->p_src);
|
||
|
|
}
|
||
|
|
|
||
|
|
return fx_unbox(struct ivy_token, entry, t_entry);
|
||
|
|
}
|
||
|
|
|
||
|
|
struct ivy_token *peek_next_token(struct ivy_parser *parser)
|
||
|
|
{
|
||
|
|
if (fx_queue_empty(&parser->p_tokens)) {
|
||
|
|
struct ivy_token *tok = parse_token(parser);
|
||
|
|
fx_queue_push_back(&parser->p_tokens, &tok->t_entry);
|
||
|
|
return ivy_lexer_peek(parser->p_src);
|
||
|
|
}
|
||
|
|
|
||
|
|
fx_queue_entry *buf = fx_queue_first(&parser->p_tokens);
|
||
|
|
if (buf) {
|
||
|
|
buf = fx_queue_next(buf);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (buf) {
|
||
|
|
return fx_unbox(struct ivy_token, buf, t_entry);
|
||
|
|
}
|
||
|
|
|
||
|
|
return ivy_lexer_peek(parser->p_src);
|
||
|
|
}
|
||
|
|
|
||
|
|
struct ivy_token *parse_token(struct ivy_parser *parser)
|
||
|
|
{
|
||
|
|
fx_queue_entry *entry = fx_queue_pop_front(&parser->p_tokens);
|
||
|
|
if (!entry) {
|
||
|
|
return ivy_lexer_read(parser->p_src);
|
||
|
|
}
|
||
|
|
|
||
|
|
return fx_unbox(struct ivy_token, entry, t_entry);
|
||
|
|
}
|
||
|
|
|
||
|
|
void discard_token(struct ivy_parser *parser)
|
||
|
|
{
|
||
|
|
struct ivy_token *tok = parse_token(parser);
|
||
|
|
if (tok) {
|
||
|
|
ivy_token_destroy(tok);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void __parse_trace(
|
||
|
|
struct ivy_parser *parser, const char *func, int line,
|
||
|
|
const char *format, ...)
|
||
|
|
{
|
||
|
|
struct ivy_token *tok = NULL;
|
||
|
|
if (parser) {
|
||
|
|
tok = peek_token(parser);
|
||
|
|
if (tok) {
|
||
|
|
fprintf(stderr, "[%zu:%zu] ", tok->t_start.c_row,
|
||
|
|
tok->t_start.c_col);
|
||
|
|
} else {
|
||
|
|
fprintf(stderr, "[EOF] ");
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
fprintf(stderr, "[UNK] ");
|
||
|
|
}
|
||
|
|
|
||
|
|
fprintf(stderr, "%s:%d: ", func, line);
|
||
|
|
|
||
|
|
if (tok) {
|
||
|
|
fprintf(stderr, "(%s) ", ivy_token_to_string(tok));
|
||
|
|
}
|
||
|
|
|
||
|
|
va_list va;
|
||
|
|
va_start(va, format);
|
||
|
|
vfprintf(stderr, format, va);
|
||
|
|
va_end(va);
|
||
|
|
|
||
|
|
fputc('\n', stderr);
|
||
|
|
}
|