Clean up primitive handling, finally.

This commit is contained in:
2024-04-16 16:20:31 -07:00
parent 763a895285
commit 7d4f182a67
19 changed files with 399 additions and 550 deletions

View File

@@ -1,6 +1,6 @@
use crate::{
eval::PrimitiveType,
syntax::{Expression, Location, Program, Statement, TopLevel},
syntax::{Expression, Location, Program, TopLevel},
util::scoped_map::ScopedMap,
};
use codespan_reporting::diagnostic::Diagnostic;
@@ -132,47 +132,12 @@ impl TopLevel {
bound_variables.release_scope();
result
}
TopLevel::Statement(stmt) => stmt.validate(bound_variables),
TopLevel::Expression(expr) => expr.validate(bound_variables),
TopLevel::Structure(_, _, _) => (vec![], vec![]),
}
}
}
impl Statement {
/// Validate that the statement makes semantic sense, not just syntactic sense.
///
/// This checks for things like references to variables that don't exist, for
/// example, and generates warnings for things that are inadvisable but not
/// actually a problem. Since statements appear in a broader context, you'll
/// need to provide the set of variables that are bound where this statement
/// occurs. We use a `HashMap` to map these bound locations to the locations
/// where their bound, because these locations are handy when generating errors
/// and warnings.
fn validate(
&self,
bound_variables: &mut ScopedMap<String, Location>,
) -> (Vec<Error>, Vec<Warning>) {
let mut errors = vec![];
let mut warnings = vec![];
match self {
Statement::Print(_, var) if bound_variables.contains_key(&var.name) => {}
Statement::Print(loc, var) => {
errors.push(Error::UnboundVariable(loc.clone(), var.to_string()))
}
Statement::Expression(e) => {
let (mut exp_errors, mut exp_warnings) = e.validate(bound_variables);
errors.append(&mut exp_errors);
warnings.append(&mut exp_warnings);
}
}
(errors, warnings)
}
}
impl Expression {
fn validate(
&self,
@@ -207,18 +172,7 @@ impl Expression {
(errs, warns)
}
Expression::Primitive(_, _, args) => {
let mut errors = vec![];
let mut warnings = vec![];
for expr in args.iter() {
let (mut err, mut warn) = expr.validate(variable_map);
errors.append(&mut err);
warnings.append(&mut warn);
}
(errors, warnings)
}
Expression::Primitive(_, _) => (vec![], vec![]),
Expression::Call(_, func, args) => {
let (mut errors, mut warnings) = func.validate(variable_map);