mirror of
https://github.com/mtshiba/pylyzer.git
synced 2025-08-03 13:58:17 +00:00
Allow multiple definition
This commit is contained in:
parent
ca5604f67b
commit
0fc2348eb7
3 changed files with 166 additions and 94 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -206,7 +206,7 @@ checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
|||
[[package]]
|
||||
name = "els"
|
||||
version = "0.1.11"
|
||||
source = "git+https://github.com/erg-lang/erg-language-server?branch=main#53928792101fc6e0768a1fffaa3decad3fd1ee36"
|
||||
source = "git+https://github.com/erg-lang/erg-language-server?branch=main#5b27e12f10581a40b170742dfd61a19c0796b8aa"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"erg_compiler",
|
||||
|
@ -227,7 +227,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "erg_common"
|
||||
version = "0.6.0-beta.3"
|
||||
source = "git+https://github.com/erg-lang/erg?branch=main#08aa4054a19828511ae36514276f42f35ad502ff"
|
||||
source = "git+https://github.com/erg-lang/erg?branch=main#da2ff544f9cc4f6b1f875c24e513599d5d7fc4f7"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
|
@ -237,7 +237,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "erg_compiler"
|
||||
version = "0.6.0-beta.3"
|
||||
source = "git+https://github.com/erg-lang/erg?branch=main#08aa4054a19828511ae36514276f42f35ad502ff"
|
||||
source = "git+https://github.com/erg-lang/erg?branch=main#da2ff544f9cc4f6b1f875c24e513599d5d7fc4f7"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"erg_parser",
|
||||
|
@ -246,7 +246,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "erg_parser"
|
||||
version = "0.6.0-beta.3"
|
||||
source = "git+https://github.com/erg-lang/erg?branch=main#08aa4054a19828511ae36514276f42f35ad502ff"
|
||||
source = "git+https://github.com/erg-lang/erg?branch=main#da2ff544f9cc4f6b1f875c24e513599d5d7fc4f7"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"unicode-xid 0.2.4",
|
||||
|
@ -372,9 +372,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.138"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
|
|
|
@ -52,10 +52,12 @@ pylyzer converts Python ASTs to Erg ASTs and passes them to Erg's type checker.
|
|||
|
||||
## Limitation
|
||||
|
||||
* pylyzer's type inspector only assumes (potentially) statically typed code, so you cannot use `exec`, etc.
|
||||
* pylyzer's type inspector only assumes (potentially) statically typed code, so you cannot check any code uses reflections, such as `exec`, `setattr`, etc.
|
||||
|
||||
* Type checking of compound types such as Union types is not supported yet (will be implemented soon).
|
||||
|
||||
* pylyzer has its own type declarations for the Python standard APIs. Typing of all APIs is not complete and may result in an error that such an API does not exist.
|
||||
|
||||
## TODOs
|
||||
|
||||
* [x] type checking
|
||||
|
|
|
@ -4,6 +4,7 @@ use rustpython_parser::ast::{StatementType, ExpressionType, Located, Program, Nu
|
|||
use rustpython_parser::ast::Location as PyLocation;
|
||||
|
||||
use erg_common::set::Set as HashSet;
|
||||
use erg_common::dict::Dict as HashMap;
|
||||
use erg_compiler::erg_parser::token::{Token, TokenKind, EQUAL, COLON, DOT};
|
||||
use erg_compiler::erg_parser::ast::{
|
||||
Expr, Module, Signature, VarSignature, VarPattern, Params, Identifier, VarName, DefBody, DefId, Block, Def, Literal, Args, PosArg, Accessor, ClassAttrs, ClassAttr, RecordAttrs,
|
||||
|
@ -70,20 +71,73 @@ fn op_to_token(op: Operator) -> Token {
|
|||
Token::from_str(kind, cont)
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct NameInfo {
|
||||
// last_defined_line: usize,
|
||||
defined_times: usize,
|
||||
}
|
||||
|
||||
impl NameInfo {
|
||||
pub const fn new(defined_times: usize) -> Self {
|
||||
Self {
|
||||
// last_defined_line,
|
||||
defined_times,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ASTConverter {
|
||||
namespace: Vec<String>,
|
||||
/// Erg does not allow variables to be defined multiple times, so rename them using this
|
||||
names: Vec<HashMap<String, NameInfo>>,
|
||||
}
|
||||
|
||||
impl Default for ASTConverter {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl ASTConverter {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
namespace: vec![String::from("<module>")],
|
||||
names: vec![HashMap::new()],
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_ident(name: String, loc: PyLocation) -> Identifier {
|
||||
let token = Token::new(TokenKind::Symbol, escape_name(name), loc.row(), loc.column() - 1);
|
||||
fn get_name_global(&self, name: &str) -> Option<&NameInfo> {
|
||||
for space in self.names.iter().rev() {
|
||||
if let Some(name) = space.get(name) {
|
||||
return Some(name);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn _get_mut_name_global(&mut self, name: &str) -> Option<&mut NameInfo> {
|
||||
for space in self.names.iter_mut().rev() {
|
||||
if let Some(name) = space.get_mut(name) {
|
||||
return Some(name);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn convert_ident(&self, name: String, loc: PyLocation) -> Identifier {
|
||||
let name = escape_name(name);
|
||||
let cont = if let Some(name_info) = self.get_name_global(&name) {
|
||||
if name_info.defined_times > 1 {
|
||||
// HACK: add zero-width characters as postfix
|
||||
format!("{name}{}", "\0".repeat(name_info.defined_times))
|
||||
} else {
|
||||
name
|
||||
}
|
||||
} else {
|
||||
name
|
||||
};
|
||||
let token = Token::new(TokenKind::Symbol, cont, loc.row(), loc.column() - 1);
|
||||
let name = VarName::new(token);
|
||||
let dot = Token::new(TokenKind::Dot, ".", loc.row(), loc.column() - 1);
|
||||
Identifier::new(Some(dot), name)
|
||||
|
@ -95,10 +149,10 @@ impl ASTConverter {
|
|||
ParamPattern::VarName(name)
|
||||
}
|
||||
|
||||
fn convert_nd_param(param: Parameter) -> NonDefaultParamSignature {
|
||||
fn convert_nd_param(&self, param: Parameter) -> NonDefaultParamSignature {
|
||||
let pat = Self::convert_param_pattern(param.arg, param.location);
|
||||
let t_spec = param.annotation
|
||||
.map(|anot| Self::convert_type_spec(*anot))
|
||||
.map(|anot| self.convert_type_spec(*anot))
|
||||
.map(|t_spec| TypeSpecWithOp::new(COLON, t_spec));
|
||||
NonDefaultParamSignature::new(pat, t_spec)
|
||||
}
|
||||
|
@ -108,8 +162,8 @@ impl ASTConverter {
|
|||
}
|
||||
|
||||
// TODO: defaults
|
||||
fn convert_params(args: Box<Parameters>) -> Params {
|
||||
let non_defaults = args.args.into_iter().map(Self::convert_nd_param).collect();
|
||||
fn convert_params(&self, args: Box<Parameters>) -> Params {
|
||||
let non_defaults = args.args.into_iter().map(|p| self.convert_nd_param(p)).collect();
|
||||
// let defaults = args. args.defaults.into_iter().map(convert_default_param).collect();
|
||||
Params::new(non_defaults, None, vec![], None)
|
||||
}
|
||||
|
@ -128,7 +182,7 @@ impl ASTConverter {
|
|||
}
|
||||
|
||||
/// (i, j) => $1 (i = $1[0]; j = $1[1])
|
||||
fn convert_expr_to_param(expr: Located<ExpressionType>) -> (NonDefaultParamSignature, Vec<Expr>) {
|
||||
fn convert_expr_to_param(&self, expr: Located<ExpressionType>) -> (NonDefaultParamSignature, Vec<Expr>) {
|
||||
match expr.node {
|
||||
ExpressionType::Identifier { name } => (Self::convert_for_param(name, expr.location), vec![]),
|
||||
ExpressionType::Tuple { elements } => {
|
||||
|
@ -138,9 +192,9 @@ impl ASTConverter {
|
|||
let mut block = vec![];
|
||||
for (i, elem) in elements.into_iter().enumerate() {
|
||||
let index = Literal::new(Token::new(TokenKind::NatLit, i.to_string(), elem.location.row(), elem.location.column() - 1));
|
||||
let (param, mut blocks) = Self::convert_expr_to_param(elem);
|
||||
let (param, mut blocks) = self.convert_expr_to_param(elem);
|
||||
let sig = Signature::Var(VarSignature::new(Self::param_pattern_to_var(param.pat), param.t_spec.map(|t| t.t_spec)));
|
||||
let method = tmp_expr.clone().attr_expr(Self::convert_ident("__Tuple_getitem__".to_string(), expr.location));
|
||||
let method = tmp_expr.clone().attr_expr(self.convert_ident("__Tuple_getitem__".to_string(), expr.location));
|
||||
let args = Args::new(vec![PosArg::new(Expr::Lit(index))], vec![], None);
|
||||
let tuple_acc = method.call_expr(args);
|
||||
let body = DefBody::new(EQUAL, Block::new(vec![tuple_acc]), DefId(0));
|
||||
|
@ -159,7 +213,7 @@ impl ASTConverter {
|
|||
}
|
||||
|
||||
fn convert_for_body(&mut self, lhs: Located<ExpressionType>, body: Suite) -> Lambda {
|
||||
let (param, block) = Self::convert_expr_to_param(lhs);
|
||||
let (param, block) = self.convert_expr_to_param(lhs);
|
||||
let params = Params::new(vec![param], None, vec![], None);
|
||||
let body = body.into_iter().map(|stmt| self.convert_statement(stmt, true)).collect::<Vec<_>>();
|
||||
let body = block.into_iter().chain(body).collect();
|
||||
|
@ -168,10 +222,10 @@ impl ASTConverter {
|
|||
Lambda::new(sig, op, Block::new(body), DefId(0))
|
||||
}
|
||||
|
||||
fn convert_type_spec(expr: Located<ExpressionType>) -> TypeSpec {
|
||||
fn convert_type_spec(&self, expr: Located<ExpressionType>) -> TypeSpec {
|
||||
match expr.node {
|
||||
ExpressionType::Identifier { name } =>
|
||||
TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple(SimpleTypeSpec::new(Self::convert_ident(name, expr.location), ConstArgs::empty()))),
|
||||
TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple(SimpleTypeSpec::new(self.convert_ident(name, expr.location), ConstArgs::empty()))),
|
||||
_other => TypeSpec::Infer(Token::new(TokenKind::UBar, "_", expr.location.row(), expr.location.column() - 1)),
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +249,7 @@ impl ASTConverter {
|
|||
(l_brace, r_brace)
|
||||
}
|
||||
|
||||
fn convert_expr(expr: Located<ExpressionType>) -> Expr {
|
||||
fn convert_expr(&self, expr: Located<ExpressionType>) -> Expr {
|
||||
match expr.node {
|
||||
ExpressionType::Number { value } => {
|
||||
let (kind, cont) = match value {
|
||||
|
@ -228,33 +282,33 @@ impl ASTConverter {
|
|||
Expr::Lit(Literal::new(Token::new(TokenKind::EllipsisLit, "Ellipsis", expr.location.row(), expr.location.column() - 1)))
|
||||
}
|
||||
ExpressionType::IfExpression { test, body, orelse } => {
|
||||
let block = Self::convert_expr(*body);
|
||||
let block = self.convert_expr(*body);
|
||||
let params = Params::new(vec![], None, vec![], None);
|
||||
let sig = LambdaSignature::new(params.clone(), None, TypeBoundSpecs::empty());
|
||||
let body = Lambda::new(sig, Token::DUMMY, Block::new(vec![block]), DefId(0));
|
||||
let test = Self::convert_expr(*test);
|
||||
let if_ident = Self::convert_ident("if".to_string(), expr.location);
|
||||
let test = self.convert_expr(*test);
|
||||
let if_ident = self.convert_ident("if".to_string(), expr.location);
|
||||
let if_acc = Expr::Accessor(Accessor::Ident(if_ident));
|
||||
let else_block = Self::convert_expr(*orelse);
|
||||
let else_block = self.convert_expr(*orelse);
|
||||
let sig = LambdaSignature::new(params, None, TypeBoundSpecs::empty());
|
||||
let else_body = Lambda::new(sig, Token::DUMMY, Block::new(vec![else_block]), DefId(0));
|
||||
let args = Args::new(vec![PosArg::new(test), PosArg::new(Expr::Lambda(body)), PosArg::new(Expr::Lambda(else_body))], vec![], None);
|
||||
if_acc.call_expr(args)
|
||||
}
|
||||
ExpressionType::Call { function, args, keywords: _ } => {
|
||||
let function = Self::convert_expr(*function);
|
||||
let pos_args = args.into_iter().map(|ex| PosArg::new(Self::convert_expr(ex))).collect::<Vec<_>>();
|
||||
let function = self.convert_expr(*function);
|
||||
let pos_args = args.into_iter().map(|ex| PosArg::new(self.convert_expr(ex))).collect::<Vec<_>>();
|
||||
let args = Args::new(pos_args, vec![], None);
|
||||
function.call_expr(args)
|
||||
}
|
||||
ExpressionType::Binop { a, op, b } => {
|
||||
let lhs = Self::convert_expr(*a);
|
||||
let rhs = Self::convert_expr(*b);
|
||||
let lhs = self.convert_expr(*a);
|
||||
let rhs = self.convert_expr(*b);
|
||||
let op = op_to_token(op);
|
||||
Expr::BinOp(BinOp::new(op, lhs, rhs))
|
||||
}
|
||||
ExpressionType::Unop { op, a } => {
|
||||
let rhs = Self::convert_expr(*a);
|
||||
let rhs = self.convert_expr(*a);
|
||||
let (kind, cont) = match op {
|
||||
UnaryOperator::Pos => (TokenKind::PrePlus, "+"),
|
||||
// UnaryOperator::Not => (TokenKind::PreBitNot, "not"),
|
||||
|
@ -267,8 +321,8 @@ impl ASTConverter {
|
|||
}
|
||||
// TODO
|
||||
ExpressionType::BoolOp { op, mut values } => {
|
||||
let lhs = Self::convert_expr(values.remove(0));
|
||||
let rhs = Self::convert_expr(values.remove(0));
|
||||
let lhs = self.convert_expr(values.remove(0));
|
||||
let rhs = self.convert_expr(values.remove(0));
|
||||
let (kind, cont) = match op {
|
||||
BooleanOperator::And => (TokenKind::AndOp, "and"),
|
||||
BooleanOperator::Or => (TokenKind::OrOp, "or"),
|
||||
|
@ -278,8 +332,8 @@ impl ASTConverter {
|
|||
}
|
||||
// TODO: multiple comparisons
|
||||
ExpressionType::Compare { mut vals, mut ops } => {
|
||||
let lhs = Self::convert_expr(vals.remove(0));
|
||||
let rhs = Self::convert_expr(vals.remove(0));
|
||||
let lhs = self.convert_expr(vals.remove(0));
|
||||
let rhs = self.convert_expr(vals.remove(0));
|
||||
let (kind, cont) = match ops.remove(0) {
|
||||
Comparison::Equal => (TokenKind::Equal, "=="),
|
||||
Comparison::NotEqual => (TokenKind::NotEq, "!="),
|
||||
|
@ -296,17 +350,17 @@ impl ASTConverter {
|
|||
Expr::BinOp(BinOp::new(op, lhs, rhs))
|
||||
}
|
||||
ExpressionType::Identifier { name } => {
|
||||
let ident = Self::convert_ident(name, expr.location);
|
||||
let ident = self.convert_ident(name, expr.location);
|
||||
Expr::Accessor(Accessor::Ident(ident))
|
||||
}
|
||||
ExpressionType::Attribute { value, name } => {
|
||||
let obj = Self::convert_expr(*value);
|
||||
let name = Self::convert_ident(name, expr.location);
|
||||
let obj = self.convert_expr(*value);
|
||||
let name = self.convert_ident(name, expr.location);
|
||||
Expr::Accessor(Accessor::attr(obj, name))
|
||||
}
|
||||
ExpressionType::Lambda { args, body } => {
|
||||
let params = Self::convert_params(args);
|
||||
let body = vec![Self::convert_expr(*body)];
|
||||
let params = self.convert_params(args);
|
||||
let body = vec![self.convert_expr(*body)];
|
||||
let sig = LambdaSignature::new(params, None, TypeBoundSpecs::empty());
|
||||
let op = Token::from_str(TokenKind::ProcArrow, "=>");
|
||||
Expr::Lambda(Lambda::new(sig, op, Block::new(body), DefId(0)))
|
||||
|
@ -314,7 +368,7 @@ impl ASTConverter {
|
|||
ExpressionType::List { elements } => {
|
||||
let (l_sqbr, r_sqbr) = Self::gen_enclosure_tokens(TokenKind::LSqBr, elements.iter(), expr.location);
|
||||
let elements = elements.into_iter()
|
||||
.map(|ex| PosArg::new(Self::convert_expr(ex)))
|
||||
.map(|ex| PosArg::new(self.convert_expr(ex)))
|
||||
.collect::<Vec<_>>();
|
||||
let elems = Args::new(elements, vec![], None);
|
||||
Expr::Array(Array::Normal(NormalArray::new(l_sqbr, r_sqbr, elems)))
|
||||
|
@ -322,7 +376,7 @@ impl ASTConverter {
|
|||
ExpressionType::Set { elements } => {
|
||||
let (l_brace, r_brace) = Self::gen_enclosure_tokens(TokenKind::LBrace, elements.iter(), expr.location);
|
||||
let elements = elements.into_iter()
|
||||
.map(|ex| PosArg::new(Self::convert_expr(ex)))
|
||||
.map(|ex| PosArg::new(self.convert_expr(ex)))
|
||||
.collect::<Vec<_>>();
|
||||
let elems = Args::new(elements, vec![], None);
|
||||
Expr::Set(Set::Normal(NormalSet::new(l_brace, r_brace, elems)))
|
||||
|
@ -331,21 +385,21 @@ impl ASTConverter {
|
|||
let (l_brace, r_brace) = Self::gen_enclosure_tokens(TokenKind::LBrace, elements.iter().map(|(_, v)| v), expr.location);
|
||||
let kvs = elements.into_iter()
|
||||
.map(|(k, v)|
|
||||
KeyValue::new(k.map(Self::convert_expr).unwrap_or(Expr::Dummy(Dummy::empty())), Self::convert_expr(v))
|
||||
KeyValue::new(k.map(|k| self.convert_expr(k)).unwrap_or(Expr::Dummy(Dummy::empty())), self.convert_expr(v))
|
||||
).collect::<Vec<_>>();
|
||||
Expr::Dict(Dict::Normal(NormalDict::new(l_brace, r_brace, kvs)))
|
||||
}
|
||||
ExpressionType::Tuple { elements } => {
|
||||
let elements = elements.into_iter()
|
||||
.map(|ex| PosArg::new(Self::convert_expr(ex)))
|
||||
.map(|ex| PosArg::new(self.convert_expr(ex)))
|
||||
.collect::<Vec<_>>();
|
||||
let elems = Args::new(elements, vec![], None);
|
||||
Expr::Tuple(Tuple::Normal(NormalTuple::new(elems)))
|
||||
}
|
||||
ExpressionType::Subscript { a, b } => {
|
||||
let obj = Self::convert_expr(*a);
|
||||
let method = obj.attr_expr(Self::convert_ident("__getitem__".to_string(), expr.location));
|
||||
let args = Args::new(vec![PosArg::new(Self::convert_expr(*b))], vec![], None);
|
||||
let obj = self.convert_expr(*a);
|
||||
let method = obj.attr_expr(self.convert_ident("__getitem__".to_string(), expr.location));
|
||||
let args = Args::new(vec![PosArg::new(self.convert_expr(*b))], vec![], None);
|
||||
method.call_expr(args)
|
||||
}
|
||||
_other => {
|
||||
|
@ -454,13 +508,14 @@ impl ASTConverter {
|
|||
loc: PyLocation,
|
||||
) -> Expr {
|
||||
self.namespace.push(name.clone());
|
||||
let _decos = decorator_list.into_iter().map(Self::convert_expr).collect::<Vec<_>>();
|
||||
let _bases = bases.into_iter().map(Self::convert_expr).collect::<Vec<_>>();
|
||||
let ident = Self::convert_ident(name, loc);
|
||||
let _decos = decorator_list.into_iter().map(|deco| self.convert_expr(deco)).collect::<Vec<_>>();
|
||||
let _bases = bases.into_iter().map(|base| self.convert_expr(base)).collect::<Vec<_>>();
|
||||
self.register_name_info(&name);
|
||||
let ident = self.convert_ident(name, loc);
|
||||
let sig = Signature::Var(VarSignature::new(VarPattern::Ident(ident.clone()), None));
|
||||
let (base_type, methods) = self.extract_method_list(ident, body);
|
||||
let args = Args::new(vec![PosArg::new(base_type)], vec![], None);
|
||||
let class_acc = Expr::Accessor(Accessor::Ident(Self::convert_ident("Class".to_string(), loc)));
|
||||
let class_acc = Expr::Accessor(Accessor::Ident(self.convert_ident("Class".to_string(), loc)));
|
||||
let class_call = class_acc.call_expr(args);
|
||||
let body = DefBody::new(EQUAL, Block::new(vec![class_call]), DefId(0));
|
||||
let def = Def::new(sig, body);
|
||||
|
@ -469,17 +524,27 @@ impl ASTConverter {
|
|||
Expr::ClassDef(classdef)
|
||||
}
|
||||
|
||||
fn register_name_info(&mut self, name: &str) {
|
||||
if let Some(name_info) = self.names.last_mut().unwrap().get_mut(name) {
|
||||
// name_info.last_defined_line = loc.row();
|
||||
name_info.defined_times += 1;
|
||||
} else {
|
||||
self.names.last_mut().unwrap().insert(String::from(name), NameInfo::new(1));
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_statement(&mut self, stmt: Located<StatementType>, dont_call_return: bool) -> Expr {
|
||||
match stmt.node {
|
||||
StatementType::Expression { expression } => Self::convert_expr(expression),
|
||||
StatementType::Expression { expression } => self.convert_expr(expression),
|
||||
StatementType::AnnAssign { target, annotation, value } => {
|
||||
let t_spec = Self::convert_type_spec(*annotation);
|
||||
let t_spec = self.convert_type_spec(*annotation);
|
||||
match target.node {
|
||||
ExpressionType::Identifier { name } => {
|
||||
let ident = Self::convert_ident(name, stmt.location);
|
||||
self.register_name_info(&name);
|
||||
let ident = self.convert_ident(name, stmt.location);
|
||||
if let Some(value) = value {
|
||||
let sig = Signature::Var(VarSignature::new(VarPattern::Ident(ident), Some(t_spec)));
|
||||
let block = Block::new(vec![Self::convert_expr(value)]);
|
||||
let block = Block::new(vec![self.convert_expr(value)]);
|
||||
let body = DefBody::new(EQUAL, block, DefId(0));
|
||||
let def = Def::new(sig, body);
|
||||
Expr::Def(def)
|
||||
|
@ -489,9 +554,9 @@ impl ASTConverter {
|
|||
}
|
||||
}
|
||||
ExpressionType::Attribute { value: attr, name } => {
|
||||
let attr = Self::convert_expr(*attr).attr(Self::convert_ident(name, target.location));
|
||||
let attr = self.convert_expr(*attr).attr(self.convert_ident(name, target.location));
|
||||
if let Some(value) = value {
|
||||
let expr = Self::convert_expr(value);
|
||||
let expr = self.convert_expr(value);
|
||||
let adef = AttrDef::new(attr, expr);
|
||||
Expr::AttrDef(adef)
|
||||
} else {
|
||||
|
@ -507,16 +572,17 @@ impl ASTConverter {
|
|||
let lhs = targets.remove(0);
|
||||
match lhs.node {
|
||||
ExpressionType::Identifier { name } => {
|
||||
let ident = Self::convert_ident(name, stmt.location);
|
||||
self.register_name_info(&name);
|
||||
let ident = self.convert_ident(name, stmt.location);
|
||||
let sig = Signature::Var(VarSignature::new(VarPattern::Ident(ident), None));
|
||||
let block = Block::new(vec![Self::convert_expr(value)]);
|
||||
let block = Block::new(vec![self.convert_expr(value)]);
|
||||
let body = DefBody::new(EQUAL, block, DefId(0));
|
||||
let def = Def::new(sig, body);
|
||||
Expr::Def(def)
|
||||
}
|
||||
ExpressionType::Attribute { value: attr, name } => {
|
||||
let attr = Self::convert_expr(*attr).attr(Self::convert_ident(name, lhs.location));
|
||||
let expr = Self::convert_expr(value);
|
||||
let attr = self.convert_expr(*attr).attr(self.convert_ident(name, lhs.location));
|
||||
let expr = self.convert_expr(value);
|
||||
let adef = AttrDef::new(attr, expr);
|
||||
Expr::AttrDef(adef)
|
||||
}
|
||||
|
@ -526,14 +592,14 @@ impl ASTConverter {
|
|||
let tmp_ident = Identifier::new(Some(DOT), tmp_name);
|
||||
let tmp_expr = Expr::Accessor(Accessor::Ident(tmp_ident.clone()));
|
||||
let sig = Signature::Var(VarSignature::new(VarPattern::Ident(tmp_ident), None));
|
||||
let body = DefBody::new(EQUAL, Block::new(vec![Self::convert_expr(value)]), DefId(0));
|
||||
let body = DefBody::new(EQUAL, Block::new(vec![self.convert_expr(value)]), DefId(0));
|
||||
let tmp_def = Expr::Def(Def::new(sig, body));
|
||||
let mut defs = vec![tmp_def];
|
||||
for (i, elem) in elements.into_iter().enumerate() {
|
||||
let index = Literal::new(Token::new(TokenKind::NatLit, i.to_string(), elem.location.row(), elem.location.column() - 1));
|
||||
let (param, mut blocks) = Self::convert_expr_to_param(elem);
|
||||
let (param, mut blocks) = self.convert_expr_to_param(elem);
|
||||
let sig = Signature::Var(VarSignature::new(Self::param_pattern_to_var(param.pat), param.t_spec.map(|t| t.t_spec)));
|
||||
let method = tmp_expr.clone().attr_expr(Self::convert_ident("__Tuple_getitem__".to_string(), stmt.location));
|
||||
let method = tmp_expr.clone().attr_expr(self.convert_ident("__Tuple_getitem__".to_string(), stmt.location));
|
||||
let args = Args::new(vec![PosArg::new(Expr::Lit(index))], vec![], None);
|
||||
let tuple_acc = method.call_expr(args);
|
||||
let body = DefBody::new(EQUAL, Block::new(vec![tuple_acc]), DefId(0));
|
||||
|
@ -546,12 +612,13 @@ impl ASTConverter {
|
|||
_other => Expr::Dummy(Dummy::empty()),
|
||||
}
|
||||
} else {
|
||||
let value = Self::convert_expr(value);
|
||||
let value = self.convert_expr(value);
|
||||
let mut defs = vec![];
|
||||
for target in targets {
|
||||
match target.node {
|
||||
ExpressionType::Identifier { name } => {
|
||||
let ident = Self::convert_ident(name, stmt.location);
|
||||
self.register_name_info(&name);
|
||||
let ident = self.convert_ident(name, stmt.location);
|
||||
let sig = Signature::Var(VarSignature::new(VarPattern::Ident(ident), None));
|
||||
let body = DefBody::new(EQUAL, Block::new(vec![value.clone()]), DefId(0));
|
||||
let def = Expr::Def(Def::new(sig, body));
|
||||
|
@ -569,9 +636,11 @@ impl ASTConverter {
|
|||
let op = op_to_token(op);
|
||||
match target.node {
|
||||
ExpressionType::Identifier { name } => {
|
||||
let ident = Self::convert_ident(name, stmt.location);
|
||||
let val = Self::convert_expr(*value);
|
||||
let bin = BinOp::new(op, Expr::Accessor(Accessor::Ident(ident.clone())), val);
|
||||
let prev_ident = self.convert_ident(name.clone(), stmt.location);
|
||||
self.register_name_info(&name);
|
||||
let ident = self.convert_ident(name, stmt.location);
|
||||
let val = self.convert_expr(*value);
|
||||
let bin = BinOp::new(op, Expr::Accessor(Accessor::Ident(prev_ident)), val);
|
||||
let sig = Signature::Var(VarSignature::new(VarPattern::Ident(ident), None));
|
||||
let block = Block::new(vec![Expr::BinOp(bin)]);
|
||||
let body = DefBody::new(EQUAL, block, DefId(0));
|
||||
|
@ -579,8 +648,8 @@ impl ASTConverter {
|
|||
Expr::Def(def)
|
||||
}
|
||||
ExpressionType::Attribute { value: attr, name } => {
|
||||
let attr = Self::convert_expr(*attr).attr(Self::convert_ident(name, target.location));
|
||||
let val = Self::convert_expr(*value);
|
||||
let attr = self.convert_expr(*attr).attr(self.convert_ident(name, target.location));
|
||||
let val = self.convert_expr(*value);
|
||||
let bin = BinOp::new(op, Expr::Accessor(attr.clone()), val);
|
||||
let adef = AttrDef::new(attr, Expr::BinOp(bin));
|
||||
Expr::AttrDef(adef)
|
||||
|
@ -597,10 +666,11 @@ impl ASTConverter {
|
|||
returns
|
||||
} => {
|
||||
self.namespace.push(name.clone());
|
||||
let decos = decorator_list.into_iter().map(|ex| Decorator(Self::convert_expr(ex))).collect::<HashSet<_>>();
|
||||
let ident = Self::convert_ident(name, stmt.location);
|
||||
let params = Self::convert_params(args);
|
||||
let return_t = returns.map(Self::convert_type_spec);
|
||||
let decos = decorator_list.into_iter().map(|ex| Decorator(self.convert_expr(ex))).collect::<HashSet<_>>();
|
||||
self.register_name_info(&name);
|
||||
let ident = self.convert_ident(name, stmt.location);
|
||||
let params = self.convert_params(args);
|
||||
let return_t = returns.map(|ret| self.convert_type_spec(ret));
|
||||
let sig = Signature::Subr(SubrSignature::new(decos, ident, TypeBoundSpecs::empty(), params, return_t));
|
||||
let block = self.convert_block(body, BlockKind::Function);
|
||||
let body = DefBody::new(EQUAL, block, DefId(0));
|
||||
|
@ -613,8 +683,8 @@ impl ASTConverter {
|
|||
}
|
||||
StatementType::For { is_async: _, target, iter, body, orelse: _ } => {
|
||||
let block = self.convert_for_body(*target, body);
|
||||
let iter = Self::convert_expr(*iter);
|
||||
let for_ident = Self::convert_ident("for".to_string(), stmt.location);
|
||||
let iter = self.convert_expr(*iter);
|
||||
let for_ident = self.convert_ident("for".to_string(), stmt.location);
|
||||
let for_acc = Expr::Accessor(Accessor::Ident(for_ident));
|
||||
for_acc.call_expr(Args::new(vec![PosArg::new(iter), PosArg::new(Expr::Lambda(block))], vec![], None))
|
||||
}
|
||||
|
@ -622,8 +692,8 @@ impl ASTConverter {
|
|||
let block = self.convert_block(body, BlockKind::While);
|
||||
let params = Params::new(vec![], None, vec![], None);
|
||||
let body = Lambda::new(LambdaSignature::new(params, None, TypeBoundSpecs::empty()), Token::DUMMY, block, DefId(0));
|
||||
let test = Self::convert_expr(test);
|
||||
let while_ident = Self::convert_ident("while".to_string(), stmt.location);
|
||||
let test = self.convert_expr(test);
|
||||
let while_ident = self.convert_ident("while".to_string(), stmt.location);
|
||||
let while_acc = Expr::Accessor(Accessor::Ident(while_ident));
|
||||
while_acc.call_expr(Args::new(vec![PosArg::new(test), PosArg::new(Expr::Lambda(body))], vec![], None))
|
||||
}
|
||||
|
@ -632,8 +702,8 @@ impl ASTConverter {
|
|||
let params = Params::new(vec![], None, vec![], None);
|
||||
let sig = LambdaSignature::new(params.clone(), None, TypeBoundSpecs::empty());
|
||||
let body = Lambda::new(sig, Token::DUMMY, block, DefId(0));
|
||||
let test = Self::convert_expr(test);
|
||||
let if_ident = Self::convert_ident("if".to_string(), stmt.location);
|
||||
let test = self.convert_expr(test);
|
||||
let if_ident = self.convert_ident("if".to_string(), stmt.location);
|
||||
let if_acc = Expr::Accessor(Accessor::Ident(if_ident));
|
||||
if let Some(orelse) = orelse {
|
||||
let else_block = self.convert_block(orelse, BlockKind::If);
|
||||
|
@ -647,42 +717,42 @@ impl ASTConverter {
|
|||
}
|
||||
}
|
||||
StatementType::Return { value } => {
|
||||
let value = value.map(Self::convert_expr)
|
||||
let value = value.map(|val| self.convert_expr(val))
|
||||
.unwrap_or_else(||Expr::Tuple(Tuple::Normal(NormalTuple::new(Args::empty()))));
|
||||
if dont_call_return {
|
||||
value
|
||||
} else {
|
||||
let func_acc = Expr::Accessor(Accessor::Ident(Self::convert_ident(self.namespace.last().unwrap().clone(), stmt.location)));
|
||||
let return_acc = Self::convert_ident("return".to_string(), stmt.location);
|
||||
let func_acc = Expr::Accessor(Accessor::Ident(self.convert_ident(self.namespace.last().unwrap().clone(), stmt.location)));
|
||||
let return_acc = self.convert_ident("return".to_string(), stmt.location);
|
||||
let return_acc = Expr::Accessor(Accessor::attr(func_acc, return_acc));
|
||||
erg_common::log!(err "{return_acc}");
|
||||
return_acc.call_expr(Args::new(vec![PosArg::new(value)], vec![], None))
|
||||
}
|
||||
}
|
||||
StatementType::Assert { test, msg } => {
|
||||
let test = Self::convert_expr(test);
|
||||
let test = self.convert_expr(test);
|
||||
let args = if let Some(msg) = msg {
|
||||
let msg = Self::convert_expr(msg);
|
||||
let msg = self.convert_expr(msg);
|
||||
Args::new(vec![PosArg::new(test), PosArg::new(msg)], vec![], None)
|
||||
} else {
|
||||
Args::new(vec![PosArg::new(test)], vec![], None)
|
||||
};
|
||||
let assert_acc = Expr::Accessor(Accessor::Ident(Self::convert_ident("assert".to_string(), stmt.location)));
|
||||
let assert_acc = Expr::Accessor(Accessor::Ident(self.convert_ident("assert".to_string(), stmt.location)));
|
||||
assert_acc.call_expr(args)
|
||||
}
|
||||
StatementType::Import { names } => {
|
||||
let mut imports = vec![];
|
||||
for name in names {
|
||||
let import_acc = Expr::Accessor(Accessor::Ident(Self::convert_ident("__import__".to_string(), stmt.location)));
|
||||
let import_acc = Expr::Accessor(Accessor::Ident(self.convert_ident("__import__".to_string(), stmt.location)));
|
||||
let cont = format!("\"{}\"", name.symbol);
|
||||
let mod_name = Expr::Lit(Literal::new(Token::new(TokenKind::StrLit, cont, stmt.location.row(), stmt.location.column() - 1)));
|
||||
let args = Args::new(vec![PosArg::new(mod_name)], vec![], None);
|
||||
let call = import_acc.call_expr(args);
|
||||
let def = if let Some(alias) = name.alias {
|
||||
let var = VarSignature::new(VarPattern::Ident(Self::convert_ident(alias, stmt.location)), None);
|
||||
let var = VarSignature::new(VarPattern::Ident(self.convert_ident(alias, stmt.location)), None);
|
||||
Def::new(Signature::Var(var), DefBody::new(EQUAL, Block::new(vec![call]), DefId(0)))
|
||||
} else {
|
||||
let var = VarSignature::new(VarPattern::Ident(Self::convert_ident(name.symbol, stmt.location)), None);
|
||||
let var = VarSignature::new(VarPattern::Ident(self.convert_ident(name.symbol, stmt.location)), None);
|
||||
Def::new(Signature::Var(var), DefBody::new(EQUAL, Block::new(vec![call]), DefId(0)))
|
||||
};
|
||||
imports.push(Expr::Def(def));
|
||||
|
@ -690,23 +760,23 @@ impl ASTConverter {
|
|||
Expr::Dummy(Dummy::new(imports))
|
||||
}
|
||||
StatementType::ImportFrom { level: _, module, names } => {
|
||||
let import_acc = Expr::Accessor(Accessor::Ident(Self::convert_ident("__import__".to_string(), stmt.location)));
|
||||
let import_acc = Expr::Accessor(Accessor::Ident(self.convert_ident("__import__".to_string(), stmt.location)));
|
||||
let cont = format!("\"{}\"", module.clone().unwrap());
|
||||
let mod_name = Expr::Lit(Literal::new(Token::new(TokenKind::StrLit, cont, stmt.location.row(), stmt.location.column() - 1)));
|
||||
let args = Args::new(vec![PosArg::new(mod_name)], vec![], None);
|
||||
let call = import_acc.call_expr(args);
|
||||
let mod_ident = Self::convert_ident(module.unwrap(), stmt.location);
|
||||
let mod_ident = self.convert_ident(module.unwrap(), stmt.location);
|
||||
let mod_expr = Expr::Accessor(Accessor::Ident(mod_ident.clone()));
|
||||
let var = VarSignature::new(VarPattern::Ident(mod_ident), None);
|
||||
let moddef = Expr::Def(Def::new(Signature::Var(var), DefBody::new(EQUAL, Block::new(vec![call]), DefId(0))));
|
||||
let mut imports = vec![];
|
||||
for name in names {
|
||||
let var = if let Some(alias) = name.alias {
|
||||
VarSignature::new(VarPattern::Ident(Self::convert_ident(alias, stmt.location)), None)
|
||||
VarSignature::new(VarPattern::Ident(self.convert_ident(alias, stmt.location)), None)
|
||||
} else {
|
||||
VarSignature::new(VarPattern::Ident(Self::convert_ident(name.symbol.clone(), stmt.location)), None)
|
||||
VarSignature::new(VarPattern::Ident(self.convert_ident(name.symbol.clone(), stmt.location)), None)
|
||||
};
|
||||
let attr = mod_expr.clone().attr_expr(Self::convert_ident(name.symbol, stmt.location));
|
||||
let attr = mod_expr.clone().attr_expr(self.convert_ident(name.symbol, stmt.location));
|
||||
let def = Def::new(Signature::Var(var), DefBody::new(EQUAL, Block::new(vec![attr]), DefId(0)));
|
||||
imports.push(Expr::Def(def));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue