summaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 16:31:32 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 17:11:51 +0200
commitd9f17fc0025272dace18fcc6286dc3515cfbef43 (patch)
treee8f20d330fd0ce08e6629411ad42657357be1c9d /crates
parent1ff5827e6a1b4f8b58b1790aa1843c7cd7a54ea8 (diff)
downloadrebel-d9f17fc0025272dace18fcc6286dc3515cfbef43.tar
rebel-d9f17fc0025272dace18fcc6286dc3515cfbef43.zip
rebel-lang: add validation and typechecking benchmark
Diffstat (limited to 'crates')
-rw-r--r--crates/rebel-lang/Cargo.toml5
-rw-r--r--crates/rebel-lang/benches/recipe.rs63
-rw-r--r--crates/rebel-lang/src/scope.rs6
3 files changed, 71 insertions, 3 deletions
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),