Skip to content

Commit

Permalink
Merge branch 'match_expr' into target_test
Browse files Browse the repository at this point in the history
  • Loading branch information
chriseth committed Sep 25, 2024
2 parents 1008a55 + 4a23a7a commit fcb7c89
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
52 changes: 48 additions & 4 deletions jit-compiler/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use powdr_ast::{
display::quote,
types::{ArrayType, FunctionType, Type, TypeScheme},
ArrayLiteral, BinaryOperation, BinaryOperator, BlockExpression, FunctionCall, IfExpression,
IndexAccess, LambdaExpression, Number, StatementInsideBlock, UnaryOperation,
IndexAccess, LambdaExpression, MatchArm, MatchExpression, Number, Pattern,
StatementInsideBlock, UnaryOperation,
},
};
use powdr_number::FieldElement;
Expand Down Expand Up @@ -281,6 +282,22 @@ impl<'a, T: FieldElement> CodeGenerator<'a, T> {
.unwrap_or_default()
)
}
Expression::MatchExpression(_, MatchExpression { scrutinee, arms }) => {
format!(
"match {} {{\n{}\n}}",
self.format_expr(scrutinee)?,
arms.iter()
.map(|MatchArm { pattern, value }| {
Ok(format!(
"{} => {},",
format_pattern(pattern),
self.format_expr(value)?,
))
})
.collect::<Result<Vec<_>, String>>()?
.join("\n")
)
}
_ => return Err(format!("Implement {e}")),
})
}
Expand All @@ -303,6 +320,31 @@ impl<'a, T: FieldElement> CodeGenerator<'a, T> {
}
}

fn format_pattern(pattern: &Pattern) -> String {
match pattern {
Pattern::CatchAll(_) => "_".to_string(),
Pattern::Ellipsis(_) => "..".to_string(),
Pattern::Number(_, n) => {
// TODO this should probably fail if the number is too large.
n.to_string()
}
Pattern::String(_, s) => quote(s),
Pattern::Tuple(_, items) => {
format!("({})", items.iter().map(format_pattern).join(", "))
}
Pattern::Array(_, items) => {
format!("[{}]", items.iter().map(format_pattern).join(", "))
}
Pattern::Variable(_, var) => var.clone(),
Pattern::Enum(_, name, None) => escape_symbol(&name.to_string()),
Pattern::Enum(_, name, Some(fields)) => format!(
"{}({})",
escape_symbol(&name.to_string()),
fields.iter().map(format_pattern).join(", ")
),
}
}

pub fn escape_symbol(s: &str) -> String {
// TODO better escaping
s.replace('.', "_").replace("::", "_")
Expand All @@ -324,10 +366,12 @@ fn map_type(ty: &Type) -> String {
),
Type::TypeVar(tv) => tv.to_string(),
Type::NamedType(path, type_args) => {
if type_args.is_some() {
unimplemented!()
let name = escape_symbol(&path.to_string());
if let Some(type_args) = type_args {
format!("{name}::<{}>", type_args.iter().map(map_type).join(", "))
} else {
name
}
escape_symbol(&path.to_string())
}
Type::Col | Type::Inter => unreachable!(),
}
Expand Down
13 changes: 10 additions & 3 deletions jit-compiler/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub fn generate_glue_code<T: FieldElement>(
let ty = analyzed.type_of_symbol(sym);
if ty != int_int_fun && ty.ty != Type::Col {
return Err(format!(
"Only (int -> int) functions and columns are supported, but requested {}",
"Only (int -> int) functions and columns are supported, but requested{}",
format_type_scheme_around_name(sym, &Some(ty)),
));
}
Expand Down Expand Up @@ -84,7 +84,7 @@ version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["dylib"]
crate-type = ["cdylib"]
[dependencies]
ibig = { version = "0.3.6", features = [], default-features = false }
Expand All @@ -110,10 +110,17 @@ pub fn call_cargo(code: &str) -> Result<(Temp, String), String> {
let stderr = from_utf8(&out.stderr).unwrap_or("UTF-8 error in error message.");
return Err(format!("Failed to compile: {stderr}."));
}
let extension = if cfg!(target_os = "windows") {
"dll"
} else if cfg!(target_os = "macos") {
"dylib"
} else {
"so"
};
let lib_path = dir
.join("target")
.join("release")
.join("libpowdr_jit_compiled.so");
.join(format!("libpowdr_jit_compiled.{extension}"));
Ok((dir, lib_path.to_str().unwrap().to_string()))
}

Expand Down
2 changes: 1 addition & 1 deletion jit-compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub fn compile<T: FieldElement>(
let metadata = fs::metadata(&lib_path).unwrap();

log::info!(
"Loading library with size {} MB...",
"Loading library of size {} MB...",
metadata.len() as f64 / 1000000.0
);

Expand Down
6 changes: 6 additions & 0 deletions jit-compiler/tests/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ fn sqrt() {
assert_eq!(f(0), 0);
}

#[test]
#[should_panic = "Only (int -> int) functions and columns are supported, but requested c: int -> bool"]
fn invalid_function() {
let _ = compile("let c: int -> bool = |i| true;", "c");
}

#[test]
fn assigned_functions() {
let input = r#"
Expand Down

0 comments on commit fcb7c89

Please sign in to comment.