mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-09 09:38:24 +00:00
if else type analysis
This commit is contained in:
parent
c568cf08e9
commit
10cc3ae591
27
README.md
27
README.md
|
@ -5,12 +5,29 @@ A toy language I'm making to learn LLVM and compilers.
|
||||||
Syntax is subject to change any time right now. It has a rusty style for now.
|
Syntax is subject to change any time right now. It has a rusty style for now.
|
||||||
|
|
||||||
```
|
```
|
||||||
fn add(a: i64, b: i64) -> i64 {
|
struct Hello {
|
||||||
return a + b;
|
x: i32,
|
||||||
|
y: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn test(x: Hello) {
|
||||||
let x = 2 + 3;
|
return;
|
||||||
let y = add(x, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn works(x: i64) -> i64 {
|
||||||
|
let z = 0;
|
||||||
|
if 2 == x {
|
||||||
|
z = x * 2;
|
||||||
|
} else {
|
||||||
|
z = x * 3;
|
||||||
|
}
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> i64 {
|
||||||
|
let y: i64 = 2;
|
||||||
|
let z = y;
|
||||||
|
return works(z);
|
||||||
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -8,8 +8,8 @@ fn test(x: Hello) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn works(x: i64) -> i64 {
|
fn works(x: i64) -> i64 {
|
||||||
let z: i64 = 0;
|
let z = 0;
|
||||||
if x == 2 {
|
if 2 == x {
|
||||||
z = x * 2;
|
z = x * 2;
|
||||||
} else {
|
} else {
|
||||||
z = x * 3;
|
z = x * 3;
|
||||||
|
|
|
@ -489,10 +489,11 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
let (lhs, lhs_type) = self
|
let (lhs, lhs_type) = self
|
||||||
.compile_expression(lhs, variables, types)?
|
.compile_expression(lhs, variables, types)?
|
||||||
.expect("should have result");
|
.expect("should have result");
|
||||||
let (rhs, _rhs_type) = self
|
let (rhs, rhs_type) = self
|
||||||
.compile_expression(rhs, variables, types)?
|
.compile_expression(rhs, variables, types)?
|
||||||
.expect("should have result");
|
.expect("should have result");
|
||||||
|
|
||||||
|
assert_eq!(lhs_type, rhs_type);
|
||||||
let lhs = lhs.into_int_value();
|
let lhs = lhs.into_int_value();
|
||||||
let rhs = rhs.into_int_value();
|
let rhs = rhs.into_int_value();
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,10 @@ pub fn type_inference(ast: &mut ast::Program) {
|
||||||
let ret_type = function.return_type.clone();
|
let ret_type = function.return_type.clone();
|
||||||
let mut var_cache: HashMap<String, TypeExp> = HashMap::new();
|
let mut var_cache: HashMap<String, TypeExp> = HashMap::new();
|
||||||
|
|
||||||
|
for arg in &function.params {
|
||||||
|
var_cache.insert(arg.ident.clone(), arg.type_exp.clone());
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(ret_type) = &ret_type {
|
if let Some(ret_type) = &ret_type {
|
||||||
let ret_type_exp = fn_return_type(function);
|
let ret_type_exp = fn_return_type(function);
|
||||||
|
|
||||||
|
@ -175,6 +179,7 @@ fn set_exp_types_from_cache(
|
||||||
if let Some(value_type) = value_type {
|
if let Some(value_type) = value_type {
|
||||||
// todo: check types matches?
|
// todo: check types matches?
|
||||||
var_cache.insert(name, value_type.clone());
|
var_cache.insert(name, value_type.clone());
|
||||||
|
*env = Some(value_type.clone());
|
||||||
} else if var_cache.contains_key(&name) {
|
} else if var_cache.contains_key(&name) {
|
||||||
*value_type = var_cache.get(&name).cloned();
|
*value_type = var_cache.get(&name).cloned();
|
||||||
if env.is_none() {
|
if env.is_none() {
|
||||||
|
@ -183,10 +188,16 @@ fn set_exp_types_from_cache(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::BinaryOp(lhs, op, rhs) => match op {
|
Expression::BinaryOp(lhs, op, rhs) => match op {
|
||||||
ast::OpCode::Eq | ast::OpCode::Ne => {}
|
ast::OpCode::Eq | ast::OpCode::Ne => {
|
||||||
|
set_exp_types_from_cache(lhs, var_cache, env);
|
||||||
|
set_exp_types_from_cache(rhs, var_cache, env);
|
||||||
|
set_exp_types_from_cache(lhs, var_cache, env);
|
||||||
|
*env = Some(TypeExp::Boolean);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
set_exp_types_from_cache(lhs, var_cache, env);
|
set_exp_types_from_cache(lhs, var_cache, env);
|
||||||
set_exp_types_from_cache(rhs, var_cache, env);
|
set_exp_types_from_cache(rhs, var_cache, env);
|
||||||
|
set_exp_types_from_cache(lhs, var_cache, env); // needed in case 2 == x
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Expression::Literal(lit) => match lit {
|
Expression::Literal(lit) => match lit {
|
||||||
|
@ -241,7 +252,7 @@ fn set_expression_type(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::BinaryOp(lhs, op, rhs) => match op {
|
Expression::BinaryOp(lhs, op, rhs) => match op {
|
||||||
ast::OpCode::Eq | ast::OpCode::Ne => {}
|
// ast::OpCode::Eq | ast::OpCode::Ne => {}
|
||||||
_ => {
|
_ => {
|
||||||
set_expression_type(lhs, expected_type, var_cache);
|
set_expression_type(lhs, expected_type, var_cache);
|
||||||
set_expression_type(rhs, expected_type, var_cache);
|
set_expression_type(rhs, expected_type, var_cache);
|
||||||
|
|
Loading…
Reference in a new issue