feat: full while/until loops support, important bug fixes and more tests

This commit is contained in:
Gu://em_ 2026-01-30 23:43:49 +01:00
parent 9e522b2a68
commit f31fca4204
6 changed files with 85 additions and 37 deletions

View file

@ -101,17 +101,13 @@ static void add_first_redir(void)
add_first(RULE_REDIRECTION, TOKEN_REDIR_RIGHT_PIPE);
}
// === Functions
int grammar_init(void)
// Adds only direct tokens to rules firsts into the firsts map
static void add_firsts_tokens(void)
{
// Initialize the firsts map
bool success = init_firsts_map();
if (success != true)
return false;
// Populate the firsts map
// TODO CHECK ORDER
// Redirection
add_first_redir();
// %RIP Matteo 30/01/2026
// %RAX Guillem 30/01/2026 hehe
// If
add_first(RULE_IF, TOKEN_IF);
@ -127,7 +123,7 @@ int grammar_init(void)
add_first(RULE_WHILE, TOKEN_WHILE);
// Until
add_first(RULE_WHILE, TOKEN_UNTIL);
add_first(RULE_UNTIL, TOKEN_UNTIL);
// Case
add_first(RULE_CASE, TOKEN_CASE);
@ -136,33 +132,57 @@ int grammar_init(void)
add_first(RULE_CASE_ITEM, TOKEN_LEFT_PAREN);
add_first(RULE_CASE_ITEM, TOKEN_WORD);
// Case clause
add_firsts(RULE_CASE_CLAUSE, first(RULE_CASE_ITEM));
// Shell command
add_first(RULE_SHELL_COMMAND, TOKEN_LEFT_BRACKET);
add_first(RULE_SHELL_COMMAND, TOKEN_LEFT_PAREN);
// Redirection
add_first_redir();
// %RIP Matteo 30/01/2026
// %RAX Guillem 30/01/2026 hehe
// Simple command
add_first(RULE_SIMPLE_COMMAND, TOKEN_WORD);
add_first(RULE_SIMPLE_COMMAND, TOKEN_EXPORT);
// Element
add_first(RULE_ELEMENT, TOKEN_WORD);
add_first(RULE_ELEMENT, TOKEN_ASSIGNMENT_WORD);
add_firsts(RULE_ELEMENT, first(RULE_REDIRECTION));
// Prefix
add_first(RULE_PREFIX, TOKEN_ASSIGNMENT_WORD);
// Pipeline
add_first(RULE_PIPELINE, TOKEN_WORD);
// Compound list
add_first(RULE_COMPOUND_LIST, TOKEN_NEWLINE);
// Input
add_first(RULE_INPUT, TOKEN_NEWLINE);
add_first(RULE_INPUT, TOKEN_EOF);
// Funcdec
add_first(RULE_FUNCDEC, TOKEN_WORD);
}
// Adds only firsts that depend on other rules to the firsts map
// WARNING order matters
static void add_firsts_rec(void)
{
// Case clause
add_firsts(RULE_CASE_CLAUSE, first(RULE_CASE_ITEM));
// Element
add_firsts(RULE_ELEMENT, first(RULE_REDIRECTION));
// Prefix
add_firsts(RULE_PREFIX, first(RULE_REDIRECTION));
// Shell command
add_firsts(RULE_SHELL_COMMAND, first(RULE_IF));
add_firsts(RULE_SHELL_COMMAND, first(RULE_FOR));
add_firsts(RULE_SHELL_COMMAND, first(RULE_WHILE));
add_firsts(RULE_SHELL_COMMAND, first(RULE_UNTIL));
add_firsts(RULE_SHELL_COMMAND, first(RULE_CASE));
// Simple command
add_firsts(RULE_SIMPLE_COMMAND, first(RULE_PREFIX));
add_first(RULE_SIMPLE_COMMAND, TOKEN_WORD);
add_first(RULE_SIMPLE_COMMAND, TOKEN_EXPORT);
// Funcdec
add_first(RULE_FUNCDEC, TOKEN_WORD);
// Command
add_firsts(RULE_COMMAND, first(RULE_SIMPLE_COMMAND));
@ -170,23 +190,33 @@ int grammar_init(void)
add_firsts(RULE_COMMAND, first(RULE_FUNCDEC));
// Pipeline
add_first(RULE_PIPELINE, TOKEN_WORD);
add_firsts(RULE_PIPELINE, first(RULE_COMMAND));
// And Or
add_firsts(RULE_AND_OR, first(RULE_PIPELINE));
// Compound list
add_first(RULE_COMPOUND_LIST, TOKEN_NEWLINE);
add_firsts(RULE_COMPOUND_LIST, first(RULE_AND_OR));
// List
add_firsts(RULE_LIST, first(RULE_AND_OR));
// Input
add_first(RULE_INPUT, TOKEN_NEWLINE);
add_first(RULE_INPUT, TOKEN_EOF);
add_firsts(RULE_INPUT, first(RULE_LIST));
}
// === Functions
int grammar_init(void)
{
// Initialize the firsts map
bool success = init_firsts_map();
if (success != true)
return false;
// Populate the firsts map
add_firsts_tokens();
add_firsts_rec();
return true;
}