λ Support functions! #5

Open
acw wants to merge 59 commits from awick/functions into develop
2 changed files with 41 additions and 0 deletions
Showing only changes of commit 0cc2b4ea9d - Show all commits

View File

@@ -0,0 +1,10 @@
x = 1;
function add_x(y) x + y
a = 3;
function add_x_twice(y) add_x(y) + x
print x;
result = add_x(a);
print x;
print result;
result = add_x_twice(a);
print result;

View File

@@ -328,6 +328,7 @@ pub fn solve_constraints(
loc, from_type, to_type,
));
}
println!("changed something because finished CanCastTo");
changed_something = true;
}
@@ -349,6 +350,7 @@ pub fn solve_constraints(
TypeOrVar::Function(args2, ret2),
));
}
println!("changed something because finished CanCastTo (2)");
changed_something = true;
}
@@ -358,6 +360,7 @@ pub fn solve_constraints(
pt @ TypeOrVar::Primitive(_),
) => {
errors.push(TypeInferenceError::CannotCastFromFunctionType(loc, pt));
println!("changed something because finished CanCastTo (3)");
changed_something = true;
}
@@ -368,17 +371,20 @@ pub fn solve_constraints(
) => {
errors.push(TypeInferenceError::CannotCastToFunctionType(loc, pt));
changed_something = true;
println!("changed something because finished CanCastTo (4)");
}
// if we're testing if an actual primitive type is numeric, that's pretty easy
Constraint::ConstantNumericType(_, TypeOrVar::Primitive(_)) => {
changed_something = true;
println!("changed something because constant numeric type (1)");
}
// if we're testing if a function type is numeric, then throw a useful warning
Constraint::ConstantNumericType(loc, t @ TypeOrVar::Function(_, _)) => {
errors.push(TypeInferenceError::CannotMakeNumberAFunction(loc, t, None));
changed_something = true;
println!("changed something because constant numeric type (2)");
}
// if we're testing if a number can fit into a numeric type, we can just do that!
@@ -393,6 +399,7 @@ pub fn solve_constraints(
Some(_) => {}
}
changed_something = true;
println!("changed something because fits in numeric type (1)");
}
// if we're testing if a function type can fit into a numeric type, that's a problem
@@ -403,12 +410,14 @@ pub fn solve_constraints(
Some(val),
));
changed_something = true;
println!("changed something because fits in numeric type (2)");
}
// if we want to know if a type is something, and it is something, then we're done
Constraint::IsSomething(_, TypeOrVar::Function(_, _))
| Constraint::IsSomething(_, TypeOrVar::Primitive(_)) => {
changed_something = true;
println!("changed something because 1");
}
// if we want to know if something is signed, we can check its primitive type
@@ -417,34 +426,40 @@ pub fn solve_constraints(
errors.push(TypeInferenceError::IsNotSigned(loc, pt));
}
changed_something = true;
println!("changed something because 2");
}
// again with the functions and the numbers
Constraint::IsSigned(loc, t @ TypeOrVar::Function(_, _)) => {
errors.push(TypeInferenceError::CannotCastFromFunctionType(loc, t));
changed_something = true;
println!("changed something because 3");
}
// if we're testing if an actual primitive type is numeric, that's pretty easy
Constraint::NumericType(_, TypeOrVar::Primitive(_)) => {
changed_something = true;
println!("changed something because 4");
}
// if we're testing if a function type is numeric, then throw a useful warning
Constraint::NumericType(loc, t @ TypeOrVar::Function(_, _)) => {
errors.push(TypeInferenceError::CannotMakeNumberAFunction(loc, t, None));
changed_something = true;
println!("changed something because 5");
}
// all of our primitive types are printable
Constraint::Printable(_, TypeOrVar::Primitive(_)) => {
changed_something = true;
println!("changed something because 6");
}
// function types are definitely not printable
Constraint::Printable(loc, TypeOrVar::Function(_, _)) => {
errors.push(TypeInferenceError::FunctionsAreNotPrintable(loc));
changed_something = true;
println!("changed something because 7");
}
Constraint::ProperPrimitiveArgs(loc, prim, mut args, ret) => match prim {
@@ -463,6 +478,7 @@ pub fn solve_constraints(
new_constraints.push(Constraint::Equivalent(loc.clone(), left, ret));
changed_something = true;
all_constraints_solved = false;
println!("changed something because 8");
}
Primitive::Minus if args.len() == 1 => {
@@ -472,6 +488,7 @@ pub fn solve_constraints(
new_constraints.push(Constraint::Equivalent(loc, value, ret));
changed_something = true;
all_constraints_solved = false;
println!("changed something because 9");
}
Primitive::Plus | Primitive::Times | Primitive::Divide => {
@@ -483,6 +500,7 @@ pub fn solve_constraints(
args.len(),
));
changed_something = true;
println!("changed something because 10");
}
Primitive::Minus => {
@@ -494,6 +512,7 @@ pub fn solve_constraints(
args.len(),
));
changed_something = true;
println!("changed something because 11");
}
},
@@ -511,6 +530,7 @@ pub fn solve_constraints(
));
}
changed_something = true;
println!("changed something because 12");
}
Constraint::Equivalent(
@@ -524,6 +544,11 @@ pub fn solve_constraints(
pt @ TypeOrVar::Primitive(_),
) => {
errors.push(TypeInferenceError::NotEquivalent(loc, pt, ft));
changed_something = true;
println!("changed something because 13");
}
Constraint::Equivalent(_, TypeOrVar::Variable(_, name1), TypeOrVar::Variable(_, name2)) if name1 == name2 => {
changed_something = true;
}
@@ -545,12 +570,16 @@ pub fn solve_constraints(
}
changed_something = true;
println!("changed something because 14");
}
Constraint::Equivalent(_, TypeOrVar::Variable(_, ref name), ref rhs) => {
changed_something |= replace_variable(&mut constraint_db, name, rhs);
changed_something |= replace_variable(&mut new_constraints, name, rhs);
all_constraints_solved &= rhs.is_resolved();
if changed_something {
println!("changed something because 15, maybe (name is {})", name);
}
new_constraints.push(constraint);
}
@@ -558,6 +587,7 @@ pub fn solve_constraints(
new_constraints.push(Constraint::Equivalent(loc, rhs, lhs));
changed_something = true;
all_constraints_solved = false;
println!("changed something because 16");
}
Constraint::CanCastTo(_, TypeOrVar::Variable(_, _), _)
@@ -602,6 +632,7 @@ pub fn solve_constraints(
resty.clone(),
));
warnings.push(TypeInferenceWarning::DefaultedTo(loc.clone(), resty));
println!("Adding number equivalence");
false
} else {
true