[fine] While loops, nothing
This commit is contained in:
parent
1cc5ce6ca9
commit
ac3c158a81
7 changed files with 166 additions and 48 deletions
|
|
@ -171,7 +171,7 @@ impl fmt::Display for Type {
|
|||
Error => write!(f, "<< INTERNAL ERROR >>"),
|
||||
Unreachable => write!(f, "<< UNREACHABLE >>"),
|
||||
Assignment(_) => write!(f, "assignment"),
|
||||
Nothing => write!(f, "()"),
|
||||
Nothing => write!(f, "nothing"),
|
||||
F64 => write!(f, "f64"),
|
||||
I64 => write!(f, "i64"),
|
||||
String => write!(f, "string"),
|
||||
|
|
@ -1139,9 +1139,9 @@ impl<'a> Semantics<'a> {
|
|||
TreeKind::Block => self.type_of_block(tree),
|
||||
TreeKind::CallExpression => self.type_of_call(tree),
|
||||
TreeKind::ClassDecl => self.type_of_class_decl(t, tree),
|
||||
TreeKind::FieldDecl => self.type_of_field_decl(tree),
|
||||
TreeKind::ConditionalExpression => self.type_of_conditional(tree),
|
||||
TreeKind::ExpressionStatement => self.type_of_expression_statement(tree),
|
||||
TreeKind::FieldDecl => self.type_of_field_decl(tree),
|
||||
TreeKind::FieldValue => self.type_of_field_value(t, tree),
|
||||
TreeKind::ForStatement => Some(Type::Nothing),
|
||||
TreeKind::FunctionDecl => self.type_of_function_decl(tree),
|
||||
|
|
@ -1153,6 +1153,9 @@ impl<'a> Semantics<'a> {
|
|||
TreeKind::ListConstructor => self.type_of_list_constructor(t, tree),
|
||||
TreeKind::ListConstructorElement => self.type_of_list_constructor_element(tree),
|
||||
TreeKind::LiteralExpression => self.type_of_literal(tree),
|
||||
TreeKind::MatchArm => self.type_of_match_arm(tree),
|
||||
TreeKind::MatchBody => self.type_of_match_body(tree),
|
||||
TreeKind::MatchExpression => self.type_of_match_expression(tree),
|
||||
TreeKind::MemberAccess => self.type_of_member_access(tree),
|
||||
TreeKind::NewObjectExpression => self.type_of_new_object_expression(tree),
|
||||
TreeKind::Parameter => self.type_of_parameter(tree),
|
||||
|
|
@ -1164,10 +1167,7 @@ impl<'a> Semantics<'a> {
|
|||
TreeKind::TypeIdentifier => self.type_of_type_identifier(t, tree),
|
||||
TreeKind::TypeParameter => self.type_of_type_parameter(tree),
|
||||
TreeKind::UnaryExpression => self.type_of_unary(tree),
|
||||
|
||||
TreeKind::MatchExpression => self.type_of_match_expression(tree),
|
||||
TreeKind::MatchBody => self.type_of_match_body(tree),
|
||||
TreeKind::MatchArm => self.type_of_match_arm(tree),
|
||||
TreeKind::WhileStatement => Some(Type::Nothing),
|
||||
|
||||
_ => self.internal_compiler_error(Some(t), "asking for a nonsense type"),
|
||||
};
|
||||
|
|
@ -1241,6 +1241,16 @@ impl<'a> Semantics<'a> {
|
|||
(TokenKind::EqualEqual, Type::Bool, Type::Bool) => Some(Type::Bool),
|
||||
(TokenKind::EqualEqual, Type::Nothing, Type::Nothing) => Some(Type::Bool),
|
||||
|
||||
(TokenKind::Less, Type::F64, Type::F64) => Some(Type::Bool),
|
||||
(TokenKind::LessEqual, Type::F64, Type::F64) => Some(Type::Bool),
|
||||
(TokenKind::Greater, Type::F64, Type::F64) => Some(Type::Bool),
|
||||
(TokenKind::GreaterEqual, Type::F64, Type::F64) => Some(Type::Bool),
|
||||
|
||||
(TokenKind::Less, Type::String, Type::String) => Some(Type::Bool),
|
||||
(TokenKind::LessEqual, Type::String, Type::String) => Some(Type::Bool),
|
||||
(TokenKind::Greater, Type::String, Type::String) => Some(Type::Bool),
|
||||
(TokenKind::GreaterEqual, Type::String, Type::String) => Some(Type::Bool),
|
||||
|
||||
// This is dumb and should be punished, probably.
|
||||
(_, _, Type::Unreachable) => {
|
||||
self.report_error(
|
||||
|
|
@ -1353,7 +1363,7 @@ impl<'a> Semantics<'a> {
|
|||
"f64" => Some(Type::F64),
|
||||
"string" => Some(Type::String),
|
||||
"bool" => Some(Type::Bool),
|
||||
"()" => Some(Type::Nothing),
|
||||
"nothing" => Some(Type::Nothing),
|
||||
"list" => {
|
||||
let args =
|
||||
tree.child_tree_of_kind(self.syntax_tree, TreeKind::TypeParameterList)?;
|
||||
|
|
@ -2041,6 +2051,8 @@ pub fn check(s: &Semantics) {
|
|||
TreeKind::MatchArm => {}
|
||||
TreeKind::MatchBody => check_match_body(s, t, tree),
|
||||
TreeKind::MatchExpression => {}
|
||||
|
||||
TreeKind::WhileStatement => check_while_statement(s, tree),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2240,6 +2252,7 @@ fn check_match_body(s: &Semantics, t: TreeRef, _tree: &Tree) {
|
|||
let _ = s.type_of(t); // Checks arm count and compatibility.
|
||||
|
||||
// TODO: completeness checks
|
||||
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_pattern_analysis/usefulness/index.html
|
||||
|
||||
// let arms: Vec<_> = tree
|
||||
// .children_of_kind(s.syntax_tree, TreeKind::MatchArm)
|
||||
|
|
@ -2253,6 +2266,18 @@ fn check_match_body(s: &Semantics, t: TreeRef, _tree: &Tree) {
|
|||
// }
|
||||
}
|
||||
|
||||
fn check_while_statement(s: &Semantics, tree: &Tree) {
|
||||
if let Some(expr) = tree.nth_tree(1) {
|
||||
let expr_type = s.type_of(expr);
|
||||
if !s.can_convert(&expr_type, &Type::Bool) {
|
||||
s.report_error_tree_ref(
|
||||
expr,
|
||||
"the condition of the while loop must produce a boolean",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue