Change the way types are declared

main
trivernis 4 months ago
parent 6e4e13d56d
commit ef07ffd2d9
Signed by: Trivernis
GPG Key ID: 7E6D18B61C8D2F4B

113
Cargo.lock generated

@ -17,6 +17,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "colored"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
dependencies = [
"lazy_static",
"windows-sys",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.12" version = "0.2.12"
@ -56,6 +66,12 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.155" version = "0.2.155"
@ -85,6 +101,19 @@ dependencies = [
"ucd-trie", "ucd-trie",
] ]
[[package]]
name = "pest-test"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a426ffa96d4df49eb2a43b010059dc085c4a0b655fd229de11b49340d1deaffe"
dependencies = [
"colored",
"pest",
"pest_derive",
"snailquote",
"thiserror",
]
[[package]] [[package]]
name = "pest_derive" name = "pest_derive"
version = "2.7.11" version = "2.7.11"
@ -148,11 +177,23 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "snailquote"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec62a949bda7f15800481a711909f946e1204f2460f89210eaf7f57730f88f86"
dependencies = [
"thiserror",
"unicode_categories",
]
[[package]] [[package]]
name = "snek-parser" name = "snek-parser"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"lazy_static",
"pest", "pest",
"pest-test",
"pest_derive", "pest_derive",
] ]
@ -205,8 +246,80 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode_categories"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"

@ -6,5 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
lazy_static = "1.5.0"
pest = "2.7.11" pest = "2.7.11"
pest-test = "0.1.6"
pest_derive = "2.7.11" pest_derive = "2.7.11"

@ -68,39 +68,38 @@ let complex_addition a b c = {
### Complex types ### Complex types
All type declarations follow a similar patter.
The value for a type is one of the following: The value for a type is one of the following:
- `#[...]` enum - `enum {...}` enum
- `#{...}` record - `rec {...}` record
- `#(...)` tuple - `#(...)` tuple
These expressions can be nested. These expressions can be nested.
```sk ```sk
type MyEnum = #[ type MyEnum = enum {
Var1 Int Var1 Int
Var2 Bool Var2 Bool
] }
type MyRec = #{ type MyRec = rec {
field1: Float field1: Float
field2: Str field2: Str
} }
// records declared in one line need to put a semicolon after each field declaration // records declared in one line need to put a semicolon after each field declaration
type MyRecOneline = #{field1: Float; field2: Str} type MyRecOneline = rec {field1: Float; field2: Str}
// tuples can be declared in one line without a semicolon because there's no ambiguity // tuples can be declared in one line without a semicolon because there's no ambiguity
type MyTuple = #(Float Str) type MyTuple = #(Float Str)
type Nested = #{ type Nested = rec {
field1: #[ field1: enum {
Boolean Bool Boolean Bool
Number Float Number Float
] }
field2: #(Bool Bool) field2: #(Bool Bool)
field3: #{ field3: rec {
first: Int first: Int
second: Int second: Int
} }

@ -1,40 +1,40 @@
type Food = #[ type Food = enum {
Apple Num Apple Num
Banana Num Banana Num
Cereal Num Cereal Num
Milk #(String Num) Milk #(String Num)
] }
type Utils = #[ type Utils = enum {
Paper Num Paper Num
Detergent Num Detergent Num
Pencils Num Pencils Num
] }
type Packaging = #[ type Packaging = enum {
Bag Bag
PlasticBag PlasticBag
] }
type ShoppingList = #{ type ShoppingList = rec {
food: Food food: Food
utils: Utils utils: Utils
packaging: Packaging packaging: Packaging
} }
type NestedHell = #[ type NestedHell = enum {
NoNesting Num NoNesting Num
Nesting #[ Nesting enum {
FirstLevel #[ FirstLevel enum {
SecondLevel #[ SecondLevel enum {
Third Lvl<a> Third Lvl<a>
] }
Second #{ Second rec {
first: Num first: Num
second: Num second: Num
} }
] }
StillFirst Num<a> StillFirst Num<a>
] }
] }

@ -8,17 +8,20 @@ block = { "{" ~ MLF ~ block_line ~ MLF ~ "}" }
block_line = _{ expr | (statement ~ MLF)* } block_line = _{ expr | (statement ~ MLF)* }
type_decl = { "type" ~ #name = type_ident ~ "=" ~ type_expr } type_decl = { "type" ~ #name = type_ident ~ "=" ~ type_expr }
type_expr = { tuple | rec | enum | type_ident } type_expr = { type_term | func | type_ident }
type_term = _{ tuple | rec | enum | type_ident }
tuple = { "#(" ~ MLF ~ tuple_entry* ~ MLF ~ ")" } tuple = { "#(" ~ MLF ~ tuple_entry* ~ MLF ~ ")" }
tuple_entry = _{ type_expr ~ MLF } tuple_entry = _{ type_expr ~ MLF }
rec = { "#{" ~ MLF ~ (rec_field ~ TERMINATE ~ MLF)* ~ rec_field? ~ MLF ~ "}" } rec = { "rec" ~ "{" ~ MLF ~ (rec_field ~ TERMINATE ~ MLF)* ~ rec_field? ~ MLF ~ "}" }
rec_field = { #field_name = ident ~ ":" ~ #field_type = type_expr* } rec_field = { #field_name = ident ~ ":" ~ #field_type = type_expr* }
enum = { "#[" ~ MLF ~ (enum_vrt ~ TERMINATE ~ MLF)* ~ enum_vrt? ~ "]" } enum = { "enum" ~ "{" ~ MLF ~ (enum_vrt ~ TERMINATE ~ MLF)* ~ enum_vrt? ~ "}" }
enum_vrt = { #vrt_name = ident ~ type_expr? } enum_vrt = { #vrt_name = ident ~ type_expr? }
func = { type_term ~ "->" ~ type_expr }
type_ident = ${ #name = ident ~ #args = type_args? } type_ident = ${ #name = ident ~ #args = type_args? }
type_args = { "<" ~ MLF ~ type_ident* ~ MLF ~ ">" } type_args = { "<" ~ MLF ~ type_ident* ~ MLF ~ ">" }
@ -48,7 +51,7 @@ float = @{
byte = @{ "0x" ~ ASCII_HEX_DIGIT{1, 2} | "0b" ~ ASCII_BIN_DIGIT{0, 8} } byte = @{ "0x" ~ ASCII_HEX_DIGIT{1, 2} | "0b" ~ ASCII_BIN_DIGIT{0, 8} }
boolean = @{ "true" | "false" } boolean = @{ "true" | "false" }
KEYWORD = _{ "let" } KEYWORD = _{ "let" | "rec" | "enum" }
TERMINATE = _{ LF | EOI | ";" } TERMINATE = _{ LF | EOI | ";" }
MLF = _{ (LF)* } MLF = _{ (LF)* }
LF = _{ "\n" | "\r" } LF = _{ "\n" | "\r" }

@ -4,6 +4,21 @@ mod statements;
mod types; mod types;
use crate::parse; use crate::parse;
use std::{collections::HashSet, path::PathBuf};
use lazy_static::lazy_static;
use pest_test::PestTester;
use crate::{Rule, SnekParser};
fn s_tester<D: Into<PathBuf>>(dir: D) -> PestTester<Rule, SnekParser> {
PestTester::new(
PathBuf::from("tests/corpus").join(dir.into()),
"txt",
Rule::file,
HashSet::new(),
)
}
#[test] #[test]
fn it_parse_types() { fn it_parse_types() {
@ -22,3 +37,12 @@ fn it_parse_declarations() {
panic!("{e}") panic!("{e}")
} }
} }
lazy_static! {
static ref TESTER: PestTester<Rule, SnekParser> = PestTester::new(
PathBuf::from("test/corpus"),
"txt",
Rule::file,
HashSet::new()
);
}

@ -1,6 +1,12 @@
use pest::{consumes_to, parses_to}; use pest::{consumes_to, parses_to};
use pest_test::PestTester;
use crate::{Rule, SnekParser}; use crate::{Rule, SnekParser};
use lazy_static::lazy_static;
lazy_static! {
static ref TESTER: PestTester<Rule, SnekParser> = super::s_tester("types");
}
#[test] #[test]
fn it_parses_aliases() { fn it_parses_aliases() {
@ -51,97 +57,21 @@ fn it_parses_tuples() {
#[test] #[test]
fn it_parses_recs() { fn it_parses_recs() {
parses_to!(parser: SnekParser, input: "type MyRec = #{\nfield1: Num\n field2: Num2 }", rule: Rule::statement, tokens: [ if let Err(e) = (*TESTER).evaluate_strict("recs") {
statement(0, 43, [ panic!("{e}")
type_decl(0, 43, [ }
type_ident(5, 10, [
ident(5, 10)
]),
type_expr(13, 43, [
rec(13, 43, [
rec_field(16, 27, [
ident(16, 22),
type_expr(24, 27, [
type_ident(24, 27, [
ident(24, 27)
])
]),
]),
rec_field(29, 41, [
ident(29, 35),
type_expr(37, 41, [
type_ident(37, 41, [
ident(37, 41)
])
]),
])
])
])
]),
EOI(43, 43)
])
]);
} }
#[test] #[test]
fn it_parses_enums() { fn it_parses_enums() {
parses_to!(parser: SnekParser, input: "type MyEnum = #[Var1 Num\nVar2 Type\n]", rule: Rule::statement, tokens: [ if let Err(e) = (*TESTER).evaluate_strict("enums") {
statement(0, 36, [ panic!("{e}")
type_decl(0, 36, [ }
type_ident(5, 11, [
ident(5, 11)
]),
type_expr(14, 36, [
r#enum(14, 36, [
enum_vrt(16, 24, [
ident(16, 20),
type_expr(21, 24, [
type_ident(21, 24, [
ident(21, 24)
])
]),
]),
enum_vrt(25, 34, [
ident(25, 29),
type_expr(30, 34, [
type_ident(30, 34, [
ident(30, 34)
])
]),
]),
])
])
]),
EOI(36, 36)
])
]);
} }
#[test] #[test]
fn it_parses_generics() { fn it_parses_generics() {
parses_to!(parser: SnekParser, input: "type MyNum<a> = Num<a>", rule: Rule::statement, tokens: [ if let Err(e) = (*TESTER).evaluate_strict("generics") {
statement(0, 22, [ panic!("{e}")
type_decl(0, 22, [ }
type_ident(5, 13, [
ident(5, 10),
type_args(10, 13, [
type_ident(11, 12, [
ident(11, 12)
])
])
]),
type_expr(16, 22, [
type_ident(16, 22, [
ident(16, 19),
type_args(19, 22, [
type_ident(20, 21, [
ident(20, 21)
])
])
])
])
]),
EOI(22, 22)
])
]);
} }

@ -0,0 +1,41 @@
Enums Test
======
type MyEnum = enum {
First Num
Second Str
}
======
(file
(statement
(type_decl
(type_ident
(ident: "MyEnum")
)
(type_expr
(enum
(enum_vrt
(ident: "First")
(type_expr
(type_ident
(ident: "Num")
)
)
)
(enum_vrt
(ident: "Second")
(type_expr
(type_ident
(ident: "Str")
)
)
)
)
)
)
)
(EOI: "")
)

@ -0,0 +1,33 @@
Generics Test
======
type MyNum<a> = Num<a>
======
(file
(statement
(type_decl
(type_ident
(ident: "MyNum")
(type_args
(type_ident
(ident: "a")
)
)
)
(type_expr
(type_ident
(ident: "Num")
(type_args
(type_ident
(ident: "a")
)
)
)
)
)
)
(EOI: "")
)

@ -0,0 +1,41 @@
Recs Test
======
type MyRec = rec {
first: Num
second: Str
}
======
(file
(statement
(type_decl
(type_ident
(ident: "MyRec")
)
(type_expr
(rec
(rec_field
(ident: "first")
(type_expr
(type_ident
(ident: "Num")
)
)
)
(rec_field
(ident: "second")
(type_expr
(type_ident
(ident: "Str")
)
)
)
)
)
)
)
(EOI: "")
)
Loading…
Cancel
Save