Author | Jakob Wakeling <[email protected]> |
Date | 2022-03-22 09:55:02 |
Commit | 2232f077c81d49826f6e297514b634c261cc11ed |
Parent | 7d78e11e3b891e2e490936e53484ffc884b2c089 |
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,