aboutsummaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/ast.c21
-rw-r--r--src/parser/ast.h11
-rw-r--r--src/parser/parser.c25
3 files changed, 57 insertions, 0 deletions
diff --git a/src/parser/ast.c b/src/parser/ast.c
index 979dff0..3f360cc 100644
--- a/src/parser/ast.c
+++ b/src/parser/ast.c
@@ -8,17 +8,25 @@ struct Program create_program(void)
program.consts = NULL;
program.const_count = 0;
program.const_capacity = 0;
+ program.data_decls = NULL;
+ program.data_count = 0;
+ program.data_capacity = 0;
return program;
}
void free_program(struct Program* program)
{
free(program->consts);
+ free(program->data_decls);
program->consts = NULL;
program->const_count = 0;
program->const_capacity = 0;
+ program->data_decls = NULL;
+ program->data_count = 0;
+ program->data_capacity = 0;
}
+// TODO: generalize this growable-array boilerplate once a third list appears
void add_const(struct Program* program, struct ConstDecl decl)
{
if (program->const_count == program->const_capacity)
@@ -31,3 +39,16 @@ void add_const(struct Program* program, struct ConstDecl decl)
program->consts[program->const_count] = decl;
program->const_count += 1;
}
+
+void add_data(struct Program* program, struct DataDecl decl)
+{
+ if (program->data_count == program->data_capacity)
+ {
+ size_t capacity = program->data_capacity < 8 ? 8 : program->data_capacity * 2;
+ program->data_decls = realloc(program->data_decls, capacity * sizeof(struct DataDecl));
+ program->data_capacity = capacity;
+ }
+
+ program->data_decls[program->data_count] = decl;
+ program->data_count += 1;
+}
diff --git a/src/parser/ast.h b/src/parser/ast.h
index 7079305..30dd1e7 100644
--- a/src/parser/ast.h
+++ b/src/parser/ast.h
@@ -10,13 +10,24 @@ struct ConstDecl
struct Token value;
};
+struct DataDecl
+{
+ struct Token name;
+ struct Token value;
+};
+
struct Program
{
struct ConstDecl* consts;
size_t const_count;
size_t const_capacity;
+
+ struct DataDecl* data_decls;
+ size_t data_count;
+ size_t data_capacity;
};
struct Program create_program(void);
void free_program(struct Program* program);
void add_const(struct Program* program, struct ConstDecl decl);
+void add_data(struct Program* program, struct DataDecl decl);
diff --git a/src/parser/parser.c b/src/parser/parser.c
index 5845ad4..4fb85ef 100644
--- a/src/parser/parser.c
+++ b/src/parser/parser.c
@@ -58,6 +58,25 @@ static bool parse_const(struct Parser* parser, struct Program* program)
return true;
}
+static bool parse_data(struct Parser* parser, struct Program* program)
+{
+ struct DataDecl decl;
+
+ if (!consume(parser, TOKEN_IDENTIFIER, "expected data name after 'data'"))
+ return false;
+ decl.name = parser->previous;
+
+ if (!consume(parser, TOKEN_EQUAL, "expected '=' after data name"))
+ return false;
+
+ if (!consume(parser, TOKEN_STRING, "expected string value after '='"))
+ return false;
+ decl.value = parser->previous;
+
+ add_data(program, decl);
+ return true;
+}
+
bool parse_program(struct Lexer* lexer, struct Program* out)
{
struct Parser parser;
@@ -75,6 +94,12 @@ bool parse_program(struct Lexer* lexer, struct Program* out)
if (!parse_const(&parser, out))
return false;
}
+ else if (check(&parser, TOKEN_DATA))
+ {
+ advance_parser(&parser);
+ if (!parse_data(&parser, out))
+ return false;
+ }
else
{
error_at(&parser, parser.current, "expected a top-level declaration");