started grammar parsing

This commit is contained in:
Jolimaitre Matthieu 2022-05-25 20:09:59 +03:00
parent 43f42ecccd
commit 7aa98bdd04
5 changed files with 322 additions and 1 deletions

99
Cargo.lock generated
View file

@ -2,6 +2,105 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 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 = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chumsky"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d02796e4586c6c41aeb68eae9bfb4558a522c35f1430c14b40136c3706e09e4"
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 = "getrandom"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[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.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]] [[package]]
name = "prout" name = "prout"
version = "0.1.0" version = "0.1.0"
dependencies = [
"chumsky",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

View file

@ -6,3 +6,4 @@ 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]
chumsky = "0.8.0"

View file

@ -5,7 +5,12 @@ pub mod syntax_tree;
pub mod value; pub mod value;
fn main() { fn main() {
println!("Hello, world!"); use prelude::std_prelude;
let input = todo!();
// let parsed = syntax_tree::parser::Parser::parse(input);
// let executable = execution_tree::parser::Parser::parse(parsed, |b| std_prelude(b));
// let runtime = runtime::Runtime::new();
// runtime.execute(&executable);
} }
#[test] #[test]

View file

@ -9,6 +9,10 @@ pub struct Program {
pub struct Expr(pub Box<ExprInner>); pub struct Expr(pub Box<ExprInner>);
impl Expr { impl Expr {
pub fn new(inner: ExprInner) -> Self {
Self(Box::new(inner))
}
pub fn inner(&self) -> &ExprInner { pub fn inner(&self) -> &ExprInner {
let Self(inner) = self; let Self(inner) = self;
inner inner
@ -76,6 +80,72 @@ impl Expr {
} }
} }
impl From<Scope> for Expr {
fn from(input: Scope) -> Self {
Self::new(ExprInner::Scope(input))
}
}
impl From<Literal> for Expr {
fn from(input: Literal) -> Self {
Self::new(ExprInner::Literal(input))
}
}
impl From<VarDef> for Expr {
fn from(input: VarDef) -> Self {
Self::new(ExprInner::VarDef(input))
}
}
impl From<VarAssign> for Expr {
fn from(input: VarAssign) -> Self {
Self::new(ExprInner::VarAssign(input))
}
}
impl From<VarCall> for Expr {
fn from(input: VarCall) -> Self {
Self::new(ExprInner::VarCall(input))
}
}
impl From<FnDef> for Expr {
fn from(input: FnDef) -> Self {
Self::new(ExprInner::FnDef(input))
}
}
impl From<FnCall> for Expr {
fn from(input: FnCall) -> Self {
Self::new(ExprInner::FnCall(input))
}
}
impl From<FnRet> for Expr {
fn from(input: FnRet) -> Self {
Self::new(ExprInner::FnRet(input))
}
}
impl From<Loop> for Expr {
fn from(input: Loop) -> Self {
Self::new(ExprInner::Loop(input))
}
}
impl From<LoopBr> for Expr {
fn from(input: LoopBr) -> Self {
Self::new(ExprInner::LoopBr(input))
}
}
impl From<Cond> for Expr {
fn from(input: Cond) -> Self {
Self::new(ExprInner::Cond(input))
}
}
impl<T> From<T> for Expr impl<T> From<T> for Expr
where where
T: Into<Value>, T: Into<Value>,
@ -164,3 +234,5 @@ pub struct Cond {
pub arm_true: Expr, pub arm_true: Expr,
pub arm_false: Option<Expr>, pub arm_false: Option<Expr>,
} }
pub mod parser;

144
src/syntax_tree/parser.rs Normal file
View file

@ -0,0 +1,144 @@
use chumsky::prelude::*;
use super::*;
pub fn scope_parser() -> impl Parser<char, Scope, Error = Simple<char>> {
expression_parser()
.chain(
just(';')
.padded()
.ignore_then(expression_parser())
.repeated(),
)
.delimited_by(just('{'), just('}'))
.map(|instructions| Scope { instructions })
}
pub fn literal_value() -> impl Parser<char, Value, Error = Simple<char>> {
let frac = just('.').chain(text::digits(10));
let number = just('-')
.or_not()
.chain(text::int(10))
.chain::<char, _, _>(frac.or_not().flatten())
.collect::<String>()
.from_str()
.unwrapped();
let literal = number.clone().map(|n| Value::Number(n)); // TODO: add other types
literal
}
pub fn name() -> impl Parser<char, String, Error = Simple<char>> {
let name = just('a')
.or(just('b'))
.or(just('c'))
.or(just('d'))
.or(just('e'))
.or(just('f'))
.or(just('g'))
.or(just('h'))
.or(just('i'))
.or(just('j'))
.or(just('k'))
.or(just('l'))
.or(just('m'))
.or(just('n'))
.or(just('o'))
.or(just('p'))
.or(just('q'))
.or(just('r'))
.or(just('s'))
.or(just('t'))
.or(just('u'))
.or(just('v'))
.or(just('w'))
.or(just('x'))
.or(just('y'))
.or(just('z'))
.or(just('-'))
.or(just('_'))
.repeated()
.map(|v| String::from_iter(&v));
name
}
pub fn variable_definition_parser() -> impl Parser<char, VarDef, Error = Simple<char>> {
name()
.padded()
.then_ignore(just(":"))
.padded()
.then(expression_parser())
.map(|(name, value)| VarDef { name, value })
}
pub fn variable_assignement_parser() -> impl Parser<char, VarAssign, Error = Simpl<char>> {
expression_parser().then() name()
}
pub fn expression_parser() -> impl Parser<char, Expr, Error = Simple<char>> {
let scope = scope_parser().map(|s| s.into());
let litteral = literal_value().map(|v| Expr::new_literal(v));
let variable_definition = variable_definition_parser().map(|s| s.into());
let variable_assignment;
let variable_call;
let function_definition;
let function_call;
let function_return;
let loop_;
let loop_break;
let condition;
scope
.or(litteral)
.or(variable_definition)
.or(variable_assignment)
.or(variable_call)
.or(function_definition)
.or(function_call)
.or(function_return)
.or(loop_)
.or(loop_break)
.or(condition)
}
pub fn parser() -> impl Parser<char, Program, Error = Simple<char>> {
let scope = expression_parser().chain(
just(';')
.padded()
.ignore_then(expression_parser())
.repeated(),
);
let program = scope
.map(|instructions| {
let body = Scope { instructions };
Program { body }
})
.then_ignore(end().recover_with(skip_then_retry_until([])));
program
}
// impl Parser {
// pub fn parse(input: &str) -> Program {
// todo!()
// }
// }
/*
// example
my-print: (input) => {
concatenated: {
"now I would like to interject for a moment" + input
};
print(input);
}
a: 5.2;
loop {
if a <= 0 {
break true
} else {
a - 1 -> a
}
}
*/