add identifiers to scope in multiple definition
This commit is contained in:
parent
e7ca2ab9e1
commit
0c9923d15d
2 changed files with 63 additions and 4 deletions
5
examples/multi_return_sum.code
Normal file
5
examples/multi_return_sum.code
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
def foo():
|
||||||
|
return 1, 2
|
||||||
|
def main():
|
||||||
|
a, b = foo()
|
||||||
|
return a + b
|
|
@ -116,26 +116,36 @@ impl Checker {
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
Statement::MultipleDefinition(e1, e2) => {
|
Statement::MultipleDefinition(e1, e2) => {
|
||||||
println!("{:?} = {:?}", e1, e2);
|
|
||||||
match e1 {
|
match e1 {
|
||||||
|
// left side has to be a List
|
||||||
Expression::List(ref values) => {
|
Expression::List(ref values) => {
|
||||||
println!("{:?}", values);
|
let mut identifiers = Vec::new();
|
||||||
let all_identifiers = values.into_iter().fold(true, |acc, x| {
|
let all_identifiers = values.into_iter().fold(true, |acc, x| {
|
||||||
match x.clone() {
|
match x.clone() {
|
||||||
Expression::Identifier(_) => {
|
Expression::Identifier(i) => {
|
||||||
|
identifiers.push(i);
|
||||||
acc && true
|
acc && true
|
||||||
},
|
},
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
match all_identifiers {
|
match all_identifiers {
|
||||||
|
// All elements of the left side have to be identifiers
|
||||||
true => {
|
true => {
|
||||||
match e2 {
|
match e2 {
|
||||||
|
// Right side has to be a function call
|
||||||
Expression::FunctionCall(id, arguments) => {
|
Expression::FunctionCall(id, arguments) => {
|
||||||
println!("{:?} , {:?}", id, arguments);
|
|
||||||
match self.find_function(id, arguments) {
|
match self.find_function(id, arguments) {
|
||||||
|
// the function has to be defined
|
||||||
Some(f) => {
|
Some(f) => {
|
||||||
if f.return_count == values.len() {
|
if f.return_count == values.len() {
|
||||||
|
// the return count has to match the left side
|
||||||
|
for id in identifiers {
|
||||||
|
self.scope.insert(Symbol {
|
||||||
|
id: id.to_string(),
|
||||||
|
level: self.level
|
||||||
|
});
|
||||||
|
}
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
Err(format!("{:?} returns {} values but left side is of size {}", f.id, f.return_count, values.len()))
|
Err(format!("{:?} returns {} values but left side is of size {}", f.id, f.return_count, values.len()))
|
||||||
|
@ -469,4 +479,48 @@ mod tests {
|
||||||
let mut checker = Checker::new_with_args(HashSet::new(), 0, HashSet::new());
|
let mut checker = Checker::new_with_args(HashSet::new(), 0, HashSet::new());
|
||||||
assert_eq!(checker.check_function(bar), Err(("\"a\" is undefined".to_string())));
|
assert_eq!(checker.check_function(bar), Err(("\"a\" is undefined".to_string())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multi_def() {
|
||||||
|
// def foo():
|
||||||
|
// return 1, 2
|
||||||
|
// def bar():
|
||||||
|
// a, b = foo()
|
||||||
|
// return a + b
|
||||||
|
//
|
||||||
|
// should pass
|
||||||
|
let bar_statements: Vec<Statement<FieldPrime>> = vec![
|
||||||
|
Statement::MultipleDefinition(
|
||||||
|
Expression::List(vec![Expression::Identifier("a".to_string()), Expression::Identifier("b".to_string())]),
|
||||||
|
Expression::FunctionCall("foo".to_string(), vec![])
|
||||||
|
),
|
||||||
|
Statement::Return(
|
||||||
|
Expression::List(vec![
|
||||||
|
Expression::Add(
|
||||||
|
box Expression::Identifier("a".to_string()),
|
||||||
|
box Expression::Identifier("b".to_string())
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
let foo = FunctionDeclaration {
|
||||||
|
id: "foo".to_string(),
|
||||||
|
arg_count: 0,
|
||||||
|
return_count: 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut functions = HashSet::new();
|
||||||
|
functions.insert(foo);
|
||||||
|
|
||||||
|
let bar = Function {
|
||||||
|
id: "bar".to_string(),
|
||||||
|
arguments: vec![],
|
||||||
|
statements: bar_statements,
|
||||||
|
return_count: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut checker = Checker::new_with_args(HashSet::new(), 0, functions);
|
||||||
|
assert_eq!(checker.check_function(bar), Ok(()));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue