Starting to overhaul functions again. Expanding EBNF.
This commit is contained in:
parent
592ddb7baa
commit
2ad400167a
4 changed files with 167 additions and 20 deletions
127
ava.ebnf
127
ava.ebnf
|
@ -1,9 +1,17 @@
|
||||||
|
(* ======================== *)
|
||||||
(* Core Character Sequences *)
|
(* Core Character Sequences *)
|
||||||
|
(* ======================== *)
|
||||||
|
|
||||||
white_space ::= '\u0020' | '\u0009' | '\u000D' | '\u000A'
|
white_space ::= '\u0020' | '\u0009' | '\u000D' | '\u000A'
|
||||||
paren ::= '(' | ')';
|
lparen ::= '(';
|
||||||
bracket ::= '[' | ']';
|
rparen ::= ')';
|
||||||
brace ::= '{' | '}';
|
paren ::= lparen | rparen;
|
||||||
|
lbracket ::= '[';
|
||||||
|
rbracket ::= ']';
|
||||||
|
bracket ::= lbracket | rbracket;
|
||||||
|
lbrace ::= '{';
|
||||||
|
rbrace ::= '}';
|
||||||
|
brace ::= lbrace | rbrace;
|
||||||
digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
||||||
hex ::= '0' | ... | '9' | 'A' | ... | 'F' | 'a' | ... | 'f' ;
|
hex ::= '0' | ... | '9' | 'A' | ... | 'F' | 'a' | ... | 'f' ;
|
||||||
upper ::= 'A' | ... | 'Z' | Lu | Lt | Nl
|
upper ::= 'A' | ... | 'Z' | Lu | Lt | Nl
|
||||||
|
@ -30,22 +38,9 @@ string_char ::= printable_char without newline or double quote
|
||||||
comment ::= '-', '-', {utf8};
|
comment ::= '-', '-', {utf8};
|
||||||
docstring ::= '-', '-', '-', {utf8};
|
docstring ::= '-', '-', '-', {utf8};
|
||||||
|
|
||||||
(* Literal Values *)
|
(* ======== *)
|
||||||
|
|
||||||
literal_bool ::= 'true' | 'false';
|
|
||||||
literal_integer ::= ['-'], number_integer;
|
|
||||||
literal_float ::= ['-'], number_float;
|
|
||||||
literal_char ::= "'", char_char, "'";
|
|
||||||
literal_string ::= '"', {string_char}, "'";
|
|
||||||
empty_tuple ::= '(', ')';
|
|
||||||
literal ::= literal_bool
|
|
||||||
| literal_integer
|
|
||||||
| literal_float
|
|
||||||
| literal_char
|
|
||||||
| literal_string
|
|
||||||
| empty_tuple;
|
|
||||||
|
|
||||||
(* Keywords *)
|
(* Keywords *)
|
||||||
|
(* ======== *)
|
||||||
|
|
||||||
k_type ::= 't', 'y', 'p', 'e';
|
k_type ::= 't', 'y', 'p', 'e';
|
||||||
k_class ::= 'c', 'l', 'a', 's', 's';
|
k_class ::= 'c', 'l', 'a', 's', 's';
|
||||||
|
@ -62,18 +57,112 @@ k_namespace ::= 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e';
|
||||||
k_infix ::= 'i', 'n', 'f', 'i', 'x';
|
k_infix ::= 'i', 'n', 'f', 'i', 'x';
|
||||||
k_fn ::= 'f', 'n';
|
k_fn ::= 'f', 'n';
|
||||||
k_end ::= 'e', 'n', 'd';
|
k_end ::= 'e', 'n', 'd';
|
||||||
|
|
||||||
|
(* Initiates a pattern match against some value. *)
|
||||||
k_match ::= 'm', 'a', 't', 'c', 'h';
|
k_match ::= 'm', 'a', 't', 'c', 'h';
|
||||||
|
|
||||||
|
(* Initiates a pattern matching case. Applicable to functions and matches. *)
|
||||||
k_case ::= 'c', 'a', 's', 'e';
|
k_case ::= 'c', 'a', 's', 'e';
|
||||||
|
|
||||||
|
(* Used in if/else syntax. Starts such a block and used in 'else if'. *)
|
||||||
k_if ::= 'i', 'f';
|
k_if ::= 'i', 'f';
|
||||||
|
|
||||||
|
(* Used in if/else syntax. Must follow the condition of any 'if'. *)
|
||||||
k_then ::= 't', 'h', 'e', 'n';
|
k_then ::= 't', 'h', 'e', 'n';
|
||||||
|
|
||||||
|
(* Used in if/else syntax. Indicates an 'else if' or 'else'. *)
|
||||||
k_else ::= 'e', 'l', 's', 'e';
|
k_else ::= 'e', 'l', 's', 'e';
|
||||||
|
|
||||||
|
(* Used in do/return syntax. Indicates the start of such a structure. *)
|
||||||
k_do ::= 'd', 'o';
|
k_do ::= 'd', 'o';
|
||||||
|
|
||||||
|
(* Used in do/return syntax. Indicates the final output value. *)
|
||||||
k_return ::= 'r', 'e', 't', 'u', 'r', 'n';
|
k_return ::= 'r', 'e', 't', 'u', 'r', 'n';
|
||||||
|
|
||||||
|
(* Indicates a type constructor. *)
|
||||||
k_given ::= 'g', 'i', 'v', 'e', 'n';
|
k_given ::= 'g', 'i', 'v', 'e', 'n';
|
||||||
|
|
||||||
|
(* Function modifier which restricts use to the enclosing scope. *)
|
||||||
|
k_private ::= 'p', 'r', 'i', 'v', 'a', 't', 'e';
|
||||||
|
|
||||||
|
(* true is a Boolean literal *)
|
||||||
k_true ::= 't', 'r', 'u', 'e';
|
k_true ::= 't', 'r', 'u', 'e';
|
||||||
|
|
||||||
|
(* false is a Boolean literal *)
|
||||||
k_false ::= 'f', 'a', 'l', 's', 'e';
|
k_false ::= 'f', 'a', 'l', 's', 'e';
|
||||||
|
|
||||||
keyword ::= k_type | k_class | k_alias | k_const | k_enum | k_record
|
keyword ::= k_type | k_class | k_alias | k_const | k_enum | k_record
|
||||||
| k_object | k_let | k_mut | k_export | k_import
|
| k_object | k_let | k_mut | k_export | k_import
|
||||||
| k_namespace | k_infix | k_fn | k_end | k_match | k_case
|
| k_namespace | k_infix | k_fn | k_end | k_match | k_case
|
||||||
| k_if | k_then | k_else | k_do | k_return | k_given
|
| k_if | k_then | k_else | k_do | k_return | k_given
|
||||||
| k_true | k_false;
|
| k_private | k_true | k_false;
|
||||||
|
|
||||||
|
(* ============== *)
|
||||||
|
(* Literal Values *)
|
||||||
|
(* ============== *)
|
||||||
|
|
||||||
|
literal_bool ::= k_true | k_false;
|
||||||
|
literal_integer ::= ['-'], number_integer;
|
||||||
|
literal_float ::= ['-'], number_float;
|
||||||
|
literal_char ::= "'", char_char, "'";
|
||||||
|
literal_string ::= '"', {string_char}, "'";
|
||||||
|
empty_tuple ::= lparen, rparen;
|
||||||
|
empty_list ::= lbracket, rbracket;
|
||||||
|
literal ::= literal_bool
|
||||||
|
| literal_integer
|
||||||
|
| literal_float
|
||||||
|
| literal_char
|
||||||
|
| literal_string
|
||||||
|
| empty_tuple
|
||||||
|
| empty_list;
|
||||||
|
|
||||||
|
(* ========= *)
|
||||||
|
(* Operators *)
|
||||||
|
(* ========= *)
|
||||||
|
|
||||||
|
(* Type hole used for development -- will resolve/compile, but fail at
|
||||||
|
runtime. *)
|
||||||
|
hole ::= '?', '?', '?';
|
||||||
|
|
||||||
|
(* Used to access members. Relevant for namespaces, records, enums, classes. *)
|
||||||
|
op_member ::= '.';
|
||||||
|
|
||||||
|
(* Standard separator for type definitions, tuples and records. *)
|
||||||
|
op_comma ::= ',';
|
||||||
|
|
||||||
|
(* A | B is a type which can be either A or B. *)
|
||||||
|
op_type_union ::= '|';
|
||||||
|
|
||||||
|
(* List operator. Prepend LHS to RHS. Can be used in pattern matching. *)
|
||||||
|
op_list_prepend ::= ':';
|
||||||
|
|
||||||
|
(* Only valid adjacent to a name declaration. Explicitly declare the type that
|
||||||
|
the name has. *)
|
||||||
|
op_bind_type ::= ':';
|
||||||
|
|
||||||
|
(* Bind the RHS expression to the LHS name. *)
|
||||||
|
op_bind_value ::= ':', '=';
|
||||||
|
|
||||||
|
(* Used in function definitions: the LHS input produces RHS output. *)
|
||||||
|
op_fn_return ::= '-', '>';
|
||||||
|
|
||||||
|
(* Binds the result contained in the RHS expression to the name on the LHS. *)
|
||||||
|
(* Note that "contained" refers to the value in the [Bi]Monad. *)
|
||||||
|
op_bind_do ::= '<', '-';
|
||||||
|
|
||||||
|
(* Indicates some type is constrained by some type class, ex F * :: Functor *)
|
||||||
|
op_class_member ::= ':', ':';
|
||||||
|
|
||||||
|
(* Indicates the start of a case, case <pattern> => <expr> *)
|
||||||
|
op_case ::= '=', '>';
|
||||||
|
|
||||||
|
(* ===== *)
|
||||||
|
(* Names *)
|
||||||
|
(* ===== *)
|
||||||
|
|
||||||
|
(* Used to denote an anonymous value, such as ignoring a pattern part. *)
|
||||||
|
name_anon_value ::= '_';
|
||||||
|
|
||||||
|
(* Used to denote an anonymous parameter in a type definition. Helps to describe
|
||||||
|
some type with a particular shape without naming each part. *)
|
||||||
|
name_anon_type ::= '*';
|
||||||
|
|
47
functions.md
47
functions.md
|
@ -1,10 +1,55 @@
|
||||||
# Functions
|
# Functions
|
||||||
|
|
||||||
|
- Functions accept a single input and produce an output.
|
||||||
|
- All functions are inherently curried.
|
||||||
|
|
||||||
|
## Private Functions
|
||||||
|
|
||||||
|
- Any function may be marked `private`.
|
||||||
|
- `private` functions are only available in the current scope.
|
||||||
|
- Scope is file, class, instance, etc. (any function holder)
|
||||||
|
- `private` functions are NOT exported.
|
||||||
|
|
||||||
|
```
|
||||||
|
given F *
|
||||||
|
class Functor
|
||||||
|
given A, B
|
||||||
|
fn map: (A -> B) -> F A -> F B
|
||||||
|
end class
|
||||||
|
|
||||||
|
instance Functor List
|
||||||
|
given A, B
|
||||||
|
fn map: (A -> B) -> [A] -> [B]
|
||||||
|
case _ [] => []
|
||||||
|
case f [h : t] => f h : map f t
|
||||||
|
end fn
|
||||||
|
end instance
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
map (+ 1) [1, 2, 3]
|
||||||
|
-- produces [2, 3, 4]
|
||||||
|
|
||||||
|
-- Assuming F is given, F A -> F B
|
||||||
|
let plus_one := map (+ 1)
|
||||||
|
```
|
||||||
|
|
||||||
|
note define infix in parens as prefix!!!
|
||||||
|
|
||||||
|
```
|
||||||
|
given F * *
|
||||||
|
Map String Int32
|
||||||
|
|
||||||
|
-- F[*[*]]
|
||||||
|
given F (* *)
|
||||||
|
List (List String)
|
||||||
|
```
|
||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
```
|
```
|
||||||
[given T1, T2, ... TN]
|
[given T1, T2, ... TN]
|
||||||
fn <name>: <input> => <output> :=
|
fn <name>: <input> => <output>
|
||||||
<body>
|
<body>
|
||||||
end fn
|
end fn
|
||||||
```
|
```
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
- `given`
|
- `given`
|
||||||
- `true`
|
- `true`
|
||||||
- `false`
|
- `false`
|
||||||
|
- `private`
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
|
|
12
lists.md
12
lists.md
|
@ -30,3 +30,15 @@ record NonEmptyList: (head: A, tail: List[A])
|
||||||
## Indexing
|
## Indexing
|
||||||
|
|
||||||
Lists cannot be accessed by index.
|
Lists cannot be accessed by index.
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
|
```
|
||||||
|
given A
|
||||||
|
enum List
|
||||||
|
object Nil
|
||||||
|
|
||||||
|
given A
|
||||||
|
record List(head: A, tail: List[A])
|
||||||
|
end enum
|
||||||
|
```
|
||||||
|
|
Loading…
Add table
Reference in a new issue