From d9f17fc0025272dace18fcc6286dc3515cfbef43 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 28 Apr 2024 16:31:32 +0200 Subject: rebel-lang: add validation and typechecking benchmark --- crates/rebel-lang/Cargo.toml | 5 +++ crates/rebel-lang/benches/recipe.rs | 63 +++++++++++++++++++++++++++++++++++++ crates/rebel-lang/src/scope.rs | 6 ++-- 3 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 crates/rebel-lang/benches/recipe.rs (limited to 'crates') 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)>, pub methods: HashMap>, @@ -83,7 +83,7 @@ impl Context { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Module(pub HashMap>); impl Module { @@ -109,7 +109,7 @@ impl Default for Module { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum ModuleEntry { Module(Module), Def(T), -- cgit v1.2.3