type checking on constructor arguments
This commit is contained in:
parent
0945d385d0
commit
b83c4bb0cc
3 changed files with 37 additions and 21 deletions
|
|
@ -160,21 +160,6 @@ impl Compiler {
|
|||
registry: &mut HashMap<String, Chunk>,
|
||||
) -> Result<(), CompilerErrorAtLine> {
|
||||
match expression {
|
||||
// Expression::FunctionCall {
|
||||
// name, arguments, ..
|
||||
// } => {
|
||||
// let qname = format!("{}.{}", namespace, name);
|
||||
// let name_index = self
|
||||
// .chunk
|
||||
// .find_constant(&qname)
|
||||
// .unwrap_or_else(|| self.chunk.add_constant(Value::String(qname)));
|
||||
//
|
||||
// for argument in arguments {
|
||||
// self.compile_expression(namespace, argument, registry)?;
|
||||
// }
|
||||
// self.emit_bytes(OP_CALL, name_index as u16);
|
||||
// self.emit_byte(arguments.len() as u16);
|
||||
// }
|
||||
Expression::FunctionCall {
|
||||
name, arguments, ..
|
||||
} => {
|
||||
|
|
@ -281,7 +266,9 @@ impl Compiler {
|
|||
}
|
||||
}
|
||||
Expression::Stop { .. } => {}
|
||||
NamedParameter { value,.. } => {self.compile_expression(namespace, value, symbols, registry)?}
|
||||
NamedParameter { value, .. } => {
|
||||
self.compile_expression(namespace, value, symbols, registry)?
|
||||
}
|
||||
Expression::ListGet { index, list } => {
|
||||
self.compile_expression(namespace, list, symbols, registry)?;
|
||||
self.compile_expression(namespace, index, symbols, registry)?;
|
||||
|
|
@ -305,11 +292,16 @@ impl Compiler {
|
|||
) -> Result<(), CompilerErrorAtLine> {
|
||||
for parameter in parameters {
|
||||
for argument in arguments {
|
||||
if let NamedParameter { name, .. } = argument {
|
||||
if let NamedParameter { name, value, .. } = argument {
|
||||
if name.lexeme == parameter.name.lexeme {
|
||||
let value_type = infer_type(value, symbols);
|
||||
if parameter.var_type != value_type {
|
||||
return Err(CompilerErrorAtLine::raise(CompilerError::IncompatibleTypes(parameter.var_type.clone(), value_type), argument.line()));
|
||||
} else {
|
||||
self.compile_expression(namespace, argument, symbols, registry)?;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.compile_expression(namespace, argument, symbols, registry)?;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -147,6 +147,21 @@ p"#);
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn declare_and_instantiate_object_wrong_type() {
|
||||
let r = run(r#"
|
||||
object Person:
|
||||
name: string
|
||||
|
||||
let p = Person(name: 0x42)
|
||||
p"#);
|
||||
assert!(r.is_err());
|
||||
assert_eq!(
|
||||
r#"Compilation failed: error at line 5, Expected string, found integer"#,
|
||||
format!("{}", r.unwrap_err().to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn literal_map() {
|
||||
let result = run(r#"{"name": "Dent", "age": 40 }"#);
|
||||
|
|
|
|||
13
src/vm.rs
13
src/vm.rs
|
|
@ -220,11 +220,20 @@ impl Vm {
|
|||
|
||||
if let Some(params) = constructor {
|
||||
if params.len() != args.len() {
|
||||
return Err(RuntimeError::IllegalArgumentsException(function_name, params.len(), args.len()));
|
||||
return Err(RuntimeError::IllegalArgumentsException(
|
||||
function_name,
|
||||
params.len(),
|
||||
args.len(),
|
||||
));
|
||||
}
|
||||
|
||||
let mut fields = vec![];
|
||||
params.iter().zip(args.into_iter()).for_each(|(param, arg)| {fields.push((param.name.lexeme.clone(), arg))});
|
||||
params
|
||||
.iter()
|
||||
.zip(args.into_iter())
|
||||
.for_each(|(param, arg)| {
|
||||
fields.push((param.name.lexeme.clone(), arg))
|
||||
});
|
||||
let new_instance = Value::ObjectType(Box::new(Object {
|
||||
definition: function_name,
|
||||
fields,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue