forked from M-Labs/nac3
nac3core: optimized by using HashSet
This commit is contained in:
parent
d81249cabe
commit
6633eabb89
|
@ -3,18 +3,18 @@ use crate::typecheck::typedef::TypeEnum;
|
||||||
use super::type_inferencer::Inferencer;
|
use super::type_inferencer::Inferencer;
|
||||||
use super::typedef::Type;
|
use super::typedef::Type;
|
||||||
use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind};
|
use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind};
|
||||||
use std::iter::once;
|
use std::{collections::HashSet, iter::once};
|
||||||
|
|
||||||
impl<'a> Inferencer<'a> {
|
impl<'a> Inferencer<'a> {
|
||||||
fn check_pattern(
|
fn check_pattern(
|
||||||
&mut self,
|
&mut self,
|
||||||
pattern: &Expr<Option<Type>>,
|
pattern: &Expr<Option<Type>>,
|
||||||
defined_identifiers: &mut Vec<String>,
|
defined_identifiers: &mut HashSet<String>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
match &pattern.node {
|
match &pattern.node {
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
if !defined_identifiers.contains(id) {
|
if !defined_identifiers.contains(id) {
|
||||||
defined_identifiers.push(id.clone());
|
defined_identifiers.insert(id.clone());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ impl<'a> Inferencer<'a> {
|
||||||
fn check_expr(
|
fn check_expr(
|
||||||
&mut self,
|
&mut self,
|
||||||
expr: &Expr<Option<Type>>,
|
expr: &Expr<Option<Type>>,
|
||||||
defined_identifiers: &mut Vec<String>,
|
defined_identifiers: &mut HashSet<String>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// there are some cases where the custom field is None
|
// there are some cases where the custom field is None
|
||||||
if let Some(ty) = &expr.custom {
|
if let Some(ty) = &expr.custom {
|
||||||
|
@ -58,7 +58,7 @@ impl<'a> Inferencer<'a> {
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
if !defined_identifiers.contains(id) {
|
if !defined_identifiers.contains(id) {
|
||||||
if self.function_data.resolver.get_identifier_def(id).is_some() {
|
if self.function_data.resolver.get_identifier_def(id).is_some() {
|
||||||
defined_identifiers.push(id.clone());
|
defined_identifiers.insert(id.clone());
|
||||||
} else {
|
} else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"unknown identifier {} (use before def?) at {}",
|
"unknown identifier {} (use before def?) at {}",
|
||||||
|
@ -104,10 +104,10 @@ impl<'a> Inferencer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Lambda { args, body } => {
|
ExprKind::Lambda { args, body } => {
|
||||||
let mut defined_identifiers = defined_identifiers.to_vec();
|
let mut defined_identifiers = defined_identifiers.clone();
|
||||||
for arg in args.args.iter() {
|
for arg in args.args.iter() {
|
||||||
if !defined_identifiers.contains(&arg.node.arg) {
|
if !defined_identifiers.contains(&arg.node.arg) {
|
||||||
defined_identifiers.push(arg.node.arg.clone());
|
defined_identifiers.insert(arg.node.arg.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.check_expr(body, &mut defined_identifiers)?;
|
self.check_expr(body, &mut defined_identifiers)?;
|
||||||
|
@ -116,7 +116,7 @@ impl<'a> Inferencer<'a> {
|
||||||
// in our type inference stage, we already make sure that there is only 1 generator
|
// in our type inference stage, we already make sure that there is only 1 generator
|
||||||
let ast::Comprehension { target, iter, ifs, .. } = &generators[0];
|
let ast::Comprehension { target, iter, ifs, .. } = &generators[0];
|
||||||
self.check_expr(iter, defined_identifiers)?;
|
self.check_expr(iter, defined_identifiers)?;
|
||||||
let mut defined_identifiers = defined_identifiers.to_vec();
|
let mut defined_identifiers = defined_identifiers.clone();
|
||||||
self.check_pattern(target, &mut defined_identifiers)?;
|
self.check_pattern(target, &mut defined_identifiers)?;
|
||||||
for term in once(elt.as_ref()).chain(ifs.iter()) {
|
for term in once(elt.as_ref()).chain(ifs.iter()) {
|
||||||
self.check_expr(term, &mut defined_identifiers)?;
|
self.check_expr(term, &mut defined_identifiers)?;
|
||||||
|
@ -143,7 +143,7 @@ impl<'a> Inferencer<'a> {
|
||||||
fn check_stmt(
|
fn check_stmt(
|
||||||
&mut self,
|
&mut self,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
defined_identifiers: &mut Vec<String>,
|
defined_identifiers: &mut HashSet<String>,
|
||||||
) -> Result<bool, String> {
|
) -> Result<bool, String> {
|
||||||
match &stmt.node {
|
match &stmt.node {
|
||||||
StmtKind::For { target, iter, body, orelse, .. } => {
|
StmtKind::For { target, iter, body, orelse, .. } => {
|
||||||
|
@ -167,7 +167,7 @@ impl<'a> Inferencer<'a> {
|
||||||
|
|
||||||
for ident in body_identifiers.iter() {
|
for ident in body_identifiers.iter() {
|
||||||
if !defined_identifiers.contains(ident) && orelse_identifiers.contains(ident) {
|
if !defined_identifiers.contains(ident) && orelse_identifiers.contains(ident) {
|
||||||
defined_identifiers.push(ident.clone())
|
defined_identifiers.insert(ident.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(body_returned && orelse_returned)
|
Ok(body_returned && orelse_returned)
|
||||||
|
@ -217,7 +217,7 @@ impl<'a> Inferencer<'a> {
|
||||||
pub fn check_block(
|
pub fn check_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
block: &[Stmt<Option<Type>>],
|
block: &[Stmt<Option<Type>>],
|
||||||
defined_identifiers: &mut Vec<String>,
|
defined_identifiers: &mut HashSet<String>,
|
||||||
) -> Result<bool, String> {
|
) -> Result<bool, String> {
|
||||||
let mut ret = false;
|
let mut ret = false;
|
||||||
for stmt in block {
|
for stmt in block {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::convert::{From, TryInto};
|
use std::convert::{From, TryInto};
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use std::{cell::RefCell, sync::Arc};
|
use std::{cell::RefCell, sync::Arc};
|
||||||
|
@ -45,7 +45,7 @@ pub struct FunctionData {
|
||||||
|
|
||||||
pub struct Inferencer<'a> {
|
pub struct Inferencer<'a> {
|
||||||
pub top_level: &'a TopLevelContext,
|
pub top_level: &'a TopLevelContext,
|
||||||
pub defined_identifiers: Vec<String>,
|
pub defined_identifiers: HashSet<String>,
|
||||||
pub function_data: &'a mut FunctionData,
|
pub function_data: &'a mut FunctionData,
|
||||||
pub unifier: &'a mut Unifier,
|
pub unifier: &'a mut Unifier,
|
||||||
pub primitives: &'a PrimitiveStore,
|
pub primitives: &'a PrimitiveStore,
|
||||||
|
@ -161,7 +161,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
||||||
ast::ExprKind::Name { id, .. } => {
|
ast::ExprKind::Name { id, .. } => {
|
||||||
if !self.defined_identifiers.contains(id) {
|
if !self.defined_identifiers.contains(id) {
|
||||||
if self.function_data.resolver.get_identifier_def(id.as_str()).is_some() {
|
if self.function_data.resolver.get_identifier_def(id.as_str()).is_some() {
|
||||||
self.defined_identifiers.push(id.clone());
|
self.defined_identifiers.insert(id.clone());
|
||||||
} else {
|
} else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"unknown identifier {} (use before def?) at {}",
|
"unknown identifier {} (use before def?) at {}",
|
||||||
|
@ -215,7 +215,7 @@ impl<'a> Inferencer<'a> {
|
||||||
match &pattern.node {
|
match &pattern.node {
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
if !self.defined_identifiers.contains(id) {
|
if !self.defined_identifiers.contains(id) {
|
||||||
self.defined_identifiers.push(id.clone());
|
self.defined_identifiers.insert(id.clone());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@ impl<'a> Inferencer<'a> {
|
||||||
for arg in args.args.iter() {
|
for arg in args.args.iter() {
|
||||||
let name = &arg.node.arg;
|
let name = &arg.node.arg;
|
||||||
if !defined_identifiers.contains(name) {
|
if !defined_identifiers.contains(name) {
|
||||||
defined_identifiers.push(name.clone());
|
defined_identifiers.insert(name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let fn_args: Vec<_> = args
|
let fn_args: Vec<_> = args
|
||||||
|
|
Loading…
Reference in New Issue