diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-28 16:31:32 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-28 17:11:51 +0200 |
commit | d9f17fc0025272dace18fcc6286dc3515cfbef43 (patch) | |
tree | e8f20d330fd0ce08e6629411ad42657357be1c9d | |
parent | 1ff5827e6a1b4f8b58b1790aa1843c7cd7a54ea8 (diff) | |
download | rebel-d9f17fc0025272dace18fcc6286dc3515cfbef43.tar rebel-d9f17fc0025272dace18fcc6286dc3515cfbef43.zip |
rebel-lang: add validation and typechecking benchmark
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | crates/rebel-lang/Cargo.toml | 5 | ||||
-rw-r--r-- | crates/rebel-lang/benches/recipe.rs | 63 | ||||
-rw-r--r-- | crates/rebel-lang/src/scope.rs | 6 |
4 files changed, 72 insertions, 3 deletions
@@ -743,6 +743,7 @@ name = "rebel-lang" version = "0.1.0" dependencies = [ "clap", + "divan", "enum-kinds", "rebel-common", "rebel-parse", diff --git a/crates/rebel-lang/Cargo.toml b/crates/rebel-lang/Cargo.toml index 6601c8e..d0971e4 100644 --- a/crates/rebel-lang/Cargo.toml +++ b/crates/rebel-lang/Cargo.toml @@ -15,4 +15,9 @@ enum-kinds = "0.5.1" [dev-dependencies] clap = { version = "4.0.0", features = ["derive"] } +divan = "0.1.14" reedline = "0.31.0" + +[[bench]] +name = "recipe" +harness = false diff --git a/crates/rebel-lang/benches/recipe.rs b/crates/rebel-lang/benches/recipe.rs new file mode 100644 index 0000000..ceb8520 --- /dev/null +++ b/crates/rebel-lang/benches/recipe.rs @@ -0,0 +1,63 @@ +use rebel_lang::{ + scope::{Context, ModuleEntry}, + typing::Type, +}; +use rebel_parse::ast; + +fn main() { + divan::main(); +} + +const RECIPE: &str = include_str!("../../../examples/recipes/gmp/build.recipe"); + +fn recipe() -> ast::Recipe<'static> { + let tokens = rebel_parse::tokenize::token_stream(RECIPE).unwrap(); + rebel_parse::recipe::recipe(&tokens).unwrap() +} + +fn context() -> Context { + let mut ctx = Context::default(); + + ctx.values + .0 + .insert("workdir".to_owned(), ModuleEntry::Def((Type::Str, None))); + ctx.values + .0 + .insert("name".to_owned(), ModuleEntry::Def((Type::Str, None))); + + ctx +} + +#[divan::bench] +fn validate(bencher: divan::Bencher) { + let recipe = recipe(); + + bencher.bench(|| { + for stmt in divan::black_box(&recipe) { + stmt.validate().unwrap(); + } + }); +} + +#[divan::bench] +fn typecheck(bencher: divan::Bencher) { + let recipe = recipe(); + let ctx = context(); + + for stmt in &recipe { + stmt.validate().unwrap(); + } + + bencher.bench(|| { + let mut ctx = divan::black_box(ctx.clone()); + + for stmt in divan::black_box(&recipe) { + let ast::RecipeStmt::BodyStmt(stmt) = stmt else { + // TODO: Check other statements + continue; + }; + + ctx.record_type(stmt).unwrap(); + } + }); +} diff --git a/crates/rebel-lang/src/scope.rs b/crates/rebel-lang/src/scope.rs index a030f47..7542a1e 100644 --- a/crates/rebel-lang/src/scope.rs +++ b/crates/rebel-lang/src/scope.rs @@ -8,7 +8,7 @@ use crate::{ value::{self, EvalError, Value}, }; -#[derive(Debug, Default)] +#[derive(Debug, Clone, Default)] pub struct Context { pub values: Module<(Type, Option<Value>)>, pub methods: HashMap<TypeFamily, HashMap<&'static str, Func>>, @@ -83,7 +83,7 @@ impl Context { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Module<T>(pub HashMap<String, ModuleEntry<T>>); impl<T> Module<T> { @@ -109,7 +109,7 @@ impl<T> Default for Module<T> { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum ModuleEntry<T> { Module(Module<T>), Def(T), |