[fine] Garbage Compile
This commit is contained in:
parent
8d09076586
commit
6d2fd446ee
3 changed files with 113 additions and 38 deletions
|
|
@ -389,9 +389,7 @@ impl<'a> Semantics<'a> {
|
|||
};
|
||||
|
||||
let declaration_type = match tree.nth_tree(3) {
|
||||
Some(expr) => self
|
||||
.type_of(expr)
|
||||
.expect("the tree in the expression should yield a type"),
|
||||
Some(expr) => self.type_of(expr),
|
||||
|
||||
// The syntax error should already have been reported, so we'll
|
||||
// stick with error type here. (But bind the name, because we see
|
||||
|
|
@ -432,7 +430,6 @@ impl<'a> Semantics<'a> {
|
|||
|
||||
let declaration_type = if let Some(type_expression) = param.nth_tree(2) {
|
||||
self.type_of(type_expression)
|
||||
.expect("the type expression should yield *some* type here")
|
||||
} else {
|
||||
Type::Error
|
||||
};
|
||||
|
|
@ -445,17 +442,17 @@ impl<'a> Semantics<'a> {
|
|||
EnvironmentRef::new(environment)
|
||||
}
|
||||
|
||||
pub fn type_of(&self, t: TreeRef) -> Option<Type> {
|
||||
pub fn type_of(&self, t: TreeRef) -> Type {
|
||||
{
|
||||
let state = &mut self.types.borrow_mut()[t.index()];
|
||||
match state {
|
||||
Incremental::None => (),
|
||||
Incremental::Complete(existing) => return Some(existing.clone()),
|
||||
Incremental::Complete(existing) => return existing.clone(),
|
||||
Incremental::InProgress => {
|
||||
// eprintln!("type_of circular => {t:?}");
|
||||
self.report_error_tree_ref(t, "The type of this expression depends on itself");
|
||||
*state = Incremental::Complete(Type::Error);
|
||||
return Some(Type::Error);
|
||||
return Type::Error;
|
||||
}
|
||||
}
|
||||
*state = Incremental::InProgress;
|
||||
|
|
@ -488,7 +485,7 @@ impl<'a> Semantics<'a> {
|
|||
let result = result.unwrap_or(Type::Error);
|
||||
|
||||
self.types.borrow_mut()[t.index()] = Incremental::Complete(result.clone());
|
||||
Some(result)
|
||||
result
|
||||
}
|
||||
|
||||
fn type_of_unary(&self, tree: &Tree) -> Option<Type> {
|
||||
|
|
@ -497,10 +494,7 @@ impl<'a> Semantics<'a> {
|
|||
let op = tree.nth_token(0)?;
|
||||
let expr = tree.nth_tree(1)?;
|
||||
|
||||
let argument_type = self
|
||||
.type_of(expr)
|
||||
.expect("Our argument should be an expression");
|
||||
|
||||
let argument_type = self.type_of(expr);
|
||||
match (op.kind, argument_type) {
|
||||
(TokenKind::Plus, Type::F64) => Some(Type::F64),
|
||||
(TokenKind::Minus, Type::F64) => Some(Type::F64),
|
||||
|
|
@ -534,13 +528,9 @@ impl<'a> Semantics<'a> {
|
|||
|
||||
fn type_of_binary(&self, tree: &Tree) -> Option<Type> {
|
||||
assert_eq!(tree.kind, TreeKind::BinaryExpression);
|
||||
let lhs = self
|
||||
.type_of(tree.nth_tree(0)?)
|
||||
.expect("must be an expression");
|
||||
let lhs = self.type_of(tree.nth_tree(0)?);
|
||||
let op = tree.nth_token(1)?;
|
||||
let rhs = self
|
||||
.type_of(tree.nth_tree(2)?)
|
||||
.expect("must be an expression");
|
||||
let rhs = self.type_of(tree.nth_tree(2)?);
|
||||
|
||||
match (op.kind, lhs, rhs) {
|
||||
(
|
||||
|
|
@ -618,22 +608,17 @@ impl<'a> Semantics<'a> {
|
|||
let mut is_unreachable = false;
|
||||
for i in 1..last_index {
|
||||
// TODO: if `is_unreachable` here then we actually have
|
||||
// unreachable code here! We should warn about it I guess.
|
||||
|
||||
is_unreachable = self
|
||||
.type_of(tree.nth_tree(i)?)
|
||||
.map(|t| matches!(t, Type::Unreachable))
|
||||
.unwrap_or(false)
|
||||
|| is_unreachable;
|
||||
// unreachable code here! We should warn about it
|
||||
// I guess.
|
||||
is_unreachable =
|
||||
matches!(self.type_of(tree.nth_tree(i)?), Type::Unreachable) || is_unreachable;
|
||||
}
|
||||
|
||||
// NOTE: If for some reason the last statement is unsuitable for a
|
||||
// type then we consider the type of the block to be Nothing.
|
||||
// (And explicitly not Error, which is what returning None
|
||||
// would yield.)
|
||||
let last_type = self
|
||||
.type_of(tree.nth_tree(last_index)?)
|
||||
.unwrap_or(Type::Nothing);
|
||||
let last_type = self.type_of(tree.nth_tree(last_index)?);
|
||||
|
||||
// If anything in this block generated an "Unreachable" then the
|
||||
// whole type of the block is "unreachable" no matter what.
|
||||
|
|
@ -660,26 +645,22 @@ impl<'a> Semantics<'a> {
|
|||
fn type_of_grouping(&self, tree: &Tree) -> Option<Type> {
|
||||
assert_eq!(tree.kind, TreeKind::GroupingExpression);
|
||||
|
||||
let expr = tree.nth_tree(1)?;
|
||||
Some(
|
||||
self.type_of(expr)
|
||||
.expect("the thing in the parenthesis must have some type"),
|
||||
)
|
||||
tree.nth_tree(1).map(|t| self.type_of(t))
|
||||
}
|
||||
|
||||
fn type_of_conditional(&self, tree: &Tree) -> Option<Type> {
|
||||
assert_eq!(tree.kind, TreeKind::ConditionalExpression);
|
||||
|
||||
let cond_tree = tree.nth_tree(1)?;
|
||||
let cond_type = self.type_of(cond_tree).expect("must be expression");
|
||||
let then_type = self.type_of(tree.nth_tree(2)?).expect("must be expression");
|
||||
let cond_type = self.type_of(cond_tree);
|
||||
let then_type = self.type_of(tree.nth_tree(2)?);
|
||||
|
||||
let has_else = tree
|
||||
.nth_token(3)
|
||||
.map(|t| t.kind == TokenKind::Else)
|
||||
.unwrap_or(false);
|
||||
let else_type = if has_else {
|
||||
Some(self.type_of(tree.nth_tree(4)?).expect("must be expression"))
|
||||
Some(self.type_of(tree.nth_tree(4)?))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
@ -731,7 +712,7 @@ impl<'a> Semantics<'a> {
|
|||
.map(|t| t.kind == TokenKind::Semicolon)
|
||||
.unwrap_or(false);
|
||||
|
||||
let expression_type = self.type_of(tree.nth_tree(0)?).expect("must be expression");
|
||||
let expression_type = self.type_of(tree.nth_tree(0)?);
|
||||
Some(match expression_type {
|
||||
Type::Unreachable => Type::Unreachable,
|
||||
_ => {
|
||||
|
|
@ -802,7 +783,7 @@ impl<'a> Semantics<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn internal_compiler_error(&self, tr: Option<TreeRef>, message: &str) -> ! {
|
||||
pub fn internal_compiler_error(&self, tr: Option<TreeRef>, message: &str) -> ! {
|
||||
eprintln!("Internal compiler error: {message}!");
|
||||
self.dump_compiler_state(tr);
|
||||
panic!("INTERNAL COMPILER ERROR: {message}")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue