fix: merge conflict
This commit is contained in:
commit
69ee869af0
6 changed files with 118 additions and 40 deletions
|
|
@ -2,8 +2,8 @@
|
||||||
#define EXECUTION_H
|
#define EXECUTION_H
|
||||||
|
|
||||||
#include "../utils/ast/ast.h"
|
#include "../utils/ast/ast.h"
|
||||||
#include "../utils/lists/lists.h"
|
|
||||||
#include "../utils/hash_map/hash_map.h"
|
#include "../utils/hash_map/hash_map.h"
|
||||||
|
#include "../utils/lists/lists.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute the AST
|
* @brief Execute the AST
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,14 @@ static void set_token_keyword(struct token *tok, char *begin, ssize_t size)
|
||||||
{
|
{
|
||||||
tok->type = TOKEN_ELIF;
|
tok->type = TOKEN_ELIF;
|
||||||
}
|
}
|
||||||
|
else if (strncmp(begin, "&&", size) == 0)
|
||||||
|
{
|
||||||
|
tok->type = TOKEN_AND;
|
||||||
|
}
|
||||||
|
else if (strncmp(begin, "||", size) == 0)
|
||||||
|
{
|
||||||
|
tok->type = TOKEN_OR;
|
||||||
|
}
|
||||||
|
|
||||||
// no keywords found.
|
// no keywords found.
|
||||||
if (tok->type == TOKEN_NULL)
|
if (tok->type == TOKEN_NULL)
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,9 @@ enum token_type
|
||||||
TOKEN_THEN,
|
TOKEN_THEN,
|
||||||
TOKEN_ELSE,
|
TOKEN_ELSE,
|
||||||
TOKEN_FI,
|
TOKEN_FI,
|
||||||
TOKEN_ELIF
|
TOKEN_ELIF,
|
||||||
|
TOKEN_AND,
|
||||||
|
TOKEN_OR
|
||||||
};
|
};
|
||||||
|
|
||||||
struct token
|
struct token
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,24 @@
|
||||||
#include "../utils/lists/lists.h"
|
#include "../utils/lists/lists.h"
|
||||||
#include "grammar.h"
|
#include "grammar.h"
|
||||||
|
|
||||||
|
// === Static functions
|
||||||
|
|
||||||
|
enum ast_and_or_type and_or_tok_to_ast(enum token_type tok_type)
|
||||||
|
{
|
||||||
|
switch (tok_type)
|
||||||
|
{
|
||||||
|
case TOKEN_AND:
|
||||||
|
return AST_AND_OR_TYPE_AND;
|
||||||
|
case TOKEN_OR:
|
||||||
|
return AST_AND_OR_TYPE_OR;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "and_or impossible to init, wrong token type");
|
||||||
|
return AST_AND_OR_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Functions
|
||||||
|
|
||||||
struct ast *parse_list(struct lexer_context *ctx)
|
struct ast *parse_list(struct lexer_context *ctx)
|
||||||
{
|
{
|
||||||
struct list *result_list = NULL;
|
struct list *result_list = NULL;
|
||||||
|
|
@ -41,7 +59,37 @@ struct ast *parse_list(struct lexer_context *ctx)
|
||||||
|
|
||||||
struct ast *parse_and_or(struct lexer_context *ctx)
|
struct ast *parse_and_or(struct lexer_context *ctx)
|
||||||
{
|
{
|
||||||
return parse_pipeline(ctx);
|
struct ast *result = parse_pipeline(ctx);
|
||||||
|
struct token *token = PEEK_TOKEN();
|
||||||
|
|
||||||
|
if (token->type == TOKEN_AND || token->type == TOKEN_OR)
|
||||||
|
{
|
||||||
|
// set left part
|
||||||
|
|
||||||
|
struct ast *left = result;
|
||||||
|
|
||||||
|
// eat and_or token
|
||||||
|
token = POP_TOKEN();
|
||||||
|
|
||||||
|
// set type
|
||||||
|
enum ast_and_or_type type = and_or_tok_to_ast(token->type);
|
||||||
|
|
||||||
|
token = PEEK_TOKEN();
|
||||||
|
|
||||||
|
// skip newlines
|
||||||
|
while (token->type == TOKEN_NEWLINE)
|
||||||
|
{
|
||||||
|
token = POP_TOKEN();
|
||||||
|
token = PEEK_TOKEN();
|
||||||
|
}
|
||||||
|
|
||||||
|
// right part
|
||||||
|
struct ast *right = parse_pipeline(ctx);
|
||||||
|
|
||||||
|
result = ast_create_and_or(left, right, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ast *parse_pipeline(struct lexer_context *ctx)
|
struct ast *parse_pipeline(struct lexer_context *ctx)
|
||||||
|
|
@ -190,31 +238,34 @@ struct ast *parse_compound_list(struct lexer_context *ctx)
|
||||||
while (token->type == TOKEN_NEWLINE)
|
while (token->type == TOKEN_NEWLINE)
|
||||||
{
|
{
|
||||||
token = POP_TOKEN();
|
token = POP_TOKEN();
|
||||||
|
token = PEEK_TOKEN();
|
||||||
}
|
}
|
||||||
|
|
||||||
// and_or
|
// and_or
|
||||||
current_cmd = parse_and_or(ctx);
|
current_cmd = parse_and_or(ctx);
|
||||||
if (current_cmd == NULL)
|
if (current_cmd == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
list_append(result_list, current_cmd);
|
result_list = list_append(result_list, current_cmd);
|
||||||
|
|
||||||
// Following commands
|
// Following commands
|
||||||
token = PEEK_TOKEN();
|
token = PEEK_TOKEN();
|
||||||
while (token->type == TOKEN_SEMICOLON || token->type == TOKEN_NEWLINE)
|
while (token->type == TOKEN_SEMICOLON || token->type == TOKEN_NEWLINE)
|
||||||
{
|
{
|
||||||
POP_TOKEN();
|
POP_TOKEN();
|
||||||
|
token = PEEK_TOKEN();
|
||||||
|
|
||||||
// Skip newlines
|
// Skip newlines
|
||||||
while (token->type == TOKEN_NEWLINE)
|
while (token->type == TOKEN_NEWLINE)
|
||||||
{
|
{
|
||||||
token = POP_TOKEN();
|
token = POP_TOKEN();
|
||||||
|
token = PEEK_TOKEN();
|
||||||
}
|
}
|
||||||
|
|
||||||
// and_or
|
// and_or
|
||||||
current_cmd = parse_and_or(ctx);
|
current_cmd = parse_and_or(ctx);
|
||||||
if (current_cmd == NULL)
|
if (current_cmd == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
list_append(result_list, current_cmd);
|
result_list = list_append(result_list, current_cmd);
|
||||||
|
|
||||||
token = PEEK_TOKEN();
|
token = PEEK_TOKEN();
|
||||||
}
|
}
|
||||||
|
|
@ -223,12 +274,14 @@ struct ast *parse_compound_list(struct lexer_context *ctx)
|
||||||
if (token->type == TOKEN_SEMICOLON)
|
if (token->type == TOKEN_SEMICOLON)
|
||||||
{
|
{
|
||||||
token = POP_TOKEN();
|
token = POP_TOKEN();
|
||||||
|
token = PEEK_TOKEN();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip newlines
|
// Skip newlines
|
||||||
while (token->type == TOKEN_NEWLINE)
|
while (token->type == TOKEN_NEWLINE)
|
||||||
{
|
{
|
||||||
token = POP_TOKEN();
|
token = POP_TOKEN();
|
||||||
|
token = PEEK_TOKEN();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ast *result = ast_create_list(result_list);
|
struct ast *result = ast_create_list(result_list);
|
||||||
|
|
@ -276,8 +329,8 @@ struct ast *parse_else_clause(struct lexer_context *ctx)
|
||||||
|
|
||||||
if (token->type == TOKEN_ELSE)
|
if (token->type == TOKEN_ELSE)
|
||||||
{
|
{
|
||||||
|
token = POP_TOKEN(); // eat else
|
||||||
result = parse_compound_list(ctx);
|
result = parse_compound_list(ctx);
|
||||||
token = POP_TOKEN(); // Forward
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,44 @@
|
||||||
|
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void ast_free(struct ast **node)
|
||||||
|
{
|
||||||
|
if (*node == NULL)
|
||||||
|
return;
|
||||||
|
// ast void does not need to be freed.
|
||||||
|
if (ast_is_if(*node))
|
||||||
|
ast_free_if(ast_get_if(*node));
|
||||||
|
else if (ast_is_command(*node))
|
||||||
|
ast_free_command(ast_get_command(*node));
|
||||||
|
else if (ast_is_list(*node))
|
||||||
|
ast_free_list(ast_get_list(*node));
|
||||||
|
else if (ast_is_and_or(*node))
|
||||||
|
ast_free_and_or(ast_get_and_or(*node));
|
||||||
|
else if (ast_is_redir(*node))
|
||||||
|
ast_free_redir(ast_get_redir(*node));
|
||||||
|
|
||||||
|
free(*node);
|
||||||
|
*node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ast *ast_create(enum ast_type type, void *data)
|
||||||
|
{
|
||||||
|
struct ast *node = malloc(sizeof(struct ast));
|
||||||
|
if (!node)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
node->type = type;
|
||||||
|
node->data = data;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
static void ast_print_dot_recursive(struct ast *node, FILE *out)
|
static void ast_print_dot_recursive(struct ast *node, FILE *out)
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
|
|
@ -13,6 +47,20 @@ static void ast_print_dot_recursive(struct ast *node, FILE *out)
|
||||||
|
|
||||||
switch (node->type)
|
switch (node->type)
|
||||||
{
|
{
|
||||||
|
case AST_LIST: {
|
||||||
|
struct ast_list *ast_list = ast_get_list(node);
|
||||||
|
fprintf(out, " node%p [label=\"LIST\"];\n", (void *)node);
|
||||||
|
|
||||||
|
struct list *elt = ast_list->children;
|
||||||
|
while (elt != NULL)
|
||||||
|
{
|
||||||
|
struct ast *child = (struct ast *)elt->data;
|
||||||
|
fprintf(out, " node%p -> node%p;\n", (void *)node, (void *)child);
|
||||||
|
ast_print_dot_recursive(child, out);
|
||||||
|
elt = elt->next;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case AST_IF: {
|
case AST_IF: {
|
||||||
struct ast_if *if_data = ast_get_if(node);
|
struct ast_if *if_data = ast_get_if(node);
|
||||||
fprintf(out, " node%p [label=\"IF\"];\n", (void *)node);
|
fprintf(out, " node%p [label=\"IF\"];\n", (void *)node);
|
||||||
|
|
@ -81,38 +129,4 @@ void ast_print_dot(struct ast *ast)
|
||||||
ast_print_dot_recursive(ast, dot_pipe);
|
ast_print_dot_recursive(ast, dot_pipe);
|
||||||
fprintf(dot_pipe, "}\n");
|
fprintf(dot_pipe, "}\n");
|
||||||
pclose(dot_pipe);
|
pclose(dot_pipe);
|
||||||
|
|
||||||
system("open ast.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ast_free(struct ast **node)
|
|
||||||
{
|
|
||||||
if (*node == NULL)
|
|
||||||
return;
|
|
||||||
// ast void does not need to be freed.
|
|
||||||
if (ast_is_if(*node))
|
|
||||||
ast_free_if(ast_get_if(*node));
|
|
||||||
else if (ast_is_command(*node))
|
|
||||||
ast_free_command(ast_get_command(*node));
|
|
||||||
else if (ast_is_list(*node))
|
|
||||||
ast_free_list(ast_get_list(*node));
|
|
||||||
else if (ast_is_and_or(*node))
|
|
||||||
ast_free_and_or(ast_get_and_or(*node));
|
|
||||||
else if (ast_is_redir(*node))
|
|
||||||
ast_free_redir(ast_get_redir(*node));
|
|
||||||
|
|
||||||
free(*node);
|
|
||||||
*node = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ast *ast_create(enum ast_type type, void *data)
|
|
||||||
{
|
|
||||||
struct ast *node = malloc(sizeof(struct ast));
|
|
||||||
if (node == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
node->type = type;
|
|
||||||
node->data = data;
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
enum ast_and_or_type
|
enum ast_and_or_type
|
||||||
{
|
{
|
||||||
|
AST_AND_OR_NULL,
|
||||||
AST_AND_OR_TYPE_AND,
|
AST_AND_OR_TYPE_AND,
|
||||||
AST_AND_OR_TYPE_OR
|
AST_AND_OR_TYPE_OR
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue