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: "")
+)