feat: while and for loops support for parser, plus new ASTs, new tokens and fixes inside parser

This commit is contained in:
Gu://em_ 2026-01-30 19:48:31 +01:00
parent f8b91d4da3
commit 423793903d
9 changed files with 341 additions and 35 deletions

View file

@ -81,3 +81,145 @@ struct ast *parse_prefix(struct lexer_context *ctx)
return NULL;
}
}
// TODO NOT IMPLEMENTED
struct ast *parse_funcdec(struct lexer_context *ctx)
{
(void)ctx;
perror("Error: usage of a not implemented function (parse_funcdec)");
return NULL;
}
struct ast *parse_for(struct lexer_context *ctx)
{
(void)ctx;
perror("Error: usage of a not implemented function (parse_for)");
return NULL;
}
struct ast *parse_while(struct lexer_context *ctx)
{
struct token *token = PEEK_TOKEN();
// 'while'
if (token->type != TOKEN_WHILE)
{
perror(
"Internal error: expected a TOKEN_WHILE but got a different type");
return NULL;
}
POP_TOKEN();
// condition
struct ast *condition = parse_compound_list(ctx);
if (condition == NULL)
return NULL;
token = PEEK_TOKEN();
// 'do'
if (token->type != TOKEN_DO)
{
ast_free(&condition);
perror("Syntax error: expected the 'do' keyowrd but got a different "
"token");
return NULL;
}
POP_TOKEN();
token = PEEK_TOKEN();
// body
struct ast *body = parse_compound_list(ctx);
if (body == NULL)
{
ast_free(&condition);
return NULL;
}
token = PEEK_TOKEN();
// 'done'
if (token->type != TOKEN_DONE)
{
ast_free(&condition);
perror("Syntax error: expected the 'done' keyowrd but got a different "
"token");
return NULL;
}
POP_TOKEN();
struct ast *result = ast_create_loop(condition, body);
if (result == NULL)
{
ast_free(&condition);
ast_free(&body);
perror("Internal error: could not create ast node (is your memory full "
"?)");
return NULL;
}
return result;
}
struct ast *parse_until(struct lexer_context *ctx)
{
struct token *token = PEEK_TOKEN();
// 'while'
if (token->type != TOKEN_UNTIL)
{
perror(
"Internal error: expected a TOKEN_WHILE but got a different type");
return NULL;
}
POP_TOKEN();
// condition
struct ast *condition = parse_compound_list(ctx);
if (condition == NULL)
return NULL;
condition =
ast_create_neg(true, condition); // TODO check result (beware to not
// exceed function lines limit)
token = PEEK_TOKEN();
// 'do'
if (token->type != TOKEN_DO)
{
ast_free(&condition);
perror("Syntax error: expected the 'do' keyowrd but got a different "
"token");
return NULL;
}
POP_TOKEN();
token = PEEK_TOKEN();
// body
struct ast *body = parse_compound_list(ctx);
if (body == NULL)
{
ast_free(&condition);
return NULL;
}
token = PEEK_TOKEN();
// 'done'
if (token->type != TOKEN_DONE)
{
ast_free(&condition);
perror("Syntax error: expected the 'done' keyowrd but got a different "
"token");
return NULL;
}
POP_TOKEN();
struct ast *result = ast_create_loop(condition, body);
if (result == NULL)
{
ast_free(&condition);
ast_free(&body);
perror("Internal error: could not create ast node (is your memory full "
"?)");
return NULL;
}
return result;
}