test: function call semantics
This commit is contained in:
parent
3475b55db5
commit
6bfe840314
@ -23,7 +23,10 @@ impl SemanticCheck for FunctionCall<'_> {
|
|||||||
let Type::Function(parameters, _) = function_datatype else {
|
let Type::Function(parameters, _) = function_datatype else {
|
||||||
let (error_start, error_end) = fun.get_position();
|
let (error_start, error_end) = fun.get_position();
|
||||||
let label = ErrorLabel {
|
let label = ErrorLabel {
|
||||||
message: format!("Expected a function type, got {:?}", function_datatype),
|
message: format!(
|
||||||
|
"Expected this expression to be a function, found a {:?}",
|
||||||
|
function_datatype
|
||||||
|
),
|
||||||
start: error_start,
|
start: error_start,
|
||||||
end: error_end,
|
end: error_end,
|
||||||
};
|
};
|
||||||
@ -88,3 +91,81 @@ impl SemanticCheck for FunctionCall<'_> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::{
|
||||||
|
error_handling::error_messages::{
|
||||||
|
SEMANTIC_INVALID_REFERENCE, SEMANTIC_MISMATCHED_TYPES, SEMANTIC_MISSING_REFERENCE,
|
||||||
|
},
|
||||||
|
lexic::{get_tokens, token::Token},
|
||||||
|
semantic::{
|
||||||
|
impls::SemanticCheck,
|
||||||
|
symbol_table::SymbolTable,
|
||||||
|
types::{global::INT, Type},
|
||||||
|
},
|
||||||
|
syntax::{
|
||||||
|
ast::{functions::FunctionCall, Expression},
|
||||||
|
parseable::Parseable,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn t(i: &str) -> Vec<Token> {
|
||||||
|
get_tokens(&i.into()).unwrap()
|
||||||
|
}
|
||||||
|
fn exp<'a>(t: &'a Vec<Token>) -> FunctionCall<'a> {
|
||||||
|
let e = Expression::try_parse(t, 0).unwrap().0;
|
||||||
|
match e {
|
||||||
|
Expression::FunctionCall(f) => f,
|
||||||
|
_ => panic!("Expected to parse a function call"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_fail_on_ref_not_exist() {
|
||||||
|
let b = t("my_fun()");
|
||||||
|
let expr = exp(&b);
|
||||||
|
|
||||||
|
let scope = SymbolTable::new();
|
||||||
|
|
||||||
|
let output = expr.check_semantics(&scope);
|
||||||
|
match output {
|
||||||
|
Ok(_) => panic!("Expected an error"),
|
||||||
|
Err(err) => {
|
||||||
|
assert_eq!(err.error_code, SEMANTIC_MISSING_REFERENCE);
|
||||||
|
assert_eq!(err.error_offset, 0);
|
||||||
|
|
||||||
|
let label = &err.labels[0];
|
||||||
|
assert_eq!(label.message, "Cannot find this identifier in this scope");
|
||||||
|
assert_eq!(label.start, 0);
|
||||||
|
assert_eq!(label.end, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_fail_on_ref_not_a_function() {
|
||||||
|
let b = t("my_fun()");
|
||||||
|
let expr = exp(&b);
|
||||||
|
|
||||||
|
let scope = SymbolTable::new();
|
||||||
|
scope.insert(String::from("my_fun"), Type::Value(INT.into()));
|
||||||
|
|
||||||
|
let output = expr.check_semantics(&scope);
|
||||||
|
match output {
|
||||||
|
Ok(_) => panic!("Expected an error"),
|
||||||
|
Err(err) => {
|
||||||
|
assert_eq!(err.error_code, SEMANTIC_MISMATCHED_TYPES);
|
||||||
|
assert_eq!(err.error_offset, 0);
|
||||||
|
|
||||||
|
let label = &err.labels[0];
|
||||||
|
assert_eq!(
|
||||||
|
label.message,
|
||||||
|
"Expected this expression to be a function, found a `Int`"
|
||||||
|
);
|
||||||
|
assert_eq!(label.start, 0);
|
||||||
|
assert_eq!(label.end, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error_handling::{
|
error_handling::{
|
||||||
error_messages::{
|
error_messages::{COMPILER_TODO, SEMANTIC_INVALID_REFERENCE, SEMANTIC_MISMATCHED_TYPES},
|
||||||
COMPILER_TODO, SEMANTIC_INVALID_REFERENCE, SEMANTIC_MISMATCHED_ARGUMENT_COUNT,
|
|
||||||
SEMANTIC_MISMATCHED_TYPES,
|
|
||||||
},
|
|
||||||
ErrorContainer, ErrorLabel, MistiError,
|
ErrorContainer, ErrorLabel, MistiError,
|
||||||
},
|
},
|
||||||
semantic::{
|
semantic::{
|
||||||
@ -272,7 +269,7 @@ impl SemanticCheck for Expression<'_> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
lexic::{self, get_tokens, token::Token},
|
lexic::{get_tokens, token::Token},
|
||||||
semantic::{impls::SemanticCheck, std::populate, symbol_table::SymbolTable},
|
semantic::{impls::SemanticCheck, std::populate, symbol_table::SymbolTable},
|
||||||
syntax::{
|
syntax::{
|
||||||
ast::{
|
ast::{
|
||||||
@ -290,25 +287,6 @@ mod tests {
|
|||||||
Expression::try_parse(t, 0).unwrap().0
|
Expression::try_parse(t, 0).unwrap().0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_error_on_undefined_symbol() {
|
|
||||||
// source code: `print()`
|
|
||||||
let b = t("print()");
|
|
||||||
let expr = exp(&b);
|
|
||||||
|
|
||||||
let scope = SymbolTable::new();
|
|
||||||
|
|
||||||
let output = expr.check_semantics(&scope);
|
|
||||||
match output {
|
|
||||||
Ok(_) => panic!("Expected an error"),
|
|
||||||
Err(err) => {
|
|
||||||
//assert_eq!(err.reason, "Cannot find `print` in this scope.");
|
|
||||||
assert_eq!(err.error_offset, 0);
|
|
||||||
//assert_eq!(err.error_end, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_error_on_invalid_function_argument() {
|
fn should_error_on_invalid_function_argument() {
|
||||||
// source code: `print(322)`
|
// source code: `print(322)`
|
||||||
|
Loading…
Reference in New Issue
Block a user