Support for bools. Also fix fallible/infallible mixup for ctors.

This commit is contained in:
Chris Fallin
2021-09-09 16:26:35 -07:00
parent a412cce615
commit edc95c51a0
4 changed files with 35 additions and 6 deletions

View File

@@ -1,4 +1,5 @@
(type u32 (primitive u32)) (type u32 (primitive u32))
(type bool (primitive bool))
(type A (enum (A1 (x u32)))) (type A (enum (A1 (x u32))))
(decl Ext1 (u32) A) (decl Ext1 (u32) A)
@@ -6,6 +7,9 @@
(extern extractor Ext1 ext1) (extern extractor Ext1 ext1)
(extern extractor Ext2 ext2) (extern extractor Ext2 ext2)
(decl C (bool) A)
(extern constructor C c)
(decl Lower (A) A) (decl Lower (A) A)
(rule (rule
@@ -14,4 +18,4 @@
a a
(Ext1 x) (Ext1 x)
(Ext2 =x))) (Ext2 =x)))
a) (C #t))

View File

@@ -711,6 +711,18 @@ impl<'a> Codegen<'a> {
ctx.values.insert(value.clone(), (is_ref, ty)); ctx.values.insert(value.clone(), (is_ref, ty));
} }
fn const_int(&self, val: i64, ty: TypeId) -> String {
let is_bool = match &self.typeenv.types[ty.index()] {
&Type::Primitive(_, name) => &self.typeenv.syms[name.index()] == "bool",
_ => unreachable!(),
};
if is_bool {
format!("{}", val != 0)
} else {
format!("{}", val)
}
}
fn generate_internal_term_constructors(&self, code: &mut dyn Write) -> Result<(), Error> { fn generate_internal_term_constructors(&self, code: &mut dyn Write) -> Result<(), Error> {
for (&termid, trie) in &self.functions_by_term { for (&termid, trie) in &self.functions_by_term {
let termdata = &self.termenv.terms[termid.index()]; let termdata = &self.termenv.terms[termid.index()];
@@ -775,8 +787,15 @@ impl<'a> Codegen<'a> {
}; };
self.define_val(&value, ctx, /* is_ref = */ false, ty); self.define_val(&value, ctx, /* is_ref = */ false, ty);
let name = self.value_name(&value); let name = self.value_name(&value);
let ty = self.type_name(ty, /* by_ref = */ false); let ty_name = self.type_name(ty, /* by_ref = */ false);
writeln!(code, "{}let {}: {} = {};", indent, name, ty, val)?; writeln!(
code,
"{}let {}: {} = {};",
indent,
name,
ty_name,
self.const_int(val, ty)
)?;
} }
&ExprInst::CreateVariant { &ExprInst::CreateVariant {
ref inputs, ref inputs,
@@ -1027,7 +1046,7 @@ impl<'a> Codegen<'a> {
"{}let {} = {};", "{}let {} = {};",
indent, indent,
self.value_name(&output), self.value_name(&output),
val self.const_int(val, ty),
)?; )?;
self.define_val(&output, ctx, /* is_ref = */ false, ty); self.define_val(&output, ctx, /* is_ref = */ false, ty);
Ok(true) Ok(true)

View File

@@ -519,7 +519,7 @@ impl ExprSequence {
&arg_values_tys[..], &arg_values_tys[..],
ty, ty,
term, term,
/* infallible = */ true, /* infallible = */ false,
) )
} }
&TermKind::ExternalConstructor { .. } => { &TermKind::ExternalConstructor { .. } => {
@@ -527,7 +527,7 @@ impl ExprSequence {
&arg_values_tys[..], &arg_values_tys[..],
ty, ty,
term, term,
/* infallible = */ false, /* infallible = */ true,
) )
} }
_ => panic!("Should have been caught by typechecking"), _ => panic!("Should have been caught by typechecking"),

View File

@@ -423,6 +423,12 @@ impl<'a> Parser<'a> {
self.rparen()?; self.rparen()?;
Ok(Expr::Term { sym, args }) Ok(Expr::Term { sym, args })
} }
} else if self.is_sym_str("#t") {
self.symbol()?;
Ok(Expr::ConstInt { val: 1 })
} else if self.is_sym_str("#f") {
self.symbol()?;
Ok(Expr::ConstInt { val: 0 })
} else if self.is_sym() { } else if self.is_sym() {
let name = self.parse_ident()?; let name = self.parse_ident()?;
Ok(Expr::Var { name }) Ok(Expr::Var { name })