summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast.c7
-rw-r--r--src/ast.h11
-rw-r--r--src/gas_assembly_generator.c3
-rw-r--r--src/parser.c27
-rw-r--r--src/parser.h4
-rw-r--r--src/pipac.c5
-rw-r--r--src/scope.c6
-rw-r--r--src/scope.h7
8 files changed, 58 insertions, 12 deletions
diff --git a/src/ast.c b/src/ast.c
index d3e9a28..49d772a 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -108,6 +108,13 @@ ast_node_init_variable_declaration(ast_node_t *node, string_view_t variable_name
}
void
+ast_node_init_variable(ast_node_t *node, ast_identifier_t *identifier)
+{
+ node->kind = AST_VARIABLE;
+ node->data = (ast_node_data_t){ .variable_ex = { .identifier = identifier } };
+}
+
+void
ast_node_init_identifier(ast_node_t *node, string_view_t name)
{
node->kind = AST_IDENTIFIER;
diff --git a/src/ast.h b/src/ast.h
index e25f1bb..4fd1d1d 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -37,6 +37,11 @@ typedef struct ast_identifier_t
string_view_t name;
} ast_identifier_t;
+typedef struct ast_variable_t
+{
+ ast_identifier_t *identifier;
+} ast_variable_t;
+
typedef struct ast_function_declaration_t
{
ast_identifier_t identifier;
@@ -91,6 +96,7 @@ typedef enum
AST_RETURN_STMT,
AST_UNKOWN_NODE,
AST_VARIABLE_DECLARATION,
+ AST_VARIABLE
} ast_node_kind_t;
typedef union
@@ -99,8 +105,9 @@ typedef union
ast_function_declaration_t function;
ast_literal_t literal;
ast_return_stmt_t return_stmt;
- ast_variable_declaration_t variable;
+ ast_variable_declaration_t variable; // FIXME: Rename to variable_declaration
ast_identifier_t identifier;
+ ast_variable_t variable_ex; // FIXME: Rename to variable
} ast_node_data_t;
typedef struct ast_node_t
@@ -127,5 +134,7 @@ ast_node_init_variable_declaration(ast_node_t *node, string_view_t variable_name
// FIXME: use the naming convention
void
ast_literal_integer_create(ast_node_t *node, uint32_t number);
+void
+ast_node_init_variable(ast_node_t *node, ast_identifier_t *identifier);
#endif /* AST_H */
diff --git a/src/gas_assembly_generator.c b/src/gas_assembly_generator.c
index ea76c5f..f09b60d 100644
--- a/src/gas_assembly_generator.c
+++ b/src/gas_assembly_generator.c
@@ -61,6 +61,9 @@ gas_assembly_generator_compile(gas_assembly_generator_t *gen, ast_node_t *ast)
case AST_VARIABLE_DECLARATION:
assert(false && "TODO: ast variable declaration not implemented yet");
break;
+ case AST_VARIABLE:
+ assert(false && "TODO: ast variable not implemented yet");
+ break;
case AST_UNKOWN_NODE:
assert(false && "unreachable");
}
diff --git a/src/parser.c b/src/parser.c
index 6b954c2..469fa99 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -24,14 +24,16 @@
#include "ast.h"
#include "lexer.h"
#include "parser.h"
+#include "scope.h"
#include "vector.h"
void
-parser_init(parser_t *parser, lexer_t *lexer)
+parser_init(parser_t *parser, lexer_t *lexer, scope_t *scope)
{
assert(parser && "parser must be defined");
assert(lexer && "lexer must be defined");
parser->lexer = lexer;
+ parser->scope = scope;
parser->errors_len = 0;
}
@@ -134,8 +136,16 @@ parser_parse_factor(parser_t *parser, ast_node_t *node)
return false;
return true;
case TOKEN_NAME:
- /// FIXME: Check if the identifier is defined
ast_node_init_identifier(node, token.value);
+ // TODO: Check node kind, today accepts only variables
+ if (scope_get(parser->scope, token.value) == NULL) {
+ parser_error_t error;
+ error.token = token;
+ sprintf(error.message, "identifier '" SVFMT "' not defined", SVARG(&token.value));
+ parser->errors[parser->errors_len++] = error;
+ return false;
+ }
+
return true;
default: {
parser_error_t error;
@@ -143,7 +153,7 @@ parser_parse_factor(parser_t *parser, ast_node_t *node)
sprintf(error.message, "unexpected '%s (" SVFMT ")' token", token_kind_to_str(token.kind), SVARG(&token.value));
parser->errors[parser->errors_len++] = error;
return false;
- }
+ }
}
}
@@ -247,6 +257,7 @@ parser_parse_variable_definition(parser_t *parser, string_view_t variable_name,
}
ast_node_init_variable_declaration(node, variable_name, type, expression);
+ scope_push(parser->scope, &node->data.variable.identifier, node);
return true;
}
@@ -333,11 +344,17 @@ parser_parse_function_declaration(parser_t *parser, ast_node_t *node)
return false;
vector_t *body = vector_new();
+ ast_node_init_function_declaration(node, func_name_token.value, return_type, body);
+ scope_push(parser->scope, &node->data.function.identifier, node);
+
+ scope_enter(parser->scope);
- if (!parser_parse_block_declarations(parser, body))
+ if (!parser_parse_block_declarations(parser, body)) {
+ scope_leave(parser->scope);
return false;
+ }
- ast_node_init_function_declaration(node, func_name_token.value, return_type, body);
+ scope_leave(parser->scope);
return true;
}
diff --git a/src/parser.h b/src/parser.h
index bdf0c5a..d3e1431 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -19,6 +19,7 @@
#include "ast.h"
#include "lexer.h"
+#include "scope.h"
#include "string_view.h"
typedef struct parser_error_t
@@ -30,13 +31,14 @@ typedef struct parser_error_t
typedef struct parser_t
{
lexer_t *lexer;
+ scope_t *scope;
int errors_len;
// FIXME: replace with vector
parser_error_t errors[1];
} parser_t;
void
-parser_init(parser_t *parser, lexer_t *lexer);
+parser_init(parser_t *parser, lexer_t *lexer, scope_t *scope);
bool
parser_parse_function_declaration(parser_t *parser, ast_node_t *node);
diff --git a/src/pipac.c b/src/pipac.c
index b31b8b5..2041218 100644
--- a/src/pipac.c
+++ b/src/pipac.c
@@ -22,6 +22,7 @@
#include "gas_assembly_generator.h"
#include "lexer.h"
#include "parser.h"
+#include "scope.h"
#include "string_view.h"
static void
@@ -62,8 +63,9 @@ main(int argc, char **argv)
lexer_t lexer;
lexer_init(&lexer, filepath);
+ scope_t *scope = scope_new();
parser_t parser;
- parser_init(&parser, &lexer);
+ parser_init(&parser, &lexer, scope);
ast_node_t *func = ast_node_new();
@@ -74,6 +76,7 @@ main(int argc, char **argv)
generate_gas_x86_64_linux(func);
+ scope_destroy(scope);
ast_node_destroy(func);
return EXIT_SUCCESS;
}
diff --git a/src/scope.c b/src/scope.c
index 5b696ad..662e59c 100644
--- a/src/scope.c
+++ b/src/scope.c
@@ -54,7 +54,7 @@ scope_new(void)
void
scope_destroy(scope_t *scope)
{
- if (scope->stack->size) {
+ if (scope->stack->size != 1) {
fprintf(stderr,
"Stack not cleaned before destroying. This may lead to memory leaks.\n"
"Please make sure to call the leave function before destroying it.");
@@ -97,7 +97,7 @@ scope_leave(scope_t *scope)
}
ast_node_t *
-scope_get(scope_t *scope, ast_identifier_t *identifier)
+scope_get(scope_t *scope, string_view_t name)
{
for (size_t i = scope->stack->size; i > 0; i--) {
vector_t *current_level = vector_at(scope->stack, i - 1);
@@ -105,7 +105,7 @@ scope_get(scope_t *scope, ast_identifier_t *identifier)
for (size_t j = 0; j < current_level->size; j++) {
scope_item_t *item = vector_at(current_level, j);
- if (string_view_eq(identifier->name, item->identifier->name)) {
+ if (string_view_eq(name, item->identifier->name)) {
return item->node;
}
}
diff --git a/src/scope.h b/src/scope.h
index c221703..2636990 100644
--- a/src/scope.h
+++ b/src/scope.h
@@ -14,6 +14,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#ifndef SCOPE_H
+#define SCOPE_H
+
#include "ast.h"
#include "string_view.h"
#include "vector.h"
@@ -41,6 +44,8 @@ void
scope_leave(scope_t *scope);
ast_node_t *
-scope_get(scope_t *scope, ast_identifier_t *identifier);
+scope_get(scope_t *scope, string_view_t name);
void
scope_push(scope_t *scope, ast_identifier_t *identifier, ast_node_t *node);
+
+#endif /* SCOPE_H */