Compare commits
2 Commits
853021e4f8
...
cf1a5c1c3b
Author | SHA1 | Date |
---|---|---|
NotAFile | cf1a5c1c3b | |
NotAFile | 3f08a838d2 |
|
@ -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();
|
||||||
|
|
|
@ -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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue