trunk
Alona EM 2021-12-16 18:23:02 +00:00
commit 066e5d03e0
11 changed files with 1554 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

557
Cargo.lock generated Normal file
View File

@ -0,0 +1,557 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
dependencies = [
"const-random",
]
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "ascii-canvas"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6"
dependencies = [
"term",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "beef"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bed554bd50246729a1ec158d08aa3235d1b69d94ad120ebe187e28894787e736"
[[package]]
name = "bit-set"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chumsky"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75efcada9a5471698704a9518888b76c7f363a086357f86671d7c84d54671eb1"
dependencies = [
"ahash",
]
[[package]]
name = "const-random"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f590d95d011aa80b063ffe3253422ed5aa462af4e9867d43ce8337562bac77c4"
dependencies = [
"const-random-macro",
"proc-macro-hack",
]
[[package]]
name = "const-random-macro"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40"
dependencies = [
"getrandom",
"lazy_static",
"proc-macro-hack",
"tiny-keccak",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "diff"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "ena"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3"
dependencies = [
"log",
]
[[package]]
name = "fixedbitset"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "handball"
version = "0.1.0"
dependencies = [
"chumsky",
"lalrpop",
"lalrpop-util",
"logos",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "indexmap"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]]
name = "itertools"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
dependencies = [
"either",
]
[[package]]
name = "lalrpop"
version = "0.19.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15174f1c529af5bf1283c3bc0058266b483a67156f79589fab2a25e23cf8988"
dependencies = [
"ascii-canvas",
"atty",
"bit-set",
"diff",
"ena",
"itertools",
"lalrpop-util",
"petgraph",
"pico-args",
"regex",
"regex-syntax",
"string_cache",
"term",
"tiny-keccak",
"unicode-xid",
]
[[package]]
name = "lalrpop-util"
version = "0.19.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3e58cce361efcc90ba8a0a5f982c741ff86b603495bb15a998412e957dcd278"
dependencies = [
"regex",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
[[package]]
name = "lock_api"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "logos"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427e2abca5be13136da9afdbf874e6b34ad9001dd70f2b103b083a85daa7b345"
dependencies = [
"logos-derive",
]
[[package]]
name = "logos-derive"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56a7d287fd2ac3f75b11f19a1c8a874a7d55744bd91f7a1b3e7cf87d4343c36d"
dependencies = [
"beef",
"fnv",
"proc-macro2",
"quote",
"regex-syntax",
"syn",
"utf8-ranges",
]
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]]
name = "petgraph"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher",
]
[[package]]
name = "pico-args"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom",
"redox_syscall",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rustversion"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "siphasher"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
[[package]]
name = "smallvec"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
[[package]]
name = "string_cache"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "923f0f39b6267d37d23ce71ae7235602134b250ace715dd2c90421998ddac0c6"
dependencies = [
"lazy_static",
"new_debug_unreachable",
"parking_lot",
"phf_shared",
"precomputed-hash",
]
[[package]]
name = "syn"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "utf8-ranges"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

14
Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "handball"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chumsky = "0.6.0"
lalrpop-util = "0.19.6"
logos = "0.12.0"
[build-dependencies]
lalrpop = "0.19.6"

6
build.rs Normal file
View File

@ -0,0 +1,6 @@
fn main() {
lalrpop::Configuration::new()
.generate_in_source_tree()
.process()
.unwrap();
}

22
schemes.md Normal file
View File

@ -0,0 +1,22 @@
chicken
guile
https://small.r7rs.org/wiki/ImplementationSupport/
chezscheme ✔ gambit-scheme ✔ mit-scheme ✔ scheme48 ✔
chibi-scheme ✔ gerbil-scheme ✔ sagittarius-scheme ✔ sisc-scheme ✔
csi (GOOD)
guile
chez
chibi-scheme
/usr/local/Cellar/gambit-scheme/4.9.3_2/v4.9.3/bin/gsi
gxi
mit-scheme (GOOD)
sash
scheme48 (GOOD)
sisc-scheme (GOOD)

33
src/grammar.lalrpop Normal file
View File

@ -0,0 +1,33 @@
use crate::{Token, Tree, Val};
grammar<'s>();
pub(crate) Trees = Tree*;
Tree: Tree<'s> = {
"(" <Trees> ")" => Tree::Branch(<>),
Val => Tree::Leaf(<>)
}
Val: Val<'s> = {
"@int" => Val::Int(<>),
"@float" => Val::Float(<>),
"@id" => Val::Ident(<>),
}
extern {
type Location = usize;
type Error = crate::LexError;
enum Token<'s> {
"(" => Token::Lparen,
")" => Token::Rparen,
"@id" => Token::Ident(<&'s str>),
"@int" => Token::Int(<i64>),
"@float" => Token::Float(<f64>),
}
}

767
src/grammar.rs Normal file
View File

@ -0,0 +1,767 @@
// auto-generated: "lalrpop 0.19.6"
// sha3: b4e129326576b92bdcb244ce79862d1fd8d25830fd43a283867e772251d1f229
use crate::{Token, Tree, Val};
#[allow(unused_extern_crates)]
extern crate lalrpop_util as __lalrpop_util;
#[allow(unused_imports)]
use self::__lalrpop_util::state_machine as __state_machine;
extern crate core;
extern crate alloc;
#[cfg_attr(rustfmt, rustfmt_skip)]
mod __parse__Trees {
#![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)]
use crate::{Token, Tree, Val};
#[allow(unused_extern_crates)]
extern crate lalrpop_util as __lalrpop_util;
#[allow(unused_imports)]
use self::__lalrpop_util::state_machine as __state_machine;
extern crate core;
extern crate alloc;
use super::__ToTriple;
#[allow(dead_code)]
pub(crate) enum __Symbol<'s>
{
Variant0(Token<'s>),
Variant1(f64),
Variant2(&'s str),
Variant3(i64),
Variant4(Tree<'s>),
Variant5(alloc::vec::Vec<Tree<'s>>),
Variant6(Val<'s>),
}
const __ACTION: &[i8] = &[
// State 0
3, 0, 7, 8, 9,
// State 1
3, -8, 7, 8, 9,
// State 2
3, -7, 7, 8, 9,
// State 3
-5, -5, -5, -5, -5,
// State 4
0, 0, 0, 0, 0,
// State 5
-2, -2, -2, -2, -2,
// State 6
-10, -10, -10, -10, -10,
// State 7
-11, -11, -11, -11, -11,
// State 8
-9, -9, -9, -9, -9,
// State 9
-6, -6, -6, -6, -6,
// State 10
0, 12, 0, 0, 0,
// State 11
-1, -1, -1, -1, -1,
];
fn __action(state: i8, integer: usize) -> i8 {
__ACTION[(state as usize) * 5 + integer]
}
const __EOF_ACTION: &[i8] = &[
// State 0
-7,
// State 1
-8,
// State 2
0,
// State 3
-5,
// State 4
-12,
// State 5
-2,
// State 6
-10,
// State 7
-11,
// State 8
-9,
// State 9
-6,
// State 10
0,
// State 11
-1,
];
fn __goto(state: i8, nt: usize) -> i8 {
match nt {
0 => match state {
1 => 9,
_ => 3,
},
2 => 1,
3 => match state {
2 => 10,
_ => 4,
},
4 => 5,
_ => 0,
}
}
fn __expected_tokens(__state: i8) -> alloc::vec::Vec<alloc::string::String> {
const __TERMINAL: &[&str] = &[
r###""(""###,
r###"")""###,
r###""@float""###,
r###""@id""###,
r###""@int""###,
];
__TERMINAL.iter().enumerate().filter_map(|(index, terminal)| {
let next_state = __action(__state, index);
if next_state == 0 {
None
} else {
Some(alloc::string::ToString::to_string(terminal))
}
}).collect()
}
pub(crate) struct __StateMachine<'s>
where
{
__phantom: core::marker::PhantomData<(&'s ())>,
}
impl<'s> __state_machine::ParserDefinition for __StateMachine<'s>
where
{
type Location = usize;
type Error = crate::LexError;
type Token = Token<'s>;
type TokenIndex = usize;
type Symbol = __Symbol<'s>;
type Success = alloc::vec::Vec<Tree<'s>>;
type StateIndex = i8;
type Action = i8;
type ReduceIndex = i8;
type NonterminalIndex = usize;
#[inline]
fn start_location(&self) -> Self::Location {
Default::default()
}
#[inline]
fn start_state(&self) -> Self::StateIndex {
0
}
#[inline]
fn token_to_index(&self, token: &Self::Token) -> Option<usize> {
__token_to_integer(token, core::marker::PhantomData::<(&())>)
}
#[inline]
fn action(&self, state: i8, integer: usize) -> i8 {
__action(state, integer)
}
#[inline]
fn error_action(&self, state: i8) -> i8 {
__action(state, 5 - 1)
}
#[inline]
fn eof_action(&self, state: i8) -> i8 {
__EOF_ACTION[state as usize]
}
#[inline]
fn goto(&self, state: i8, nt: usize) -> i8 {
__goto(state, nt)
}
fn token_to_symbol(&self, token_index: usize, token: Self::Token) -> Self::Symbol {
__token_to_symbol(token_index, token, core::marker::PhantomData::<(&())>)
}
fn expected_tokens(&self, state: i8) -> alloc::vec::Vec<alloc::string::String> {
__expected_tokens(state)
}
#[inline]
fn uses_error_recovery(&self) -> bool {
false
}
#[inline]
fn error_recovery_symbol(
&self,
recovery: __state_machine::ErrorRecovery<Self>,
) -> Self::Symbol {
panic!("error recovery not enabled for this grammar")
}
fn reduce(
&mut self,
action: i8,
start_location: Option<&Self::Location>,
states: &mut alloc::vec::Vec<i8>,
symbols: &mut alloc::vec::Vec<__state_machine::SymbolTriple<Self>>,
) -> Option<__state_machine::ParseResult<Self>> {
__reduce(
action,
start_location,
states,
symbols,
core::marker::PhantomData::<(&())>,
)
}
fn simulate_reduce(&self, action: i8) -> __state_machine::SimulatedReduce<Self> {
panic!("error recovery not enabled for this grammar")
}
}
fn __token_to_integer<
's,
>(
__token: &Token<'s>,
_: core::marker::PhantomData<(&'s ())>,
) -> Option<usize>
{
match *__token {
Token::Lparen if true => Some(0),
Token::Rparen if true => Some(1),
Token::Float(_) if true => Some(2),
Token::Ident(_) if true => Some(3),
Token::Int(_) if true => Some(4),
_ => None,
}
}
fn __token_to_symbol<
's,
>(
__token_index: usize,
__token: Token<'s>,
_: core::marker::PhantomData<(&'s ())>,
) -> __Symbol<'s>
{
match __token_index {
0 | 1 => __Symbol::Variant0(__token),
2 => match __token {
Token::Float(__tok0) if true => __Symbol::Variant1(__tok0),
_ => unreachable!(),
},
3 => match __token {
Token::Ident(__tok0) if true => __Symbol::Variant2(__tok0),
_ => unreachable!(),
},
4 => match __token {
Token::Int(__tok0) if true => __Symbol::Variant3(__tok0),
_ => unreachable!(),
},
_ => unreachable!(),
}
}
pub(crate) struct TreesParser {
_priv: (),
}
impl TreesParser {
pub(crate) fn new() -> TreesParser {
TreesParser {
_priv: (),
}
}
#[allow(dead_code)]
pub(crate) fn parse<
's,
__TOKEN: __ToTriple<'s, >,
__TOKENS: IntoIterator<Item=__TOKEN>,
>(
&self,
__tokens0: __TOKENS,
) -> Result<alloc::vec::Vec<Tree<'s>>, __lalrpop_util::ParseError<usize, Token<'s>, crate::LexError>>
{
let __tokens = __tokens0.into_iter();
let mut __tokens = __tokens.map(|t| __ToTriple::to_triple(t));
__state_machine::Parser::drive(
__StateMachine {
__phantom: core::marker::PhantomData::<(&())>,
},
__tokens,
)
}
}
pub(crate) fn __reduce<
's,
>(
__action: i8,
__lookahead_start: Option<&usize>,
__states: &mut alloc::vec::Vec<i8>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> Option<Result<alloc::vec::Vec<Tree<'s>>,__lalrpop_util::ParseError<usize, Token<'s>, crate::LexError>>>
{
let (__pop_states, __nonterminal) = match __action {
0 => {
__reduce0(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
1 => {
__reduce1(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
2 => {
__reduce2(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
3 => {
__reduce3(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
4 => {
__reduce4(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
5 => {
__reduce5(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
6 => {
__reduce6(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
7 => {
__reduce7(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
8 => {
__reduce8(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
9 => {
__reduce9(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
10 => {
__reduce10(__lookahead_start, __symbols, core::marker::PhantomData::<(&())>)
}
11 => {
// __Trees = Trees => ActionFn(0);
let __sym0 = __pop_Variant5(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action0::<>(__sym0);
return Some(Ok(__nt));
}
_ => panic!("invalid action code {}", __action)
};
let __states_len = __states.len();
__states.truncate(__states_len - __pop_states);
let __state = *__states.last().unwrap();
let __next_state = __goto(__state, __nonterminal);
__states.push(__next_state);
None
}
#[inline(never)]
fn __symbol_type_mismatch() -> ! {
panic!("symbol type mismatch")
}
fn __pop_Variant0<
's,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>
) -> (usize, Token<'s>, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant0(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant4<
's,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>
) -> (usize, Tree<'s>, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant6<
's,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>
) -> (usize, Val<'s>, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant5<
's,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>
) -> (usize, alloc::vec::Vec<Tree<'s>>, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant1<
's,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>
) -> (usize, f64, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant1(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant3<
's,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>
) -> (usize, i64, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant2<
's,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>
) -> (usize, &'s str, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
pub(crate) fn __reduce0<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Tree = "(", Trees, ")" => ActionFn(2);
assert!(__symbols.len() >= 3);
let __sym2 = __pop_Variant0(__symbols);
let __sym1 = __pop_Variant5(__symbols);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone();
let __end = __sym2.2.clone();
let __nt = super::__action2::<>(__sym0, __sym1, __sym2);
__symbols.push((__start, __Symbol::Variant4(__nt), __end));
(3, 0)
}
pub(crate) fn __reduce1<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Tree = Val => ActionFn(3);
let __sym0 = __pop_Variant6(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action3::<>(__sym0);
__symbols.push((__start, __Symbol::Variant4(__nt), __end));
(1, 0)
}
pub(crate) fn __reduce2<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Tree* = => ActionFn(7);
let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default();
let __end = __start.clone();
let __nt = super::__action7::<>(&__start, &__end);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(0, 1)
}
pub(crate) fn __reduce3<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Tree* = Tree+ => ActionFn(8);
let __sym0 = __pop_Variant5(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action8::<>(__sym0);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(1, 1)
}
pub(crate) fn __reduce4<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Tree+ = Tree => ActionFn(9);
let __sym0 = __pop_Variant4(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action9::<>(__sym0);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(1, 2)
}
pub(crate) fn __reduce5<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Tree+ = Tree+, Tree => ActionFn(10);
assert!(__symbols.len() >= 2);
let __sym1 = __pop_Variant4(__symbols);
let __sym0 = __pop_Variant5(__symbols);
let __start = __sym0.0.clone();
let __end = __sym1.2.clone();
let __nt = super::__action10::<>(__sym0, __sym1);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(2, 2)
}
pub(crate) fn __reduce6<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Trees = => ActionFn(11);
let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default();
let __end = __start.clone();
let __nt = super::__action11::<>(&__start, &__end);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(0, 3)
}
pub(crate) fn __reduce7<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Trees = Tree+ => ActionFn(12);
let __sym0 = __pop_Variant5(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action12::<>(__sym0);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(1, 3)
}
pub(crate) fn __reduce8<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Val = "@int" => ActionFn(4);
let __sym0 = __pop_Variant3(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action4::<>(__sym0);
__symbols.push((__start, __Symbol::Variant6(__nt), __end));
(1, 4)
}
pub(crate) fn __reduce9<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Val = "@float" => ActionFn(5);
let __sym0 = __pop_Variant1(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action5::<>(__sym0);
__symbols.push((__start, __Symbol::Variant6(__nt), __end));
(1, 4)
}
pub(crate) fn __reduce10<
's,
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'s>,usize)>,
_: core::marker::PhantomData<(&'s ())>,
) -> (usize, usize)
{
// Val = "@id" => ActionFn(6);
let __sym0 = __pop_Variant2(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action6::<>(__sym0);
__symbols.push((__start, __Symbol::Variant6(__nt), __end));
(1, 4)
}
}
pub(crate) use self::__parse__Trees::TreesParser;
fn __action0<
's,
>(
(_, __0, _): (usize, alloc::vec::Vec<Tree<'s>>, usize),
) -> alloc::vec::Vec<Tree<'s>>
{
__0
}
fn __action1<
's,
>(
(_, __0, _): (usize, alloc::vec::Vec<Tree<'s>>, usize),
) -> alloc::vec::Vec<Tree<'s>>
{
__0
}
fn __action2<
's,
>(
(_, _, _): (usize, Token<'s>, usize),
(_, __0, _): (usize, alloc::vec::Vec<Tree<'s>>, usize),
(_, _, _): (usize, Token<'s>, usize),
) -> Tree<'s>
{
Tree::Branch(__0)
}
fn __action3<
's,
>(
(_, __0, _): (usize, Val<'s>, usize),
) -> Tree<'s>
{
Tree::Leaf(__0)
}
fn __action4<
's,
>(
(_, __0, _): (usize, i64, usize),
) -> Val<'s>
{
Val::Int(__0)
}
fn __action5<
's,
>(
(_, __0, _): (usize, f64, usize),
) -> Val<'s>
{
Val::Float(__0)
}
fn __action6<
's,
>(
(_, __0, _): (usize, &'s str, usize),
) -> Val<'s>
{
Val::Ident(__0)
}
fn __action7<
's,
>(
__lookbehind: &usize,
__lookahead: &usize,
) -> alloc::vec::Vec<Tree<'s>>
{
alloc::vec![]
}
fn __action8<
's,
>(
(_, v, _): (usize, alloc::vec::Vec<Tree<'s>>, usize),
) -> alloc::vec::Vec<Tree<'s>>
{
v
}
fn __action9<
's,
>(
(_, __0, _): (usize, Tree<'s>, usize),
) -> alloc::vec::Vec<Tree<'s>>
{
alloc::vec![__0]
}
fn __action10<
's,
>(
(_, v, _): (usize, alloc::vec::Vec<Tree<'s>>, usize),
(_, e, _): (usize, Tree<'s>, usize),
) -> alloc::vec::Vec<Tree<'s>>
{
{ let mut v = v; v.push(e); v }
}
fn __action11<
's,
>(
__lookbehind: &usize,
__lookahead: &usize,
) -> alloc::vec::Vec<Tree<'s>>
{
let __start0 = __lookbehind.clone();
let __end0 = __lookahead.clone();
let __temp0 = __action7(
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action1(
__temp0,
)
}
fn __action12<
's,
>(
__0: (usize, alloc::vec::Vec<Tree<'s>>, usize),
) -> alloc::vec::Vec<Tree<'s>>
{
let __start0 = __0.0.clone();
let __end0 = __0.2.clone();
let __temp0 = __action8(
__0,
);
let __temp0 = (__start0, __temp0, __end0);
__action1(
__temp0,
)
}
pub trait __ToTriple<'s, > {
fn to_triple(value: Self) -> Result<(usize,Token<'s>,usize), __lalrpop_util::ParseError<usize, Token<'s>, crate::LexError>>;
}
impl<'s, > __ToTriple<'s, > for (usize, Token<'s>, usize) {
fn to_triple(value: Self) -> Result<(usize,Token<'s>,usize), __lalrpop_util::ParseError<usize, Token<'s>, crate::LexError>> {
Ok(value)
}
}
impl<'s, > __ToTriple<'s, > for Result<(usize, Token<'s>, usize), crate::LexError> {
fn to_triple(value: Self) -> Result<(usize,Token<'s>,usize), __lalrpop_util::ParseError<usize, Token<'s>, crate::LexError>> {
match value {
Ok(v) => Ok(v),
Err(error) => Err(__lalrpop_util::ParseError::User { error }),
}
}
}

146
src/main.rs Normal file
View File

@ -0,0 +1,146 @@
use logos::Logos;
mod grammar;
#[derive(Logos, Debug, PartialEq)]
enum LogosToken {
#[regex(r"[0-9]+", priority = 2)]
Int,
#[regex(r"[0-9]+(\\.[0-9]+)?")]
Float,
#[regex(r"[A-Za-z0-9!$%&*+\-./:<=>?@^_~]+")]
Ident,
#[error]
#[regex(r"[ \t\n\f]+", logos::skip)]
Error,
#[token(r"(")]
Lparen,
#[token(r")")]
Rparen,
}
#[derive(Debug)]
pub struct LexError;
type Spanned<Tok, Loc, Error> = Result<(Loc, Tok, Loc), Error>;
struct Lexer<'a>(logos::Lexer<'a, LogosToken>);
impl<'a> Lexer<'a> {
fn new(src: &'a str) -> Self {
Self(LogosToken::lexer(src))
}
}
#[derive(Clone, Debug)]
pub enum Token<'s> {
Int(i64),
Float(f64),
Ident(&'s str),
Lparen,
Rparen,
}
impl<'a> Iterator for Lexer<'a> {
type Item = Spanned<Token<'a>, usize, LexError>;
fn next(&mut self) -> Option<Self::Item> {
let kind = self.0.next()?;
let span = self.0.span();
let text = self.0.slice();
let t = match kind {
LogosToken::Int => Token::Int(text.parse().unwrap()),
LogosToken::Float => Token::Float(text.parse().unwrap()),
LogosToken::Ident => Token::Ident(text),
LogosToken::Lparen => Token::Lparen,
LogosToken::Rparen => Token::Rparen,
LogosToken::Error => return Some(Err(LexError)),
};
Some(Ok((span.start, t, span.end)))
}
}
#[derive(Clone, Debug)]
pub enum Tree<'s> {
Leaf(Val<'s>),
Branch(Vec<Tree<'s>>),
}
#[derive(Clone, Debug)]
pub enum Val<'s> {
Int(i64),
Float(f64),
Ident(&'s str),
}
enum Func {}
enum RVal {
Func(Func),
Num(f64),
}
enum Op {
Push(RVal),
Call(u8),
Print,
}
fn comp_to(t: &Tree)
fn eval(t: &Tree<'_>) -> f64 {
match t {
Tree::Leaf(Val::Ident(_)) => panic!("Need number got {:?}", t),
Tree::Leaf(Val::Float(f)) => *f,
Tree::Leaf(Val::Int(i)) => *i as f64,
Tree::Branch(v) => {
if let Tree::Leaf(Val::Ident(f)) = v[0] {
match f {
"min" => v[1..].iter().map(eval).reduce(f64::min).unwrap(),
"max" => v[1..].iter().map(eval).reduce(f64::max).unwrap(),
"+" => v[1..].iter().map(eval).sum(),
"*" => v[1..].iter().map(eval).product(),
"/" => eval(&v[1]) / v[2..].iter().map(eval).product::<f64>(),
"-" => eval(&v[1]) - v[2..].iter().map(eval).sum::<f64>(),
_ => panic!("Unknown func {:?}", f),
}
} else {
panic!("Not a function")
}
}
}
}
fn main() {
let src = std::fs::read_to_string(std::env::args().nth(1).unwrap()).unwrap();
let tree = grammar::TreesParser::new().parse(Lexer::new(&src));
let t = dbg!(tree).unwrap();
dbg!(eval(&t[0]));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn math_exprs() {
fn test(s: &str, v: f64) {
let tree = grammar::TreesParser::new().parse(Lexer::new(s)).unwrap();
assert_eq!(tree.len(), 1);
assert_eq!(eval(&tree[0]), v);
}
test("1", 1.0);
test("(+ 1 2)", 3.0);
test("(+ 1 2 (/ 2 3 4 5))", 3.033333333333333);
}
}

1
test/fail/l.scm Normal file
View File

@ -0,0 +1 @@
((())

1
test/pass/math.scm Normal file
View File

@ -0,0 +1 @@
(+ 1 2 (/ 2 3 4 5))

6
test/pass/real-i0.scm Normal file
View File

@ -0,0 +1,6 @@
(display (real? 2.5+0.0i))
(newline)
(display (real? 2.5+0i))
(newline)
;; Chicken semantics seem nicer