nac3standalone: better support for global assignment
This commit is contained in:
parent
ee7c1eb11d
commit
99c103b35b
|
@ -399,7 +399,7 @@ pub fn parse_parameter_default_value(default: &ast::Expr, resolver: &(dyn Symbol
|
|||
ast::ExprKind::Name { id, .. } => {
|
||||
resolver.get_default_param_value(default).ok_or_else(
|
||||
|| format!(
|
||||
"this module global `{}` cannot be used as a default parameter at {} (should be primitive type or tuple)",
|
||||
"`{}` cannot be used as a default parameter at {} (not primitive type or tuple / not defined?)",
|
||||
id,
|
||||
default.location
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ use nac3core::{
|
|||
codegen::CodeGenContext,
|
||||
location::Location,
|
||||
symbol_resolver::{SymbolResolver, SymbolValue},
|
||||
toplevel::{DefinitionId, TopLevelDef, helper::parse_parameter_default_value},
|
||||
toplevel::{DefinitionId, TopLevelDef},
|
||||
typecheck::{
|
||||
type_inferencer::PrimitiveStore,
|
||||
typedef::{Type, Unifier},
|
||||
|
@ -17,7 +17,7 @@ pub struct ResolverInternal {
|
|||
pub id_to_type: Mutex<HashMap<StrRef, Type>>,
|
||||
pub id_to_def: Mutex<HashMap<StrRef, DefinitionId>>,
|
||||
pub class_names: Mutex<HashMap<StrRef, Type>>,
|
||||
pub module_globals: Mutex<HashMap<StrRef, ast::Expr>>,
|
||||
pub module_globals: Mutex<HashMap<StrRef, SymbolValue>>,
|
||||
}
|
||||
|
||||
impl ResolverInternal {
|
||||
|
@ -29,8 +29,8 @@ impl ResolverInternal {
|
|||
self.id_to_type.lock().insert(id, ty);
|
||||
}
|
||||
|
||||
pub fn add_module_global(&self, id: StrRef, expr: &ast::Expr) {
|
||||
self.module_globals.lock().insert(id, expr.clone());
|
||||
pub fn add_module_global(&self, id: StrRef, val: SymbolValue) {
|
||||
self.module_globals.lock().insert(id, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,10 +40,7 @@ impl SymbolResolver for Resolver {
|
|||
fn get_default_param_value(&self, expr: &ast::Expr) -> Option<SymbolValue> {
|
||||
match &expr.node {
|
||||
ast::ExprKind::Name { id, .. } => {
|
||||
let expr = self.0.module_globals.lock().get(id).cloned();
|
||||
expr.map(|x| {
|
||||
parse_parameter_default_value(&x, self).unwrap()
|
||||
})
|
||||
self.0.module_globals.lock().get(id).cloned()
|
||||
}
|
||||
_ => unimplemented!("other type of expr not supported at {}", expr.location)
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ use inkwell::{
|
|||
OptimizationLevel,
|
||||
};
|
||||
use nac3core::typecheck::type_inferencer::PrimitiveStore;
|
||||
use nac3parser::{ast::{ExprKind, StmtKind}, parser};
|
||||
use std::env;
|
||||
use nac3parser::{ast::{Expr, ExprKind, StmtKind}, parser};
|
||||
use std::{borrow::Borrow, env};
|
||||
use std::fs;
|
||||
use std::{collections::HashMap, path::Path, sync::Arc, time::SystemTime};
|
||||
|
||||
|
@ -15,7 +15,7 @@ use nac3core::{
|
|||
WorkerRegistry,
|
||||
},
|
||||
symbol_resolver::SymbolResolver,
|
||||
toplevel::{composer::TopLevelComposer, TopLevelDef},
|
||||
toplevel::{composer::TopLevelComposer, TopLevelDef, helper::parse_parameter_default_value},
|
||||
typecheck::typedef::FunSignature,
|
||||
};
|
||||
|
||||
|
@ -67,14 +67,57 @@ fn main() {
|
|||
);
|
||||
|
||||
for stmt in parser_result.into_iter() {
|
||||
// handle module globals
|
||||
if let StmtKind::Assign { targets, value, .. } = &stmt.node {
|
||||
fn handle_assignment_pattern(
|
||||
targets: &[Expr],
|
||||
value: &Expr,
|
||||
resolver: &(dyn SymbolResolver + Send + Sync),
|
||||
internal_resolver: &ResolverInternal,
|
||||
) -> Result<(), String> {
|
||||
if targets.len() == 1 {
|
||||
if let ExprKind::Name { id, .. } = &targets[0].node {
|
||||
internal_resolver.add_module_global(*id, value);
|
||||
match &targets[0].node {
|
||||
ExprKind::Name { id, .. } => {
|
||||
let val = parse_parameter_default_value(value.borrow(), resolver)?;
|
||||
internal_resolver.add_module_global(*id, val);
|
||||
Ok(())
|
||||
}
|
||||
ExprKind::List { elts, .. }
|
||||
| ExprKind::Tuple { elts, .. } => {
|
||||
handle_assignment_pattern(elts, value, resolver, internal_resolver)?;
|
||||
Ok(())
|
||||
}
|
||||
_ => unreachable!("cannot be assigned")
|
||||
}
|
||||
} else {
|
||||
unimplemented!("only single assign supported now")
|
||||
match &value.node {
|
||||
ExprKind::List { elts, .. }
|
||||
| ExprKind::Tuple { elts, .. } => {
|
||||
if elts.len() != targets.len() {
|
||||
Err(format!(
|
||||
"number of elements to unpack does not match (expect {}, found {}) at {}",
|
||||
targets.len(),
|
||||
elts.len(),
|
||||
value.location
|
||||
))
|
||||
} else {
|
||||
for (tar, val) in targets.iter().zip(elts) {
|
||||
handle_assignment_pattern(
|
||||
std::slice::from_ref(tar),
|
||||
val,
|
||||
resolver,
|
||||
internal_resolver
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
_ => Err(format!("unpack of this expression is not supported at {}", value.location))
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Err(err) = handle_assignment_pattern(targets, value, resolver.as_ref(), internal_resolver.as_ref()) {
|
||||
eprintln!("{}", err);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue