[fine] Parse alternate types

This commit is contained in:
John Doty 2024-02-01 07:56:30 -08:00
parent f7acfd588d
commit afa4812074
10 changed files with 73 additions and 26 deletions

View file

@ -143,6 +143,9 @@ pub enum Type {
// class need to be fetched explicitly from the semantics via the
// TreeRef and `Semantics::class_of`; they are computed lazily.
Object(TreeRef, Rc<str>),
// An alternate is one or another type.
Alternate(Box<Type>, Box<Type>),
}
impl Type {
@ -204,6 +207,7 @@ impl fmt::Display for Type {
List(t) => write!(f, "list<{t}>"),
Object(_, name) => write!(f, "{} instance", name),
Class(_, name) => write!(f, "class {}", name),
Alternate(l, r) => write!(f, "{l} or {r}"),
}
}
}
@ -592,7 +596,7 @@ impl<'a> Semantics<'a> {
}
let tree = &self.syntax_tree[t];
eprintln!(">>> environment_of => {tree:?}");
// eprintln!(">>> environment_of => {tree:?}");
let parent = match self.logical_parents[t.index()] {
Some(t) => self.environment_of(t),
@ -613,7 +617,7 @@ impl<'a> Semantics<'a> {
};
self.environments.borrow_mut()[t.index()] = Incremental::Complete(result.clone());
eprintln!("<<< environment_of => {tree:?}");
// eprintln!("<<< environment_of => {tree:?}");
result
}
@ -986,11 +990,12 @@ impl<'a> Semantics<'a> {
}
let tree = &self.syntax_tree[t];
eprintln!(">>> type_of => {tree:?}");
// eprintln!(">>> type_of => {tree:?}");
let result = match tree.kind {
TreeKind::Error => Some(Type::Error),
TreeKind::AlternateType => self.type_of_alternate_type(tree),
TreeKind::Argument => self.type_of_argument(tree),
TreeKind::BinaryExpression => self.type_of_binary(tree),
TreeKind::Block => self.type_of_block(tree),
@ -1016,7 +1021,8 @@ impl<'a> Semantics<'a> {
TreeKind::ReturnType => self.type_of_return_type(tree),
TreeKind::SelfParameter => self.type_of_self_parameter(tree),
TreeKind::SelfReference => self.type_of_self_reference(t, tree),
TreeKind::TypeExpression => self.type_of_type_expr(t, tree),
TreeKind::TypeExpression => self.type_of_type_expr(tree),
TreeKind::TypeIdentifier => self.type_of_type_identifier(t, tree),
TreeKind::TypeParameter => self.type_of_type_parameter(tree),
TreeKind::UnaryExpression => self.type_of_unary(tree),
@ -1026,7 +1032,7 @@ impl<'a> Semantics<'a> {
// NOTE: These return `None` if they encounter some problem.
let result = result.unwrap_or(Type::Error);
self.types.borrow_mut()[t.index()] = Incremental::Complete(result.clone());
eprintln!("<<< type_of => {tree:?}");
// eprintln!("<<< type_of => {tree:?}");
result
}
@ -1190,8 +1196,13 @@ impl<'a> Semantics<'a> {
}
}
fn type_of_type_expr(&self, t: TreeRef, tree: &Tree) -> Option<Type> {
fn type_of_type_expr(&self, tree: &Tree) -> Option<Type> {
assert_eq!(tree.kind, TreeKind::TypeExpression);
Some(self.type_of(tree.nth_tree(0)?))
}
fn type_of_type_identifier(&self, t: TreeRef, tree: &Tree) -> Option<Type> {
assert_eq!(tree.kind, TreeKind::TypeIdentifier);
// TODO: This will *clearly* need to get better.
let token = tree.nth_token(0)?;
@ -1711,6 +1722,13 @@ impl<'a> Semantics<'a> {
Some(self.type_of(tree.nth_tree(0)?))
}
fn type_of_alternate_type(&self, tree: &Tree) -> Option<Type> {
// TODO: IDEA: nth_tree returns a bogus tree if not a tree, stop returning Option?
let left = self.type_of(tree.nth_tree(0)?);
let right = self.type_of(tree.nth_tree(2)?);
Some(Type::Alternate(Box::new(left), Box::new(right)))
}
pub fn dump_compiler_state(&self, tr: Option<TreeRef>) {
eprintln!("Parsed the tree as:");
eprintln!("\n{}", self.syntax_tree.dump(true));
@ -1789,7 +1807,7 @@ pub fn check(s: &Semantics) {
TreeKind::Parameter => {
let _ = s.type_of(t);
}
TreeKind::TypeExpression => {
TreeKind::TypeExpression | TreeKind::AlternateType | TreeKind::TypeIdentifier => {
let _ = s.type_of(t);
}
TreeKind::Block => {