allowing compatison of types
This commit is contained in:
parent
aa83ed2ec9
commit
fb119bc6eb
|
@ -514,9 +514,16 @@ note: this does not work on scalar values
|
|||
|
||||
#### generic_functions
|
||||
```hb
|
||||
add := fn($T: type, a: T, b: T): T return a + b
|
||||
add := fn($T: type, a: T, b: T): T {
|
||||
if T != void {
|
||||
return a + b
|
||||
}
|
||||
}
|
||||
|
||||
main := fn(): uint {
|
||||
add(void, {
|
||||
}, {
|
||||
})
|
||||
return add(u32, 2, 2) - add(uint, 1, 3)
|
||||
}
|
||||
```
|
||||
|
|
|
@ -340,6 +340,12 @@ pub mod ty {
|
|||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
pub struct Id(NonZeroU32);
|
||||
|
||||
impl From<Id> for i64 {
|
||||
fn from(value: Id) -> Self {
|
||||
value.0.get() as _
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::ctx_map::CtxEntry for Id {
|
||||
type Ctx = crate::TypeIns;
|
||||
type Key<'a> = crate::SymKey<'a>;
|
||||
|
@ -638,6 +644,12 @@ pub mod ty {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<$variant> for i64 {
|
||||
fn from(value: $variant) -> Self {
|
||||
Id::from(value).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$variant> for Id {
|
||||
fn from(value: $variant) -> Self {
|
||||
$name::$variant(value).compress()
|
||||
|
|
101
lang/src/son.rs
101
lang/src/son.rs
|
@ -19,6 +19,7 @@ use {
|
|||
},
|
||||
alloc::{string::String, vec::Vec},
|
||||
core::{
|
||||
any::Any,
|
||||
assert_matches::debug_assert_matches,
|
||||
cell::{Cell, RefCell},
|
||||
fmt::{self, Debug, Display, Write},
|
||||
|
@ -768,12 +769,12 @@ impl Nodes {
|
|||
}
|
||||
stack.append(&mut self.queued_peeps);
|
||||
|
||||
debug_assert_matches!(
|
||||
self.iter().find(|(i, n)| n.lock_rc.get() != 0
|
||||
&& n.kind.is_peeped()
|
||||
&& !stack.contains(i)),
|
||||
None
|
||||
);
|
||||
//debug_assert_matches!(
|
||||
// self.iter().find(|(i, n)| n.lock_rc.get() != 0
|
||||
// && n.kind.is_peeped()
|
||||
// && !stack.contains(i)),
|
||||
// None
|
||||
//);
|
||||
}
|
||||
|
||||
debug_assert!(self.queued_peeps.is_empty());
|
||||
|
@ -2748,6 +2749,9 @@ impl<'a> Codegen<'a> {
|
|||
Expr::Float { value, .. } => {
|
||||
self.gen_inferred_const(ctx, ty::Id::F32, value as i64, ty::Id::is_float)
|
||||
}
|
||||
Expr::Ident { id, .. } if let Ok(bt) = ty::Builtin::try_from(id) => {
|
||||
Some(self.ci.nodes.new_const_lit(ty::Id::TYPE, bt))
|
||||
}
|
||||
Expr::Ident { id, .. }
|
||||
if let Some(index) = self.ci.scope.vars.iter().rposition(|v| v.id == id) =>
|
||||
{
|
||||
|
@ -3108,6 +3112,8 @@ impl<'a> Codegen<'a> {
|
|||
_ if lhs.ty.is_pointer()
|
||||
|| lhs.ty.is_integer()
|
||||
|| lhs.ty == ty::Id::BOOL
|
||||
|| (lhs.ty == ty::Id::TYPE
|
||||
&& matches!(op, TokenKind::Eq | TokenKind::Ne))
|
||||
|| (lhs.ty.is_float() && op.is_supported_float_op()) =>
|
||||
{
|
||||
self.strip_ptr(&mut lhs);
|
||||
|
@ -3667,7 +3673,7 @@ impl<'a> Codegen<'a> {
|
|||
});
|
||||
|
||||
for var in self.ci.scope.vars.iter_mut().skip(self.ci.inline_var_base) {
|
||||
if !var.ptr && var.value() != NEVER {
|
||||
if var.ty != ty::Id::TYPE && !var.ptr {
|
||||
var.set_value(VOID, &mut self.ci.nodes);
|
||||
}
|
||||
}
|
||||
|
@ -4141,7 +4147,13 @@ impl<'a> Codegen<'a> {
|
|||
while let (Some(aty), Some(arg)) = (tys.next(self.tys), args.next()) {
|
||||
let carg = cargs.next().unwrap();
|
||||
let var = match aty {
|
||||
Arg::Type(id) => Variable::new(carg.id, id, false, NEVER, &mut self.ci.nodes),
|
||||
Arg::Type(id) => Variable::new(
|
||||
carg.id,
|
||||
ty::Id::TYPE,
|
||||
false,
|
||||
self.ci.nodes.new_const(ty::Id::TYPE, id),
|
||||
&mut self.ci.nodes,
|
||||
),
|
||||
Arg::Value(ty) => {
|
||||
let mut value = self.raw_expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
||||
self.strip_var(&mut value);
|
||||
|
@ -4428,7 +4440,7 @@ impl<'a> Codegen<'a> {
|
|||
let sym = parser::find_symbol(&fast.symbols, carg.id);
|
||||
let ty = if sym.flags & idfl::COMPTIME == 0 {
|
||||
// FIXME: could fuck us
|
||||
ty::Id::UNDECLARED
|
||||
continue;
|
||||
} else {
|
||||
if ty != ty::Id::TYPE {
|
||||
self.error(
|
||||
|
@ -4449,9 +4461,9 @@ impl<'a> Codegen<'a> {
|
|||
|
||||
self.ci.scope.vars.push(Variable::new(
|
||||
carg.id,
|
||||
ty,
|
||||
ty::Id::TYPE,
|
||||
false,
|
||||
NEVER,
|
||||
self.ci.nodes.new_const(ty::Id::TYPE, ty),
|
||||
&mut self.ci.nodes,
|
||||
));
|
||||
}
|
||||
|
@ -4632,19 +4644,11 @@ impl<'a> Codegen<'a> {
|
|||
self.ci.pos.push(pos);
|
||||
|
||||
let mut tys = sig.args.args();
|
||||
let mut args = args.iter();
|
||||
let mut argsi = args.iter();
|
||||
while let Some(aty) = tys.next(self.tys) {
|
||||
let arg = args.next().unwrap();
|
||||
let arg = argsi.next().unwrap();
|
||||
match aty {
|
||||
Arg::Type(ty) => {
|
||||
self.ci.scope.vars.push(Variable::new(
|
||||
arg.id,
|
||||
ty,
|
||||
false,
|
||||
NEVER,
|
||||
&mut self.ci.nodes,
|
||||
));
|
||||
}
|
||||
Arg::Type(_) => {}
|
||||
Arg::Value(ty) => {
|
||||
let mut deps = Vc::from([VOID]);
|
||||
if ty.loc(self.tys) == Loc::Stack && self.tys.size_of(ty) <= 16 {
|
||||
|
@ -4668,6 +4672,24 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
let mut tys = sig.args.args();
|
||||
let mut args = args.iter();
|
||||
while let Some(aty) = tys.next(self.tys) {
|
||||
let arg = args.next().unwrap();
|
||||
match aty {
|
||||
Arg::Type(ty) => {
|
||||
self.ci.scope.vars.push(Variable::new(
|
||||
arg.id,
|
||||
ty::Id::TYPE,
|
||||
false,
|
||||
self.ci.nodes.new_const(ty::Id::TYPE, ty),
|
||||
&mut self.ci.nodes,
|
||||
));
|
||||
}
|
||||
Arg::Value(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
if self.expr(body).is_some() {
|
||||
if sig.ret == ty::Id::VOID {
|
||||
self.expr(&Expr::Return { pos: body.pos(), val: None });
|
||||
|
@ -5018,21 +5040,39 @@ impl<'a> Codegen<'a> {
|
|||
|
||||
fn eval_const(&mut self, file: Module, expr: &Expr, ret: ty::Id) -> u64 {
|
||||
self.ct.activate();
|
||||
let mut scope = mem::take(&mut self.ci.scope.vars);
|
||||
let scope = self
|
||||
.ci
|
||||
.scope
|
||||
.vars
|
||||
.iter()
|
||||
.filter(|v| v.ty == ty::Id::TYPE)
|
||||
.map(|v| match self.ci.nodes[v.value.get()].kind {
|
||||
Kind::CInt { value } => (value, v.id),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
self.pool.push_ci(file, Some(ret), self.tys.tasks.len(), &mut self.ci);
|
||||
self.ci.scope.vars = scope;
|
||||
self.ci.scope.vars = scope
|
||||
.into_iter()
|
||||
.map(|(v, id)| {
|
||||
Variable::new(
|
||||
id,
|
||||
ty::Id::TYPE,
|
||||
false,
|
||||
self.ci.nodes.new_const(ty::Id::TYPE, v),
|
||||
&mut self.ci.nodes,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let prev_err_len = self.errors.borrow().len();
|
||||
|
||||
self.expr(&Expr::Return { pos: expr.pos(), val: Some(expr) });
|
||||
|
||||
scope = mem::take(&mut self.ci.scope.vars);
|
||||
|
||||
let res =
|
||||
if self.finalize(prev_err_len) { self.emit_and_eval(file, ret, &mut []) } else { 1 };
|
||||
|
||||
self.pool.pop_ci(&mut self.ci);
|
||||
self.ci.scope.vars = scope;
|
||||
|
||||
self.ct.deactivate();
|
||||
res
|
||||
|
@ -5096,7 +5136,12 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
|
||||
fn find_local_ty(&mut self, ident: Ident) -> Option<ty::Id> {
|
||||
self.ci.scope.vars.iter().rfind(|v| (v.id == ident && v.value() == NEVER)).map(|v| v.ty)
|
||||
self.ci.scope.vars.iter().rfind(|v| (v.id == ident && v.ty == ty::Id::TYPE)).map(|v| {
|
||||
match self.ci.nodes[v.value.get()].kind {
|
||||
Kind::CInt { value } => ty::Id::from(value as u64),
|
||||
k => unreachable!("{k:?}"),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn find_type(
|
||||
|
|
Loading…
Reference in a new issue