Compare commits

..

No commits in common. "cce8a3bde4f28a3ad9bbdf2d37246da1c18328f9" and "270713b3f965ac1e709897e282073b037ccd647f" have entirely different histories.

5 changed files with 13 additions and 143 deletions

View File

@ -133,11 +133,7 @@ impl Context {
match &expr.kind { match &expr.kind {
typed_ir::ExprKind::Literal(lit) => Ok(lit.clone()), typed_ir::ExprKind::Literal(lit) => Ok(lit.clone()),
typed_ir::ExprKind::Path(_) => todo!("evaluate path"), typed_ir::ExprKind::Path(_) => todo!("evaluate path"),
typed_ir::ExprKind::Call { typed_ir::ExprKind::Call { called, args } => todo!("evaluate call"),
called,
args,
genargs,
} => todo!("evaluate call"),
} }
} }
@ -178,7 +174,6 @@ impl Context {
kind: typed_ir::ExprKind::Call { kind: typed_ir::ExprKind::Call {
called: self.callables.builtins.bitnot, called: self.callables.builtins.bitnot,
args: vec![a], args: vec![a],
genargs: vec![],
}, },
typ: self.types.primitives.infer, typ: self.types.primitives.infer,
} }
@ -190,7 +185,6 @@ impl Context {
kind: typed_ir::ExprKind::Call { kind: typed_ir::ExprKind::Call {
called: self.callables.builtins.xor, called: self.callables.builtins.xor,
args: vec![a, b], args: vec![a, b],
genargs: vec![],
}, },
typ: self.types.primitives.infer, typ: self.types.primitives.infer,
} }
@ -209,17 +203,11 @@ impl Context {
expected: called_callable.argcount(), expected: called_callable.argcount(),
})); }));
} }
let genargs_resolved = called_callable
.genargs
.iter()
.map(|genarg| genarg.1)
.collect();
typed_ir::Expr { typed_ir::Expr {
id, id,
kind: typed_ir::ExprKind::Call { kind: typed_ir::ExprKind::Call {
called, called,
args: args_resolved, args: args_resolved,
genargs: genargs_resolved,
}, },
typ: self.types.primitives.infer, typ: self.types.primitives.infer,
} }
@ -282,43 +270,6 @@ impl Context {
))) )))
} }
pub fn infer_expr_types(&mut self, expr: &typed_ir::Expr) -> typed_ir::Expr {
if self.types.is_fully_typed(expr.typ) {
// there is nothing more to infer
return expr.clone();
}
match &expr.kind {
typed_ir::ExprKind::Literal(_) => todo!(),
typed_ir::ExprKind::Path(_) => todo!(),
typed_ir::ExprKind::Call {
called,
args,
genargs,
} => {
let args_typed: Vec<_> = args.iter().map(|ex| self.infer_expr_types(ex)).collect();
let callee_def = self.callables.get(*called);
if self.types.is_fully_typed(callee_def.ret_type) {
expr.clone().with_type(callee_def.ret_type)
} else {
let param_types: Vec<_> = callee_def.args.iter().map(|param| param.1).collect();
let mut genargs = callee_def.genargs.clone();
let inferred_args: Vec<_> = param_types
.iter()
.zip(args_typed)
.map(|(param, arg)| self.types.infer_type(*param, arg.typ))
.collect();
expr.clone().with_type(callee_def.ret_type)
}
}
}
}
pub fn infer_types(&mut self, mut block: typed_ir::Block) -> typed_ir::Block {
let new_root = self.infer_expr_types(&block.expr);
block.expr = new_root;
block
}
pub fn pretty_typed_block( pub fn pretty_typed_block(
&self, &self,
w: &mut dyn std::fmt::Write, w: &mut dyn std::fmt::Write,
@ -341,11 +292,7 @@ impl Context {
let expr_pretty = match &expr.kind { let expr_pretty = match &expr.kind {
typed_ir::ExprKind::Literal(_) => todo!(), typed_ir::ExprKind::Literal(_) => todo!(),
typed_ir::ExprKind::Path(path) => format!("sig_{}", path.0), typed_ir::ExprKind::Path(path) => format!("sig_{}", path.0),
typed_ir::ExprKind::Call { typed_ir::ExprKind::Call { called, args } => {
called,
args,
genargs,
} => {
let args = args let args = args
.iter() .iter()
.map(|arg| { .map(|arg| {
@ -354,20 +301,7 @@ impl Context {
}) })
.collect::<Result<Vec<_>, std::fmt::Error>>()?; .collect::<Result<Vec<_>, std::fmt::Error>>()?;
let callable = self.callables.get(*called); let callable = self.callables.get(*called);
let genargs = genargs format!("{}({})", callable.name(), args.join(", "))
.iter()
.map(|param| {
let mut type_str = String::new();
self.types.pretty_type(&mut type_str, *param)?;
Ok(type_str)
})
.collect::<Result<Vec<_>, std::fmt::Error>>()?;
format!(
"{}<{}>({})",
callable.name(),
genargs.join(", "),
args.join(", ")
)
} }
}; };
let mut type_pretty = String::new(); let mut type_pretty = String::new();

View File

@ -1,4 +1,4 @@
use super::types::{Type, TypingContext}; use super::types::{GenericArg, Type, TypingContext};
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq, Ord)] #[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq, Ord)]
pub struct CallableId(pub usize); pub struct CallableId(pub usize);
@ -6,8 +6,7 @@ pub struct CallableId(pub usize);
pub struct Callable { pub struct Callable {
pub name: String, pub name: String,
pub args: Vec<(Option<String>, Type)>, pub args: Vec<(Option<String>, Type)>,
pub genargs: Vec<(Option<String>, Type)>, pub ret_type: Option<Type>,
pub ret_type: Type,
} }
impl<'ty> Callable { impl<'ty> Callable {
@ -39,29 +38,22 @@ impl CallableContext {
reduce_or: CallableId(2), reduce_or: CallableId(2),
}; };
let logic1 = typectx.make_logic_size(1); let logic1 = typectx.make_logic_size(1);
let logic_tvar0 = typectx.make_typevar(0, 0);
Self { Self {
callables: vec![ callables: vec![
Callable { Callable {
name: "builtin::xor".to_string(), name: "builtin::xor".to_string(),
args: vec![ args: vec![],
(Some("a".to_string()), logic_tvar0), ret_type: Some(typectx.primitives.logic),
(Some("b".to_string()), logic_tvar0),
],
genargs: vec![(Some("T".to_string()), typectx.primitives.logic)],
ret_type: logic_tvar0,
}, },
Callable { Callable {
name: "builtin::bitnot".to_string(), name: "builtin::bitnot".to_string(),
args: vec![(Some("a".to_string()), logic_tvar0)], args: vec![],
genargs: vec![(Some("T".to_string()), typectx.primitives.logic)], ret_type: Some(typectx.primitives.logic),
ret_type: logic_tvar0,
}, },
Callable { Callable {
name: "builtin::reduce_or".to_string(), name: "builtin::reduce_or".to_string(),
args: vec![(Some("a".to_string()), typectx.primitives.logic)], args: vec![(Some("a".to_string()), typectx.primitives.logic)],
genargs: vec![], ret_type: Some(logic1),
ret_type: logic1,
}, },
], ],
builtins, builtins,

View File

@ -32,11 +32,7 @@ pub struct Expr {
pub enum ExprKind { pub enum ExprKind {
Literal(ElabData), Literal(ElabData),
Path(DefId), Path(DefId),
Call { Call { called: CallableId, args: Vec<Expr> },
called: CallableId,
args: Vec<Expr>,
genargs: Vec<Type>,
},
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -51,10 +47,3 @@ pub struct Block {
pub signals: Vec<Signal>, pub signals: Vec<Signal>,
pub expr: Expr, pub expr: Expr,
} }
impl Expr {
pub fn with_type(mut self, typ: Type) -> Self {
self.typ = typ;
self
}
}

View File

@ -30,9 +30,6 @@ enum TypeKind {
Callable(FnSig), Callable(FnSig),
/// A type that was not given and needs to be inferred /// A type that was not given and needs to be inferred
Infer, Infer,
/// A reference to a type variable as DeBruijn index
/// (scope, param)
TypeVar(u32, u32),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -134,12 +131,6 @@ impl TypingContext {
.unwrap() .unwrap()
} }
pub fn make_typevar(&mut self, dbi: u32, tvar: u32) -> Type {
self.add(TypeStruct {
kind: TypeKind::TypeVar(dbi, tvar),
})
}
pub fn parameterize(&mut self, typ: Type, params: &[GenericArg]) -> Option<Type> { pub fn parameterize(&mut self, typ: Type, params: &[GenericArg]) -> Option<Type> {
// TODO: return proper error type here // TODO: return proper error type here
match &self.get(typ).kind { match &self.get(typ).kind {
@ -168,36 +159,7 @@ impl TypingContext {
TypeKind::UInt(_) => todo!(), TypeKind::UInt(_) => todo!(),
TypeKind::Callable(_sig) => todo!("callable generic params"), TypeKind::Callable(_sig) => todo!("callable generic params"),
// need to know what the type is to parameterize it // need to know what the type is to parameterize it
TypeKind::Infer | &TypeKind::TypeVar(_, _) => None, TypeKind::Infer => None,
}
}
/// Given the type of a variable in two locations, infer what the true type should be
pub fn infer_type(&mut self, typ_a: Type, typ_b: Type) -> Type {
match (&self.get(typ_a).kind, &self.get(typ_b).kind) {
(a, b) => panic!("cannot infer between: {:?}, {:?}", a, b),
}
}
/// return whether the type has no unfilled parameters
pub fn is_fully_typed(&self, typ: Type) -> bool {
match &self.get(typ).kind {
TypeKind::ElabType(_) => todo!(),
TypeKind::Logic(data) => {
if let ElabValue::Concrete(_) = data.value {
true
} else {
false
}
}
TypeKind::UInt(_) => todo!(),
TypeKind::Callable(_) => todo!(),
TypeKind::Infer => false,
TypeKind::TypeVar(dbi, _tvar) => {
// if the DeBruijn index is 0, there is no further information to gain
// from a surrounding scope
*dbi != 0
}
} }
} }
@ -223,7 +185,6 @@ impl TypingContext {
TypeKind::Infer => write!(w, "?"), TypeKind::Infer => write!(w, "?"),
TypeKind::UInt(_) => todo!("print uint"), TypeKind::UInt(_) => todo!("print uint"),
TypeKind::Callable(_sig) => todo!("print callable"), TypeKind::Callable(_sig) => todo!("print callable"),
TypeKind::TypeVar(_, tvar) => write!(w, "T{}", tvar),
} }
} }
} }

View File

@ -67,14 +67,8 @@ fn main() {
frontendcontext frontendcontext
.pretty_typed_block(&mut pretty_block, &block) .pretty_typed_block(&mut pretty_block, &block)
.unwrap(); .unwrap();
println!("{}", &pretty_block);
let typed_inferred = frontendcontext.infer_types(block);
let mut pretty_block = String::new();
frontendcontext
.pretty_typed_block(&mut pretty_block, &typed_inferred)
.unwrap();
println!("{}", &pretty_block);
} }
println!("{}", &pretty_block);
} }
/* /*
match lowered { match lowered {