Skip to content

Commit

Permalink
[BUG] Update grammar.ebnf amber-lang#608 (amber-lang#609)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ph0enixKM authored and lens0021 committed Dec 12, 2024
1 parent e69eebb commit ea94342
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 36 deletions.
154 changes: 118 additions & 36 deletions grammar.ebnf
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,107 @@
root = { statement_global } ;
(* Statement *)
statement_local = expression | variable_init | variable_set
| loop | loop_array | if_statement | if_chain ;
statement_global = statement_local | function_def | main
| import_all | import_ids;
statement_local =
builtins_statement |
expression |
if_chain |
if_statement |
loop |
loop_array |
variable_init_const |
variable_init_mut |
variable_set ;
statement_global =
function_def |
import_all |
import_ids |
main |
statement_local ;
(* Block *)
singleline_block = ':', statement_local ;
multiline_block = '{', { statement_local }, '}' ;
block = singleline_block | multiline_block ;
(* Expression *)
expression = number | text | boolean | null | list | command
| binary_operation | unary_operation | parentheses | ternary
| range | range_inclusive | identifier | function_call ;
expression =
binary_operation |
boolean |
builtins_expression |
command |
function_call |
identifier |
list |
null |
number |
parentheses |
range |
range_inclusive |
ternary |
text |
unary_operation ;
(* Keywords *)
KEYWORD_AND = 'and' ;
KEYWORD_AS = 'as' ;
KEYWORD_BREAK = 'break' ;
KEYWORD_CD = 'cd' ;
KEYWORD_CONST = 'const' ;
KEYWORD_CONTINUE = 'continue' ;
KEYWORD_ECHO = 'echo' ;
KEYWORD_ELSE = 'else' ;
KEYWORD_EXIT = 'exit' ;
KEYWORD_FAIL = 'fail' ;
KEYWORD_FAILED = 'failed' ;
KEYWORD_FOR = 'for' ;
KEYWORD_FROM = 'from' ;
KEYWORD_FUN = 'fun' ;
KEYWORD_IF = 'if' ;
KEYWORD_IMPORT = 'import' ;
KEYWORD_IN = 'in' ;
KEYWORD_IS = 'is' ;
KEYWORD_LEN = 'len' ;
KEYWORD_LET = 'let' ;
KEYWORD_LINES = 'lines' ;
KEYWORD_LOOP = 'loop' ;
KEYWORD_MAIN = 'main' ;
KEYWORD_MV = 'mv' ;
KEYWORD_NAMEOF = 'nameof' ;
KEYWORD_NOT = 'not' ;
KEYWORD_OR = 'or' ;
KEYWORD_PUB = 'pub' ;
KEYWORD_REF = 'ref' ;
KEYWORD_RETURN = 'return' ;
KEYWORD_SILENT = 'silent' ;
KEYWORD_STATUS = 'status' ;
KEYWORD_THEN = 'then' ;
KEYWORD_TRUST = 'trust' ;
KEYWORD_UNSAFE = 'unsafe' ;
(* Terminals *)
ANY_CHAR = ? any character ? ;
LETTER = 'A'..'Z' | 'a'..'z' ;
DIGIT = '0'..'9' ;
TYPE = 'Text' | 'Num' | 'Bool' | 'Null';
UNARY_OP = '-' | 'not' ;
BINARY_OP = '+' | '-' | '*' | '/' | '%' | 'and' | 'or' | '==' | '!=' | '<' | '<=' | '>' | '>=' ;
SILENT_MOD = 'silent' ;
TRUST_MOD = 'trust' ;
VISIBILITY = 'pub' ;
UNARY_OP = '-' | KEYWORD_NOT ;
BINARY_OP = '+' | '-' | '*' | '/' | '%' | KEYWORD_AND | KEYWORD_OR | '==' | '!=' | '<' | '<=' | '>' | '>=' ;
SILENT_MOD = KEYWORD_SILENT ;
TRUST_MOD = KEYWORD_TRUST ;
VISIBILITY = KEYWORD_PUB ;
(* Identifier *)
any_identifier = (LETTER | '_') , { LETTER | '_' | DIGIT } ;
internal_identifier = '__' , { LETTER | '_' | DIGIT } ;
any_identifier = (LETTER | '_'), { LETTER | '_' | DIGIT } ;
internal_identifier = '__', { LETTER | '_' | DIGIT } ;
identifier = any_identifier - internal_identifier ;
(* `Num` literal *)
integer = DIGIT , { DIGIT } ;
real = integer , '.' , integer ;
integer = DIGIT, { DIGIT } ;
real = integer, '.', integer ;
number = integer | real ;
(* `Text` literal *)
interpolation = '{' , expression , '}' ;
text = '"' , { ANY_CHAR | interpolation } , '"' ;
interpolation = '{', expression, '}' ;
text = '"', { ANY_CHAR | interpolation }, '"' ;
(* `Bool` literal *)
boolean = 'true' | 'false' ;
Expand All @@ -53,8 +115,8 @@ boolean = 'true' | 'false' ;
null = 'null' ;
(* `List` literal *)
empty_list = '[' , TYPE , ']' ;
full_list = '[' , [ expression , { ',' , expression } ] , ']' ;
empty_list = '[', TYPE, ']' ;
full_list = '[', [ expression, { ',', expression } ], ']' ;
list = empty_list | full_list ;
(* Command expression *)
Expand All @@ -66,52 +128,72 @@ command = [ SILENT_MOD ], command_base, [ failure_handler ] ;
command_trust = [ SILENT_MOD ], TRUST_MOD, command_base ;
(* Operations *)
binary_operation = expression , BINARY_OP , expression ;
unary_operation = UNARY_OP , expression ;
binary_operation = expression, BINARY_OP, expression ;
unary_operation = UNARY_OP, expression ;
(* Parentheses *)
parentheses = '(', expression, ')' ;
(* Failure handler *)
failure_propagation = '?';
failure_block = 'failed', block ;
failure_block = KEYWORD_FAILED, block ;
failure_handler = failure_propagation | failure_block ;
(* Variable *)
variable_index = '[', expression, ']' ;
variable_init = 'let', identifier, '=', expression ;
variable_init_mut = KEYWORD_LET, identifier, '=', expression ;
variable_init_const = KEYWORD_CONST, identifier, '=', expression ;
variable_get = identifier, variable_index? ;
variable_set = identifier, variable_index?, '=', expression ;
(* Function *)
function_call = identifier, '(', [ expression, { ',', expression } ], ')' ;
function_call_failed = [ SILENT_MOD ], function_call, failure_handler ;
function_call_trust = [ SILENT_MOD ], TRUST_MOD, function_call ;
function_def = [ VISIBILITY ], 'fun', identifier, '(', [ identifier, { ',', identifier } ], ')', block ;
function_def_typed = [ VISIBILITY ], 'fun', identifier, '(',
function_def = [ VISIBILITY ], KEYWORD_FUN, identifier, '(', [ identifier, { ',', identifier } ], ')', block ;
function_def_typed = [ VISIBILITY ], KEYWORD_FUN, identifier, '(',
[ identifier, ':', TYPE, { ',', identifier, ':', TYPE } ], ')', ':', TYPE, block ;
(* Loop *)
loop = 'loop', block ;
loop_array = 'loop', identifier, 'in', expression, block ;
loop_array_iterator = 'loop', identifier, ',', identifier, 'in', expression, block ;
loop = KEYWORD_LOOP, block ;
loop_array = KEYWORD_FOR | KEYWORD_LOOP, identifier, KEYWORD_IN, expression, block ;
loop_array_iterator = KEYWORD_FOR | KEYWORD_LOOP, identifier, ',', identifier, KEYWORD_IN, expression, block ;
(* Ranges *)
range = expression, '..', expression ;
range_inclusive = expression, '..=', expression ;
(* Conditional *)
if_statement = 'if', expression, block, [ 'else', block ] ;
if_chain = 'if', '{', { expression, block }, [ 'else', block ], '}' ;
ternary = expression, 'then', expression, 'else', expression ;
if_statement = KEYWORD_IF, expression, block, [ KEYWORD_ELSE, block ] ;
if_chain = KEYWORD_IF, '{', { expression, block }, [ KEYWORD_ELSE, block ], '}' ;
ternary = expression, KEYWORD_THEN, expression, KEYWORD_ELSE, expression ;
(* Main *)
main = 'main', [ '(', identifier, ')' ], block ;
main = KEYWORD_MAIN, [ '(', identifier, ')' ], block ;
(* Imports *)
import_path = '"', { ANY_CHAR }, '"' ;
import_all = [ VISIBILITY ], 'import', '*', 'from', import_path ;
import_ids = [ VISIBILITY ], 'import', '{', { identifier, [ 'as', identifier ] }, '}', 'from', import_path ;
import_all = [ VISIBILITY ], KEYWORD_IMPORT, '*', KEYWORD_FROM, import_path ;
import_ids = [ VISIBILITY ], KEYWORD_IMPORT, '{', { identifier, [ KEYWORD_AS, identifier ], [ ',' ] }, '}', KEYWORD_FROM, import_path ;
(* Comment *)
comment = '//', { ANY_CHAR }, '\n'
comment = '//', { ANY_CHAR }, '\n' ;
(* Built-ins *)
builtins_statement =
builtin_cd |
builtin_echo |
builtin_exit |
builtin_mv ;
builtin_cd = KEYWORD_CD, expression ;
builtin_echo = KEYWORD_ECHO, expression ;
builtin_exit = KEYWORD_EXIT, expression ;
builtin_mv = KEYWORD_MV, expression ;
builtins_expression =
builtin_len |
builtin_lines |
builtin_nameof ;
builtin_len = KEYWORD_LEN, expression ;
builtin_lines = KEYWORD_LINES, expression ;
builtin_nameof = KEYWORD_NAMEOF, expression ;
28 changes: 28 additions & 0 deletions keywords.ab
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#! /usr/bin/env amber

import {
replace,
starts_with,
words,
} from "std/text"

main (args) {
let keywords = [Text]
let should_append = false
for line in lines("grammar.ebnf") {
if not should_append and not starts_with(line, "KEYWORD"): continue
should_append = true
for token in words(line) {
if {
starts_with(token, "'"): keywords += [replace(token, "'", "")]
token == ";": should_append = false
}
}
}
let result = $ echo "\$\{{nameof keywords}[@]}" | sort $ failed {
echo "Something went wrong while sorting the keywords"
}
for item in words(result) {
echo item
}
}

0 comments on commit ea94342

Please sign in to comment.