From 49240a80ad9ae20d842c0e2a3fa5d9a219eb3670 Mon Sep 17 00:00:00 2001 From: ychenfo Date: Wed, 24 Nov 2021 18:24:16 +0800 Subject: [PATCH] nac3standalone: iteration over multiple typevar assignment in the same line --- nac3core/src/toplevel/mod.rs | 2 +- nac3standalone/src/main.rs | 97 ++++++++++++++++++++++++++++++++---- 2 files changed, 89 insertions(+), 10 deletions(-) diff --git a/nac3core/src/toplevel/mod.rs b/nac3core/src/toplevel/mod.rs index f6fc15b..bcf1e62 100644 --- a/nac3core/src/toplevel/mod.rs +++ b/nac3core/src/toplevel/mod.rs @@ -24,7 +24,7 @@ pub struct DefinitionId(pub usize); pub mod composer; pub mod helper; -mod type_annotation; +pub mod type_annotation; use composer::*; use type_annotation::*; #[cfg(test)] diff --git a/nac3standalone/src/main.rs b/nac3standalone/src/main.rs index f6c4be6..55c66d9 100644 --- a/nac3standalone/src/main.rs +++ b/nac3standalone/src/main.rs @@ -3,8 +3,9 @@ use inkwell::{ targets::*, OptimizationLevel, }; -use nac3core::typecheck::type_inferencer::PrimitiveStore; +use nac3core::typecheck::{type_inferencer::PrimitiveStore, typedef::{Type, Unifier}}; use nac3parser::{ast::{Expr, ExprKind, StmtKind}, parser}; +use parking_lot::RwLock; use std::{borrow::Borrow, env}; use std::fs; use std::{collections::HashMap, path::Path, sync::Arc, time::SystemTime}; @@ -15,7 +16,11 @@ use nac3core::{ WorkerRegistry, }, symbol_resolver::SymbolResolver, - toplevel::{composer::TopLevelComposer, TopLevelDef, helper::parse_parameter_default_value}, + toplevel::{ + composer::TopLevelComposer, + TopLevelDef, helper::parse_parameter_default_value, + type_annotation::*, + }, typecheck::typedef::FunSignature, }; @@ -68,25 +73,84 @@ fn main() { for stmt in parser_result.into_iter() { if let StmtKind::Assign { targets, value, .. } = &stmt.node { + fn handle_typevar_definition( + var: &Expr, + resolver: &(dyn SymbolResolver + Send + Sync), + def_list: &[Arc>], + unifier: &mut Unifier, + primitives: &PrimitiveStore, + ) -> Result { + if let ExprKind::Call { func, args, .. } = &var.node { + if matches!(&func.node, ExprKind::Name { id, .. } if id == &"TypeVar".into()) { + let constraints = args + .iter() + .skip(1) + .map(|x| -> Result { + let ty = parse_ast_to_type_annotation_kinds( + resolver, + def_list, + unifier, + primitives, + x, + Default::default(), + )?; + get_type_from_type_annotation_kinds(def_list, unifier, primitives, &ty) + }) + .collect::, _>>()?; + Ok(unifier.get_fresh_var_with_range(&constraints).0) + } else { + Err(format!("expression {:?} cannot be handled as a TypeVar in global scope", var)) + } + } else { + Err(format!("expression {:?} cannot be handled as a TypeVar in global scope", var)) + } + } + fn handle_assignment_pattern( targets: &[Expr], value: &Expr, resolver: &(dyn SymbolResolver + Send + Sync), internal_resolver: &ResolverInternal, + def_list: &[Arc>], + unifier: &mut Unifier, + primitives: &PrimitiveStore, ) -> Result<(), String> { if targets.len() == 1 { match &targets[0].node { ExprKind::Name { id, .. } => { - let val = parse_parameter_default_value(value.borrow(), resolver)?; - internal_resolver.add_module_global(*id, val); - Ok(()) + if let Ok(var) = handle_typevar_definition( + value.borrow(), + resolver, + def_list, + unifier, + primitives, + ) { + internal_resolver.add_id_type(*id, var); + Ok(()) + } else if let Ok(val) = parse_parameter_default_value(value.borrow(), resolver) { + internal_resolver.add_module_global(*id, val); + Ok(()) + } else { + Err(format!("fails to evaluate this expression `{:?}` as a constant or TypeVar at {}", + targets[0].node, + targets[0].location, + )) + } } ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => { - handle_assignment_pattern(elts, value, resolver, internal_resolver)?; + handle_assignment_pattern( + elts, + value, + resolver, + internal_resolver, + def_list, + unifier, + primitives + )?; Ok(()) } - _ => unreachable!("cannot be assigned") + _ => Err(format!("assignment to {:?} is not supported at {}", targets[0], targets[0].location)) } } else { match &value.node { @@ -105,7 +169,10 @@ fn main() { std::slice::from_ref(tar), val, resolver, - internal_resolver + internal_resolver, + def_list, + unifier, + primitives )?; } Ok(()) @@ -115,7 +182,19 @@ fn main() { } } } - if let Err(err) = handle_assignment_pattern(targets, value, resolver.as_ref(), internal_resolver.as_ref()) { + + let def_list = composer.extract_def_list(); + let unifier = &mut composer.unifier; + let primitives = &composer.primitives_ty; + if let Err(err) = handle_assignment_pattern( + targets, + value, + resolver.as_ref(), + internal_resolver.as_ref(), + &def_list, + unifier, + primitives, + ) { eprintln!("{}", err); return; }