1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00
This commit is contained in:
schaeff 2019-08-02 12:49:43 +02:00
parent c84c0c5ca7
commit 266320f7d9
7 changed files with 473 additions and 226 deletions

16
t.code Normal file
View file

@ -0,0 +1,16 @@
struct Foo {
a: field,
b: field[2],
}
struct Bar {
a: Foo,
b: field[2]
}
def f(Foo a) -> (Foo):
return a
def main(Bar a) -> (Foo):
return f(a.a)

View file

@ -7,15 +7,25 @@ use zokrates_pest_ast as pest;
impl<'ast, T: Field> From<pest::File<'ast>> for absy::Module<'ast, T> {
fn from(prog: pest::File<'ast>) -> absy::Module<T> {
absy::Module {
types: prog
// types: prog
// .structs
// .into_iter()
// .map(|t| absy::TypeDeclarationNode::from(t))
// .collect(),
// functions: prog
// .functions
// .into_iter()
// .map(|f| absy::FunctionDeclarationNode::from(f))
// .collect(),
symbols: prog
.structs
.into_iter()
.map(|t| absy::TypeDeclarationNode::from(t))
.collect(),
functions: prog
.functions
.into_iter()
.map(|f| absy::FunctionDeclarationNode::from(f))
.map(|t| absy::SymbolDeclarationNode::from(t))
.chain(
prog.functions
.into_iter()
.map(|f| absy::SymbolDeclarationNode::from(f)),
)
.collect(),
imports: prog
.imports
@ -35,8 +45,8 @@ impl<'ast> From<pest::ImportDirective<'ast>> for absy::ImportNode<'ast> {
}
}
impl<'ast> From<pest::StructDefinition<'ast>> for absy::TypeDeclarationNode<'ast> {
fn from(definition: pest::StructDefinition<'ast>) -> absy::TypeDeclarationNode {
impl<'ast, T: Field> From<pest::StructDefinition<'ast>> for absy::SymbolDeclarationNode<'ast, T> {
fn from(definition: pest::StructDefinition<'ast>) -> absy::SymbolDeclarationNode<'ast, T> {
use absy::NodeValue;
let span = definition.span;
@ -52,9 +62,9 @@ impl<'ast> From<pest::StructDefinition<'ast>> for absy::TypeDeclarationNode<'ast
}
.span(span.clone()); // TODO check
absy::TypeDeclaration {
absy::SymbolDeclaration {
id,
symbol: absy::TypeSymbol::Here(ty),
symbol: absy::Symbol::HereType(ty),
}
.span(span)
}
@ -74,8 +84,8 @@ impl<'ast> From<pest::StructField<'ast>> for absy::StructFieldNode<'ast> {
}
}
impl<'ast, T: Field> From<pest::Function<'ast>> for absy::FunctionDeclarationNode<'ast, T> {
fn from(function: pest::Function<'ast>) -> absy::FunctionDeclarationNode<T> {
impl<'ast, T: Field> From<pest::Function<'ast>> for absy::SymbolDeclarationNode<'ast, T> {
fn from(function: pest::Function<'ast>) -> absy::SymbolDeclarationNode<T> {
use absy::NodeValue;
let span = function.span;
@ -115,9 +125,9 @@ impl<'ast, T: Field> From<pest::Function<'ast>> for absy::FunctionDeclarationNod
}
.span(span.clone()); // TODO check
absy::FunctionDeclaration {
absy::SymbolDeclaration {
id,
symbol: absy::FunctionSymbol::Here(function),
symbol: absy::Symbol::HereFunction(function),
}
.span(span)
}

View file

@ -31,11 +31,8 @@ pub type ModuleId = String;
/// A collection of `Module`s
pub type Modules<'ast, T> = HashMap<ModuleId, Module<'ast, T>>;
/// A collection of `FunctionDeclaration`. Duplicates are allowed here as they are fine syntatically.
pub type FunctionDeclarations<'ast, T> = Vec<FunctionDeclarationNode<'ast, T>>;
/// A collection of `StructDeclaration`. Duplicates are allowed here as they are fine syntatically.
pub type TypeDeclarations<'ast> = Vec<TypeDeclarationNode<'ast>>;
/// A collection of `SymbolDeclaration`. Duplicates are allowed here as they are fine syntatically.
pub type Declarations<'ast, T> = Vec<SymbolDeclarationNode<'ast, T>>;
/// A `Program` is a collection of `Module`s and an id of the main `Module`
pub struct Program<'ast, T: Field> {
@ -45,34 +42,26 @@ pub struct Program<'ast, T: Field> {
/// A declaration of a `FunctionSymbol`, be it from an import or a function definition
#[derive(PartialEq, Debug, Clone)]
pub struct FunctionDeclaration<'ast, T: Field> {
pub struct SymbolDeclaration<'ast, T: Field> {
pub id: Identifier<'ast>,
pub symbol: FunctionSymbol<'ast, T>,
pub symbol: Symbol<'ast, T>,
}
/// A declaration of a `TypeSymbol`, be it from an import or a function definition
#[derive(PartialEq, Debug, Clone)]
pub struct TypeDeclaration<'ast> {
pub id: Identifier<'ast>,
pub symbol: TypeSymbol<'ast>,
pub enum Symbol<'ast, T: Field> {
HereType(StructTypeNode<'ast>),
HereFunction(FunctionNode<'ast, T>),
There(SymbolImportNode<'ast>),
Flat(FlatEmbed),
}
impl<'ast> fmt::Display for TypeDeclaration<'ast> {
impl<'ast, T: Field> fmt::Display for SymbolDeclaration<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.symbol {
TypeSymbol::Here(ref s) => write!(f, "struct {} {}", self.id, s),
}
}
}
type TypeDeclarationNode<'ast> = Node<TypeDeclaration<'ast>>;
impl<'ast, T: Field> fmt::Display for FunctionDeclaration<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.symbol {
FunctionSymbol::Here(ref fun) => write!(f, "def {}{}", self.id, fun),
FunctionSymbol::There(ref import) => write!(f, "import {} as {}", import, self.id),
FunctionSymbol::Flat(ref flat_fun) => write!(
Symbol::HereType(ref t) => write!(f, "struct {} {}", self.id, t),
Symbol::HereFunction(ref fun) => write!(f, "def {}{}", self.id, fun),
Symbol::There(ref import) => write!(f, "import {} as {}", import, self.id),
Symbol::Flat(ref flat_fun) => write!(
f,
"def {}{}:\n\t// hidden",
self.id,
@ -82,31 +71,30 @@ impl<'ast, T: Field> fmt::Display for FunctionDeclaration<'ast, T> {
}
}
type FunctionDeclarationNode<'ast, T> = Node<FunctionDeclaration<'ast, T>>;
type SymbolDeclarationNode<'ast, T> = Node<SymbolDeclaration<'ast, T>>;
/// A module as a collection of `FunctionDeclaration`s
#[derive(Clone, PartialEq)]
pub struct Module<'ast, T: Field> {
/// Structs of the module
pub types: TypeDeclarations<'ast>,
/// Functions of the module
pub functions: FunctionDeclarations<'ast, T>,
/// Symbols of the module
pub symbols: Declarations<'ast, T>,
pub imports: Vec<ImportNode<'ast>>, // we still use `imports` as they are not directly converted into `FunctionDeclaration`s after the importer is done, `imports` is empty
}
/// A function, be it defined in this module, imported from another module or a flat embed
#[derive(Debug, Clone, PartialEq)]
pub enum FunctionSymbol<'ast, T: Field> {
Here(FunctionNode<'ast, T>),
There(FunctionImportNode<'ast>),
Flat(FlatEmbed),
}
// /// A function, be it defined in this module, imported from another module or a flat embed
// #[derive(Debug, Clone, PartialEq)]
// pub enum FunctionSymbol<'ast, T: Field> {
// Here(FunctionNode<'ast, T>),
// There(FunctionImportNode<'ast>),
// Flat(FlatEmbed),
// }
/// A user defined type, a struct defined in this module for now // TODO allow importing types
#[derive(Debug, Clone, PartialEq)]
pub enum TypeSymbol<'ast> {
Here(StructTypeNode<'ast>),
}
// /// A user defined type, a struct defined in this module for now // TODO allow importing types
// #[derive(Debug, Clone, PartialEq)]
// pub enum TypeSymbol<'ast> {
// Here(StructTypeNode<'ast>),
// There(TypeImportNode<'ast>),
// }
/// A struct type definition
#[derive(Debug, Clone, PartialEq)]
@ -145,32 +133,32 @@ impl<'ast> fmt::Display for StructField<'ast> {
type StructFieldNode<'ast> = Node<StructField<'ast>>;
/// A function import
/// An import
#[derive(Debug, Clone, PartialEq)]
pub struct FunctionImport<'ast> {
/// the id of the function in the target module. Note: there may be many candidates as imports statements do not specify the signature
pub function_id: Identifier<'ast>,
pub struct SymbolImport<'ast> {
/// the id of the symbol in the target module. Note: there may be many candidates as imports statements do not specify the signature. In that case they must all be functions however.
pub symbol_id: Identifier<'ast>,
/// the id of the module to import from
pub module_id: ModuleId,
}
type FunctionImportNode<'ast> = Node<FunctionImport<'ast>>;
type SymbolImportNode<'ast> = Node<SymbolImport<'ast>>;
impl<'ast> FunctionImport<'ast> {
impl<'ast> SymbolImport<'ast> {
pub fn with_id_in_module<S: Into<Identifier<'ast>>, U: Into<ModuleId>>(
function_id: S,
symbol_id: S,
module_id: U,
) -> Self {
FunctionImport {
function_id: function_id.into(),
SymbolImport {
symbol_id: symbol_id.into(),
module_id: module_id.into(),
}
}
}
impl<'ast> fmt::Display for FunctionImport<'ast> {
impl<'ast> fmt::Display for SymbolImport<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} from {}", self.function_id, self.module_id)
write!(f, "{} from {}", self.symbol_id, self.module_id)
}
}
@ -184,7 +172,7 @@ impl<'ast, T: Field> fmt::Display for Module<'ast, T> {
.collect::<Vec<_>>(),
);
res.extend(
self.functions
self.symbols
.iter()
.map(|x| format!("{}", x))
.collect::<Vec<_>>(),
@ -197,13 +185,13 @@ impl<'ast, T: Field> fmt::Debug for Module<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"module(\n\timports:\n\t\t{}\n\tfunctions:\n\t\t{}\n)",
"module(\n\timports:\n\t\t{}\n\tsymbols:\n\t\t{}\n)",
self.imports
.iter()
.map(|x| format!("{:?}", x))
.collect::<Vec<_>>()
.join("\n\t\t"),
self.functions
self.symbols
.iter()
.map(|x| format!("{:?}", x))
.collect::<Vec<_>>()

View file

@ -74,13 +74,12 @@ impl<'ast, T: Field> NodeValue for Expression<'ast, T> {}
impl<'ast, T: Field> NodeValue for ExpressionList<'ast, T> {}
impl<'ast, T: Field> NodeValue for Assignee<'ast, T> {}
impl<'ast, T: Field> NodeValue for Statement<'ast, T> {}
impl<'ast, T: Field> NodeValue for FunctionDeclaration<'ast, T> {}
impl<'ast> NodeValue for TypeDeclaration<'ast> {}
impl<'ast, T: Field> NodeValue for SymbolDeclaration<'ast, T> {}
impl<'ast> NodeValue for StructType<'ast> {}
impl<'ast> NodeValue for StructField<'ast> {}
impl<'ast, T: Field> NodeValue for Function<'ast, T> {}
impl<'ast, T: Field> NodeValue for Module<'ast, T> {}
impl<'ast> NodeValue for FunctionImport<'ast> {}
impl<'ast> NodeValue for SymbolImport<'ast> {}
impl<'ast> NodeValue for Variable<'ast> {}
impl<'ast> NodeValue for Parameter<'ast> {}
impl<'ast> NodeValue for Import<'ast> {}

View file

@ -124,7 +124,7 @@ impl Importer {
modules: &mut HashMap<ModuleId, Module<'ast, T>>,
arena: &'ast Arena<String>,
) -> Result<Module<'ast, T>, CompileErrors> {
let mut functions: Vec<_> = vec![];
let mut symbols: Vec<_> = vec![];
for import in destination.imports {
let pos = import.pos();
@ -136,10 +136,10 @@ impl Importer {
"EMBED/sha256round" => {
let alias = alias.unwrap_or("sha256round");
functions.push(
FunctionDeclaration {
symbols.push(
SymbolDeclaration {
id: &alias,
symbol: FunctionSymbol::Flat(FlatEmbed::Sha256Round),
symbol: Symbol::Flat(FlatEmbed::Sha256Round),
}
.start_end(pos.0, pos.1),
);
@ -147,10 +147,10 @@ impl Importer {
"EMBED/unpack" => {
let alias = alias.unwrap_or("unpack");
functions.push(
FunctionDeclaration {
symbols.push(
SymbolDeclaration {
id: &alias,
symbol: FunctionSymbol::Flat(FlatEmbed::Unpack),
symbol: Symbol::Flat(FlatEmbed::Unpack),
}
.start_end(pos.0, pos.1),
);
@ -185,11 +185,11 @@ impl Importer {
modules.insert(import.source.to_string(), compiled);
functions.push(
FunctionDeclaration {
symbols.push(
SymbolDeclaration {
id: &alias,
symbol: FunctionSymbol::There(
FunctionImport::with_id_in_module(
symbol: Symbol::There(
SymbolImport::with_id_in_module(
"main",
import.source.clone(),
)
@ -218,11 +218,11 @@ impl Importer {
}
}
functions.extend(destination.functions);
symbols.extend(destination.symbols);
Ok(Module {
imports: vec![],
functions: functions,
symbols,
..destination
})
}

View file

@ -159,17 +159,17 @@ impl<'ast> Checker<'ast> {
let mut errors = vec![];
match Checker::check_single_main(modules.get(&program.main).unwrap()) {
Ok(_) => {}
Err(e) => errors.push(e),
};
// recursively type-check modules starting with `main`
match self.check_module(&program.main, &mut modules, &mut typed_modules) {
Ok(()) => {}
Err(e) => errors.extend(e),
};
match Checker::check_single_main(typed_modules.get(&program.main).unwrap()) {
Ok(_) => {}
Err(e) => errors.push(e),
};
if errors.len() > 0 {
return Err(errors);
}
@ -180,19 +180,61 @@ impl<'ast> Checker<'ast> {
})
}
fn check_type_symbol<T: Field>(
&mut self,
s: TypeSymbol<'ast>,
module_id: &ModuleId,
modules: &mut Modules<'ast, T>,
typed_modules: &mut TypedModules<'ast, T>,
) -> Result<Type, Vec<Error>> {
match s {
TypeSymbol::Here(t) => {
self.check_struct_type_declaration(t, module_id, modules, typed_modules)
}
}
}
// fn check_type_symbol<T: Field>(
// &mut self,
// s: StructTypeNode<'ast>,
// module_id: &ModuleId,
// modules: &mut Modules<'ast, T>,
// typed_modules: &mut TypedModules<'ast, T>,
// ) -> Result<Type, Vec<Error>> {
// let mut errors = vec![];
// match s {
// TypeSymbol::Here(t) => {
// self.check_struct_type_declaration(t, module_id, modules, typed_modules)
// }
// TypeSymbol::There(import_node) => {
// let pos = import_node.pos();
// let import = import_node.value;
// let res =
// match Checker::new().check_module(&import.module_id, modules, typed_modules) {
// Ok(()) => {
// match self
// .types
// .get(&import.module_id)
// .unwrap()
// .get(import.type_id)
// {
// Some(ty) => Some(ty),
// None => {
// errors.push(Error {
// pos: Some(pos),
// message: format!(
// "Type {} not found in module {}",
// import.type_id, import.module_id
// ),
// });
// None
// }
// }
// }
// Err(e) => {
// errors.extend(e);
// None
// }
// };
// // return if any errors occured
// if errors.len() > 0 {
// return Err(errors);
// }
// Ok(res.unwrap().clone())
// }
// }
// }
fn check_struct_type_declaration<T: Field>(
&mut self,
@ -235,81 +277,268 @@ impl<'ast> Checker<'ast> {
Some(module) => {
assert_eq!(module.imports.len(), 0);
for declaration in module.types {
let ids = HashSet::new();
for declaration in module.symbols {
let pos = declaration.pos();
let declaration = declaration.value;
let ty = self
.check_type_symbol(declaration.symbol, module_id, modules, typed_modules)
.unwrap();
self.types
.entry(module_id.clone())
.or_default()
.insert(declaration.id.to_string(), ty);
}
match declaration.symbol {
Symbol::HereType(t) => {
match ids.insert(declaration.id) {
true => errors.push(Error {
pos: Some(pos),
message: format!(
"Another symbol with id {} is already defined",
declaration.id,
),
}),
false => {}
};
for declaration in module.functions {
self.enter_scope();
let ty = self
.check_struct_type_declaration(t, module_id, modules, typed_modules)
.unwrap();
let pos = declaration.pos();
let declaration = declaration.value;
self.types
.entry(module_id.clone())
.or_default()
.insert(declaration.id.to_string(), ty);
}
Symbol::HereFunction(f) => {
self.enter_scope();
match self.check_function_symbol(
declaration.symbol,
module_id,
modules,
typed_modules,
) {
Ok(checked_function_symbols) => {
for funct in checked_function_symbols {
let query = FunctionQuery::new(
declaration.id.clone(),
&funct.signature(&typed_modules).inputs,
&funct
.signature(&typed_modules)
.outputs
.clone()
.into_iter()
.map(|o| Some(o))
.collect(),
);
match self.check_function(f, module_id) {
Ok(funct) => {
let query = FunctionQuery::new(
declaration.id.clone(),
&funct.signature(&typed_modules).inputs,
&funct
.signature(&typed_modules)
.outputs
.clone()
.into_iter()
.map(|o| Some(o))
.collect(),
);
let candidates = self.find_candidates(&query);
let candidates = self.find_candidates(&query);
match candidates.len() {
1 => {
errors.push(Error {
match candidates.len() {
1 => {
errors.push(Error {
pos: Some(pos),
message: format!(
"Duplicate definition for function {} with signature {}",
declaration.id,
funct.signature(&typed_modules)
),
});
}
0 => {}
_ => panic!(
"duplicate function declaration should have been caught"
),
}
ids.insert(declaration.id);
self.functions.insert(
FunctionKey::with_id(declaration.id.clone())
.signature(funct.signature(&typed_modules).clone()),
);
checked_functions.insert(
FunctionKey::with_id(declaration.id.clone())
.signature(funct.signature(&typed_modules).clone()),
funct,
);
}
Err(e) => {
errors.extend(e);
}
}
self.exit_scope();
}
Symbol::There(import) => {
let pos = import.pos();
let import = import.value;
match Checker::new().check_module(
&import.module_id,
modules,
typed_modules,
) {
Ok(()) => {
// find candidates in the checked module
let function_candidates: Vec<_> = typed_modules
.get(&import.module_id)
.unwrap()
.functions
.iter()
.filter(|(k, _)| k.id == import.symbol_id)
.map(|(_, v)| FunctionKey {
id: import.symbol_id.clone(),
signature: v.signature(&typed_modules).clone(),
})
.collect();
// find candidates in the types
let type_candidate = self
.types
.get(&import.module_id)
.map(|m| m.get(import.symbol_id));
match (function_candidates.len(), type_candidate) {
(0, Some(t)) => errors.push(Error {
pos: Some(pos),
message: format!(
"Duplicate definition for function {} with signature {}",
declaration.id,
funct.signature(&typed_modules)
"Duplicate symbol {} in module {}",
import.symbol_id, import.module_id
),
});
}),
(0, None) => unreachable!(),
_ => {
ids.insert(declaration.id);
for candidate in function_candidates {
self.functions
.insert(candidate.clone().id(declaration.id));
checked_functions.insert(
candidate.clone().id(declaration.id),
TypedFunctionSymbol::There(
candidate,
import.module_id.clone(),
),
);
}
}
}
0 => {}
_ => panic!(
"duplicate function declaration should have been caught"
),
}
self.functions.insert(
FunctionKey::with_id(declaration.id.clone())
.signature(funct.signature(&typed_modules).clone()),
);
checked_functions.insert(
FunctionKey::with_id(declaration.id.clone())
.signature(funct.signature(&typed_modules).clone()),
funct,
);
}
Err(e) => {
errors.extend(e);
}
};
}
Err(e) => {
errors.extend(e);
Symbol::Flat(funct) => {
let query = FunctionQuery::new(
declaration.id.clone(),
&funct.signature::<T>().inputs,
&funct
.signature::<T>()
.outputs
.clone()
.into_iter()
.map(|o| Some(o))
.collect(),
);
let candidates = self.find_candidates(&query);
match candidates.len() {
1 => {
errors.push(Error {
pos: Some(pos),
message: format!(
"Duplicate definition for function {} with signature {}",
declaration.id,
funct.signature::<T>()
),
});
}
0 => {}
_ => {
panic!("duplicate function declaration should have been caught")
}
}
ids.insert(declaration.id);
self.functions.insert(
FunctionKey::with_id(declaration.id.clone())
.signature(funct.signature::<T>().clone()),
);
checked_functions.insert(
FunctionKey::with_id(declaration.id.clone())
.signature(funct.signature::<T>().clone()),
TypedFunctionSymbol::Flat(funct),
);
}
}
self.exit_scope();
}
// for declaration in module.types {
// let pos = declaration.pos();
// let declaration = declaration.value;
// let ty = self
// .check_type_symbol(declaration.symbol, module_id, modules, typed_modules)
// .unwrap();
// self.types
// .entry(module_id.clone())
// .or_default()
// .insert(declaration.id.to_string(), ty);
// }
// for declaration in module.functions {
// self.enter_scope();
// let pos = declaration.pos();
// let declaration = declaration.value;
// match self.check_function_symbol(
// declaration.symbol,
// module_id,
// modules,
// typed_modules,
// ) {
// Ok(checked_function_symbols) => {
// for funct in checked_function_symbols {
// let query = FunctionQuery::new(
// declaration.id.clone(),
// &funct.signature(&typed_modules).inputs,
// &funct
// .signature(&typed_modules)
// .outputs
// .clone()
// .into_iter()
// .map(|o| Some(o))
// .collect(),
// );
// let candidates = self.find_candidates(&query);
// match candidates.len() {
// 1 => {
// errors.push(Error {
// pos: Some(pos),
// message: format!(
// "Duplicate definition for function {} with signature {}",
// declaration.id,
// funct.signature(&typed_modules)
// ),
// });
// }
// 0 => {}
// _ => panic!(
// "duplicate function declaration should have been caught"
// ),
// }
// self.functions.insert(
// FunctionKey::with_id(declaration.id.clone())
// .signature(funct.signature(&typed_modules).clone()),
// );
// checked_functions.insert(
// FunctionKey::with_id(declaration.id.clone())
// .signature(funct.signature(&typed_modules).clone()),
// funct,
// );
// }
// }
// Err(e) => {
// errors.extend(e);
// }
// }
// self.exit_scope();
// }
Some(TypedModule {
functions: checked_functions,
})
@ -336,11 +565,11 @@ impl<'ast> Checker<'ast> {
Ok(())
}
fn check_single_main<T: Field>(module: &Module<T>) -> Result<(), Error> {
fn check_single_main<T: Field>(module: &TypedModule<T>) -> Result<(), Error> {
match module
.functions
.iter()
.filter(|node| node.value.id == "main")
.filter(|(key, _)| key.id == "main")
.count()
{
1 => Ok(()),
@ -369,7 +598,7 @@ impl<'ast> Checker<'ast> {
&mut self,
funct_node: FunctionNode<'ast, T>,
module_id: &ModuleId,
) -> Result<TypedFunction<'ast, T>, Vec<Error>> {
) -> Result<TypedFunctionSymbol<'ast, T>, Vec<Error>> {
let mut errors = vec![];
let funct = funct_node.value;
@ -401,7 +630,7 @@ impl<'ast> Checker<'ast> {
return Err(errors);
}
Ok(TypedFunction {
Ok(TypedFunctionSymbol::Here(TypedFunction {
arguments: funct
.arguments
.into_iter()
@ -409,7 +638,7 @@ impl<'ast> Checker<'ast> {
.collect(),
statements: statements_checked,
signature,
})
}))
}
fn check_parameter(&self, p: ParameterNode<'ast>, module_id: &ModuleId) -> Parameter<'ast> {
@ -452,69 +681,69 @@ impl<'ast> Checker<'ast> {
}
}
fn check_function_symbol<T: Field>(
&mut self,
funct_symbol: FunctionSymbol<'ast, T>,
module_id: &ModuleId,
modules: &mut Modules<'ast, T>,
typed_modules: &mut TypedModules<'ast, T>,
) -> Result<Vec<TypedFunctionSymbol<'ast, T>>, Vec<Error>> {
let mut symbols = vec![];
let mut errors = vec![];
// fn check_function_symbol<T: Field>(
// &mut self,
// funct_symbol: FunctionSymbol<'ast, T>,
// module_id: &ModuleId,
// modules: &mut Modules<'ast, T>,
// typed_modules: &mut TypedModules<'ast, T>,
// ) -> Result<Vec<TypedFunctionSymbol<'ast, T>>, Vec<Error>> {
// let mut symbols = vec![];
// let mut errors = vec![];
match funct_symbol {
FunctionSymbol::Here(funct_node) => self
.check_function(funct_node, module_id)
.map(|f| vec![TypedFunctionSymbol::Here(f)]),
FunctionSymbol::There(import_node) => {
let pos = import_node.pos();
let import = import_node.value;
// match funct_symbol {
// FunctionSymbol::Here(funct_node) => self
// .check_function(funct_node, module_id)
// .map(|f| vec![TypedFunctionSymbol::Here(f)]),
// FunctionSymbol::There(import_node) => {
// let pos = import_node.pos();
// let import = import_node.value;
match Checker::new().check_module(&import.module_id, modules, typed_modules) {
Ok(()) => {
// find candidates in the checked module
let candidates: Vec<_> = typed_modules
.get(&import.module_id)
.unwrap()
.functions
.iter()
.filter(|(k, _)| k.id == import.function_id)
.map(|(_, v)| FunctionKey {
id: import.function_id.clone(),
signature: v.signature(&typed_modules).clone(),
})
.collect();
// match Checker::new().check_module(&import.module_id, modules, typed_modules) {
// Ok(()) => {
// // find candidates in the checked module
// let candidates: Vec<_> = typed_modules
// .get(&import.module_id)
// .unwrap()
// .functions
// .iter()
// .filter(|(k, _)| k.id == import.function_id)
// .map(|(_, v)| FunctionKey {
// id: import.function_id.clone(),
// signature: v.signature(&typed_modules).clone(),
// })
// .collect();
match candidates.len() {
0 => errors.push(Error {
pos: Some(pos),
message: format!(
"Function {} not found in module {}",
import.function_id, import.module_id
),
}),
_ => {
symbols.extend(candidates.into_iter().map(|f| {
TypedFunctionSymbol::There(f, import.module_id.clone())
}))
}
}
}
Err(e) => {
errors.extend(e);
}
};
// match candidates.len() {
// 0 => errors.push(Error {
// pos: Some(pos),
// message: format!(
// "Function {} not found in module {}",
// import.function_id, import.module_id
// ),
// }),
// _ => {
// symbols.extend(candidates.into_iter().map(|f| {
// TypedFunctionSymbol::There(f, import.module_id.clone())
// }))
// }
// }
// }
// Err(e) => {
// errors.extend(e);
// }
// };
// return if any errors occured
if errors.len() > 0 {
return Err(errors);
}
// // return if any errors occured
// if errors.len() > 0 {
// return Err(errors);
// }
Ok(symbols)
}
FunctionSymbol::Flat(flat_fun) => Ok(vec![TypedFunctionSymbol::Flat(flat_fun)]),
}
}
// Ok(symbols)
// }
// FunctionSymbol::Flat(flat_fun) => Ok(vec![TypedFunctionSymbol::Flat(flat_fun)]),
// }
// }
fn check_variable(
&self,

View file

@ -145,6 +145,11 @@ impl<'ast> FunctionKey<'ast> {
self
}
pub fn id<S: Into<Identifier<'ast>>>(mut self, id: S) -> Self {
self.id = id.into();
self
}
pub fn to_slug(&self) -> String {
format!("{}_{}", self.id, self.signature.to_slug())
}