forked from AbleOS/holey-bytes
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
|
#### generic_functions
|
||||||
```hb
|
```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 {
|
main := fn(): uint {
|
||||||
|
add(void, {
|
||||||
|
}, {
|
||||||
|
})
|
||||||
return add(u32, 2, 2) - add(uint, 1, 3)
|
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)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||||
pub struct Id(NonZeroU32);
|
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 {
|
impl crate::ctx_map::CtxEntry for Id {
|
||||||
type Ctx = crate::TypeIns;
|
type Ctx = crate::TypeIns;
|
||||||
type Key<'a> = crate::SymKey<'a>;
|
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 {
|
impl From<$variant> for Id {
|
||||||
fn from(value: $variant) -> Self {
|
fn from(value: $variant) -> Self {
|
||||||
$name::$variant(value).compress()
|
$name::$variant(value).compress()
|
||||||
|
|
101
lang/src/son.rs
101
lang/src/son.rs
|
@ -19,6 +19,7 @@ use {
|
||||||
},
|
},
|
||||||
alloc::{string::String, vec::Vec},
|
alloc::{string::String, vec::Vec},
|
||||||
core::{
|
core::{
|
||||||
|
any::Any,
|
||||||
assert_matches::debug_assert_matches,
|
assert_matches::debug_assert_matches,
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
fmt::{self, Debug, Display, Write},
|
fmt::{self, Debug, Display, Write},
|
||||||
|
@ -768,12 +769,12 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
stack.append(&mut self.queued_peeps);
|
stack.append(&mut self.queued_peeps);
|
||||||
|
|
||||||
debug_assert_matches!(
|
//debug_assert_matches!(
|
||||||
self.iter().find(|(i, n)| n.lock_rc.get() != 0
|
// self.iter().find(|(i, n)| n.lock_rc.get() != 0
|
||||||
&& n.kind.is_peeped()
|
// && n.kind.is_peeped()
|
||||||
&& !stack.contains(i)),
|
// && !stack.contains(i)),
|
||||||
None
|
// None
|
||||||
);
|
//);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(self.queued_peeps.is_empty());
|
debug_assert!(self.queued_peeps.is_empty());
|
||||||
|
@ -2748,6 +2749,9 @@ impl<'a> Codegen<'a> {
|
||||||
Expr::Float { value, .. } => {
|
Expr::Float { value, .. } => {
|
||||||
self.gen_inferred_const(ctx, ty::Id::F32, value as i64, ty::Id::is_float)
|
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, .. }
|
Expr::Ident { id, .. }
|
||||||
if let Some(index) = self.ci.scope.vars.iter().rposition(|v| v.id == 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()
|
_ if lhs.ty.is_pointer()
|
||||||
|| lhs.ty.is_integer()
|
|| lhs.ty.is_integer()
|
||||||
|| lhs.ty == ty::Id::BOOL
|
|| 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()) =>
|
|| (lhs.ty.is_float() && op.is_supported_float_op()) =>
|
||||||
{
|
{
|
||||||
self.strip_ptr(&mut lhs);
|
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) {
|
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);
|
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()) {
|
while let (Some(aty), Some(arg)) = (tys.next(self.tys), args.next()) {
|
||||||
let carg = cargs.next().unwrap();
|
let carg = cargs.next().unwrap();
|
||||||
let var = match aty {
|
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) => {
|
Arg::Value(ty) => {
|
||||||
let mut value = self.raw_expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
let mut value = self.raw_expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
||||||
self.strip_var(&mut value);
|
self.strip_var(&mut value);
|
||||||
|
@ -4428,7 +4440,7 @@ impl<'a> Codegen<'a> {
|
||||||
let sym = parser::find_symbol(&fast.symbols, carg.id);
|
let sym = parser::find_symbol(&fast.symbols, carg.id);
|
||||||
let ty = if sym.flags & idfl::COMPTIME == 0 {
|
let ty = if sym.flags & idfl::COMPTIME == 0 {
|
||||||
// FIXME: could fuck us
|
// FIXME: could fuck us
|
||||||
ty::Id::UNDECLARED
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if ty != ty::Id::TYPE {
|
if ty != ty::Id::TYPE {
|
||||||
self.error(
|
self.error(
|
||||||
|
@ -4449,9 +4461,9 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
self.ci.scope.vars.push(Variable::new(
|
self.ci.scope.vars.push(Variable::new(
|
||||||
carg.id,
|
carg.id,
|
||||||
ty,
|
ty::Id::TYPE,
|
||||||
false,
|
false,
|
||||||
NEVER,
|
self.ci.nodes.new_const(ty::Id::TYPE, ty),
|
||||||
&mut self.ci.nodes,
|
&mut self.ci.nodes,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -4632,19 +4644,11 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.pos.push(pos);
|
self.ci.pos.push(pos);
|
||||||
|
|
||||||
let mut tys = sig.args.args();
|
let mut tys = sig.args.args();
|
||||||
let mut args = args.iter();
|
let mut argsi = args.iter();
|
||||||
while let Some(aty) = tys.next(self.tys) {
|
while let Some(aty) = tys.next(self.tys) {
|
||||||
let arg = args.next().unwrap();
|
let arg = argsi.next().unwrap();
|
||||||
match aty {
|
match aty {
|
||||||
Arg::Type(ty) => {
|
Arg::Type(_) => {}
|
||||||
self.ci.scope.vars.push(Variable::new(
|
|
||||||
arg.id,
|
|
||||||
ty,
|
|
||||||
false,
|
|
||||||
NEVER,
|
|
||||||
&mut self.ci.nodes,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Arg::Value(ty) => {
|
Arg::Value(ty) => {
|
||||||
let mut deps = Vc::from([VOID]);
|
let mut deps = Vc::from([VOID]);
|
||||||
if ty.loc(self.tys) == Loc::Stack && self.tys.size_of(ty) <= 16 {
|
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 self.expr(body).is_some() {
|
||||||
if sig.ret == ty::Id::VOID {
|
if sig.ret == ty::Id::VOID {
|
||||||
self.expr(&Expr::Return { pos: body.pos(), val: None });
|
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 {
|
fn eval_const(&mut self, file: Module, expr: &Expr, ret: ty::Id) -> u64 {
|
||||||
self.ct.activate();
|
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.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();
|
let prev_err_len = self.errors.borrow().len();
|
||||||
|
|
||||||
self.expr(&Expr::Return { pos: expr.pos(), val: Some(expr) });
|
self.expr(&Expr::Return { pos: expr.pos(), val: Some(expr) });
|
||||||
|
|
||||||
scope = mem::take(&mut self.ci.scope.vars);
|
|
||||||
|
|
||||||
let res =
|
let res =
|
||||||
if self.finalize(prev_err_len) { self.emit_and_eval(file, ret, &mut []) } else { 1 };
|
if self.finalize(prev_err_len) { self.emit_and_eval(file, ret, &mut []) } else { 1 };
|
||||||
|
|
||||||
self.pool.pop_ci(&mut self.ci);
|
self.pool.pop_ci(&mut self.ci);
|
||||||
self.ci.scope.vars = scope;
|
|
||||||
|
|
||||||
self.ct.deactivate();
|
self.ct.deactivate();
|
||||||
res
|
res
|
||||||
|
@ -5096,7 +5136,12 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_local_ty(&mut self, ident: Ident) -> Option<ty::Id> {
|
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(
|
fn find_type(
|
||||||
|
|
Loading…
Reference in a new issue