commit b28fe5aa427edb710a2aa4b0996e90ad61727dac
parent aaceda710f77c7337c774278bd99cc91495a5976
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 1 Nov 2020 15:10:41 -0500
Initial scaffolding for parser
Diffstat:
6 files changed, 119 insertions(+), 33 deletions(-)
diff --git a/configure b/configure
@@ -6,6 +6,7 @@ harec() {
genrules harec \
src/lex.c \
src/main.c \
+ src/parse.c \
src/utf8.c
}
diff --git a/include/ast.h b/include/ast.h
@@ -0,0 +1,48 @@
+#ifndef HARE_AST_H
+#define HARE_AST_H
+#include "identifier.h"
+
+enum ast_import_mode {
+ AST_IMPORT_IDENTIFIER, // use foo::bar;
+ AST_IMPORT_ALIAS, // use foo::bar = x::y;
+ AST_IMPORT_MEMBERS, // use foo::bar::{a, b, c};
+};
+
+struct ast_imports {
+ enum ast_import_mode mode;
+ union {
+ struct identifier ident;
+ struct identifier *alias;
+ struct ast_imports *members;
+ };
+ struct ast_imports *next;
+};
+
+enum ast_declaration_type {
+ AST_DECL_FUNC,
+ AST_DECL_TYPE,
+ AST_DECL_VAR,
+ AST_DECL_CONST,
+};
+
+struct ast_declaration {
+ enum ast_declaration_type type;
+};
+
+struct ast_declarations {
+ struct ast_declaration decl;
+ struct ast_declarations *next;
+};
+
+struct ast_subunit {
+ struct ast_imports *imports;
+ struct ast_declarations decls;
+ struct ast_subunit *next;
+};
+
+struct ast_unit {
+ struct identifier *ns;
+ struct ast_subunit subunits;
+};
+
+#endif
diff --git a/include/identifier.h b/include/identifier.h
@@ -0,0 +1,9 @@
+#ifndef HARE_IDENTIFIER_H
+#define HARE_IDENTIFIER_H
+
+struct identifier {
+ char *name;
+ struct identifier *ns;
+};
+
+#endif
diff --git a/include/parse.h b/include/parse.h
@@ -0,0 +1,11 @@
+#ifndef HAREC_PARSE_H
+#define HAREC_PARSE_H
+#include <stdio.h>
+
+struct ast_unit;
+struct identifier;
+struct lexer;
+
+void parse(struct lexer *lexer, struct identifier *ns, struct ast_unit *unit);
+
+#endif
diff --git a/src/main.c b/src/main.c
@@ -1,6 +1,7 @@
#include <stdio.h>
+#include "ast.h"
#include "lex.h"
-#include "utf8.h"
+#include "parse.h"
int
main(int argc, char *argv[])
@@ -8,38 +9,8 @@ main(int argc, char *argv[])
struct lexer lexer;
lex_init(&lexer, stdin);
- struct token tok;
- while (tok.token != T_EOF) {
- token_finish(&tok);
- lex(&lexer, &tok);
- switch (tok.token) {
- case T_NAME:
- fprintf(stderr, "'%s'\n", tok.name);
- break;
- case T_LITERAL:
- fprintf(stderr, "(%s)\n", tok.literal);
- break;
- case T_RUNE:
- putc('\'', stderr);
- utf8_fputch(stderr, tok.rune);
- putc('\'', stderr);
- putc('\n', stderr);
- break;
- case T_STRING:
- fprintf(stderr, "\"%*s\"\n", (int)tok.string.len,
- tok.string.value);
- break;
- case T_ERROR:
- fprintf(stderr, "ERROR\n");
- break;
- case T_EOF:
- fprintf(stderr, "EOF\n");
- break;
- default:
- fprintf(stderr, "%s\n", token_str(&tok));
- break;
- }
- };
+ struct ast_unit unit;
+ parse(&lexer, NULL, &unit);
lex_finish(&lexer);
return 0;
diff --git a/src/parse.c b/src/parse.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include "ast.h"
+#include "identifier.h"
+#include "lex.h"
+#include "parse.h"
+#include "utf8.h"
+
+void
+parse(struct lexer *lexer, struct identifier *ns, struct ast_unit *unit)
+{
+ struct token tok = {0};
+
+ while (tok.token != T_EOF) {
+ token_finish(&tok);
+ lex(lexer, &tok);
+ switch (tok.token) {
+ case T_NAME:
+ fprintf(stderr, "'%s'\n", tok.name);
+ break;
+ case T_LITERAL:
+ fprintf(stderr, "(%s)\n", tok.literal);
+ break;
+ case T_RUNE:
+ putc('\'', stderr);
+ utf8_fputch(stderr, tok.rune);
+ putc('\'', stderr);
+ putc('\n', stderr);
+ break;
+ case T_STRING:
+ fprintf(stderr, "\"%*s\"\n", (int)tok.string.len,
+ tok.string.value);
+ break;
+ case T_ERROR:
+ fprintf(stderr, "ERROR\n");
+ break;
+ case T_EOF:
+ fprintf(stderr, "EOF\n");
+ break;
+ default:
+ fprintf(stderr, "%s\n", token_str(&tok));
+ break;
+ }
+ };
+
+ token_finish(&tok);
+}