Simple repl
parent
066e5d03e0
commit
eb7a236720
|
@ -73,6 +73,12 @@ version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.72"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -88,6 +94,17 @@ dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clipboard-win"
|
||||||
|
version = "4.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3db8340083d28acb43451166543b98c838299b7e0863621be53a338adceea0ed"
|
||||||
|
dependencies = [
|
||||||
|
"error-code",
|
||||||
|
"str-buf",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-random"
|
name = "const-random"
|
||||||
version = "0.1.13"
|
version = "0.1.13"
|
||||||
|
@ -116,6 +133,23 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "debug2"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"debug2-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "debug2-derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diff"
|
name = "diff"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
@ -158,6 +192,33 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "endian-type"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "error-code"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5115567ac25674e0043e472be13d14e537f37ea8aa4bdc4aef0c89add1db1ff"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"str-buf",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fd-lock"
|
||||||
|
version = "3.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a16910e685088843d53132b04e0f10a571fdb193224fc589685b3ba1ce4cb03d"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fixedbitset"
|
name = "fixedbitset"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -186,9 +247,12 @@ name = "handball"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chumsky",
|
"chumsky",
|
||||||
|
"debug2",
|
||||||
"lalrpop",
|
"lalrpop",
|
||||||
"lalrpop-util",
|
"lalrpop-util",
|
||||||
"logos",
|
"logos",
|
||||||
|
"rustyline",
|
||||||
|
"rustyline-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -326,12 +390,43 @@ version = "2.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "new_debug_unreachable"
|
name = "new_debug_unreachable"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nibble_vec"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43"
|
||||||
|
dependencies = [
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.23.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"memoffset",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
|
@ -412,6 +507,16 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radix_trie"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd"
|
||||||
|
dependencies = [
|
||||||
|
"endian-type",
|
||||||
|
"nibble_vec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
|
@ -454,6 +559,40 @@ version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
|
checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustyline"
|
||||||
|
version = "9.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c38cfbd0a4d7df7aab7cf53732d5d43449d0300358fd15cd4e8c8468a956aca"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if",
|
||||||
|
"clipboard-win",
|
||||||
|
"dirs-next",
|
||||||
|
"fd-lock",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"memchr",
|
||||||
|
"nix",
|
||||||
|
"radix_trie",
|
||||||
|
"scopeguard",
|
||||||
|
"smallvec",
|
||||||
|
"unicode-segmentation",
|
||||||
|
"unicode-width",
|
||||||
|
"utf8parse",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustyline-derive"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb35a55ab810b5c0fe31606fe9b47d1354e4dc519bec0a102655f78ea2b38057"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -472,6 +611,12 @@ version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "str-buf"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "string_cache"
|
name = "string_cache"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
@ -496,6 +641,18 @@ dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "synstructure"
|
||||||
|
version = "0.12.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "term"
|
name = "term"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
@ -516,6 +673,18 @@ dependencies = [
|
||||||
"crunchy",
|
"crunchy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -528,6 +697,12 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
|
checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.10.2+wasi-snapshot-preview1"
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
@ -555,3 +730,46 @@ name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f"
|
||||||
|
|
|
@ -7,8 +7,11 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chumsky = "0.6.0"
|
chumsky = "0.6.0"
|
||||||
lalrpop-util = "0.19.6"
|
lalrpop-util = { version = "0.19.6", features = ["lexer"] }
|
||||||
logos = "0.12.0"
|
logos = "0.12.0"
|
||||||
|
debug2 = {path="../debug2"}
|
||||||
|
rustyline = "9.1.1"
|
||||||
|
rustyline-derive = "0.6.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
lalrpop = "0.19.6"
|
lalrpop = "0.19.6"
|
||||||
|
|
|
@ -1,33 +1,12 @@
|
||||||
use crate::{Token, Tree, Val};
|
use crate::Tree;
|
||||||
|
|
||||||
|
|
||||||
grammar<'s>();
|
grammar<'s>();
|
||||||
|
|
||||||
|
|
||||||
pub(crate) Trees = Tree*;
|
pub Tree: Tree = {
|
||||||
|
"(" "+" <Tree*> ")" => Tree::Add(<>),
|
||||||
Tree: Tree<'s> = {
|
"(" "-" <Tree+> ")" => Tree::Sub(<>),
|
||||||
"(" <Trees> ")" => Tree::Branch(<>),
|
"(" "*" <Tree*> ")" => Tree::Mul(<>),
|
||||||
Val => Tree::Leaf(<>)
|
"(" "/" <Tree+> ")" => Tree::Div(<>),
|
||||||
|
r"[0-9]+(\.[0-9]+)?" => Tree::Val(<>.parse().unwrap()),
|
||||||
}
|
|
||||||
|
|
||||||
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>),
|
|
||||||
}
|
|
||||||
}
|
}
|
846
src/grammar.rs
846
src/grammar.rs
File diff suppressed because it is too large
Load Diff
198
src/main.rs
198
src/main.rs
|
@ -1,130 +1,63 @@
|
||||||
use logos::Logos;
|
|
||||||
|
|
||||||
mod grammar;
|
mod grammar;
|
||||||
|
|
||||||
#[derive(Logos, Debug, PartialEq)]
|
use debug2::dbg;
|
||||||
enum LogosToken {
|
|
||||||
#[regex(r"[0-9]+", priority = 2)]
|
|
||||||
Int,
|
|
||||||
|
|
||||||
#[regex(r"[0-9]+(\\.[0-9]+)?")]
|
#[derive(Debug, debug2::Debug, PartialEq)]
|
||||||
Float,
|
pub enum Tree {
|
||||||
|
Val(f64),
|
||||||
#[regex(r"[A-Za-z0-9!$%&*+\-./:<=>?@^_~]+")]
|
Add(Vec<Tree>),
|
||||||
Ident,
|
Sub(Vec<Tree>),
|
||||||
|
Mul(Vec<Tree>),
|
||||||
#[error]
|
Div(Vec<Tree>),
|
||||||
#[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)]
|
use rustyline::validate::{
|
||||||
pub enum Token<'s> {
|
MatchingBracketValidator, ValidationContext, ValidationResult, Validator,
|
||||||
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)),
|
|
||||||
};
|
};
|
||||||
|
use rustyline::{Editor, Result};
|
||||||
|
use rustyline_derive::{Completer, Helper, Highlighter, Hinter};
|
||||||
|
|
||||||
Some(Ok((span.start, t, span.end)))
|
#[derive(Completer, Helper, Highlighter, Hinter)]
|
||||||
}
|
struct InputValidator {
|
||||||
|
brackets: MatchingBracketValidator,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
impl Validator for InputValidator {
|
||||||
pub enum Tree<'s> {
|
fn validate(&self, ctx: &mut ValidationContext) -> Result<ValidationResult> {
|
||||||
Leaf(Val<'s>),
|
self.brackets.validate(ctx)
|
||||||
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() {
|
fn main() {
|
||||||
let src = std::fs::read_to_string(std::env::args().nth(1).unwrap()).unwrap();
|
// let src = std::fs::read_to_string(std::env::args().nth(1).unwrap()).unwrap();
|
||||||
|
|
||||||
let tree = grammar::TreesParser::new().parse(Lexer::new(&src));
|
// let tree = grammar::TreeParser::new().parse(&src);
|
||||||
|
|
||||||
let t = dbg!(tree).unwrap();
|
// let t = dbg!(tree.unwrap());
|
||||||
|
|
||||||
dbg!(eval(&t[0]));
|
// println!("{}", eval(&t));
|
||||||
|
|
||||||
|
let mut rl = Editor::new();
|
||||||
|
rl.set_helper(Some(InputValidator {
|
||||||
|
brackets: MatchingBracketValidator::new(),
|
||||||
|
}));
|
||||||
|
while let Ok(line) = rl.readline("> ") {
|
||||||
|
rl.add_history_entry(&line);
|
||||||
|
|
||||||
|
let tree = grammar::TreeParser::new().parse(&line).unwrap();
|
||||||
|
dbg!(&tree);
|
||||||
|
println!("< {}", eval(&tree))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eval(t: &Tree) -> f64 {
|
||||||
|
match t {
|
||||||
|
Tree::Val(v) => *v,
|
||||||
|
Tree::Add(vs) => vs.iter().map(eval).sum(),
|
||||||
|
Tree::Mul(vs) => vs.iter().map(eval).product(),
|
||||||
|
Tree::Sub(vs) => eval(&vs[0]) - vs[1..].iter().map(eval).sum::<f64>(),
|
||||||
|
Tree::Div(vs) => eval(&vs[0]) / vs[1..].iter().map(eval).product::<f64>(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -132,15 +65,42 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn math_exprs() {
|
fn simple_math_space() {
|
||||||
fn test(s: &str, v: f64) {
|
let t = grammar::TreeParser::new()
|
||||||
let tree = grammar::TreesParser::new().parse(Lexer::new(s)).unwrap();
|
.parse("( + 1 2 ( / 2 3 4 5) )")
|
||||||
assert_eq!(tree.len(), 1);
|
.unwrap();
|
||||||
assert_eq!(eval(&tree[0]), v);
|
assert_eq!(
|
||||||
|
t,
|
||||||
|
Tree::Add(vec![
|
||||||
|
Tree::Val(1.0),
|
||||||
|
Tree::Val(2.0),
|
||||||
|
Tree::Div(vec![
|
||||||
|
Tree::Val(2.0),
|
||||||
|
Tree::Val(3.0),
|
||||||
|
Tree::Val(4.0),
|
||||||
|
Tree::Val(5.0),
|
||||||
|
])
|
||||||
|
])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
test("1", 1.0);
|
#[test]
|
||||||
test("(+ 1 2)", 3.0);
|
fn simple_math_dence() {
|
||||||
test("(+ 1 2 (/ 2 3 4 5))", 3.033333333333333);
|
let t = grammar::TreeParser::new()
|
||||||
|
.parse("(+ 1 2 (/ 2 3 4 5))")
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
t,
|
||||||
|
Tree::Add(vec![
|
||||||
|
Tree::Val(1.0),
|
||||||
|
Tree::Val(2.0),
|
||||||
|
Tree::Div(vec![
|
||||||
|
Tree::Val(2.0),
|
||||||
|
Tree::Val(3.0),
|
||||||
|
Tree::Val(4.0),
|
||||||
|
Tree::Val(5.0),
|
||||||
|
])
|
||||||
|
])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue