forked from M-Labs/nac3
1
0
Fork 0

nac3core: optimized by using HashSet

This commit is contained in:
pca006132 2021-08-27 12:36:51 +08:00
parent d81249cabe
commit 6633eabb89
2 changed files with 16 additions and 16 deletions

View File

@ -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 {

View File

@ -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