Skip to content

Commit

Permalink
draft: evaluate more types
Browse files Browse the repository at this point in the history
  • Loading branch information
Glyphack committed Sep 8, 2023
1 parent 52d05d9 commit ec29d9f
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 9 deletions.
2 changes: 2 additions & 0 deletions typechecker/src/type_check/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ pub const LIST_TYPE: &str = "builtins.list";
pub const TUPLE_TYPE: &str = "builtins.tuple";
pub const DICT_TYPE: &str = "builtins.dict";
pub const SET_TYPE: &str = "builtins.set";

pub const ITER_TYPE: &str = "Iterator";
77 changes: 68 additions & 9 deletions typechecker/src/type_check/type_evaluator.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use parser::ast;

use crate::{
Expand Down Expand Up @@ -87,17 +89,74 @@ impl TypeEvaluator {
args: vec![elm_type],
})
}
ast::Expression::BoolOp(_) => todo!(),
ast::Expression::UnaryOp(_) => todo!(),
ast::Expression::NamedExpr(_) => todo!(),
ast::Expression::Yield(_) => todo!(),
ast::Expression::YieldFrom(_) => todo!(),
ast::Expression::Starred(_) => todo!(),
ast::Expression::Generator(_) => todo!(),
ast::Expression::BoolOp(b) => Type::Bool,
ast::Expression::UnaryOp(u) => {
match u.op {
ast::UnaryOperator::Not => Type::Bool,
ast::UnaryOperator::Invert => {
match self.get_type(&u.operand) {
Type::Int => Type::Int,
// TODO: report some kind of error here
_ => Type::Unknown,
}
}
_ => self.get_type(&u.operand),
}
}
ast::Expression::NamedExpr(e) => self.get_type(&e.value),
ast::Expression::Yield(a) => {
let yield_type = match a.value {
Some(ref v) => self.get_type(v),
None => Type::None,
};
Type::Class(super::types::ClassType {
name: builtins::ITER_TYPE.to_string(),
args: vec![yield_type],
})
}
ast::Expression::YieldFrom(yf) => {
let yield_type = match *yf.value.clone() {
ast::Expression::List(l) => self.get_sequence_type_from_elements(&l.elements),
_ => panic!("TODO: infer type from yield from"),
};
Type::Class(super::types::ClassType {
name: builtins::ITER_TYPE.to_string(),
args: vec![yield_type],
})
}
ast::Expression::Starred(s) => self.get_type(&s.value),
ast::Expression::Generator(g) => {
let mut comp_targets: HashMap<String, Type> = HashMap::new();
for gens in &g.generators {
match *gens.target.clone() {
ast::Expression::Name(n) => {
comp_targets.insert(n.id, self.get_type(&gens.iter));
}
_ => panic!("comperhension target must be a name, or does it?"),
}
}

// TODO: Here the comp_targets must be used
self.get_type(&g.element);

Type::Unknown
}
ast::Expression::ListComp(_) => todo!(),
ast::Expression::SetComp(_) => todo!(),
ast::Expression::DictComp(_) => todo!(),
ast::Expression::Attribute(_) => todo!(),
ast::Expression::Attribute(a) => {
let value_type = &self.get_type(&a.value);
match value_type {
Type::Class(class_type) => {
if let Some(_) = class_type.args.last() {
panic!("resolve attr form class type")
} else {
Type::Unknown
}
}
_ => Type::Unknown,
}
}
ast::Expression::Subscript(s) => {
let value_type = &self.get_type(&s.value);
// if the type of value is subscriptable, then return the type of the subscript
Expand Down Expand Up @@ -447,8 +506,8 @@ impl TraversalVisitorImmutGeneric<Type> for TypeEvaluator {

#[cfg(test)]
mod tests {
use std::collections::HashMap;
use super::*;
use std::collections::HashMap;
// TODO: refactor and move the test to type check mod
fn snapshot_type_eval(source: &str) -> String {
use crate::nodes::EnderpyFile;
Expand Down

0 comments on commit ec29d9f

Please sign in to comment.