ref: split parser into separate files
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
#include <compiler/fzl_parser.h>
|
||||
#include <compiler/internals/parser.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Functions parsing
|
||||
fzl_node_t *pa_function(fzl_parser_t *parser)
|
||||
{
|
||||
if (!parser)
|
||||
return NULL;
|
||||
|
||||
fzl_token_t *fn = consume(parser);
|
||||
if (!fn || fn->type != FZL_TOKTYPE_FUNCTION)
|
||||
{
|
||||
snprintf(plast_err, sizeof(plast_err),
|
||||
"'%s': expected keyword 'fn' at %ld:%ld", last_known_tok->filename,
|
||||
last_known_tok->ln, last_known_tok->cn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fzl_token_t *name = consume(parser);
|
||||
if (!name || name->type != FZL_TOKTYPE_NAME)
|
||||
{
|
||||
snprintf(plast_err, sizeof(plast_err),
|
||||
"'%s': expected function name at %ld:%ld",
|
||||
last_known_tok->filename, last_known_tok->ln, last_known_tok->cn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fzl_token_t *lpar = consume(parser);
|
||||
if (!lpar || lpar->type != FZL_TOKTYPE_LPAREN)
|
||||
{
|
||||
snprintf(plast_err, sizeof(plast_err), "'%s': expected '(' at %ld:%ld",
|
||||
last_known_tok->filename, last_known_tok->ln, last_known_tok->cn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t remainder = 1;
|
||||
size_t count = 0;
|
||||
fzl_node_t **args = malloc(remainder * sizeof(fzl_node_t *));
|
||||
|
||||
while (peek(parser) && !is(parser, FZL_TOKTYPE_RPAREN))
|
||||
{
|
||||
fzl_node_t *arg = pa_expression(parser);
|
||||
if (!arg)
|
||||
return NULL;
|
||||
|
||||
if (remainder <= count)
|
||||
{
|
||||
remainder *= 2;
|
||||
args = realloc(args, remainder * sizeof(fzl_node_t *));
|
||||
}
|
||||
|
||||
args[count++] = arg;
|
||||
|
||||
if (is(parser, FZL_TOKTYPE_COMMA))
|
||||
consume(parser);
|
||||
}
|
||||
|
||||
fzl_token_t *rpar = consume(parser);
|
||||
if (!rpar || rpar->type != FZL_TOKTYPE_RPAREN)
|
||||
{
|
||||
free(args);
|
||||
snprintf(plast_err, sizeof(plast_err),
|
||||
"'%s': expected ')' after argument list at %ld:%ld",
|
||||
last_known_tok->filename, last_known_tok->ln, last_known_tok->cn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fzl_token_t *type = NULL;
|
||||
if (is(parser, FZL_TOKTYPE_TYPE) || is(parser, FZL_TOKTYPE_NAME))
|
||||
type = consume(parser);
|
||||
|
||||
if (!type)
|
||||
type = &null_tok;
|
||||
|
||||
if (!is(parser, FZL_TOKTYPE_LBRACE))
|
||||
{
|
||||
free(args);
|
||||
snprintf(plast_err, sizeof(plast_err),
|
||||
"'%s': expected '{' after function declaration at %ld:%ld",
|
||||
last_known_tok->filename, last_known_tok->ln, last_known_tok->cn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fzl_node_t *body = pa_statement(parser);
|
||||
if (!body)
|
||||
{
|
||||
free(args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fzl_node_t *node = fzl_mknode(FZL_NODETYPE_FUNCTION, name);
|
||||
node->fn.args = args;
|
||||
node->fn.args_count = count;
|
||||
node->fn.body = body;
|
||||
node->fn.name = name;
|
||||
node->fn.type = type;
|
||||
|
||||
return node;
|
||||
}
|
||||
Reference in New Issue
Block a user