Working example and README

This commit is contained in:
Chris Fallin
2021-09-04 20:25:10 -07:00
parent d7efd9f219
commit 4a2cd78827
5 changed files with 52 additions and 10 deletions

5
cranelift/isle/README.md Normal file
View File

@@ -0,0 +1,5 @@
```plain
$ cargo build --release
$ target/release/isle -i isle_examples/test.isle -o isle_examples/test.rs
$ rustc isle_examples/test_main.rs
```

View File

@@ -0,0 +1,8 @@
pub fn get_input<C>(ctx: &mut C, x: u32) -> Option<(test::A,)> {
None
}
fn main() {}
mod test;

View File

@@ -577,7 +577,7 @@ impl<'a> Codegen<'a> {
pos.pretty_print_line(&self.typeenv.filenames[..])
)?;
writeln!(code, "#[derive(Clone, Debug)]")?;
writeln!(code, "enum {} {{", name)?;
writeln!(code, "pub enum {} {{", name)?;
for variant in variants {
let name = &self.typeenv.syms[variant.name.index()];
writeln!(code, " {} {{", name)?;
@@ -733,9 +733,16 @@ impl<'a> Codegen<'a> {
// Get the name of the term and build up the signature.
let (func_name, _) = self.extractor_name_and_infallible(termid);
let arg_is_prim = match &self.typeenv.types[termdata.ret_ty.index()] {
&Type::Primitive(..) => true,
_ => false,
};
let arg = format!(
"arg0: {}",
self.type_name(termdata.ret_ty, /* by_ref = */ Some("&"))
self.type_name(
termdata.ret_ty,
/* by_ref = */ if arg_is_prim { None } else { Some("&") }
),
);
let ret_tuple_tys = termdata
.arg_tys
@@ -761,8 +768,7 @@ impl<'a> Codegen<'a> {
let mut body_ctx: BodyContext = Default::default();
body_ctx.expected_return_vals = ret_tuple_tys.len();
body_ctx.tuple_return = true;
self.generate_body(code, /* depth = */ 0, trie, " ", &mut body_ctx)?;
writeln!(code, " }}")?;
self.generate_body(code, /* depth = */ 0, trie, " ", &mut body_ctx)?;
writeln!(code, "}}")?;
}
@@ -873,14 +879,26 @@ impl<'a> Codegen<'a> {
ctx: &mut BodyContext,
) -> Result<bool, Error> {
match inst {
&PatternInst::Arg { index, .. } => {
&PatternInst::Arg { index, ty } => {
let output = Value::Pattern {
inst: id,
output: 0,
};
let outputname = self.value_name(&output);
let is_ref = match &self.typeenv.types[ty.index()] {
&Type::Primitive(..) => false,
_ => true,
};
writeln!(code, "{}let {} = arg{};", indent, outputname, index)?;
writeln!(code, "{}{{", indent)?;
self.define_val(
&Value::Pattern {
inst: id,
output: 0,
},
ctx,
is_ref,
);
Ok(true)
}
&PatternInst::MatchEqual { ref a, ref b, .. } => {
@@ -946,11 +964,20 @@ impl<'a> Codegen<'a> {
}
&PatternInst::Extract {
ref input,
input_ty,
ref arg_tys,
term,
..
} => {
let input = self.value_by_ref(input, ctx);
let input_ty_prim = match &self.typeenv.types[input_ty.index()] {
&Type::Primitive(..) => true,
_ => false,
};
let input = if input_ty_prim {
self.value_by_val(input, ctx)
} else {
self.value_by_ref(input, ctx)
};
let (etor_name, infallible) = self.extractor_name_and_infallible(term);
let args = arg_tys

View File

@@ -368,13 +368,13 @@ mod test {
(Load (a Reg) (dest Reg))))
(type u32 (primitive u32))
";
let defs = Parser::new("(none)", text)
let defs = Parser::new(Lexer::from_str(text, "(none)"))
.parse_defs()
.expect("should parse");
assert_eq!(
defs,
Defs {
filename: "(none)".to_string(),
filenames: vec!["(none)".to_string()],
defs: vec![
Def::Type(Type {
name: Ident("Inst".to_string()),
@@ -412,8 +412,9 @@ mod test {
}
]),
pos: Pos {
file: 0,
offset: 42,
line: 4,
line: 3,
col: 18,
},
}),
@@ -422,8 +423,9 @@ mod test {
is_extern: false,
ty: TypeValue::Primitive(Ident("u32".to_string())),
pos: Pos {
file: 0,
offset: 167,
line: 7,
line: 6,
col: 18,
},
}),