conlang: Introduce as casting
Arbitrary primitive type conversion
Currently implemented as jankily as possible in the interpreter, but it works alright™️
This commit is contained in:
@@ -365,6 +365,8 @@ pub enum ExprKind {
|
||||
Binary(Binary),
|
||||
/// A [Unary] expression: [`UnaryKind`]\* [`Expr`]
|
||||
Unary(Unary),
|
||||
/// A [Cast] expression: [`Expr`] `as` [`Ty`]
|
||||
Cast(Cast),
|
||||
/// A [Member] access expression: [`Expr`] [`MemberKind`]\*
|
||||
Member(Member),
|
||||
/// An Array [Index] expression: a[10, 20, 30]
|
||||
@@ -484,6 +486,12 @@ pub enum UnaryKind {
|
||||
Tilde,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Cast {
|
||||
pub head: Box<ExprKind>,
|
||||
pub ty: Ty,
|
||||
}
|
||||
|
||||
/// A [Member] access expression: [`Expr`] [`MemberKind`]\*
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Member {
|
||||
|
||||
@@ -433,6 +433,7 @@ mod display {
|
||||
ExprKind::Modify(v) => v.fmt(f),
|
||||
ExprKind::Binary(v) => v.fmt(f),
|
||||
ExprKind::Unary(v) => v.fmt(f),
|
||||
ExprKind::Cast(v) => v.fmt(f),
|
||||
ExprKind::Member(v) => v.fmt(f),
|
||||
ExprKind::Index(v) => v.fmt(f),
|
||||
ExprKind::Structor(v) => v.fmt(f),
|
||||
@@ -548,6 +549,13 @@ mod display {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Cast {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self { head, ty } = self;
|
||||
write!(f, "{head} as {ty}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Member {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self { head, kind } = self;
|
||||
@@ -764,6 +772,7 @@ mod convert {
|
||||
Modify => ExprKind::Modify,
|
||||
Binary => ExprKind::Binary,
|
||||
Unary => ExprKind::Unary,
|
||||
Cast => ExprKind::Cast,
|
||||
Member => ExprKind::Member,
|
||||
Index => ExprKind::Index,
|
||||
Path => ExprKind::Path,
|
||||
|
||||
@@ -276,6 +276,10 @@ pub trait Fold {
|
||||
fn fold_unary_kind(&mut self, kind: UnaryKind) -> UnaryKind {
|
||||
kind
|
||||
}
|
||||
fn fold_cast(&mut self, cast: Cast) -> Cast {
|
||||
let Cast { head, ty } = cast;
|
||||
Cast { head: Box::new(self.fold_expr_kind(*head)), ty: self.fold_ty(ty) }
|
||||
}
|
||||
fn fold_member(&mut self, m: Member) -> Member {
|
||||
let Member { head, kind } = m;
|
||||
Member { head: Box::new(self.fold_expr_kind(*head)), kind: self.fold_member_kind(kind) }
|
||||
@@ -535,6 +539,7 @@ pub fn or_fold_expr_kind<F: Fold + ?Sized>(folder: &mut F, kind: ExprKind) -> Ex
|
||||
ExprKind::Modify(m) => ExprKind::Modify(folder.fold_modify(m)),
|
||||
ExprKind::Binary(b) => ExprKind::Binary(folder.fold_binary(b)),
|
||||
ExprKind::Unary(u) => ExprKind::Unary(folder.fold_unary(u)),
|
||||
ExprKind::Cast(c) => ExprKind::Cast(folder.fold_cast(c)),
|
||||
ExprKind::Member(m) => ExprKind::Member(folder.fold_member(m)),
|
||||
ExprKind::Index(i) => ExprKind::Index(folder.fold_index(i)),
|
||||
ExprKind::Structor(s) => ExprKind::Structor(folder.fold_structor(s)),
|
||||
|
||||
@@ -238,6 +238,11 @@ pub trait Visit<'a>: Sized {
|
||||
self.visit_expr_kind(tail);
|
||||
}
|
||||
fn visit_unary_kind(&mut self, _kind: &'a UnaryKind) {}
|
||||
fn visit_cast(&mut self, cast: &'a Cast) {
|
||||
let Cast { head, ty } = cast;
|
||||
self.visit_expr_kind(head);
|
||||
self.visit_ty(ty);
|
||||
}
|
||||
fn visit_member(&mut self, m: &'a Member) {
|
||||
let Member { head, kind } = m;
|
||||
self.visit_expr_kind(head);
|
||||
@@ -456,6 +461,7 @@ pub fn or_visit_expr_kind<'a, V: Visit<'a>>(visitor: &mut V, e: &'a ExprKind) {
|
||||
ExprKind::Modify(m) => visitor.visit_modify(m),
|
||||
ExprKind::Binary(b) => visitor.visit_binary(b),
|
||||
ExprKind::Unary(u) => visitor.visit_unary(u),
|
||||
ExprKind::Cast(c) => visitor.visit_cast(c),
|
||||
ExprKind::Member(m) => visitor.visit_member(m),
|
||||
ExprKind::Index(i) => visitor.visit_index(i),
|
||||
ExprKind::Structor(s) => visitor.visit_structor(s),
|
||||
|
||||
Reference in New Issue
Block a user