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>,
|
registry: &mut HashMap<String, Chunk>,
|
||||||
) -> Result<(), CompilerErrorAtLine> {
|
) -> Result<(), CompilerErrorAtLine> {
|
||||||
match expression {
|
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 {
|
Expression::FunctionCall {
|
||||||
name, arguments, ..
|
name, arguments, ..
|
||||||
} => {
|
} => {
|
||||||
|
|
@ -281,7 +266,9 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::Stop { .. } => {}
|
Expression::Stop { .. } => {}
|
||||||
NamedParameter { value,.. } => {self.compile_expression(namespace, value, symbols, registry)?}
|
NamedParameter { value, .. } => {
|
||||||
|
self.compile_expression(namespace, value, symbols, registry)?
|
||||||
|
}
|
||||||
Expression::ListGet { index, list } => {
|
Expression::ListGet { index, list } => {
|
||||||
self.compile_expression(namespace, list, symbols, registry)?;
|
self.compile_expression(namespace, list, symbols, registry)?;
|
||||||
self.compile_expression(namespace, index, symbols, registry)?;
|
self.compile_expression(namespace, index, symbols, registry)?;
|
||||||
|
|
@ -305,11 +292,16 @@ impl Compiler {
|
||||||
) -> Result<(), CompilerErrorAtLine> {
|
) -> Result<(), CompilerErrorAtLine> {
|
||||||
for parameter in parameters {
|
for parameter in parameters {
|
||||||
for argument in arguments {
|
for argument in arguments {
|
||||||
if let NamedParameter { name, .. } = argument {
|
if let NamedParameter { name, value, .. } = argument {
|
||||||
if name.lexeme == parameter.name.lexeme {
|
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)?;
|
self.compile_expression(namespace, argument, symbols, registry)?;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.compile_expression(namespace, argument, symbols, registry)?;
|
self.compile_expression(namespace, argument, symbols, registry)?;
|
||||||
break;
|
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]
|
#[test]
|
||||||
fn literal_map() {
|
fn literal_map() {
|
||||||
let result = run(r#"{"name": "Dent", "age": 40 }"#);
|
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 let Some(params) = constructor {
|
||||||
if params.len() != args.len() {
|
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![];
|
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 {
|
let new_instance = Value::ObjectType(Box::new(Object {
|
||||||
definition: function_name,
|
definition: function_name,
|
||||||
fields,
|
fields,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue