Compare commits

..

2 Commits

Author SHA1 Message Date
NotAFile cf1a5c1c3b add back function type resolving 2022-02-16 22:17:25 +01:00
NotAFile 3f08a838d2 switch callable to interning too 2022-02-16 17:38:56 +01:00
4 changed files with 93 additions and 21 deletions

View File

@ -4,7 +4,7 @@ use std::fmt::Write;
use super::parser; use super::parser;
use crate::rtlil; use crate::rtlil;
pub use callable::Callable; pub use callable::{Callable, CallableContext, CallableId};
pub use types::{Type, TypeStruct, TypingContext}; pub use types::{Type, TypeStruct, TypingContext};
mod callable; mod callable;
@ -64,7 +64,8 @@ impl Signal {
pub struct Context { pub struct Context {
/// map callable name to callable /// map callable name to callable
callables: BTreeMap<String, Callable>, callable_names: BTreeMap<String, CallableId>,
callables: CallableContext,
/// type names /// type names
typenames: BTreeMap<String, Type>, typenames: BTreeMap<String, Type>,
types: TypingContext, types: TypingContext,
@ -89,16 +90,23 @@ impl Counter {
impl Context { impl Context {
pub fn new() -> Self { pub fn new() -> Self {
let tcx = TypingContext::new(); let mut tcx = TypingContext::new();
let ccx = CallableContext::new(&mut tcx);
let typenames = [
("Logic".to_string(), tcx.primitives.logic),
("Num".to_string(), tcx.primitives.elabnum),
]
.into();
let callable_names = [("reduce_or".to_string(), ccx.builtins.reduce_or)].into();
Context { Context {
callables: BTreeMap::new(), callables: ccx,
callable_names,
signals: BTreeMap::new(), signals: BTreeMap::new(),
types: TypingContext::new(), types: tcx,
typenames: [ typenames,
("Logic".to_string(), tcx.primitives.logic),
("Num".to_string(), tcx.primitives.elabnum),
]
.into(),
ids: Counter::new(), ids: Counter::new(),
} }
} }
@ -115,8 +123,8 @@ impl Context {
}) })
} }
fn try_get_callable(&self, callname: &str) -> Result<&Callable, CompileError> { fn try_get_callable(&self, callname: &str) -> Result<CallableId, CompileError> {
self.callables.get(callname).ok_or_else(|| { self.callable_names.get(callname).copied().ok_or_else(|| {
CompileError::new(CompileErrorKind::UndefinedReference(callname.to_owned())) CompileError::new(CompileErrorKind::UndefinedReference(callname.to_owned()))
}) })
} }
@ -164,7 +172,7 @@ impl Context {
typed_ir::Expr { typed_ir::Expr {
id, id,
kind: typed_ir::ExprKind::Call { kind: typed_ir::ExprKind::Call {
called: typed_ir::DefId(99), called: self.callables.builtins.bitnot,
args: vec![a], args: vec![a],
}, },
typ: self.types.primitives.infer, typ: self.types.primitives.infer,
@ -175,7 +183,7 @@ impl Context {
typed_ir::Expr { typed_ir::Expr {
id, id,
kind: typed_ir::ExprKind::Call { kind: typed_ir::ExprKind::Call {
called: typed_ir::DefId(99), called: self.callables.builtins.xor,
args: vec![a, b], args: vec![a, b],
}, },
typ: self.types.primitives.infer, typ: self.types.primitives.infer,
@ -187,10 +195,11 @@ impl Context {
.iter() .iter()
.map(|expr| self.type_expression(expr)) .map(|expr| self.type_expression(expr))
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
let called = self.try_get_callable(call.name.fragment())?;
typed_ir::Expr { typed_ir::Expr {
id, id,
kind: typed_ir::ExprKind::Call { kind: typed_ir::ExprKind::Call {
called: typed_ir::DefId(99), called,
args: args_resolved, args: args_resolved,
}, },
typ: self.types.primitives.infer, typ: self.types.primitives.infer,
@ -284,7 +293,8 @@ impl Context {
Ok(format!("_{}", arg.id.0)) Ok(format!("_{}", arg.id.0))
}) })
.collect::<Result<Vec<_>, std::fmt::Error>>()?; .collect::<Result<Vec<_>, std::fmt::Error>>()?;
format!("_{}({})", called.0, args.join(", ")) let callable = self.callables.get(*called);
format!("{}({})", callable.name(), args.join(", "))
} }
}; };
let mut type_pretty = String::new(); let mut type_pretty = String::new();

View File

@ -1,4 +1,8 @@
use super::types::Type; use super::types::{Type, TypingContext};
use std::collections::HashMap;
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq, Ord)]
pub struct CallableId(pub usize);
pub struct Callable { pub struct Callable {
pub name: String, pub name: String,
@ -15,3 +19,54 @@ impl<'ty> Callable {
self.args.len() self.args.len()
} }
} }
pub struct BuiltinCallables {
pub xor: CallableId,
pub bitnot: CallableId,
pub reduce_or: CallableId,
}
pub struct CallableContext {
pub builtins: BuiltinCallables,
callables: Vec<Callable>,
}
impl CallableContext {
pub fn new(typectx: &mut TypingContext) -> Self {
let builtins = BuiltinCallables {
xor: CallableId(0),
bitnot: CallableId(1),
reduce_or: CallableId(2),
};
Self {
callables: vec![
Callable {
name: "builtin::xor".to_string(),
args: vec![],
ret_type: Some(typectx.primitives.logic),
},
Callable {
name: "builtin::bitnot".to_string(),
args: vec![],
ret_type: Some(typectx.primitives.logic),
},
Callable {
name: "builtin::reduce_or".to_string(),
args: vec![],
ret_type: Some(typectx.primitives.logic),
},
],
builtins,
}
}
pub fn add(&mut self, callable: Callable) -> CallableId {
let id = self.callables.len();
self.callables.push(callable);
CallableId(id)
}
pub fn get(&self, id: CallableId) -> &Callable {
&self.callables[id.0]
}
}

View File

@ -1,3 +1,4 @@
use super::callable::CallableId;
use super::types::{ElabData, Type}; use super::types::{ElabData, Type};
use std::fmt::Debug; use std::fmt::Debug;
@ -31,7 +32,7 @@ pub struct Expr {
pub enum ExprKind { pub enum ExprKind {
Literal(ElabData), Literal(ElabData),
Path(DefId), Path(DefId),
Call { called: DefId, args: Vec<Expr> }, Call { called: CallableId, args: Vec<Expr> },
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@ -27,11 +27,17 @@ enum TypeKind {
/// UInt of generic width /// UInt of generic width
UInt(ElabData), UInt(ElabData),
/// Callable /// Callable
Callable, 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,
} }
#[derive(Debug, Clone)]
pub struct FnSig {
params: Vec<Type>,
ret: Type,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ElabData { pub struct ElabData {
typ: Type, typ: Type,
@ -145,7 +151,7 @@ impl TypingContext {
} }
} }
TypeKind::UInt(_) => todo!(), TypeKind::UInt(_) => todo!(),
TypeKind::Callable => 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 => None, TypeKind::Infer => None,
} }
@ -172,7 +178,7 @@ impl TypingContext {
} }
TypeKind::Infer => write!(w, "?"), TypeKind::Infer => write!(w, "?"),
TypeKind::UInt(_) => todo!("print uint"), TypeKind::UInt(_) => todo!("print uint"),
TypeKind::Callable => todo!("print callable"), TypeKind::Callable(_sig) => todo!("print callable"),
} }
} }
} }