ast: add gens for ty and impl, raw ptr types, make fn return value non-optional
This commit is contained in:
parent
6ba62ac1c4
commit
148ef34a01
@ -183,6 +183,7 @@ pub struct Variant {
|
|||||||
/// Sub-[items](Item) (associated functions, etc.) for a [Ty]
|
/// Sub-[items](Item) (associated functions, etc.) for a [Ty]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Impl {
|
pub struct Impl {
|
||||||
|
pub gens: Generics,
|
||||||
pub target: ImplKind,
|
pub target: ImplKind,
|
||||||
pub body: File,
|
pub body: File,
|
||||||
}
|
}
|
||||||
@ -216,6 +217,7 @@ pub enum UseTree {
|
|||||||
pub struct Ty {
|
pub struct Ty {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub kind: TyKind,
|
pub kind: TyKind,
|
||||||
|
pub gens: Generics,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about a [Ty]pe expression
|
/// Information about a [Ty]pe expression
|
||||||
@ -229,26 +231,27 @@ pub enum TyKind {
|
|||||||
Slice(TySlice),
|
Slice(TySlice),
|
||||||
Tuple(TyTuple),
|
Tuple(TyTuple),
|
||||||
Ref(TyRef),
|
Ref(TyRef),
|
||||||
|
Ptr(TyPtr),
|
||||||
Fn(TyFn),
|
Fn(TyFn),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An array of [`T`](Ty)
|
/// An array of [`T`](Ty)
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct TyArray {
|
pub struct TyArray {
|
||||||
pub ty: Box<TyKind>,
|
pub ty: Box<Ty>,
|
||||||
pub count: usize,
|
pub count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [Ty]pe slice expression: `[T]`
|
/// A [Ty]pe slice expression: `[T]`
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct TySlice {
|
pub struct TySlice {
|
||||||
pub ty: Box<TyKind>,
|
pub ty: Box<Ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A tuple of [Ty]pes
|
/// A tuple of [Ty]pes
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct TyTuple {
|
pub struct TyTuple {
|
||||||
pub types: Vec<TyKind>,
|
pub types: Vec<Ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [Ty]pe-reference expression as (number of `&`, [Path])
|
/// A [Ty]pe-reference expression as (number of `&`, [Path])
|
||||||
@ -259,11 +262,17 @@ pub struct TyRef {
|
|||||||
pub to: Box<Ty>,
|
pub to: Box<Ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [Ty]pe-reference expression as (number of `&`, [Path])
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub struct TyPtr {
|
||||||
|
pub to: Box<Ty>,
|
||||||
|
}
|
||||||
|
|
||||||
/// The args and return value for a function pointer [Ty]pe
|
/// The args and return value for a function pointer [Ty]pe
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct TyFn {
|
pub struct TyFn {
|
||||||
pub args: Box<TyKind>,
|
pub args: Box<Ty>,
|
||||||
pub rety: Option<Box<Ty>>,
|
pub rety: Box<Ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A path to an [Item] in the [Module] tree
|
/// A path to an [Item] in the [Module] tree
|
||||||
@ -274,7 +283,7 @@ pub struct Path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A single component of a [Path]
|
/// A single component of a [Path]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum PathPart {
|
pub enum PathPart {
|
||||||
SuperKw,
|
SuperKw,
|
||||||
SelfTy,
|
SelfTy,
|
||||||
@ -411,7 +420,7 @@ pub struct Array {
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ArrayRep {
|
pub struct ArrayRep {
|
||||||
pub value: Box<Expr>,
|
pub value: Box<Expr>,
|
||||||
pub repeat: usize,
|
pub repeat: Box<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An address-of expression: `&` `mut`? [`Expr`]
|
/// An address-of expression: `&` `mut`? [`Expr`]
|
||||||
|
@ -43,6 +43,7 @@ impl_from! {
|
|||||||
Path => TyKind::Path,
|
Path => TyKind::Path,
|
||||||
TyTuple => TyKind::Tuple,
|
TyTuple => TyKind::Tuple,
|
||||||
TyRef => TyKind::Ref,
|
TyRef => TyKind::Ref,
|
||||||
|
TyPtr => TyKind::Ptr,
|
||||||
TyFn => TyKind::Fn,
|
TyFn => TyKind::Fn,
|
||||||
}
|
}
|
||||||
impl From for StmtKind {
|
impl From for StmtKind {
|
||||||
|
@ -163,7 +163,7 @@ impl Display for Module {
|
|||||||
impl Display for Function {
|
impl Display for Function {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { name, gens, sign: sign @ TyFn { args, rety }, bind, body } = self;
|
let Self { name, gens, sign: sign @ TyFn { args, rety }, bind, body } = self;
|
||||||
let types = match **args {
|
let types = match args.kind {
|
||||||
TyKind::Tuple(TyTuple { ref types }) => types.as_slice(),
|
TyKind::Tuple(TyTuple { ref types }) => types.as_slice(),
|
||||||
TyKind::Empty => Default::default(),
|
TyKind::Empty => Default::default(),
|
||||||
_ => {
|
_ => {
|
||||||
@ -191,9 +191,10 @@ impl Display for Function {
|
|||||||
write!(f, "{arg}: {ty}")?;
|
write!(f, "{arg}: {ty}")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(rety) = rety {
|
if TyKind::Empty != rety.kind {
|
||||||
write!(f, " -> {rety}")?;
|
write!(f, " -> {rety}")?
|
||||||
}
|
}
|
||||||
|
|
||||||
match body {
|
match body {
|
||||||
Some(body) => write!(f, " {body}"),
|
Some(body) => write!(f, " {body}"),
|
||||||
None => ';'.fmt(f),
|
None => ';'.fmt(f),
|
||||||
@ -246,8 +247,8 @@ impl Display for Variant {
|
|||||||
|
|
||||||
impl Display for Impl {
|
impl Display for Impl {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { target, body } = self;
|
let Self { gens, target, body } = self;
|
||||||
write!(f, "impl {target} ")?;
|
write!(f, "impl{gens} {target} ")?;
|
||||||
write!(f.delimit(BRACES), "{body}")
|
write!(f.delimit(BRACES), "{body}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,7 +286,8 @@ impl Display for UseTree {
|
|||||||
|
|
||||||
impl Display for Ty {
|
impl Display for Ty {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.kind.fmt(f)
|
let Self { span: _, kind, gens } = self;
|
||||||
|
write!(f, "{kind}{gens}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,6 +302,7 @@ impl Display for TyKind {
|
|||||||
TyKind::Slice(v) => v.fmt(f),
|
TyKind::Slice(v) => v.fmt(f),
|
||||||
TyKind::Tuple(v) => v.fmt(f),
|
TyKind::Tuple(v) => v.fmt(f),
|
||||||
TyKind::Ref(v) => v.fmt(f),
|
TyKind::Ref(v) => v.fmt(f),
|
||||||
|
TyKind::Ptr(v) => v.fmt(f),
|
||||||
TyKind::Fn(v) => v.fmt(f),
|
TyKind::Fn(v) => v.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,14 +338,21 @@ impl Display for TyRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for TyPtr {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let Self { to } = self;
|
||||||
|
write!(f, "*{to}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for TyFn {
|
impl Display for TyFn {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { args, rety } = self;
|
let Self { args, rety } = self;
|
||||||
write!(f, "fn {args}")?;
|
write!(f, "fn {args}")?;
|
||||||
match rety {
|
if TyKind::Empty != rety.kind {
|
||||||
Some(v) => write!(f, " -> {v}"),
|
write!(f, " -> {rety}")?;
|
||||||
None => Ok(()),
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,8 +147,8 @@ impl WeightOf for Variant {
|
|||||||
|
|
||||||
impl WeightOf for Impl {
|
impl WeightOf for Impl {
|
||||||
fn weight_of(&self) -> usize {
|
fn weight_of(&self) -> usize {
|
||||||
let Self { target, body } = self;
|
let Self { gens, target, body } = self;
|
||||||
target.weight_of() + body.weight_of()
|
gens.weight_of() + target.weight_of() + body.weight_of()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,8 +184,8 @@ impl WeightOf for UseTree {
|
|||||||
|
|
||||||
impl WeightOf for Ty {
|
impl WeightOf for Ty {
|
||||||
fn weight_of(&self) -> usize {
|
fn weight_of(&self) -> usize {
|
||||||
let Self { span, kind } = self;
|
let Self { span, kind, gens } = self;
|
||||||
span.weight_of() + kind.weight_of()
|
span.weight_of() + kind.weight_of() + gens.weight_of()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +198,7 @@ impl WeightOf for TyKind {
|
|||||||
TyKind::Slice(v) => v.weight_of(),
|
TyKind::Slice(v) => v.weight_of(),
|
||||||
TyKind::Tuple(v) => v.weight_of(),
|
TyKind::Tuple(v) => v.weight_of(),
|
||||||
TyKind::Ref(v) => v.weight_of(),
|
TyKind::Ref(v) => v.weight_of(),
|
||||||
|
TyKind::Ptr(v) => v.weight_of(),
|
||||||
TyKind::Fn(v) => v.weight_of(),
|
TyKind::Fn(v) => v.weight_of(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,6 +232,13 @@ impl WeightOf for TyRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WeightOf for TyPtr {
|
||||||
|
fn weight_of(&self) -> usize {
|
||||||
|
let Self { to } = self;
|
||||||
|
to.weight_of()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl WeightOf for TyFn {
|
impl WeightOf for TyFn {
|
||||||
fn weight_of(&self) -> usize {
|
fn weight_of(&self) -> usize {
|
||||||
let Self { args, rety } = self;
|
let Self { args, rety } = self;
|
||||||
|
@ -156,8 +156,12 @@ pub trait Fold {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn fold_impl(&mut self, i: Impl) -> Impl {
|
fn fold_impl(&mut self, i: Impl) -> Impl {
|
||||||
let Impl { target, body } = i;
|
let Impl { gens, target, body } = i;
|
||||||
Impl { target: self.fold_impl_kind(target), body: self.fold_file(body) }
|
Impl {
|
||||||
|
gens: self.fold_generics(gens),
|
||||||
|
target: self.fold_impl_kind(target),
|
||||||
|
body: self.fold_file(body),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn fold_impl_kind(&mut self, kind: ImplKind) -> ImplKind {
|
fn fold_impl_kind(&mut self, kind: ImplKind) -> ImplKind {
|
||||||
or_fold_impl_kind(self, kind)
|
or_fold_impl_kind(self, kind)
|
||||||
@ -170,39 +174,39 @@ pub trait Fold {
|
|||||||
or_fold_use_tree(self, tree)
|
or_fold_use_tree(self, tree)
|
||||||
}
|
}
|
||||||
fn fold_ty(&mut self, t: Ty) -> Ty {
|
fn fold_ty(&mut self, t: Ty) -> Ty {
|
||||||
let Ty { span, kind } = t;
|
let Ty { span, kind, gens } = t;
|
||||||
Ty { span: self.fold_span(span), kind: self.fold_ty_kind(kind) }
|
Ty {
|
||||||
|
span: self.fold_span(span),
|
||||||
|
kind: self.fold_ty_kind(kind),
|
||||||
|
gens: self.fold_generics(gens),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn fold_ty_kind(&mut self, kind: TyKind) -> TyKind {
|
fn fold_ty_kind(&mut self, kind: TyKind) -> TyKind {
|
||||||
or_fold_ty_kind(self, kind)
|
or_fold_ty_kind(self, kind)
|
||||||
}
|
}
|
||||||
fn fold_ty_array(&mut self, a: TyArray) -> TyArray {
|
fn fold_ty_array(&mut self, a: TyArray) -> TyArray {
|
||||||
let TyArray { ty, count } = a;
|
let TyArray { ty, count } = a;
|
||||||
TyArray { ty: Box::new(self.fold_ty_kind(*ty)), count }
|
TyArray { ty: Box::new(self.fold_ty(*ty)), count }
|
||||||
}
|
}
|
||||||
fn fold_ty_slice(&mut self, s: TySlice) -> TySlice {
|
fn fold_ty_slice(&mut self, s: TySlice) -> TySlice {
|
||||||
let TySlice { ty } = s;
|
let TySlice { ty } = s;
|
||||||
TySlice { ty: Box::new(self.fold_ty_kind(*ty)) }
|
TySlice { ty: Box::new(self.fold_ty(*ty)) }
|
||||||
}
|
}
|
||||||
fn fold_ty_tuple(&mut self, t: TyTuple) -> TyTuple {
|
fn fold_ty_tuple(&mut self, t: TyTuple) -> TyTuple {
|
||||||
let TyTuple { types } = t;
|
let TyTuple { types } = t;
|
||||||
TyTuple {
|
TyTuple { types: types.into_iter().map(|kind| self.fold_ty(kind)).collect() }
|
||||||
types: types
|
|
||||||
.into_iter()
|
|
||||||
.map(|kind| self.fold_ty_kind(kind))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn fold_ty_ref(&mut self, t: TyRef) -> TyRef {
|
fn fold_ty_ref(&mut self, t: TyRef) -> TyRef {
|
||||||
let TyRef { mutable, count, to } = t;
|
let TyRef { mutable, count, to } = t;
|
||||||
TyRef { mutable: self.fold_mutability(mutable), count, to: Box::new(self.fold_ty(*to)) }
|
TyRef { mutable: self.fold_mutability(mutable), count, to: Box::new(self.fold_ty(*to)) }
|
||||||
}
|
}
|
||||||
|
fn fold_ty_ptr(&mut self, t: TyPtr) -> TyPtr {
|
||||||
|
let TyPtr { to } = t;
|
||||||
|
TyPtr { to: Box::new(self.fold_ty(*to)) }
|
||||||
|
}
|
||||||
fn fold_ty_fn(&mut self, t: TyFn) -> TyFn {
|
fn fold_ty_fn(&mut self, t: TyFn) -> TyFn {
|
||||||
let TyFn { args, rety } = t;
|
let TyFn { args, rety } = t;
|
||||||
TyFn {
|
TyFn { args: Box::new(self.fold_ty(*args)), rety: Box::new(self.fold_ty(*rety)) }
|
||||||
args: Box::new(self.fold_ty_kind(*args)),
|
|
||||||
rety: rety.map(|t| Box::new(self.fold_ty(*t))),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn fold_path(&mut self, p: Path) -> Path {
|
fn fold_path(&mut self, p: Path) -> Path {
|
||||||
let Path { absolute, parts } = p;
|
let Path { absolute, parts } = p;
|
||||||
@ -534,6 +538,7 @@ pub fn or_fold_ty_kind<F: Fold + ?Sized>(folder: &mut F, kind: TyKind) -> TyKind
|
|||||||
TyKind::Slice(s) => TyKind::Slice(folder.fold_ty_slice(s)),
|
TyKind::Slice(s) => TyKind::Slice(folder.fold_ty_slice(s)),
|
||||||
TyKind::Tuple(t) => TyKind::Tuple(folder.fold_ty_tuple(t)),
|
TyKind::Tuple(t) => TyKind::Tuple(folder.fold_ty_tuple(t)),
|
||||||
TyKind::Ref(t) => TyKind::Ref(folder.fold_ty_ref(t)),
|
TyKind::Ref(t) => TyKind::Ref(folder.fold_ty_ref(t)),
|
||||||
|
TyKind::Ptr(t) => TyKind::Ptr(folder.fold_ty_ptr(t)),
|
||||||
TyKind::Fn(t) => TyKind::Fn(folder.fold_ty_fn(t)),
|
TyKind::Fn(t) => TyKind::Fn(folder.fold_ty_fn(t)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,9 @@ pub trait Visit<'a>: Sized {
|
|||||||
fn visit_ty_ref(&mut self, value: &'a TyRef) {
|
fn visit_ty_ref(&mut self, value: &'a TyRef) {
|
||||||
value.children(self)
|
value.children(self)
|
||||||
}
|
}
|
||||||
|
fn visit_ty_ptr(&mut self, value: &'a TyPtr) {
|
||||||
|
value.children(self)
|
||||||
|
}
|
||||||
fn visit_ty_fn(&mut self, value: &'a TyFn) {
|
fn visit_ty_fn(&mut self, value: &'a TyFn) {
|
||||||
value.children(self)
|
value.children(self)
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,8 @@ impl Walk for Impl {
|
|||||||
v.visit_impl(self);
|
v.visit_impl(self);
|
||||||
}
|
}
|
||||||
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||||
let Impl { target, body } = self;
|
let Impl { gens, target, body } = self;
|
||||||
|
gens.visit_in(v);
|
||||||
target.visit_in(v);
|
target.visit_in(v);
|
||||||
body.visit_in(v);
|
body.visit_in(v);
|
||||||
}
|
}
|
||||||
@ -354,9 +355,10 @@ impl Walk for Ty {
|
|||||||
v.visit_ty(self);
|
v.visit_ty(self);
|
||||||
}
|
}
|
||||||
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||||
let Ty { span, kind } = self;
|
let Ty { span, kind, gens } = self;
|
||||||
span.visit_in(v);
|
span.visit_in(v);
|
||||||
kind.visit_in(v);
|
kind.visit_in(v);
|
||||||
|
gens.visit_in(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Walk for TyKind {
|
impl Walk for TyKind {
|
||||||
@ -374,6 +376,7 @@ impl Walk for TyKind {
|
|||||||
TyKind::Slice(value) => value.visit_in(v),
|
TyKind::Slice(value) => value.visit_in(v),
|
||||||
TyKind::Tuple(value) => value.visit_in(v),
|
TyKind::Tuple(value) => value.visit_in(v),
|
||||||
TyKind::Ref(value) => value.visit_in(v),
|
TyKind::Ref(value) => value.visit_in(v),
|
||||||
|
TyKind::Ptr(value) => value.visit_in(v),
|
||||||
TyKind::Fn(value) => value.visit_in(v),
|
TyKind::Fn(value) => value.visit_in(v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,6 +423,16 @@ impl Walk for TyRef {
|
|||||||
to.children(v);
|
to.children(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Walk for TyPtr {
|
||||||
|
#[inline]
|
||||||
|
fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||||
|
v.visit_ty_ptr(self);
|
||||||
|
}
|
||||||
|
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||||
|
let TyPtr { to } = self;
|
||||||
|
to.children(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
impl Walk for TyFn {
|
impl Walk for TyFn {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||||
@ -852,10 +865,10 @@ impl Walk for For {
|
|||||||
}
|
}
|
||||||
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||||
let For { bind, cond, pass, fail } = self;
|
let For { bind, cond, pass, fail } = self;
|
||||||
bind.visit_in(v);
|
|
||||||
cond.visit_in(v);
|
cond.visit_in(v);
|
||||||
pass.visit_in(v);
|
|
||||||
fail.visit_in(v);
|
fail.visit_in(v);
|
||||||
|
bind.visit_in(v);
|
||||||
|
pass.visit_in(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Walk for Else {
|
impl Walk for Else {
|
||||||
|
@ -46,7 +46,7 @@ impl Fold for NormalizePaths {
|
|||||||
|
|
||||||
if !absolute {
|
if !absolute {
|
||||||
for segment in self.path.parts.iter().rev() {
|
for segment in self.path.parts.iter().rev() {
|
||||||
tree = UseTree::Path(segment.clone(), Box::new(tree))
|
tree = UseTree::Path(*segment, Box::new(tree))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +191,17 @@ macro path_like() {
|
|||||||
TokenKind::Super | TokenKind::SelfTy | TokenKind::Identifier | TokenKind::ColonColon
|
TokenKind::Super | TokenKind::SelfTy | TokenKind::Identifier | TokenKind::ColonColon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Spanned<T> = (T, Span);
|
||||||
|
|
||||||
|
impl<'t, T: Parse<'t>> Parse<'t> for Spanned<T> {
|
||||||
|
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
|
let head = p.loc();
|
||||||
|
let body = p.parse()?;
|
||||||
|
let tail = p.loc();
|
||||||
|
Ok((body, Span(head, tail)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Parse<'t>: Sized {
|
pub trait Parse<'t>: Sized {
|
||||||
/// Parses a Self from the provided [Parser]
|
/// Parses a Self from the provided [Parser]
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self>;
|
fn parse(p: &mut Parser<'t>) -> PResult<Self>;
|
||||||
@ -343,8 +354,8 @@ impl Parse<'_> for ItemKind {
|
|||||||
impl Parse<'_> for Generics {
|
impl Parse<'_> for Generics {
|
||||||
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
||||||
const P: Parsing = Parsing::Generics;
|
const P: Parsing = Parsing::Generics;
|
||||||
let vars = match p.peek_kind(P)? {
|
let vars = match p.peek_kind(P) {
|
||||||
TokenKind::Lt => delim(
|
Ok(TokenKind::Lt) => delim(
|
||||||
sep(Sym::parse, TokenKind::Comma, TokenKind::Gt, P),
|
sep(Sym::parse, TokenKind::Comma, TokenKind::Gt, P),
|
||||||
(TokenKind::Lt, TokenKind::Gt),
|
(TokenKind::Lt, TokenKind::Gt),
|
||||||
P,
|
P,
|
||||||
@ -451,17 +462,16 @@ impl Parse<'_> for Function {
|
|||||||
|
|
||||||
let name = Sym::parse(p)?;
|
let name = Sym::parse(p)?;
|
||||||
let gens = Generics::parse(p)?;
|
let gens = Generics::parse(p)?;
|
||||||
let (bind, types) = delim(FnSig::parse, PARENS, P)(p)?;
|
let ((bind, types), span) = delim(Spanned::<FnSig>::parse, PARENS, P)(p)?;
|
||||||
let sign = TyFn {
|
let sign = TyFn {
|
||||||
args: Box::new(match types.len() {
|
args: Box::new(match types.len() {
|
||||||
0 => TyKind::Empty,
|
0 => Ty { span, kind: TyKind::Empty, gens: Default::default() },
|
||||||
_ => TyKind::Tuple(TyTuple { types }),
|
_ => Ty { span, kind: TyKind::Tuple(TyTuple { types }), gens: Default::default() },
|
||||||
|
}),
|
||||||
|
rety: Box::new(match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
|
||||||
|
Ok(_) => Ty::parse(p)?,
|
||||||
|
Err(_) => Ty { span, kind: TyKind::Empty, gens: Generics { vars: vec![] } },
|
||||||
}),
|
}),
|
||||||
rety: Ok(match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
|
|
||||||
Ok(_) => Some(Ty::parse(p)?),
|
|
||||||
Err(_) => None,
|
|
||||||
})?
|
|
||||||
.map(Box::new),
|
|
||||||
};
|
};
|
||||||
Ok(Function {
|
Ok(Function {
|
||||||
name,
|
name,
|
||||||
@ -479,7 +489,7 @@ impl Parse<'_> for Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type FnSig = (Pattern, Vec<TyKind>);
|
type FnSig = (Pattern, Vec<Ty>);
|
||||||
|
|
||||||
impl Parse<'_> for FnSig {
|
impl Parse<'_> for FnSig {
|
||||||
/// Parses the parameter list of a Function
|
/// Parses the parameter list of a Function
|
||||||
@ -498,17 +508,17 @@ impl Parse<'_> for FnSig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type TypedParam = (Pattern, TyKind);
|
type TypedParam = (Pattern, Ty);
|
||||||
|
|
||||||
impl Parse<'_> for TypedParam {
|
impl Parse<'_> for TypedParam {
|
||||||
/// Parses a single function parameter
|
/// Parses a single function parameter
|
||||||
fn parse(p: &mut Parser) -> PResult<(Pattern, TyKind)> {
|
fn parse(p: &mut Parser) -> PResult<(Pattern, Ty)> {
|
||||||
Ok((
|
Ok((
|
||||||
Pattern::parse(p)?,
|
Pattern::parse(p)?,
|
||||||
if p.match_type(TokenKind::Colon, Parsing::Param).is_ok() {
|
if p.match_type(TokenKind::Colon, Parsing::Param).is_ok() {
|
||||||
TyKind::parse(p)?
|
Ty::parse(p)?
|
||||||
} else {
|
} else {
|
||||||
TyKind::Infer
|
Ty { span: Span::dummy(), kind: TyKind::Infer, gens: Default::default() }
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -604,7 +614,11 @@ impl Parse<'_> for Impl {
|
|||||||
const P: Parsing = Parsing::Impl;
|
const P: Parsing = Parsing::Impl;
|
||||||
p.match_type(TokenKind::Impl, P)?;
|
p.match_type(TokenKind::Impl, P)?;
|
||||||
|
|
||||||
Ok(Impl { target: ImplKind::parse(p)?, body: delim(File::parse, CURLIES, P)(p)? })
|
Ok(Impl {
|
||||||
|
gens: Generics::parse(p)?,
|
||||||
|
target: ImplKind::parse(p)?,
|
||||||
|
body: delim(File::parse, CURLIES, P)(p)?,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,8 +696,9 @@ impl Parse<'_> for Ty {
|
|||||||
///
|
///
|
||||||
/// See also: [TyKind::parse]
|
/// See also: [TyKind::parse]
|
||||||
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
||||||
let start = p.loc();
|
let (kind, span) = p.parse()?;
|
||||||
Ok(Ty { kind: TyKind::parse(p)?, span: Span(start, p.loc()) })
|
let gens = p.parse()?;
|
||||||
|
Ok(Ty { span, kind, gens })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,9 +714,10 @@ impl Parse<'_> for TyKind {
|
|||||||
TyKind::Never
|
TyKind::Never
|
||||||
}
|
}
|
||||||
TokenKind::Amp | TokenKind::AmpAmp => TyRef::parse(p)?.into(),
|
TokenKind::Amp | TokenKind::AmpAmp => TyRef::parse(p)?.into(),
|
||||||
|
TokenKind::Star => TyPtr::parse(p)?.into(),
|
||||||
TokenKind::LBrack => {
|
TokenKind::LBrack => {
|
||||||
p.match_type(BRACKETS.0, Parsing::TySlice)?;
|
p.match_type(BRACKETS.0, Parsing::TySlice)?;
|
||||||
let ty = TyKind::parse(p)?;
|
let ty = p.parse()?;
|
||||||
let (out, kind) = match p.match_type(TokenKind::Semi, Parsing::TyArray).is_ok() {
|
let (out, kind) = match p.match_type(TokenKind::Semi, Parsing::TyArray).is_ok() {
|
||||||
true => {
|
true => {
|
||||||
let literal = p.match_type(TokenKind::Literal, Parsing::TyArray)?;
|
let literal = p.match_type(TokenKind::Literal, Parsing::TyArray)?;
|
||||||
@ -709,14 +725,11 @@ impl Parse<'_> for TyKind {
|
|||||||
Err(p.error(Unexpected(TokenKind::Literal), Parsing::TyArray))?
|
Err(p.error(Unexpected(TokenKind::Literal), Parsing::TyArray))?
|
||||||
};
|
};
|
||||||
(
|
(
|
||||||
TyKind::Array(TyArray { ty: Box::new(ty), count: count as _ }),
|
TyKind::Array(TyArray { ty, count: count as _ }),
|
||||||
Parsing::TyArray,
|
Parsing::TyArray,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
false => (
|
false => (TyKind::Slice(TySlice { ty }), Parsing::TySlice),
|
||||||
TyKind::Slice(TySlice { ty: Box::new(ty) }),
|
|
||||||
Parsing::TySlice,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
p.match_type(BRACKETS.1, kind)?;
|
p.match_type(BRACKETS.1, kind)?;
|
||||||
out
|
out
|
||||||
@ -748,9 +761,7 @@ impl Parse<'_> for TyTuple {
|
|||||||
/// [TyTuple] = `(` ([Ty] `,`)* [Ty]? `)`
|
/// [TyTuple] = `(` ([Ty] `,`)* [Ty]? `)`
|
||||||
fn parse(p: &mut Parser) -> PResult<TyTuple> {
|
fn parse(p: &mut Parser) -> PResult<TyTuple> {
|
||||||
const P: Parsing = Parsing::TyTuple;
|
const P: Parsing = Parsing::TyTuple;
|
||||||
Ok(TyTuple {
|
Ok(TyTuple { types: delim(sep(Ty::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)? })
|
||||||
types: delim(sep(TyKind::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,24 +782,36 @@ impl Parse<'_> for TyRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Parse<'_> for TyPtr {
|
||||||
|
/// [TyPtr] = `*` [Ty]
|
||||||
|
fn parse(p: &mut Parser) -> PResult<TyPtr> {
|
||||||
|
const P: Parsing = Parsing::TyRef;
|
||||||
|
p.match_type(TokenKind::Star, P)?;
|
||||||
|
Ok(TyPtr { to: p.parse()? })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Parse<'_> for TyFn {
|
impl Parse<'_> for TyFn {
|
||||||
/// [TyFn] = `fn` [TyTuple] (-> [Ty])?
|
/// [TyFn] = `fn` [TyTuple] (-> [Ty])?
|
||||||
fn parse(p: &mut Parser) -> PResult<TyFn> {
|
fn parse(p: &mut Parser) -> PResult<TyFn> {
|
||||||
const P: Parsing = Parsing::TyFn;
|
const P: Parsing = Parsing::TyFn;
|
||||||
p.match_type(TokenKind::Fn, P)?;
|
p.match_type(TokenKind::Fn, P)?;
|
||||||
|
|
||||||
let args = delim(sep(TyKind::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)?;
|
let head = p.loc();
|
||||||
|
let args = delim(sep(Ty::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)?;
|
||||||
|
let span = Span(head, p.loc());
|
||||||
|
|
||||||
Ok(TyFn {
|
Ok(TyFn {
|
||||||
args: Box::new(match args {
|
args: Box::new(match args {
|
||||||
t if t.is_empty() => TyKind::Empty,
|
t if t.is_empty() => Ty { kind: TyKind::Empty, span, gens: Default::default() },
|
||||||
types => TyKind::Tuple(TyTuple { types }),
|
types => {
|
||||||
|
Ty { kind: TyKind::Tuple(TyTuple { types }), span, gens: Default::default() }
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
rety: Box::new(match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
|
||||||
|
Ok(_) => Ty::parse(p)?,
|
||||||
|
Err(_) => Ty { span, kind: TyKind::Empty, gens: Generics { vars: vec![] } },
|
||||||
}),
|
}),
|
||||||
rety: match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
|
|
||||||
Ok(_) => Some(Ty::parse(p)?),
|
|
||||||
Err(_) => None,
|
|
||||||
}
|
|
||||||
.map(Into::into),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -847,15 +870,12 @@ impl Parse<'_> for Stmt {
|
|||||||
///
|
///
|
||||||
/// See also: [StmtKind::parse]
|
/// See also: [StmtKind::parse]
|
||||||
fn parse(p: &mut Parser) -> PResult<Stmt> {
|
fn parse(p: &mut Parser) -> PResult<Stmt> {
|
||||||
let start = p.loc();
|
let (kind, span) = Spanned::<StmtKind>::parse(p)?;
|
||||||
Ok(Stmt {
|
let semi = match p.match_type(TokenKind::Semi, Parsing::Stmt) {
|
||||||
kind: StmtKind::parse(p)?,
|
Ok(_) => Semi::Terminated,
|
||||||
semi: match p.match_type(TokenKind::Semi, Parsing::Stmt) {
|
_ => Semi::Unterminated,
|
||||||
Ok(_) => Semi::Terminated,
|
};
|
||||||
_ => Semi::Unterminated,
|
Ok(Stmt { span, kind, semi })
|
||||||
},
|
|
||||||
span: Span(start, p.loc()),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1132,7 +1152,7 @@ impl Parse<'_> for Pattern {
|
|||||||
// Name, Path, Struct, TupleStruct
|
// Name, Path, Struct, TupleStruct
|
||||||
TokenKind::Identifier => pathpattern(p)?,
|
TokenKind::Identifier => pathpattern(p)?,
|
||||||
// Literal
|
// Literal
|
||||||
TokenKind::Literal => Pattern::Literal(p.parse()?),
|
TokenKind::True | TokenKind::False | TokenKind::Literal => Pattern::Literal(p.parse()?),
|
||||||
// Rest
|
// Rest
|
||||||
TokenKind::DotDot => {
|
TokenKind::DotDot => {
|
||||||
p.consume_peeked();
|
p.consume_peeked();
|
||||||
|
@ -204,13 +204,7 @@ fn exprkind_array_rep(p: &mut Parser) -> PResult<ExprKind> {
|
|||||||
value: first.into(),
|
value: first.into(),
|
||||||
repeat: {
|
repeat: {
|
||||||
p.consume_peeked();
|
p.consume_peeked();
|
||||||
let value = p.match_type(TokenKind::Literal, Parsing::ArrayRep)?;
|
p.parse()?
|
||||||
match value.data() {
|
|
||||||
TokenData::Integer(size) => *size as usize,
|
|
||||||
_ => {
|
|
||||||
Err(p.error(ErrorKind::Unexpected(TokenKind::Literal), Parsing::ArrayRep))?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -273,7 +273,7 @@ pub mod clangify {
|
|||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { name, gens: _, sign, bind, body } = self;
|
let Self { name, gens: _, sign, bind, body } = self;
|
||||||
let TyFn { args, rety } = sign;
|
let TyFn { args, rety } = sign;
|
||||||
let types = match args.as_ref() {
|
let types = match &args.kind {
|
||||||
TyKind::Tuple(TyTuple { types }) => types.as_slice(),
|
TyKind::Tuple(TyTuple { types }) => types.as_slice(),
|
||||||
TyKind::Empty => &[],
|
TyKind::Empty => &[],
|
||||||
_ => panic!("Unsupported function args: {args}"),
|
_ => panic!("Unsupported function args: {args}"),
|
||||||
@ -282,13 +282,7 @@ pub mod clangify {
|
|||||||
Pattern::Tuple(tup) => tup.as_slice(),
|
Pattern::Tuple(tup) => tup.as_slice(),
|
||||||
_ => panic!("Unsupported function binders: {args}"),
|
_ => panic!("Unsupported function binders: {args}"),
|
||||||
};
|
};
|
||||||
match rety {
|
y.p(rety).p(" ").p(name).p(" (");
|
||||||
Some(ty) => y.p(ty),
|
|
||||||
None => y.p("void"),
|
|
||||||
}
|
|
||||||
.p(" ")
|
|
||||||
.p(name)
|
|
||||||
.p(" (");
|
|
||||||
for (idx, (bind, ty)) in bind.iter().zip(types).enumerate() {
|
for (idx, (bind, ty)) in bind.iter().zip(types).enumerate() {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
y.p(", ");
|
y.p(", ");
|
||||||
@ -347,8 +341,8 @@ pub mod clangify {
|
|||||||
}
|
}
|
||||||
impl CLangify for Impl {
|
impl CLangify for Impl {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { target, body } = self;
|
let Self { gens, target, body } = self;
|
||||||
y.nest("/* TODO: impl ").p(target).p(" { */ ");
|
y.nest("/* TODO: impl ").p(gens).p(target).p(" { */ ");
|
||||||
y.p(body);
|
y.p(body);
|
||||||
y.p("/* } // impl ").p(target).p(" */ ");
|
y.p("/* } // impl ").p(target).p(" */ ");
|
||||||
}
|
}
|
||||||
@ -477,7 +471,7 @@ pub mod clangify {
|
|||||||
}
|
}
|
||||||
TyKind::Fn(TyFn { args, rety }) => {
|
TyKind::Fn(TyFn { args, rety }) => {
|
||||||
y.nest("(").p(rety).p(" *").p(mutable).p(name).p(")(");
|
y.nest("(").p(rety).p(" *").p(mutable).p(name).p(")(");
|
||||||
match args.as_ref() {
|
match &args.kind {
|
||||||
TyKind::Empty => {}
|
TyKind::Empty => {}
|
||||||
TyKind::Tuple(TyTuple { types }) => {
|
TyKind::Tuple(TyTuple { types }) => {
|
||||||
for (idx, ty) in types.iter().enumerate() {
|
for (idx, ty) in types.iter().enumerate() {
|
||||||
@ -688,14 +682,14 @@ pub mod clangify {
|
|||||||
impl CLangify for ArrayRep {
|
impl CLangify for ArrayRep {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { value, repeat } = self;
|
let Self { value, repeat } = self;
|
||||||
|
let ExprKind::Literal(Literal::Int(repeat)) = &repeat.kind else {
|
||||||
|
eprintln!("Constant needs folding: {repeat}");
|
||||||
|
return;
|
||||||
|
};
|
||||||
{
|
{
|
||||||
let mut y = y.nest("{");
|
let mut y = y.nest("{");
|
||||||
y.endl();
|
for _ in 0..*repeat {
|
||||||
for idx in 0..*repeat {
|
y.endl().p(value).p(",");
|
||||||
if idx > 0 {
|
|
||||||
y.p(", ");
|
|
||||||
}
|
|
||||||
y.p(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
y.endl().p("}");
|
y.endl().p("}");
|
||||||
@ -797,7 +791,7 @@ pub mod clangify {
|
|||||||
}
|
}
|
||||||
impl CLangify for Ty {
|
impl CLangify for Ty {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { span: _, kind } = self;
|
let Self { span: _, kind, gens: _ } = self;
|
||||||
y.p(kind);
|
y.p(kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -806,10 +800,11 @@ pub mod clangify {
|
|||||||
match self {
|
match self {
|
||||||
TyKind::Never => y.p("Never"),
|
TyKind::Never => y.p("Never"),
|
||||||
TyKind::Empty => y.p("Empty"),
|
TyKind::Empty => y.p("Empty"),
|
||||||
TyKind::Infer => y.p("Any"),
|
TyKind::Infer => y.p("auto"),
|
||||||
TyKind::Path(t) => y.p(t),
|
TyKind::Path(t) => y.p(t),
|
||||||
TyKind::Tuple(t) => y.p(t),
|
TyKind::Tuple(t) => y.p(t),
|
||||||
TyKind::Ref(t) => y.p(t),
|
TyKind::Ref(t) => y.p(t),
|
||||||
|
TyKind::Ptr(t) => y.p(t),
|
||||||
TyKind::Fn(t) => y.p(t),
|
TyKind::Fn(t) => y.p(t),
|
||||||
TyKind::Slice(t) => y.p(t),
|
TyKind::Slice(t) => y.p(t),
|
||||||
TyKind::Array(t) => y.p(t),
|
TyKind::Array(t) => y.p(t),
|
||||||
@ -873,12 +868,18 @@ pub mod clangify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl CLangify for TyPtr {
|
||||||
|
fn print(&self, y: &mut CLangifier) {
|
||||||
|
let Self { to } = self;
|
||||||
|
y.p(to).p("*");
|
||||||
|
}
|
||||||
|
}
|
||||||
impl CLangify for TyFn {
|
impl CLangify for TyFn {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { args, rety } = self;
|
let Self { args, rety } = self;
|
||||||
// TODO: function pointer syntax
|
// TODO: function pointer syntax
|
||||||
y.nest("(").p(rety).p(" *)(");
|
y.nest("(").p(rety).p(" *)(");
|
||||||
match args.as_ref() {
|
match &args.kind {
|
||||||
TyKind::Empty => y,
|
TyKind::Empty => y,
|
||||||
TyKind::Tuple(TyTuple { types }) => {
|
TyKind::Tuple(TyTuple { types }) => {
|
||||||
for (idx, ty) in types.iter().enumerate() {
|
for (idx, ty) in types.iter().enumerate() {
|
||||||
|
@ -83,7 +83,7 @@ pub mod yamler {
|
|||||||
pub fn key(&mut self, name: impl Yamlify) -> Section {
|
pub fn key(&mut self, name: impl Yamlify) -> Section {
|
||||||
println!();
|
println!();
|
||||||
self.print_indentation(&mut std::io::stdout().lock());
|
self.print_indentation(&mut std::io::stdout().lock());
|
||||||
print!("- ");
|
print!(" ");
|
||||||
name.yaml(self);
|
name.yaml(self);
|
||||||
print!(":");
|
print!(":");
|
||||||
self.indent()
|
self.indent()
|
||||||
@ -103,8 +103,10 @@ pub mod yamler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn list<D: Yamlify>(&mut self, list: &[D]) -> &mut Self {
|
pub fn list<D: Yamlify>(&mut self, list: &[D]) -> &mut Self {
|
||||||
for (idx, value) in list.iter().enumerate() {
|
for value in list {
|
||||||
self.pair(idx, value);
|
println!();
|
||||||
|
self.print_indentation(&mut std::io::stdout().lock());
|
||||||
|
self.yaml(&"- ").yaml(value);
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -302,8 +304,11 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
impl Yamlify for Impl {
|
impl Yamlify for Impl {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { target, body } = self;
|
let Self { gens, target, body } = self;
|
||||||
y.key("Impl").pair("target", target).pair("body", body);
|
y.key("Impl")
|
||||||
|
.pair("gens", gens)
|
||||||
|
.pair("target", target)
|
||||||
|
.pair("body", body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for ImplKind {
|
impl Yamlify for ImplKind {
|
||||||
@ -536,7 +541,10 @@ pub mod yamlify {
|
|||||||
impl Yamlify for Index {
|
impl Yamlify for Index {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { head, indices } = self;
|
let Self { head, indices } = self;
|
||||||
y.key("Index").pair("head", head).list(indices);
|
y.key("Index")
|
||||||
|
.pair("head", head)
|
||||||
|
.key("indices")
|
||||||
|
.list(indices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for Structor {
|
impl Yamlify for Structor {
|
||||||
@ -589,7 +597,7 @@ pub mod yamlify {
|
|||||||
impl Yamlify for Else {
|
impl Yamlify for Else {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { body } = self;
|
let Self { body } = self;
|
||||||
y.key("Else").yaml(body);
|
y.key("fail").yaml(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for If {
|
impl Yamlify for If {
|
||||||
@ -633,8 +641,8 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
impl Yamlify for Ty {
|
impl Yamlify for Ty {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { span: _, kind } = self;
|
let Self { span: _, kind, gens } = self;
|
||||||
y.key("Ty").yaml(kind);
|
y.key("Ty").yaml(kind).yaml(gens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for TyKind {
|
impl Yamlify for TyKind {
|
||||||
@ -646,6 +654,7 @@ pub mod yamlify {
|
|||||||
TyKind::Path(t) => y.yaml(t),
|
TyKind::Path(t) => y.yaml(t),
|
||||||
TyKind::Tuple(t) => y.yaml(t),
|
TyKind::Tuple(t) => y.yaml(t),
|
||||||
TyKind::Ref(t) => y.yaml(t),
|
TyKind::Ref(t) => y.yaml(t),
|
||||||
|
TyKind::Ptr(t) => y.yaml(t),
|
||||||
TyKind::Fn(t) => y.yaml(t),
|
TyKind::Fn(t) => y.yaml(t),
|
||||||
TyKind::Slice(t) => y.yaml(t),
|
TyKind::Slice(t) => y.yaml(t),
|
||||||
TyKind::Array(t) => y.yaml(t),
|
TyKind::Array(t) => y.yaml(t),
|
||||||
@ -659,9 +668,7 @@ pub mod yamlify {
|
|||||||
if *absolute {
|
if *absolute {
|
||||||
y.pair("absolute", absolute);
|
y.pair("absolute", absolute);
|
||||||
}
|
}
|
||||||
for part in parts {
|
y.yaml(parts);
|
||||||
y.pair("part", part);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for PathPart {
|
impl Yamlify for PathPart {
|
||||||
@ -703,6 +710,13 @@ pub mod yamlify {
|
|||||||
.pair("to", to);
|
.pair("to", to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Yamlify for TyPtr {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { to } = self;
|
||||||
|
y.key("TyPtr")
|
||||||
|
.pair("to", to);
|
||||||
|
}
|
||||||
|
}
|
||||||
impl Yamlify for TyFn {
|
impl Yamlify for TyFn {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { args, rety } = self;
|
let Self { args, rety } = self;
|
||||||
@ -726,9 +740,7 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
impl<T: Yamlify> Yamlify for Vec<T> {
|
impl<T: Yamlify> Yamlify for Vec<T> {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
for thing in self {
|
y.list(self);
|
||||||
y.yaml(thing);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for () {
|
impl Yamlify for () {
|
||||||
|
@ -28,6 +28,11 @@ impl fmt::Display for Entry<'_, '_> {
|
|||||||
let h_id = self.with_id(id);
|
let h_id = self.with_id(id);
|
||||||
write_name_or(h_id, f)
|
write_name_or(h_id, f)
|
||||||
}
|
}
|
||||||
|
&TypeKind::Ptr(id) => {
|
||||||
|
f.write_str("*")?;
|
||||||
|
let h_id = self.with_id(id);
|
||||||
|
write_name_or(h_id, f)
|
||||||
|
}
|
||||||
TypeKind::Slice(id) => {
|
TypeKind::Slice(id) => {
|
||||||
write_name_or(self.with_id(*id), &mut f.delimit_with("[", "]"))
|
write_name_or(self.with_id(*id), &mut f.delimit_with("[", "]"))
|
||||||
}
|
}
|
||||||
@ -66,10 +71,7 @@ fn write_adt(adt: &Adt, h: &Entry, f: &mut impl Write) -> fmt::Result {
|
|||||||
let mut variants = variants.iter();
|
let mut variants = variants.iter();
|
||||||
separate(", ", || {
|
separate(", ", || {
|
||||||
variants.next().map(|(name, def)| {
|
variants.next().map(|(name, def)| {
|
||||||
move |f: &mut Delimit<_>| {
|
move |f: &mut Delimit<_>| write!(f, "{name}: {}", h.with_id(*def))
|
||||||
write!(f, "{name}: ")?;
|
|
||||||
write_name_or(h.with_id(*def), f)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})(f.delimit_with("enum {", "}"))
|
})(f.delimit_with("enum {", "}"))
|
||||||
}
|
}
|
||||||
@ -77,20 +79,14 @@ fn write_adt(adt: &Adt, h: &Entry, f: &mut impl Write) -> fmt::Result {
|
|||||||
let mut members = members.iter();
|
let mut members = members.iter();
|
||||||
separate(", ", || {
|
separate(", ", || {
|
||||||
let (name, vis, id) = members.next()?;
|
let (name, vis, id) = members.next()?;
|
||||||
Some(move |f: &mut Delimit<_>| {
|
Some(move |f: &mut Delimit<_>| write!(f, "{vis}{name}: {}", h.with_id(*id)))
|
||||||
write!(f, "{vis}{name}: ")?;
|
|
||||||
write_name_or(h.with_id(*id), f)
|
|
||||||
})
|
|
||||||
})(f.delimit_with("struct {", "}"))
|
})(f.delimit_with("struct {", "}"))
|
||||||
}
|
}
|
||||||
Adt::TupleStruct(members) => {
|
Adt::TupleStruct(members) => {
|
||||||
let mut members = members.iter();
|
let mut members = members.iter();
|
||||||
separate(", ", || {
|
separate(", ", || {
|
||||||
let (vis, def) = members.next()?;
|
let (vis, def) = members.next()?;
|
||||||
Some(move |f: &mut Delimit<_>| {
|
Some(move |f: &mut Delimit<_>| write!(f, "{vis}{}", h.with_id(*def)))
|
||||||
write!(f, "{vis}")?;
|
|
||||||
write_name_or(h.with_id(*def), f)
|
|
||||||
})
|
|
||||||
})(f.delimit_with("struct (", ")"))
|
})(f.delimit_with("struct (", ")"))
|
||||||
}
|
}
|
||||||
Adt::UnitStruct => write!(f, "struct"),
|
Adt::UnitStruct => write!(f, "struct"),
|
||||||
|
@ -70,7 +70,7 @@ fn import_tree<'a>(
|
|||||||
UseTree::Path(part, rest) => {
|
UseTree::Path(part, rest) => {
|
||||||
let source = table
|
let source = table
|
||||||
.nav(src, slice::from_ref(part))
|
.nav(src, slice::from_ref(part))
|
||||||
.ok_or_else(|| Error::NotFound(src, part.clone()))?;
|
.ok_or(Error::NotFound(src, *part))?;
|
||||||
import_tree(table, source, dst, rest, seen)
|
import_tree(table, source, dst, rest, seen)
|
||||||
}
|
}
|
||||||
UseTree::Alias(src_name, dst_name) => {
|
UseTree::Alias(src_name, dst_name) => {
|
||||||
|
@ -496,6 +496,7 @@ impl<'table, 'a> InferenceEngine<'table, 'a> {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
(TypeKind::Ref(a), TypeKind::Ref(b)) => self.unify(*a, *b),
|
(TypeKind::Ref(a), TypeKind::Ref(b)) => self.unify(*a, *b),
|
||||||
|
(TypeKind::Ptr(a), TypeKind::Ptr(b)) => self.unify(*a, *b),
|
||||||
(TypeKind::Slice(a), TypeKind::Slice(b)) => self.unify(*a, *b),
|
(TypeKind::Slice(a), TypeKind::Slice(b)) => self.unify(*a, *b),
|
||||||
// Slice unifies with array
|
// Slice unifies with array
|
||||||
(TypeKind::Array(a, _), TypeKind::Slice(b)) => self.unify(*a, *b),
|
(TypeKind::Array(a, _), TypeKind::Slice(b)) => self.unify(*a, *b),
|
||||||
|
@ -121,7 +121,7 @@ impl<'a> Table<'a> {
|
|||||||
self.impls.push(item);
|
self.impls.push(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_iter(&mut self) -> impl Iterator<Item = Handle> + use<> {
|
pub fn handle_iter(&self) -> impl Iterator<Item = Handle> + use<> {
|
||||||
self.kinds.keys()
|
self.kinds.keys()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//! construct type bindings in a [Table]'s typing context.
|
//! construct type bindings in a [Table]'s typing context.
|
||||||
|
|
||||||
use crate::{handle::Handle, table::Table, type_kind::TypeKind};
|
use crate::{handle::Handle, table::Table, type_kind::TypeKind};
|
||||||
use cl_ast::{PathPart, Ty, TyArray, TyFn, TyKind, TyRef, TySlice, TyTuple};
|
use cl_ast::{PathPart, Sym, Ty, TyArray, TyFn, TyKind, TyPtr, TyRef, TySlice, TyTuple};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)] // TODO: impl Display and Error
|
#[derive(Clone, Debug, PartialEq, Eq)] // TODO: impl Display and Error
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@ -48,6 +48,7 @@ impl TypeExpression for TyKind {
|
|||||||
TyKind::Slice(s) => s.evaluate(table, node),
|
TyKind::Slice(s) => s.evaluate(table, node),
|
||||||
TyKind::Tuple(t) => t.evaluate(table, node),
|
TyKind::Tuple(t) => t.evaluate(table, node),
|
||||||
TyKind::Ref(r) => r.evaluate(table, node),
|
TyKind::Ref(r) => r.evaluate(table, node),
|
||||||
|
TyKind::Ptr(r) => r.evaluate(table, node),
|
||||||
TyKind::Fn(f) => f.evaluate(table, node),
|
TyKind::Fn(f) => f.evaluate(table, node),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,6 +69,15 @@ impl TypeExpression for [PathPart] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TypeExpression for Sym {
|
||||||
|
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
|
||||||
|
let path = [PathPart::Ident(*self)];
|
||||||
|
table
|
||||||
|
.nav(node, &path)
|
||||||
|
.ok_or_else(|| Error::BadPath { parent: node, path: path.to_vec() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TypeExpression for TyArray {
|
impl TypeExpression for TyArray {
|
||||||
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
|
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
|
||||||
let Self { ty, count } = self;
|
let Self { ty, count } = self;
|
||||||
@ -107,15 +117,21 @@ impl TypeExpression for TyRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TypeExpression for TyPtr {
|
||||||
|
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
|
||||||
|
let Self { to } = self;
|
||||||
|
let mut t = to.evaluate(table, node)?;
|
||||||
|
t = table.anon_type(TypeKind::Ptr(t));
|
||||||
|
Ok(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TypeExpression for TyFn {
|
impl TypeExpression for TyFn {
|
||||||
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
|
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
|
||||||
let Self { args, rety } = self;
|
let Self { args, rety } = self;
|
||||||
let kind = TypeKind::FnSig {
|
let kind = TypeKind::FnSig {
|
||||||
args: args.evaluate(table, node)?,
|
args: args.evaluate(table, node)?,
|
||||||
rety: match rety {
|
rety: rety.evaluate(table, node)?,
|
||||||
Some(ty) => ty.evaluate(table, node)?,
|
|
||||||
None => TyKind::Empty.evaluate(table, node)?,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
Ok(table.anon_type(kind))
|
Ok(table.anon_type(kind))
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ pub enum TypeKind {
|
|||||||
Adt(Adt),
|
Adt(Adt),
|
||||||
/// A reference to an already-defined type: &T
|
/// A reference to an already-defined type: &T
|
||||||
Ref(Handle),
|
Ref(Handle),
|
||||||
|
/// A raw pointer to an already-defined type: &T
|
||||||
|
Ptr(Handle),
|
||||||
/// A contiguous view of dynamically sized memory
|
/// A contiguous view of dynamically sized memory
|
||||||
Slice(Handle),
|
Slice(Handle),
|
||||||
/// A contiguous view of statically sized memory
|
/// A contiguous view of statically sized memory
|
||||||
@ -67,6 +69,7 @@ pub enum Primitive {
|
|||||||
Integer, Float, // Inferred int and float
|
Integer, Float, // Inferred int and float
|
||||||
Bool, // boolean value
|
Bool, // boolean value
|
||||||
Char, // Unicode codepoint
|
Char, // Unicode codepoint
|
||||||
|
Str, // UTF-8 string
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
@ -117,6 +120,7 @@ impl FromStr for Primitive {
|
|||||||
"fsize" => Primitive::Fsize,
|
"fsize" => Primitive::Fsize,
|
||||||
"bool" => Primitive::Bool,
|
"bool" => Primitive::Bool,
|
||||||
"char" => Primitive::Char,
|
"char" => Primitive::Char,
|
||||||
|
"str" => Primitive::Str,
|
||||||
_ => Err(())?,
|
_ => Err(())?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ impl Display for TypeKind {
|
|||||||
TypeKind::Primitive(i) => i.fmt(f),
|
TypeKind::Primitive(i) => i.fmt(f),
|
||||||
TypeKind::Adt(a) => a.fmt(f),
|
TypeKind::Adt(a) => a.fmt(f),
|
||||||
TypeKind::Ref(def) => write!(f, "&{def}"),
|
TypeKind::Ref(def) => write!(f, "&{def}"),
|
||||||
|
TypeKind::Ptr(def) => write!(f, "*{def}"),
|
||||||
TypeKind::Slice(def) => write!(f, "slice [#{def}]"),
|
TypeKind::Slice(def) => write!(f, "slice [#{def}]"),
|
||||||
TypeKind::Array(def, size) => write!(f, "array [#{def}; {size}]"),
|
TypeKind::Array(def, size) => write!(f, "array [#{def}; {size}]"),
|
||||||
TypeKind::Tuple(defs) => {
|
TypeKind::Tuple(defs) => {
|
||||||
@ -92,6 +93,7 @@ impl Display for Primitive {
|
|||||||
Primitive::Float => f.write_str("{float}"),
|
Primitive::Float => f.write_str("{float}"),
|
||||||
Primitive::Bool => f.write_str("bool"),
|
Primitive::Bool => f.write_str("bool"),
|
||||||
Primitive::Char => f.write_str("char"),
|
Primitive::Char => f.write_str("char"),
|
||||||
|
Primitive::Str => f.write_str("str"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user