From 2ad400167a25d6d985e3173877a05a27843f5ba4 Mon Sep 17 00:00:00 2001 From: Pat Garrity Date: Wed, 31 Jan 2024 08:26:34 -0600 Subject: [PATCH] Starting to overhaul functions again. Expanding EBNF. --- ava.ebnf | 127 +++++++++++++++++++++++++++++++++++++++++++-------- functions.md | 47 ++++++++++++++++++- keywords.md | 1 + lists.md | 12 +++++ 4 files changed, 167 insertions(+), 20 deletions(-) diff --git a/ava.ebnf b/ava.ebnf index c8d28ef..0a5042f 100644 --- a/ava.ebnf +++ b/ava.ebnf @@ -1,9 +1,17 @@ +(* ======================== *) (* Core Character Sequences *) +(* ======================== *) white_space ::= '\u0020' | '\u0009' | '\u000D' | '\u000A' -paren ::= '(' | ')'; -bracket ::= '[' | ']'; -brace ::= '{' | '}'; +lparen ::= '('; +rparen ::= ')'; +paren ::= lparen | rparen; +lbracket ::= '['; +rbracket ::= ']'; +bracket ::= lbracket | rbracket; +lbrace ::= '{'; +rbrace ::= '}'; +brace ::= lbrace | rbrace; digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; hex ::= '0' | ... | '9' | 'A' | ... | 'F' | 'a' | ... | 'f' ; upper ::= 'A' | ... | 'Z' | Lu | Lt | Nl @@ -30,22 +38,9 @@ string_char ::= printable_char without newline or double quote comment ::= '-', '-', {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 *) +(* ======== *) k_type ::= 't', 'y', 'p', 'e'; 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_fn ::= 'f', 'n'; k_end ::= 'e', 'n', 'd'; + +(* Initiates a pattern match against some value. *) k_match ::= 'm', 'a', 't', 'c', 'h'; + +(* Initiates a pattern matching case. Applicable to functions and matches. *) k_case ::= 'c', 'a', 's', 'e'; + +(* Used in if/else syntax. Starts such a block and used in 'else if'. *) k_if ::= 'i', 'f'; + +(* Used in if/else syntax. Must follow the condition of any 'if'. *) k_then ::= 't', 'h', 'e', 'n'; + +(* Used in if/else syntax. Indicates an 'else if' or 'else'. *) k_else ::= 'e', 'l', 's', 'e'; + +(* Used in do/return syntax. Indicates the start of such a structure. *) k_do ::= 'd', 'o'; + +(* Used in do/return syntax. Indicates the final output value. *) k_return ::= 'r', 'e', 't', 'u', 'r', 'n'; + +(* Indicates a type constructor. *) 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'; + +(* false is a Boolean literal *) k_false ::= 'f', 'a', 'l', 's', 'e'; + keyword ::= k_type | k_class | k_alias | k_const | k_enum | k_record | k_object | k_let | k_mut | k_export | k_import | 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_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 => *) +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 ::= '*'; diff --git a/functions.md b/functions.md index f064796..5e91611 100644 --- a/functions.md +++ b/functions.md @@ -1,10 +1,55 @@ # 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 ``` [given T1, T2, ... TN] -fn : => := +fn : => end fn ``` diff --git a/keywords.md b/keywords.md index 34d0114..c84fa8a 100644 --- a/keywords.md +++ b/keywords.md @@ -25,6 +25,7 @@ - `given` - `true` - `false` +- `private` TODO: diff --git a/lists.md b/lists.md index f5448a3..71829ea 100644 --- a/lists.md +++ b/lists.md @@ -30,3 +30,15 @@ record NonEmptyList: (head: A, tail: List[A]) ## Indexing Lists cannot be accessed by index. + +## Implementation + +``` +given A +enum List + object Nil + + given A + record List(head: A, tail: List[A]) +end enum +```