G

G Programming Language
git clone http://git.omkov.net/G
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2021-09-06 15:42:35
Commit272888243bd3c867399ae0423c0b33a9f8fc0008
Parent431f98e2da1b4d79b70c00c85c1e840f49140215

parse: Streamline declaration parsing

Diffstat

M doc/g.ebnf | 11 ++++++-----
M src/g.h | 2 +-
M src/lex.c | 5 +++--
M src/parse.c | 95 +++++++++++++++++++++++++++++++++----------------------------------------------

4 files changed, 50 insertions, 63 deletions

diff --git a/doc/g.ebnf b/doc/g.ebnf
index 299abaf..259076d 100644
--- a/doc/g.ebnf
+++ b/doc/g.ebnf
@@ -9,11 +9,12 @@
 prog            = { decl } ;
 
 (* Declarations *)
-decl            = decl_variable | decl_constant | decl_procedure ;
-decl_variable   = iden, ":", ( type, [ "=", expr ] ) | ( "=", expr ), ";" ;
-decl_constant   = iden, ":", [ type ], ":", expr, ";" ;
-decl_procedure  = iden, ":", [ type ], ":", "proc", "(", [ parm_list ], ")"
-                , "->", type, "{", { decl | stmt | expr }, "}" ;
+decl            = iden, ":", decl_constant | decl_variable ;
+decl_constant   = [ type ], ":", expr, ";" ;
+decl_variable   = ( type, [ "=", expr ] ) | ( "=", expr ), ";" ;
+
+decl_procedure  = [ type ], ":", "proc", "(", [ parm_list ], ")" , "->", type
+                , "{", { decl | stmt | expr }, "}" ;
 
 (* Statements *)
 stmt            = "{", stmt, "}"
diff --git a/src/g.h b/src/g.h
index 5f39dde..d79947b 100644
--- a/src/g.h
+++ b/src/g.h
@@ -22,7 +22,7 @@ typedef enum {
 	LK_LBRACE, LK_RBRACE, LK_COLON,  LK_SCOLON,
 	LK_PERIOD, LK_COMMA,
 
-	LK_RARROW,
+	LK_EQUALS, LK_RARROW,
 
 	LK_PROC, LK_RETURN,
 } tok_k;
diff --git a/src/lex.c b/src/lex.c
index b7ad3b4..e325515 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -33,8 +33,8 @@ char *tok_ks[] = {
 	"LK_LBRACE", "LK_RBRACE", "LK_COLON",  "LK_SCOLON",
 	"LK_PERIOD", "LK_COMMA",
 
+	"LK_EQUALS", "LK_RARROW",
 
-	"LK_RARROW",
 	"LK_PROC", "LK_RETURN",
 };
 
@@ -91,6 +91,7 @@ skip:;
 		case ';': { n.k = LK_SCOLON; } goto esc_1;
 		case '.': { n.k = LK_PERIOD; } goto esc_1;
 		case ',': { n.k = LK_COMMA;  } goto esc_1;
+		case '=': { n.k = LK_EQUALS; } goto esc_1;
 		case '-': switch (D) {
 			case '>': { n.k = LK_RARROW; } goto esc_2;
 		}
diff --git a/src/parse.c b/src/parse.c
index ca9bc96..f394045 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -31,44 +31,41 @@ char *ast_ks[] = {
 	"AK_RETURN",
 };
 
-static ast *parser_parse_root(lex *l);
-static ast *parser_parse_decl(lex *l);
+static ast *parse_decl(lex *l);
 
-static ast *parser_parse_stmt(lex *l);
-static ast *parser_parse_stmt_comp(lex *l);
+static ast *parse_stmt(lex *l);
+static ast *parse_stmt_comp(lex *l);
 
-static ast *parser_parse_expr(lex *l);
-static ast *parser_parse_expr_term(lex *l);
-static ast *parser_parse_expr_fact(lex *l);
+static ast *parse_expr(lex *l);
 
-static ast *parser_parse_proc(lex *l);
-static ast *parser_parse_proc_parm(lex *l);
-static ast *parser_parse_proc_rett(lex *l);
+static ast *parse_proc(lex *l);
+static ast *parse_proc_parm(lex *l);
+static ast *parse_proc_rett(lex *l);
 
-static ast *parser_parse_int(lex *l);
+static ast *parse_int(lex *l);
 
 ast *ast_init() { return calloc(1, sizeof (ast)); }
 void ast_free(ast *a) { stack_free(a->cs); free(a); return; }
 
-ast *parse(lex *l) { return parser_parse_root(l); }
-
-static ast *parser_parse_root(lex *l) {
-	return parser_parse_decl(l);
+/* prog            = { decl } ; */
+ast *parse(lex *l) {
+	return parse_decl(l);
 }
 
-/* Parse a declaration. */
-static ast *parser_parse_decl(lex *l) {
+/* decl            = iden, ":", decl_variable | decl_constant ; */
+/* decl_constant   = [ type ], ":", expr, ";" ; */
+/* decl_variable   = ( type, [ "=", expr ] ) | ( "=", expr ), ";" ; */
+static ast *parse_decl(lex *l) {
 	ast *a = ast_init();
 
-	a->s = lex_kind(l, LK_IDN).s;
-	lex_kind(l, LK_COLON);
+	a->s = lex_kind(l, LK_IDN).s; lex_kind(l, LK_COLON);
 
-	if (lex_peek(l).k == LK_IDN) { /* lookup and store type */ }
+	if (lex_peek(l).k == LK_IDN) { /* TODO lookup and store type */ }
 
 	switch (lex_peek(l).k) {
 	case LK_COLON:  { lex_kind(l, LK_COLON);  a->k = AK_DECL; } goto decl_expr;
-	// case LK_ASSN: { lex_kind(l, LK_ASSN); a->k = AK_ASSN; } goto decl_expr;
-	decl_expr: { a->cl = parser_parse_expr(l); } break;
+	case LK_EQUALS: { lex_kind(l, LK_EQUALS); a->k = AK_DECL; } goto decl_expr;
+	decl_expr: { a->cl = parse_expr(l); } break;
 	default: { error(
 		1, "%zu:%zu: Unexpected: \"%s\" (parser_parse_decl)",
 		lex_peek(l).p.ln, lex_peek(l).p.cl, tok_ks[lex_peek(l).k]
@@ -79,11 +76,11 @@ static ast *parser_parse_decl(lex *l) {
 }
 
 /* Parse a statement. */
-static ast *parser_parse_stmt(lex *l) {
+static ast *parse_stmt(lex *l) {
 	ast *a = ast_init();
 
 	switch (lex_peek(l).k) {
-	case LK_RETURN: { a->k = AK_RETURN; lex_kind(l, LK_RETURN); a->c = parser_parse_expr(l); } break;
+	case LK_RETURN: { a->k = AK_RETURN; lex_kind(l, LK_RETURN); a->c = parse_expr(l); } break;
 	default: { error(
 		1, "%zu:%zu: Unexpected: \"%s\" (parser_parse_stmt)",
 		lex_peek(l).p.ln, lex_peek(l).p.cl, tok_ks[lex_peek(l).k]
@@ -94,7 +91,7 @@ static ast *parser_parse_stmt(lex *l) {
 }
 
 /* Parse a compound statement. */
-static ast *parser_parse_stmt_comp(lex *l) {
+static ast *parse_stmt_comp(lex *l) {
 	lex_kind(l, LK_LBRACE);
 	ast *a = ast_init(); a->k = AK_COMP;
 	a->cs = stack_init();
@@ -102,8 +99,8 @@ static ast *parser_parse_stmt_comp(lex *l) {
 	/* Parse statements and expressions until EOF or closing brace */
 	for (; lex_peek(l).k != LK_EOF && lex_peek(l).k != LK_RBRACE;) {
 		switch (lex_peek(l).k) {
-		case LK_RETURN: { stack_push(a->cs, parser_parse_stmt(l)); } break;
-		default: { stack_push(a->cs, parser_parse_expr(l)); } break;
+		case LK_RETURN: { stack_push(a->cs, parse_stmt(l)); } break;
+		default: { stack_push(a->cs, parse_expr(l)); } break;
 		}
 
 		if (lex_peek(l).k == LK_SCOLON) { lex_kind(l, LK_SCOLON); }
@@ -113,37 +110,23 @@ static ast *parser_parse_stmt_comp(lex *l) {
 }
 
 /* Parse an expression. */
-static ast *parser_parse_expr(lex *l) {
-	ast *al = parser_parse_expr_term(l);
-	
-	
-	
-	return al;
-}
-
-/* Parse an expression term. */
-static ast *parser_parse_expr_term(lex *l) {
-	ast *al = parser_parse_expr_fact(l);
-	
-	
+static ast *parse_expr(lex *l) {
+	ast *a = ast_init();
 
-	return al;
-}
-
-/* Parse an expression factor. */
-static ast *parser_parse_expr_fact(lex *l) {
 	switch (lex_peek(l).k) {
-	case LK_PROC: { return parser_parse_proc(l); } break;
-	case LK_INT: { return parser_parse_int(l); } break;
+	case LK_PROC: { return parse_proc(l); } break;
+	case LK_INT: { return parse_int(l); } break;
 	default: { error(
 		1, "%zu:%zu: Unexpected: \"%s\" (parser_parse_expr_fact)",
 		lex_peek(l).p.ln, lex_peek(l).p.cl, tok_ks[lex_peek(l).k]
 	); } break;
 	}
+	
+	return a;
 }
 
 /* Parse a procedure. */
-static ast *parser_parse_proc(lex *l) {
+static ast *parse_proc(lex *l) {
 	lex_kind(l, LK_PROC);
 	ast *a = ast_init(); a->k = AK_PROCEDURE;
 
@@ -152,11 +135,11 @@ static ast *parser_parse_proc(lex *l) {
 
 	/* Parse optional procedure parameter(s) */
 	if (lex_peek(l).k != LK_RPAREN) {
-		stack_push(a->cs, parser_parse_proc_parm(l));
+		stack_push(a->cs, parse_proc_parm(l));
 
 		while (lex_peek(l).k == LK_COMMA) {
 			lex_kind(l, LK_COMMA);
-			stack_push(a->cs, parser_parse_proc_parm(l));
+			stack_push(a->cs, parse_proc_parm(l));
 		}
 	}
 
@@ -171,22 +154,22 @@ static ast *parser_parse_proc(lex *l) {
 		lex_kind(l, LK_IDN); a->t = t_s64;
 	}
 
-	a->c = parser_parse_stmt_comp(l);
+	a->c = parse_stmt_comp(l);
 
 	return a;
 }
 
 /* Parse a procedure parameter. */
-static ast *parser_parse_proc_parm(lex *l) {
+static ast *parse_proc_parm(lex *l) {
 	return NULL; /* TODO */
 }
 
 /* Parse a procedure return type. */
-static ast *parser_parse_proc_rett(lex *l) {
+static ast *parse_proc_rett(lex *l) {
 	return NULL; /* TODO */
 }
 
-static ast *parser_parse_int(lex *l) {
+static ast *parse_int(lex *l) {
 	val v = val_strint(lex_kind(l, LK_INT).s);
 	ast *a = ast_init(); a->k = AK_INT; a->v = v;
 	return a;