Skip to content

Commit

Permalink
Merge pull request #167 from Glyphack/tuple-dict-set
Browse files Browse the repository at this point in the history
  • Loading branch information
Glyphack authored Sep 7, 2023
2 parents 17f981b + 1e87b2e commit 52d05d9
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 121 deletions.
124 changes: 31 additions & 93 deletions typechecker/src/semantic_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,9 @@ impl TraversalVisitor for SemanticAnalyzer {
}
}

fn visit_import(&mut self, _i: &parser::ast::Import) {
todo!();
}
fn visit_import(&mut self, _i: &parser::ast::Import) {}

fn visit_import_from(&mut self, _i: &parser::ast::ImportFrom) {
todo!();
}
fn visit_import_from(&mut self, _i: &parser::ast::ImportFrom) {}

fn visit_if(&mut self, i: &parser::ast::If) {
for stmt in &i.body {
Expand Down Expand Up @@ -419,99 +415,55 @@ impl TraversalVisitor for SemanticAnalyzer {

fn visit_tuple(&mut self, _t: &parser::ast::Tuple) {}

fn visit_dict(&mut self, _d: &parser::ast::Dict) {
todo!()
}
fn visit_dict(&mut self, _d: &parser::ast::Dict) {}

fn visit_set(&mut self, _s: &parser::ast::Set) {
todo!()
}
fn visit_set(&mut self, _s: &parser::ast::Set) {}

fn visit_name(&mut self, _n: &parser::ast::Name) {}

fn visit_bool_op(&mut self, _b: &parser::ast::BoolOperation) {
todo!()
}
fn visit_bool_op(&mut self, _b: &parser::ast::BoolOperation) {}

fn visit_unary_op(&mut self, _u: &parser::ast::UnaryOperation) {
todo!()
}
fn visit_unary_op(&mut self, _u: &parser::ast::UnaryOperation) {}

fn visit_bin_op(&mut self, _b: &parser::ast::BinOp) {}

fn visit_named_expr(&mut self, _n: &parser::ast::NamedExpression) {
todo!()
}
fn visit_named_expr(&mut self, _n: &parser::ast::NamedExpression) {}

fn visit_yield(&mut self, _y: &parser::ast::Yield) {
todo!()
}
fn visit_yield(&mut self, _y: &parser::ast::Yield) {}

fn visit_yield_from(&mut self, _y: &parser::ast::YieldFrom) {
todo!()
}
fn visit_yield_from(&mut self, _y: &parser::ast::YieldFrom) {}

fn visit_starred(&mut self, _s: &parser::ast::Starred) {
todo!()
}
fn visit_starred(&mut self, _s: &parser::ast::Starred) {}

fn visit_generator(&mut self, _g: &parser::ast::Generator) {
todo!()
}
fn visit_generator(&mut self, _g: &parser::ast::Generator) {}

fn visit_list_comp(&mut self, _l: &parser::ast::ListComp) {
todo!()
}
fn visit_list_comp(&mut self, _l: &parser::ast::ListComp) {}

fn visit_set_comp(&mut self, _s: &parser::ast::SetComp) {
todo!()
}
fn visit_set_comp(&mut self, _s: &parser::ast::SetComp) {}

fn visit_dict_comp(&mut self, _d: &parser::ast::DictComp) {
todo!()
}
fn visit_dict_comp(&mut self, _d: &parser::ast::DictComp) {}

fn visit_attribute(&mut self, _a: &parser::ast::Attribute) {
todo!()
}
fn visit_attribute(&mut self, _a: &parser::ast::Attribute) {}

fn visit_subscript(&mut self, _s: &parser::ast::Subscript) {
todo!()
}
fn visit_subscript(&mut self, _s: &parser::ast::Subscript) {}

fn visit_slice(&mut self, _s: &parser::ast::Slice) {
todo!()
}
fn visit_slice(&mut self, _s: &parser::ast::Slice) {}

fn visit_call(&mut self, _c: &parser::ast::Call) {}

fn visit_await(&mut self, _a: &parser::ast::Await) {
todo!()
}
fn visit_await(&mut self, _a: &parser::ast::Await) {}

fn visit_compare(&mut self, _c: &parser::ast::Compare) {
todo!()
}
fn visit_compare(&mut self, _c: &parser::ast::Compare) {}

fn visit_lambda(&mut self, _l: &parser::ast::Lambda) {
todo!()
}
fn visit_lambda(&mut self, _l: &parser::ast::Lambda) {}

fn visit_if_exp(&mut self, _i: &parser::ast::IfExp) {
todo!()
}
fn visit_if_exp(&mut self, _i: &parser::ast::IfExp) {}

fn visit_joined_str(&mut self, _j: &parser::ast::JoinedStr) {
todo!()
}
fn visit_joined_str(&mut self, _j: &parser::ast::JoinedStr) {}

fn visit_formatted_value(&mut self, _f: &parser::ast::FormattedValue) {
todo!()
}
fn visit_formatted_value(&mut self, _f: &parser::ast::FormattedValue) {}

fn visit_alias(&mut self, _a: &parser::ast::Alias) {
todo!()
}
fn visit_alias(&mut self, _a: &parser::ast::Alias) {}

fn visit_assign(&mut self, assign: &parser::ast::Assign) {
let value = &assign.value;
Expand Down Expand Up @@ -557,35 +509,21 @@ impl TraversalVisitor for SemanticAnalyzer {
self.visit_expr(&a.value);
}

fn visit_assert(&mut self, _a: &parser::ast::Assert) {
todo!()
}
fn visit_assert(&mut self, _a: &parser::ast::Assert) {}

fn visit_pass(&mut self, _p: &parser::ast::Pass) {}

fn visit_delete(&mut self, _d: &parser::ast::Delete) {
todo!()
}
fn visit_delete(&mut self, _d: &parser::ast::Delete) {}

fn visit_return(&mut self, _r: &parser::ast::Return) {}

fn visit_raise(&mut self, _r: &parser::ast::Raise) {
todo!()
}
fn visit_raise(&mut self, _r: &parser::ast::Raise) {}

fn visit_break(&mut self, _b: &parser::ast::Break) {
todo!()
}
fn visit_break(&mut self, _b: &parser::ast::Break) {}

fn visit_continue(&mut self, _c: &parser::ast::Continue) {
todo!()
}
fn visit_continue(&mut self, _c: &parser::ast::Continue) {}

fn visit_global(&mut self, _g: &parser::ast::Global) {
todo!()
}
fn visit_global(&mut self, _g: &parser::ast::Global) {}

fn visit_nonlocal(&mut self, _n: &parser::ast::Nonlocal) {
todo!()
}
fn visit_nonlocal(&mut self, _n: &parser::ast::Nonlocal) {}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
source: typechecker/src/type_check/type_evaluator.rs
description: "# define variables with various types for testing\na = 1\nb = 2\nc = True\nd = False\ne = \"hello\"\nf = \"world\"\n# g = [1,2,3]\n# h = (1,2,3)\n# i = {1,2,3}\n# j = {\"a\":1,\"b\":2,\"c\":3}\n# k = None\n\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\n\n"
description: "# define variables with various types for testing\na = 1\nb = 2\nc = True\nd = False\ne = \"hello\"\nf = \"world\"\njoined_str = f\"{e} {f}\"\n\ng = [1,2,3]\nh = (1,2,3)\ni = {1,2,3}\nj = {\"a\":1,\"b\":2,\"c\":3}\nk = None\n\na\nb\nc\nd\ne\nf\njoined_str\ng\nh\ni\nj\nk\n\n"
expression: result
---
[
Expand Down Expand Up @@ -30,22 +30,26 @@ expression: result
),
(
"g",
"Unknown",
"builtins.list[Int]",
),
(
"h",
"Unknown",
"builtins.tuple[Int]",
),
(
"i",
"Unknown",
"builtins.set[Int]",
),
(
"j",
"Unknown",
"builtins.dict[Str, Int]",
),
(
"joined_str",
"Str",
),
(
"k",
"Unknown",
"None",
),
]
3 changes: 3 additions & 0 deletions typechecker/src/type_check/builtins.rs
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
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";
13 changes: 8 additions & 5 deletions typechecker/src/type_check/testdata/inputs/type_eval_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@
d = False
e = "hello"
f = "world"
# g = [1,2,3]
# h = (1,2,3)
# i = {1,2,3}
# j = {"a":1,"b":2,"c":3}
# k = None
joined_str = f"{e} {f}"

g = [1,2,3]
h = (1,2,3)
i = {1,2,3}
j = {"a":1,"b":2,"c":3}
k = None

a
b
c
d
e
f
joined_str
g
h
i
Expand Down
56 changes: 39 additions & 17 deletions typechecker/src/type_check/type_evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,34 @@ impl TypeEvaluator {
&b.op,
),
ast::Expression::List(l) => {
let mut prev_elm_type = Type::Unknown;
for elm in &l.elements {
let elm_type = self.get_type(elm);
if prev_elm_type == Type::Unknown {
prev_elm_type = elm_type;
} else if prev_elm_type != elm_type {
prev_elm_type = Type::Unknown;
break;
}
}
let final_elm_type = prev_elm_type;
let final_elm_type = self.get_sequence_type_from_elements(&l.elements);
Type::Class(super::types::ClassType {
name: builtins::LIST_TYPE.to_string(),
args: vec![final_elm_type],
})
}
ast::Expression::Tuple(_) => todo!(),
ast::Expression::Dict(_) => todo!(),
ast::Expression::Set(_) => todo!(),
ast::Expression::Tuple(t) => {
let elm_type = self.get_sequence_type_from_elements(&t.elements);
Type::Class(super::types::ClassType {
name: builtins::TUPLE_TYPE.to_string(),
args: vec![elm_type],
})
}
ast::Expression::Dict(d) => {
let key_type = self.get_sequence_type_from_elements(&d.keys);
let value_type = self.get_sequence_type_from_elements(&d.values);
Type::Class(super::types::ClassType {
name: builtins::DICT_TYPE.to_string(),
args: vec![key_type, value_type],
})
}
ast::Expression::Set(s) => {
let elm_type = self.get_sequence_type_from_elements(&s.elements);
Type::Class(super::types::ClassType {
name: builtins::SET_TYPE.to_string(),
args: vec![elm_type],
})
}
ast::Expression::BoolOp(_) => todo!(),
ast::Expression::UnaryOp(_) => todo!(),
ast::Expression::NamedExpr(_) => todo!(),
Expand Down Expand Up @@ -110,8 +119,8 @@ impl TypeEvaluator {
ast::Expression::Compare(_) => todo!(),
ast::Expression::Lambda(_) => todo!(),
ast::Expression::IfExp(_) => todo!(),
ast::Expression::JoinedStr(_) => todo!(),
ast::Expression::FormattedValue(_) => todo!(),
ast::Expression::JoinedStr(_) => Type::Str,
ast::Expression::FormattedValue(f) => self.get_type(&f.value),
}
}

Expand Down Expand Up @@ -152,6 +161,20 @@ impl TypeEvaluator {
None => Type::Unknown,
}
}

fn get_sequence_type_from_elements(&self, elements: &Vec<ast::Expression>) -> Type {
let mut prev_elm_type = Type::Unknown;
for elm in elements {
let elm_type = self.get_type(elm);
if prev_elm_type == Type::Unknown {
prev_elm_type = elm_type;
} else if prev_elm_type != elm_type {
prev_elm_type = Type::Unknown;
break;
}
}
prev_elm_type
}
}

impl TraversalVisitorImmutGeneric<Type> for TypeEvaluator {
Expand Down Expand Up @@ -425,7 +448,6 @@ impl TraversalVisitorImmutGeneric<Type> for TypeEvaluator {
#[cfg(test)]
mod tests {
use std::collections::HashMap;

use super::*;
// TODO: refactor and move the test to type check mod
fn snapshot_type_eval(source: &str) -> String {
Expand Down

0 comments on commit 52d05d9

Please sign in to comment.