nac3standalone: iteration over multiple typevar assignment in the same line
This commit is contained in:
parent
34105b4f0e
commit
49240a80ad
|
@ -24,7 +24,7 @@ pub struct DefinitionId(pub usize);
|
||||||
|
|
||||||
pub mod composer;
|
pub mod composer;
|
||||||
pub mod helper;
|
pub mod helper;
|
||||||
mod type_annotation;
|
pub mod type_annotation;
|
||||||
use composer::*;
|
use composer::*;
|
||||||
use type_annotation::*;
|
use type_annotation::*;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -3,8 +3,9 @@ use inkwell::{
|
||||||
targets::*,
|
targets::*,
|
||||||
OptimizationLevel,
|
OptimizationLevel,
|
||||||
};
|
};
|
||||||
use nac3core::typecheck::type_inferencer::PrimitiveStore;
|
use nac3core::typecheck::{type_inferencer::PrimitiveStore, typedef::{Type, Unifier}};
|
||||||
use nac3parser::{ast::{Expr, ExprKind, StmtKind}, parser};
|
use nac3parser::{ast::{Expr, ExprKind, StmtKind}, parser};
|
||||||
|
use parking_lot::RwLock;
|
||||||
use std::{borrow::Borrow, env};
|
use std::{borrow::Borrow, env};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::{collections::HashMap, path::Path, sync::Arc, time::SystemTime};
|
use std::{collections::HashMap, path::Path, sync::Arc, time::SystemTime};
|
||||||
|
@ -15,7 +16,11 @@ use nac3core::{
|
||||||
WorkerRegistry,
|
WorkerRegistry,
|
||||||
},
|
},
|
||||||
symbol_resolver::SymbolResolver,
|
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,
|
typecheck::typedef::FunSignature,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,25 +73,84 @@ fn main() {
|
||||||
|
|
||||||
for stmt in parser_result.into_iter() {
|
for stmt in parser_result.into_iter() {
|
||||||
if let StmtKind::Assign { targets, value, .. } = &stmt.node {
|
if let StmtKind::Assign { targets, value, .. } = &stmt.node {
|
||||||
|
fn handle_typevar_definition(
|
||||||
|
var: &Expr,
|
||||||
|
resolver: &(dyn SymbolResolver + Send + Sync),
|
||||||
|
def_list: &[Arc<RwLock<TopLevelDef>>],
|
||||||
|
unifier: &mut Unifier,
|
||||||
|
primitives: &PrimitiveStore,
|
||||||
|
) -> Result<Type, String> {
|
||||||
|
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<Type, String> {
|
||||||
|
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::<Result<Vec<_>, _>>()?;
|
||||||
|
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(
|
fn handle_assignment_pattern(
|
||||||
targets: &[Expr],
|
targets: &[Expr],
|
||||||
value: &Expr,
|
value: &Expr,
|
||||||
resolver: &(dyn SymbolResolver + Send + Sync),
|
resolver: &(dyn SymbolResolver + Send + Sync),
|
||||||
internal_resolver: &ResolverInternal,
|
internal_resolver: &ResolverInternal,
|
||||||
|
def_list: &[Arc<RwLock<TopLevelDef>>],
|
||||||
|
unifier: &mut Unifier,
|
||||||
|
primitives: &PrimitiveStore,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if targets.len() == 1 {
|
if targets.len() == 1 {
|
||||||
match &targets[0].node {
|
match &targets[0].node {
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
let val = parse_parameter_default_value(value.borrow(), resolver)?;
|
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);
|
internal_resolver.add_module_global(*id, val);
|
||||||
Ok(())
|
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::List { elts, .. }
|
||||||
| ExprKind::Tuple { 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => unreachable!("cannot be assigned")
|
_ => Err(format!("assignment to {:?} is not supported at {}", targets[0], targets[0].location))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match &value.node {
|
match &value.node {
|
||||||
|
@ -105,7 +169,10 @@ fn main() {
|
||||||
std::slice::from_ref(tar),
|
std::slice::from_ref(tar),
|
||||||
val,
|
val,
|
||||||
resolver,
|
resolver,
|
||||||
internal_resolver
|
internal_resolver,
|
||||||
|
def_list,
|
||||||
|
unifier,
|
||||||
|
primitives
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
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);
|
eprintln!("{}", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue