conlang: Self is not a type, it's a path to a type
This commit is contained in:
parent
ded100bf71
commit
b3d62c09aa
@ -252,7 +252,6 @@ pub struct Ty {
|
||||
pub enum TyKind {
|
||||
Never,
|
||||
Empty,
|
||||
SelfTy,
|
||||
Path(Path),
|
||||
Tuple(TyTuple),
|
||||
Ref(TyRef),
|
||||
@ -293,6 +292,7 @@ pub struct Path {
|
||||
pub enum PathPart {
|
||||
SuperKw,
|
||||
SelfKw,
|
||||
SelfTy,
|
||||
Ident(Sym),
|
||||
}
|
||||
|
||||
|
@ -306,7 +306,6 @@ mod display {
|
||||
match self {
|
||||
TyKind::Never => "!".fmt(f),
|
||||
TyKind::Empty => "()".fmt(f),
|
||||
TyKind::SelfTy => "Self".fmt(f),
|
||||
TyKind::Path(v) => v.fmt(f),
|
||||
TyKind::Tuple(v) => v.fmt(f),
|
||||
TyKind::Ref(v) => v.fmt(f),
|
||||
@ -357,6 +356,7 @@ mod display {
|
||||
match self {
|
||||
PathPart::SuperKw => "super".fmt(f),
|
||||
PathPart::SelfKw => "self".fmt(f),
|
||||
PathPart::SelfTy => "Self".fmt(f),
|
||||
PathPart::Ident(id) => id.fmt(f),
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +200,7 @@ pub trait Fold {
|
||||
match p {
|
||||
PathPart::SuperKw => PathPart::SuperKw,
|
||||
PathPart::SelfKw => PathPart::SelfKw,
|
||||
PathPart::SelfTy => PathPart::SelfTy,
|
||||
PathPart::Ident(i) => PathPart::Ident(self.fold_sym(i)),
|
||||
}
|
||||
}
|
||||
@ -498,7 +499,6 @@ pub fn or_fold_ty_kind<F: Fold + ?Sized>(folder: &mut F, kind: TyKind) -> TyKind
|
||||
match kind {
|
||||
TyKind::Never => TyKind::Never,
|
||||
TyKind::Empty => TyKind::Empty,
|
||||
TyKind::SelfTy => TyKind::SelfTy,
|
||||
TyKind::Path(p) => TyKind::Path(folder.fold_path(p)),
|
||||
TyKind::Tuple(t) => TyKind::Tuple(folder.fold_ty_tuple(t)),
|
||||
TyKind::Ref(t) => TyKind::Ref(folder.fold_ty_ref(t)),
|
||||
|
@ -169,6 +169,7 @@ pub trait Visit<'a>: Sized {
|
||||
match p {
|
||||
PathPart::SuperKw => {}
|
||||
PathPart::SelfKw => {}
|
||||
PathPart::SelfTy => {}
|
||||
PathPart::Ident(i) => self.visit_sym(i),
|
||||
}
|
||||
}
|
||||
@ -422,7 +423,6 @@ pub fn or_visit_ty_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a TyKind) {
|
||||
match kind {
|
||||
TyKind::Never => {}
|
||||
TyKind::Empty => {}
|
||||
TyKind::SelfTy => {}
|
||||
TyKind::Path(p) => visitor.visit_path(p),
|
||||
TyKind::Tuple(t) => visitor.visit_ty_tuple(t),
|
||||
TyKind::Ref(t) => visitor.visit_ty_ref(t),
|
||||
|
@ -169,6 +169,7 @@ fn evaluate_place_expr<'e>(
|
||||
match parts.last().expect("parts should not be empty") {
|
||||
PathPart::SuperKw => Err(Error::NotAssignable),
|
||||
PathPart::SelfKw => todo!("Assignment to `self`"),
|
||||
PathPart::SelfTy => todo!("What does it mean to assign to capital-S Self?"),
|
||||
PathPart::Ident(s) => env.get_mut(*s).map(|v| (v, *s)),
|
||||
}
|
||||
}
|
||||
@ -375,6 +376,7 @@ impl Interpret for Path {
|
||||
if parts.len() == 1 {
|
||||
match parts.last().expect("parts should not be empty") {
|
||||
PathPart::SuperKw | PathPart::SelfKw => todo!("Path navigation"),
|
||||
PathPart::SelfTy => todo!("Path navigation to Self"),
|
||||
PathPart::Ident(name) => env.get(*name),
|
||||
}
|
||||
} else {
|
||||
|
@ -672,10 +672,6 @@ impl<'t> Parser<'t> {
|
||||
self.consume_peeked();
|
||||
TyKind::Never
|
||||
}
|
||||
TokenKind::SelfTy => {
|
||||
self.consume_peeked();
|
||||
TyKind::SelfTy
|
||||
}
|
||||
TokenKind::Punct(Punct::Amp) | TokenKind::Punct(Punct::AmpAmp) => self.tyref()?.into(),
|
||||
TokenKind::Punct(Punct::LParen) => {
|
||||
let out = self.tytuple()?;
|
||||
@ -751,6 +747,7 @@ macro literal_like() {
|
||||
macro path_like() {
|
||||
TokenKind::Super
|
||||
| TokenKind::SelfKw
|
||||
| TokenKind::SelfTy
|
||||
| TokenKind::Identifier
|
||||
| TokenKind::Punct(Punct::ColonColon)
|
||||
}
|
||||
@ -762,6 +759,7 @@ impl<'t> Parser<'t> {
|
||||
let out = match self.peek_kind(PARSING)? {
|
||||
TokenKind::Super => PathPart::SuperKw,
|
||||
TokenKind::SelfKw => PathPart::SelfKw,
|
||||
TokenKind::SelfTy => PathPart::SelfTy,
|
||||
TokenKind::Identifier => PathPart::Ident(self.identifier()?),
|
||||
t => return Err(self.error(Unexpected(t), PARSING)),
|
||||
};
|
||||
|
@ -610,7 +610,6 @@ pub mod yamlify {
|
||||
match self {
|
||||
TyKind::Never => y.value("Never"),
|
||||
TyKind::Empty => y.value("Empty"),
|
||||
TyKind::SelfTy => y.value("Self"),
|
||||
TyKind::Path(t) => y.yaml(t),
|
||||
TyKind::Tuple(t) => y.yaml(t),
|
||||
TyKind::Ref(t) => y.yaml(t),
|
||||
@ -635,6 +634,7 @@ pub mod yamlify {
|
||||
match self {
|
||||
PathPart::SuperKw => y.value("super"),
|
||||
PathPart::SelfKw => y.value("self"),
|
||||
PathPart::SelfTy => y.value("Self"),
|
||||
PathPart::Ident(i) => y.yaml(i),
|
||||
};
|
||||
}
|
||||
|
@ -105,8 +105,6 @@ pub enum TypeKind {
|
||||
Empty,
|
||||
/// The never type
|
||||
Never,
|
||||
/// The Self type
|
||||
SelfTy,
|
||||
/// An untyped module
|
||||
Module,
|
||||
}
|
||||
|
@ -100,7 +100,6 @@ impl Display for TypeKind {
|
||||
TypeKind::FnSig { args, rety } => write!(f, "fn (#{args}) -> #{rety}"),
|
||||
TypeKind::Empty => f.write_str("()"),
|
||||
TypeKind::Never => f.write_str("!"),
|
||||
TypeKind::SelfTy => f.write_str("Self"),
|
||||
TypeKind::Module => f.write_str("mod"),
|
||||
}
|
||||
}
|
||||
|
@ -49,16 +49,10 @@ impl Default for Project<'_> {
|
||||
kind: DefKind::Type(TypeKind::Empty),
|
||||
node: Node::new(ROOT_PATH, None),
|
||||
});
|
||||
let selfty = pool.insert(Def {
|
||||
module: module::Module::new(root),
|
||||
kind: DefKind::Type(TypeKind::SelfTy),
|
||||
node: Node::new(ROOT_PATH, None),
|
||||
});
|
||||
|
||||
let mut anon_types = HashMap::new();
|
||||
anon_types.insert(TypeKind::Empty, empty);
|
||||
anon_types.insert(TypeKind::Never, never);
|
||||
anon_types.insert(TypeKind::SelfTy, selfty);
|
||||
|
||||
Self { pool, root, anon_types }
|
||||
}
|
||||
@ -68,6 +62,7 @@ impl<'a> Project<'a> {
|
||||
pub fn parent_of(&self, module: DefID) -> Option<DefID> {
|
||||
self[module].module.parent
|
||||
}
|
||||
|
||||
pub fn root_of(&self, module: DefID) -> DefID {
|
||||
match self.parent_of(module) {
|
||||
Some(module) => self.root_of(module),
|
||||
@ -75,6 +70,15 @@ impl<'a> Project<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the DefID of the Self type within the given DefID's context
|
||||
pub fn selfty_of(&self, node: DefID) -> Option<DefID> {
|
||||
match self[node].kind {
|
||||
DefKind::Impl(id) => Some(id),
|
||||
DefKind::Type(_) => Some(node),
|
||||
_ => self.selfty_of(self.parent_of(node)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<'p>(
|
||||
&self,
|
||||
path: Path<'p>,
|
||||
@ -93,6 +97,7 @@ impl<'a> Project<'a> {
|
||||
let ty = self[within].module.get_type(*name)?;
|
||||
self.get(path.pop_front()?, ty)
|
||||
}
|
||||
[PathPart::SelfTy, ..] => self.get(path.pop_front()?, self.selfty_of(within)?),
|
||||
[PathPart::SelfKw, ..] => self.get(path.pop_front()?, within),
|
||||
[PathPart::SuperKw, ..] => self.get(path.pop_front()?, self.parent_of(within)?),
|
||||
}
|
||||
@ -108,6 +113,7 @@ impl<'a> Project<'a> {
|
||||
match front {
|
||||
PathPart::SelfKw => self.get_type(path.pop_front()?, within),
|
||||
PathPart::SuperKw => self.get_type(path.pop_front()?, module.parent?),
|
||||
PathPart::SelfTy => self.get_type(path.pop_front()?, self.selfty_of(within)?),
|
||||
PathPart::Ident(name) => match module.types.get(name) {
|
||||
Some(&submodule) => self.get_type(path.pop_front()?, submodule),
|
||||
None => Some((within, path)),
|
||||
@ -189,7 +195,6 @@ pub mod evaluate {
|
||||
// TODO: reduce duplication here
|
||||
TyKind::Never => prj.anon_types[&TypeKind::Never],
|
||||
TyKind::Empty => prj.anon_types[&TypeKind::Empty],
|
||||
TyKind::SelfTy => prj.anon_types[&TypeKind::SelfTy],
|
||||
// TyKind::Path must be looked up explicitly
|
||||
TyKind::Path(path) => path.evaluate(prj, parent)?,
|
||||
TyKind::Tuple(tup) => tup.evaluate(prj, parent)?,
|
||||
@ -280,6 +285,9 @@ pub mod evaluate {
|
||||
.parent_of(parent)
|
||||
.ok_or_else(|| "Attempt to get super of root".into()),
|
||||
PathPart::SelfKw => Ok(parent),
|
||||
PathPart::SelfTy => prj
|
||||
.selfty_of(parent)
|
||||
.ok_or_else(|| "Attempt to get Self outside a Self-able context".into()),
|
||||
PathPart::Ident(name) => name.evaluate(prj, parent),
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ TyFn = "fn" TyTuple ('->' Ty)? ;
|
||||
(* path *)
|
||||
Path = PathPart ('::' PathPart)*
|
||||
| '::' (PathPart ('::' PathPart)*)? ;
|
||||
PathPart = "super" | "self" | Identifier ;
|
||||
PathPart = "super" | "self" | "Self" | Identifier ;
|
||||
Identifier = IDENTIFIER ;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user