From a14471651ba4057667d648910f43ce3381a3e5cc Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 24 Jul 2024 21:06:26 +0200 Subject: [PATCH] Update type syntax --- README.md | 36 +++++++------- corpus/types.sk | 56 +++++++++++----------- src/grammar.pest | 20 +++++--- src/test/types.rs | 45 +++-------------- tests/corpus/statements/decl-with-type.txt | 6 +-- tests/corpus/types/aliases.txt | 23 +++++++++ tests/corpus/types/enums.txt | 14 +++--- tests/corpus/types/functions.txt | 8 ++-- tests/corpus/types/generics.txt | 18 ++----- tests/corpus/types/recs.txt | 8 ++-- tests/corpus/types/tuples.txt | 32 +++++++++++++ 11 files changed, 143 insertions(+), 123 deletions(-) create mode 100644 tests/corpus/types/aliases.txt create mode 100644 tests/corpus/types/tuples.txt diff --git a/README.md b/README.md index 8354445..5b15fb6 100644 --- a/README.md +++ b/README.md @@ -87,36 +87,36 @@ let add_all a b c: Num -> Num -> Num -> Num = The value for a type is one of the following: -- `enum {...}` enum -- `rec {...}` record +- `(|...|...)` enum +- `{...}` record - `#(...)` tuple These expressions can be nested. ```sk -type MyEnum = enum { - Var1 Int - Var2 Bool -} +type MyEnum = ( + | Var1 Int + | Var2 Bool +) -type MyRec = rec { +type MyRec = { field1: Float field2: Str } -// records declared in one line need to put a semicolon after each field declaration -type MyRecOneline = rec {field1: Float; field2: Str} +// records declared in one line need to put a comma after each field declaration +type MyRecOneline = {field1: Float, field2: Str} -// tuples can be declared in one line without a semicolon because there's no ambiguity -type MyTuple = #(Float Str) +// so need tuples +type MyTuple = #(Float, Str) -type Nested = rec { - field1: enum { - Boolean Bool - Number Float - } - field2: #(Bool Bool) - field3: rec { +type Nested = { + field1: ( + | Boolean Bool + | Number Float + ) + field2: #(Bool, Bool) + field3: { first: Int second: Int } diff --git a/corpus/types.sk b/corpus/types.sk index b9b36bf..0407c30 100644 --- a/corpus/types.sk +++ b/corpus/types.sk @@ -1,40 +1,40 @@ -type Food = enum { - Apple Num - Banana Num - Cereal Num - Milk #(String Num) -} +type Food = ( + | Apple Num + | Banana Num + | Cereal Num + | Milk #(String, Num) +) -type Utils = enum { - Paper Num - Detergent Num - Pencils Num -} +type Utils = ( + | Paper Num + | Detergent Num + | Pencils Num +) -type Packaging = enum { - Bag - PlasticBag -} +type Packaging = ( + | Bag + | PlasticBag +) -type ShoppingList = rec { +type ShoppingList = { food: Food utils: Utils packaging: Packaging } -type NestedHell = enum { - NoNesting Num - Nesting enum { - FirstLevel enum { - SecondLevel enum { - Third Lvl - } - Second rec { +type NestedHell a = ( + | NoNesting Num + | Nesting ( + | FirstLevel ( + | SecondLevel ( + | Third Lvl + ) + | Second { first: Num second: Num } - } - StillFirst Num - } -} + ) + | StillFirst Num a + ) +) diff --git a/src/grammar.pest b/src/grammar.pest index 74d671b..792d264 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -20,7 +20,7 @@ infix_expr = { } operator = { "+" | "-" | "*" | "/" | "&&" | "||" | "<" | ">" | "==" | "!=" } -ident = @{ !KEYWORD ~ ALPHABETIC ~ (ALPHABETIC | NUMBER | "_")* | quoted_indent } +ident = @{ SYM_ANY_CASE | quoted_indent } quoted_indent = _{ "`" ~ (!"`" ~ ANY)+ ~ "`" } // types @@ -31,19 +31,20 @@ type_decl = { "type" ~ #name = type_ident ~ "=" ~ type_expr } type_expr = { func | type_term | type_ident } type_term = _{ tuple | rec | enum | type_ident } -tuple = { "#(" ~ MLF ~ tuple_entry* ~ MLF ~ ")" } +tuple = { "#(" ~ MLF ~ (tuple_entry ~ SEPARATE)* ~ MLF ~ tuple_entry? ~ ")" } tuple_entry = _{ type_expr ~ MLF } -rec = { "rec" ~ "{" ~ MLF ~ (rec_field ~ TERMINATE ~ MLF)* ~ rec_field? ~ MLF ~ "}" } +rec = { "{" ~ MLF ~ (rec_field ~ SEPARATE ~ MLF)* ~ rec_field? ~ MLF ~ "}" } rec_field = { #field_name = ident ~ ":" ~ #field_type = type_expr* } -enum = { "enum" ~ "{" ~ MLF ~ (enum_vrt ~ TERMINATE ~ MLF)* ~ enum_vrt? ~ "}" } +enum = { "(" ~ MLF ~ ("|" ~ enum_vrt ~ MLF)* ~ "|"? ~ MLF ~ ")" } enum_vrt = { #vrt_name = ident ~ type_expr? } func = { type_term ~ "->" ~ type_expr } -type_ident = ${ #name = ident ~ #args = type_args? } -type_args = { "<" ~ MLF ~ type_ident* ~ MLF ~ ">" } +type_ident = { #name = type_name ~ #args = (type_arg)* } +type_name = @{ SYM_PASCAL_CASE } +type_arg = @{ SYM_CAMEL_CASE } // match patterns that destructure a variant // TODO: copy it for declarations where destructuring can only be done into one variant @@ -75,8 +76,13 @@ byte = @{ "0x" ~ ASCII_HEX_DIGIT{1, 2} | "0b" ~ ASCII_BIN_DIGIT{0, 8} } // utils -KEYWORD = _{ "let" | "rec" | "enum" | "if" | "then" | "else" } +SYM_ANY_CASE = @{ !KEYWORD ~ ASCII_ALPHA ~ (ALPHABETIC | NUMBER | "_")* } +SYM_PASCAL_CASE = @{ !KEYWORD ~ ASCII_ALPHA_UPPER ~ (ALPHABETIC | NUMBER | "_")* } +SYM_CAMEL_CASE = @{ !KEYWORD ~ ASCII_ALPHA_LOWER ~ (ALPHABETIC | NUMBER | "_")* } + +KEYWORD = _{ "let" | "enum" | "if" | "then" | "else" } TERMINATE = _{ LF | EOI | ";" } +SEPARATE = _{ LF | EOI | "," } MLF = _{ (LF)* } LF = _{ "\n" | "\r" } diff --git a/src/test/types.rs b/src/test/types.rs index 365d2ad..768bda5 100644 --- a/src/test/types.rs +++ b/src/test/types.rs @@ -10,49 +10,16 @@ lazy_static! { #[test] fn it_parses_aliases() { - parses_to!(parser: SnekParser, input: "type MyNum = Num", rule: Rule::statement, tokens: [ - statement(0, 16, [ - type_decl(0, 16, [ - type_ident(5, 10, [ - ident(5, 10) - ]), - type_expr(13, 16, [ - type_ident(13, 16, [ - ident(13, 16) - ]) - ]) - ]), - EOI(16, 16) - ]) - ]); + if let Err(e) = (*TESTER).evaluate_strict("aliases") { + panic!("{e}") + } } #[test] fn it_parses_tuples() { - parses_to!(parser: SnekParser, input: "type MyTuple = #(Str Int)", rule: Rule::statement, tokens: [ - statement(0, 25, [ - type_decl(0, 25, [ - type_ident(5, 12, [ - ident(5, 12) - ]), - type_expr(15, 25, [ - tuple(15, 25, [ - type_expr(17, 20, [ - type_ident(17, 20, [ - ident(17, 20) - ]) - ]), - type_expr(21, 24, [ - type_ident(21, 24, [ - ident(21, 24) - ]) - ]), - ]) - ]) - ]), - EOI(25, 25) - ]) - ]); + if let Err(e) = (*TESTER).evaluate_strict("tuples") { + panic!("{e}") + } } #[test] diff --git a/tests/corpus/statements/decl-with-type.txt b/tests/corpus/statements/decl-with-type.txt index 3e430de..b6c24d7 100644 --- a/tests/corpus/statements/decl-with-type.txt +++ b/tests/corpus/statements/decl-with-type.txt @@ -14,7 +14,7 @@ let add_a x: Num -> Num = x + a (type_annot (type_expr (type_ident - (ident: "Num") + (type_name: "Num") ) ) ) @@ -39,11 +39,11 @@ let add_a x: Num -> Num = x + a (type_expr (func (type_ident - (ident: "Num") + (type_name: "Num") ) (type_expr (type_ident - (ident: "Num") + (type_name: "Num") ) ) ) diff --git a/tests/corpus/types/aliases.txt b/tests/corpus/types/aliases.txt new file mode 100644 index 0000000..1341795 --- /dev/null +++ b/tests/corpus/types/aliases.txt @@ -0,0 +1,23 @@ +Aliases Test + +====== + +type MyNum = Num + +====== + +(file + (statement + (type_decl + (type_ident + (type_name: "MyNum") + ) + (type_expr + (type_ident + (type_name: "Num") + ) + ) + ) + ) + (EOI: "") +) diff --git a/tests/corpus/types/enums.txt b/tests/corpus/types/enums.txt index 1bad6b0..99c0582 100644 --- a/tests/corpus/types/enums.txt +++ b/tests/corpus/types/enums.txt @@ -2,10 +2,10 @@ Enums Test ====== -type MyEnum = enum { - First Num - Second Str -} +type MyEnum = ( + | First Num + | Second Str +) ====== @@ -13,7 +13,7 @@ type MyEnum = enum { (statement (type_decl (type_ident - (ident: "MyEnum") + (type_name: "MyEnum") ) (type_expr (enum @@ -21,7 +21,7 @@ type MyEnum = enum { (ident: "First") (type_expr (type_ident - (ident: "Num") + (type_name: "Num") ) ) ) @@ -29,7 +29,7 @@ type MyEnum = enum { (ident: "Second") (type_expr (type_ident - (ident: "Str") + (type_name: "Str") ) ) ) diff --git a/tests/corpus/types/functions.txt b/tests/corpus/types/functions.txt index e73b823..b04d842 100644 --- a/tests/corpus/types/functions.txt +++ b/tests/corpus/types/functions.txt @@ -10,21 +10,21 @@ type MyFn = Num -> Num -> Str (statement (type_decl (type_ident - (ident: "MyFn") + (type_name: "MyFn") ) (type_expr (func (type_ident - (ident: "Num") + (type_name: "Num") ) (type_expr (func (type_ident - (ident: "Num") + (type_name: "Num") ) (type_expr (type_ident - (ident: "Str") + (type_name: "Str") ) ) ) diff --git a/tests/corpus/types/generics.txt b/tests/corpus/types/generics.txt index 222e654..87b8964 100644 --- a/tests/corpus/types/generics.txt +++ b/tests/corpus/types/generics.txt @@ -2,7 +2,7 @@ Generics Test ====== -type MyNum = Num +type MyNum a = Num a ====== @@ -10,21 +10,13 @@ type MyNum = Num (statement (type_decl (type_ident - (ident: "MyNum") - (type_args - (type_ident - (ident: "a") - ) - ) + (type_name: "MyNum") + (type_arg: "a") ) (type_expr (type_ident - (ident: "Num") - (type_args - (type_ident - (ident: "a") - ) - ) + (type_name: "Num") + (type_arg: "a") ) ) ) diff --git a/tests/corpus/types/recs.txt b/tests/corpus/types/recs.txt index 12d00cd..b618c06 100644 --- a/tests/corpus/types/recs.txt +++ b/tests/corpus/types/recs.txt @@ -2,7 +2,7 @@ Recs Test ====== -type MyRec = rec { +type MyRec = { first: Num second: Str } @@ -13,7 +13,7 @@ type MyRec = rec { (statement (type_decl (type_ident - (ident: "MyRec") + (type_name: "MyRec") ) (type_expr (rec @@ -21,7 +21,7 @@ type MyRec = rec { (ident: "first") (type_expr (type_ident - (ident: "Num") + (type_name: "Num") ) ) ) @@ -29,7 +29,7 @@ type MyRec = rec { (ident: "second") (type_expr (type_ident - (ident: "Str") + (type_name: "Str") ) ) ) diff --git a/tests/corpus/types/tuples.txt b/tests/corpus/types/tuples.txt new file mode 100644 index 0000000..f3161ce --- /dev/null +++ b/tests/corpus/types/tuples.txt @@ -0,0 +1,32 @@ +Tuples Test + +====== + +type MyTuple = #(Str, Int) + +====== + +(file + (statement + (type_decl + (type_ident + (type_name: "MyTuple") + ) + (type_expr + (tuple + (type_expr + (type_ident + (type_name: "Str") + ) + ) + (type_expr + (type_ident + (type_name: "Int") + ) + ) + ) + ) + ) + ) + (EOI: "") +)