Skip to content

Commit

Permalink
Merge pull request #197 from Glyphack/type-alias
Browse files Browse the repository at this point in the history
  • Loading branch information
Glyphack authored Oct 30, 2023
2 parents dbacb79 + 971737f commit 72fe36b
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 3 deletions.
26 changes: 25 additions & 1 deletion parser/src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,9 @@ impl Parser {
Kind::Global => self.parse_global_statement(),
Kind::Nonlocal => self.parse_nonlocal_statement(),
_ => {
if self.cur_kind() == Kind::Indent {
if self.cur_kind() == Kind::Identifier && self.cur_token().value.to_string() == "type" {
self.parse_type_alias_statement()
} else if self.cur_kind() == Kind::Indent {
let node = self.start_node();
let kind = self.cur_kind();
return Err(self.unexpected_token_new(
Expand Down Expand Up @@ -3145,6 +3147,28 @@ impl Parser {
}
Ok(type_params)
}

fn parse_type_alias_statement(&mut self) -> std::result::Result<Statement, ParsingError> {
let node = self.start_node();
self.expect(Kind::Identifier)?;
let name = self.cur_token().value.to_string();
self.expect(Kind::Identifier)?;
let type_params = if self.eat(Kind::LeftBrace) {
let type_params = self.parse_type_parameters()?;
self.expect(Kind::RightBrace)?;
type_params
} else {
vec![]
};
self.expect(Kind::Assign)?;
let value = self.parse_expression_2()?;
Ok(Statement::TypeAlias(TypeAlias {
node: self.finish_node(node),
name,
type_params,
value: Box::new(value),
}))
}
}

#[cfg(test)]
Expand Down
2 changes: 2 additions & 0 deletions typechecker/src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,6 @@ impl<'a> TraversalVisitor for EnderpyFile {
fn visit_global(&mut self, _g: &parser::ast::Global) {}

fn visit_nonlocal(&mut self, _n: &parser::ast::Nonlocal) {}

fn visit_type_alias(&mut self, _t: &parser::ast::TypeAlias) {}
}
16 changes: 15 additions & 1 deletion typechecker/src/semantic_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
},
symbol_table::{
Alias, Class, Declaration, DeclarationPath, Function, Paramter, SymbolScope, SymbolTable,
SymbolTableNode, SymbolTableScope, SymbolTableType, Variable,
SymbolTableNode, SymbolTableScope, SymbolTableType, Variable, TypeAlias,
},
};

Expand Down Expand Up @@ -465,6 +465,20 @@ impl TraversalVisitor for SemanticAnalyzer {
self.create_symbol(f.name.clone(), function_declaration);
}

fn visit_type_alias(&mut self, t: &parser::ast::TypeAlias) {
let declaration_path = DeclarationPath {
module_name: self.file.module_name().clone(),
node: t.node,
};
self.create_symbol(
t.name.clone(),
Declaration::TypeAlias(TypeAlias {
declaration_path,
type_alias_node: t.clone(),
}
));
}

fn visit_async_function_def(&mut self, _f: &parser::ast::AsyncFunctionDef) {}

fn visit_class_def(&mut self, c: &parser::ast::ClassDef) {
Expand Down
10 changes: 10 additions & 0 deletions typechecker/src/symbol_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ pub enum Declaration {
// TypeParameterDeclaration represents a type parameter in a generic class or function.
// It models type parameters declared on classes and functions like T in List[T].
TypeParameter(Box<TypeParameter>),

TypeAlias(TypeAlias),
}

impl Declaration {
Expand All @@ -76,6 +78,7 @@ impl Declaration {
Declaration::Parameter(p) => &p.declaration_path,
Declaration::Alias(a) => &a.declaration_path,
Declaration::TypeParameter(t) => &t.declaration_path,
Declaration::TypeAlias(t) => &t.declaration_path,
}
}
}
Expand Down Expand Up @@ -142,6 +145,12 @@ pub struct Alias {
pub import_result: ImportResult,
}

#[derive(Debug, Clone)]
pub struct TypeAlias {
pub declaration_path: DeclarationPath,
pub type_alias_node: ast::TypeAlias,
}

#[derive(Debug, Clone, Copy)]
pub enum SymbolScope {
Global,
Expand Down Expand Up @@ -299,6 +308,7 @@ impl std::fmt::Display for Declaration {
Declaration::Parameter(p) => write!(f, "{:#?}", p),
Declaration::Alias(a) => write!(f, "{:#?}", a),
Declaration::TypeParameter(t) => write!(f, "{:#?}", t),
Declaration::TypeAlias(t) => write!(f, "{:#?}", t),
}
}
}
3 changes: 2 additions & 1 deletion typechecker/src/type_check/type_evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl TypeEvaluator {
match decl {
Some(decl) => self.get_type_from_declaration(decl),
None => Ok(PythonType::Unknown),
}
}
}
pub fn get_type(&self, expr: &ast::Expression) -> Result<PythonType> {
match expr {
Expand Down Expand Up @@ -226,6 +226,7 @@ impl TypeEvaluator {
Declaration::Parameter(_) => Ok(PythonType::Unknown),
Declaration::Alias(_) => Ok(PythonType::Unknown),
Declaration::TypeParameter(_) => Ok(PythonType::Unknown),
Declaration::TypeAlias(_) => Ok(PythonType::Unknown),
}
}

Expand Down
7 changes: 7 additions & 0 deletions typechecker/test_data/inputs/symbol_table/type_alias.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Show me some examples of type aliasing in Python try to give examples for all

type Alias1 = int
type Alias2 = str
type Alias3 = float

type AliasToAnotherAlias = Alias1
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
source: typechecker/src/build.rs
description: "# Show me some examples of type aliasing in Python try to give examples for all\n\ntype Alias1 = int\ntype Alias2 = str\ntype Alias3 = float\n\ntype AliasToAnotherAlias = Alias1\n"
expression: result
input_file: typechecker/test_data/inputs/symbol_table/type_alias.py
---
-------------------
global scope:
Symbols:
Alias1
- Declarations:
--: TypeAlias {
declaration_path: DeclarationPath {
module_name: [REDACTED]",
node: Node {
start: 81,
end: 98,
},
},
type_alias_node: TypeAlias {
node: Node {
start: 81,
end: 98,
},
name: "Alias1",
type_params: [],
value: Name(
Name {
node: Node {
start: 95,
end: 98,
},
id: "int",
},
),
},
}
Alias2
- Declarations:
--: TypeAlias {
declaration_path: DeclarationPath {
module_name: [REDACTED]",
node: Node {
start: 99,
end: 116,
},
},
type_alias_node: TypeAlias {
node: Node {
start: 99,
end: 116,
},
name: "Alias2",
type_params: [],
value: Name(
Name {
node: Node {
start: 113,
end: 116,
},
id: "str",
},
),
},
}
Alias3
- Declarations:
--: TypeAlias {
declaration_path: DeclarationPath {
module_name: [REDACTED]",
node: Node {
start: 117,
end: 136,
},
},
type_alias_node: TypeAlias {
node: Node {
start: 117,
end: 136,
},
name: "Alias3",
type_params: [],
value: Name(
Name {
node: Node {
start: 131,
end: 136,
},
id: "float",
},
),
},
}
AliasToAnotherAlias
- Declarations:
--: TypeAlias {
declaration_path: DeclarationPath {
module_name: [REDACTED]",
node: Node {
start: 138,
end: 171,
},
},
type_alias_node: TypeAlias {
node: Node {
start: 138,
end: 171,
},
name: "AliasToAnotherAlias",
type_params: [],
value: Name(
Name {
node: Node {
start: 165,
end: 171,
},
id: "Alias1",
},
),
},
}

all scopes:
-------------------

0 comments on commit 72fe36b

Please sign in to comment.