G

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

AuthorJakob Wakeling <[email protected]>
Date2022-03-22 09:55:02
Commit2232f077c81d49826f6e297514b634c261cc11ed
Parent7d78e11e3b891e2e490936e53484ffc884b2c089

ebnf: Improve statement and expression consistency

Diffstat

M README.md | 4 ++--
M doc/g.ebnf | 162 ++++++++++++++++++++++++++++++++++++++++---------------------------------------
M src/lex.c | 2 +-
M src/lex.h | 2 +-

4 files changed, 87 insertions, 83 deletions

diff --git a/README.md b/README.md
index 422ddef..b2d1210 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # The G Programming Language
 
 A modern alternative to **C** intended to be fast, simple, and pleasant.
-Influenced by **C**, **C++**, **Odin**, and **Rust**.
+Influenced by **C**, **C++**, **Odin**, **Rust**, and **Zig**.
 
 Note that at present, **G** is highly unstable and will certainly change.
 
@@ -67,9 +67,9 @@ command. The second command will output an executable file, *a.out* by default.
 - [ ] Implement the *type* type
 - [ ] Implement multiple return values
 - [ ] Implement *defer*
+- [ ] Implement *errdefer*
 - [ ] Implement *if* and *else*
 - [ ] Implement *for*
-- [ ] Implement *while*
 - [ ] Implement generics of some kind
 - [ ] Implement module definition
 - [ ] Implement module use
diff --git a/doc/g.ebnf b/doc/g.ebnf
index ed4d8a9..70a90d5 100644
--- a/doc/g.ebnf
+++ b/doc/g.ebnf
@@ -6,105 +6,103 @@
 *)
 
 (* Program *)
-prog            = { decl } ;
-
-(* Declarations *)
-decl            = iden, ":", decl_constant | decl_variable ;
-decl_constant   = [ type ], ":", expr, ";" ;
-decl_variable   = [ type ], "=", expr, ";" | type, ";" ;
+prog = { stmt_decl } ;
 
 (* Statements *)
-stmt            = stmt_compound
-                | "return", [ expr ], ";"
-                | [ expr ], ";"
-                ;
+stmt = stmt_compound
+     | stmt_decl, ";"
+     | [ expr ], ";"
+     | "return", [ expr ], ";"
+     | "if", "(", expr, ")", stmt, [ "else", stmt ]
+     | "for", "(" expr, ";", [ expr, ";" ], [ expr, ";" ], ")", stmt
+     ;
+
+stmt_compound = "{", { stmt }, "}" ;
 
-stmt_compound   = "{", { stmt }, "}" ;
+stmt_decl = iden, ":", ( decl_constant | decl_variable ) ;
+stmt_decl_constant = [ type ], ":", expr ;
+stmt_decl_variable = [ type ], "=", expr | type ;
 
 (* Expressions *)
-expr            = "(", expr, ")" | iden | literal
-                | "+", expr | "-", expr (* Unary POS and NEG *)
-                | "!", expr | "~", expr (* Logical and bitwise NOT *)
-                
-                | expr, "*", expr | expr, "/",  expr | expr, "%",  expr
-                | expr, "&", expr | expr, "<<", expr | expr, ">>", expr
-                
-                | expr, "+", expr | expr, "-", expr (* Binary ADD and SUB *)
-                | expr, "|", expr | expr, "^", expr (* Bitwise OR and XOR *)
-                
-                | expr, "==", expr | expr, "!=", expr (* EQ and NEQ *)
-                | expr, "<",  expr | expr, "<=", expr (* LT and LTE *)
-                | expr, ">",  expr | expr, ">=", expr (* GT and GTE *)
-                
-                | expr, "&&", expr | expr, "||", expr (* Logical AND and OR *)
-                
-                | expr, "?", expr, ":", expr (* Ternary operator *)
-                
-                | iden, "=",   expr | iden, "+="  expr | iden, "-=" expr
-                | iden, "*=",  expr | iden, "/="  expr | iden, "%=" expr
-                | iden, "&=",  expr | iden, "|="  expr | iden, "^=" expr
-                | iden, "<<=", expr | iden, ">>=" expr
-                ;
-
-proc            = "proc", "(", [ parm_list ], ")", [ "->", type ]
-                , stmt_compound ;
+expr = iden | literal
+     | expr_proc
+     
+     | "(", expr, ")"
+     | "+", expr | "-", expr (* Unary POS and NEG *)
+     | "!", expr | "~", expr (* Logical and bitwise NOT *)
+     
+     | expr, "*", expr | expr, "/",  expr | expr, "%",  expr
+     | expr, "&", expr | expr, "<<", expr | expr, ">>", expr
+     
+     | expr, "+", expr | expr, "-", expr (* Binary ADD and SUB *)
+     | expr, "|", expr | expr, "^", expr (* Bitwise OR and XOR *)
+     
+     | expr, "==", expr | expr, "!=", expr (* EQ and NEQ *)
+     | expr, "<",  expr | expr, "<=", expr (* LT and LTE *)
+     | expr, ">",  expr | expr, ">=", expr (* GT and GTE *)
+     
+     | expr, "&&", expr | expr, "||", expr (* Logical AND and OR *)
+     
+     | expr, "?", expr, ":", expr (* Ternary operator *)
+     
+     | iden, "=",   expr | iden, "+="  expr | iden, "-=" expr
+     | iden, "*=",  expr | iden, "/="  expr | iden, "%=" expr
+     | iden, "&=",  expr | iden, "|="  expr | iden, "^=" expr
+     | iden, "<<=", expr | iden, ">>=" expr
+     ;
+
+expr_proc = "proc", "(", [ parm_list ], ")", [ "->", type ], stmt_compound ;
 
 (* Identifiers and Parameters *)
-iden            = alpha_, { alpha_ | digit } ;
-type            = iden ;
+parm = iden, ":", type ;
+parm_list = parm, { ",", parm } ;
 
-parm            = iden, ":", type ;
-parm_list       = parm, { ",", parm } ;
+iden = alphu, { alphu | digit } ;
+type = iden ;
 
 (* Literals *)
-literal_null    = "null" ; (* null or nil or nul? *)
-literal_bool    = "true" | "false" ; (* true/false or T/F? *)
+literal_null = "null" ;
+literal_bool = "true" | "false" ;
 
-literal_bin     = "0b", digit_bin, { char_bin } ;
-literal_oct     = "0o", digit_oct, { char_oct } ;
-literal_dec     = [ "0d" ], digit_dec, { char_dec } ;
-literal_doz     = "0z", digit_doz, { char_doz } ;
-literal_hex     = "0x", digit_hex, { char_hex } ;
-literal_int     = literal_bin | literal_oct | literal_dec | literal_hex ;
+literal_bin = "0b", digit_bin, { char_bin } ;
+literal_oct = "0o", digit_oct, { char_oct } ;
+literal_dec = [ "0d" ], digit_dec, { char_dec } ;
+literal_doz = "0z", digit_doz, { char_doz } ;
+literal_hex = "0x", digit_hex, { char_hex } ;
+literal_int = literal_bin | literal_oct | literal_dec | literal_hex ;
 
-literal_flt     = digit_dec, { char_dec }, ".", digit_dec, { char_dec } ;
+literal_flt = digit_dec, { char_dec }, ".", digit_dec, { char_dec } ;
 
-literal_chr     = "'", char_chr, "'" ;
-literal_str     = '"', { char_str }, '"' ;
+literal_chr = "'", char_chr, "'" ;
+literal_str = '"', { char_str }, '"' ;
 
-literal         = literal_null | literal_bool | literal_int | literal_flt
-                | literal_chr | literal_str ;
+literal = literal_null | literal_bool | literal_int | literal_flt | literal_chr | literal_str ;
 
 (* General *)
-digit_bin       = "0" | "1" ;
-digit_oct       = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" ;
-digit_dec       = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
-digit_doz       = digit_dec | "A" | "B" ;
-digit_hex       = digit_dec | "A" | "B" | "C" | "D" | "E" | "F" ;
-digit           = digit_dec ;
-
-alpha_upper     = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J"
-                | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T"
-                | "U" | "V" | "W" | "X" | "Y" | "Z" ;
-alpha_lower     = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j"
-                | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t"
-                | "u" | "v" | "w" | "x" | "y" | "z" ;
-alpha           = alpha_upper | alpha_lower ;
-alpha_          = alpha | "_" ;
-
-char_bin        = digit_bin | "_" ;
-char_oct        = digit_oct | "_" ;
-char_dec        = digit_dec | "_" ;
-char_doz        = digit_doz | "_" ;
-char_hex        = digit_hex | "_" ;
-
-escape_std      = "\0" | "\a" | "\b" | "\t" | "\n" | "\v" | "\f" | "\r" | '\"'
-                | "\'" | "\\" ;
-escape_oct      = "\o", digit_oct, [ digit_oct, [ digit_oct ] ] ;
-escape_hex      = "\x", digit_hex, [ digit_hex ] ;
-escape_utf      = "\u", digit_hex, digit_hex, digit_hex, digit_hex
-                , [ digit_hex, digit_hex, digit_hex, digit_hex ] ;
-escape          = escape_std | escape_oct | escape_hex | escape_utf ;
-
-char_chr        = ANY_CHARACTER_EXCEPT_NEWLINE_SQUOTE_BACKSLASH | escape ;
-char_str        = ANY_CHARACTER_EXCEPT_NEWLINE_DQUOTE_BACKSLASH | escape ;
+escape = escape_std | escape_oct | escape_hex | escape_utf ;
+escape_std = "\0" | "\a" | "\b" | "\t" | "\n" | "\v" | "\f" | "\r" | '\"' | "\'" | "\\" ;
+escape_oct = "\o", digit_oct, [ digit_oct, [ digit_oct ] ] ;
+escape_hex = "\x", digit_hex, [ digit_hex ] ;
+escape_utf = "\u", quadd_hex, [ quadd_hex ] ;
+
+digit = digit_dec ;
+digit_bin = "0" | "1" ;
+digit_oct = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" ;
+digit_dec = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
+digit_doz = digit_dec | "A" | "B" ;
+digit_hex = digit_dec | "A" | "B" | "C" | "D" | "E" | "F" ;
+quadd_hex = digit_hex, digit_hex, digit_hex, digit_hex ;
+
+alphu = alpha | "_" ;
+alpha = alpha_upper | alpha_lower ;
+alpha_upper = ANY_UPPERCASE_ENGLISH_LETTER ;
+alpha_lower = ANY_LOWERCASE_ENGLISH_LETTER ;
+
+char_bin = digit_bin | "_" ;
+char_oct = digit_oct | "_" ;
+char_dec = digit_dec | "_" ;
+char_doz = digit_doz | "_" ;
+char_hex = digit_hex | "_" ;
+
+char_chr = ANY_CHARACTER_EXCEPT_NEWLINE_SQUOTE_BACKSLASH | escape ;
+char_str = ANY_CHARACTER_EXCEPT_NEWLINE_DQUOTE_BACKSLASH | escape ;
diff --git a/src/lex.c b/src/lex.c
index 93e2151..c837c1c 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -20,7 +20,7 @@
 char *tok_ks[] = {
 	"LK_NULL", "LK_EOF", "LK_ID", "LK_INT", "LK_FLT", "LK_STR",
 
-	"LK_RETURN", "LK_FOR", "LK_IF", "LK_ELSE", "LK_PROC",
+	"LK_RETURN", "LK_IF", "LK_ELSE", "LK_FOR", "LK_PROC",
 
 	"LK_LPAREN", "LK_RPAREN", "LK_LBRACK", "LK_RBRACK", "LK_LBRACE", "LK_RBRACE",
 	"LK_COLON",  "LK_SCOLON", "LK_COMMA",  "LK_PERIOD", "LK_RARROW", "LK_QMARK",
diff --git a/src/lex.h b/src/lex.h
index 8fe312e..71d6f67 100644
--- a/src/lex.h
+++ b/src/lex.h
@@ -11,7 +11,7 @@
 typedef enum {
 	LK_NULL, LK_EOF, LK_ID, LK_INT, LK_FLT, LK_STR,
 
-	LK_RETURN, LK_FOR, LK_IF, LK_ELSE, LK_PROC,
+	LK_RETURN, LK_IF, LK_ELSE, LK_FOR, LK_PROC,
 
 	LK_LPAREN, LK_RPAREN, LK_LBRACK, LK_RBRACK, LK_LBRACE, LK_RBRACE,
 	LK_COLON,  LK_SCOLON, LK_COMMA,  LK_PERIOD, LK_RARROW, LK_QMARK,