it almost fully works, need to fix arrays, circuits and function calls

This commit is contained in:
gluax 2021-03-26 15:47:11 -04:00
parent 5287b238cf
commit dd06df4b1d
14 changed files with 108 additions and 163 deletions

View File

@ -20,7 +20,6 @@ use crate::{
Circuit,
Expression,
Function,
GlobalConst,
PartialType,
Scope,
Span,
@ -50,6 +49,5 @@ pub enum ArenaNode<'a> {
Variable(Variable<'a>),
Circuit(Circuit<'a>),
Function(Function<'a>),
GlobalConst(GlobalConst<'a>),
Inner(AsgContextInner<'a>),
}

View File

@ -24,10 +24,18 @@ pub use circuit::*;
mod function;
pub use function::*;
mod global_const;
pub use global_const::*;
use crate::{ArenaNode, AsgContext, AsgConvertError, ImportResolver, Input, Scope};
use crate::{
node::FromAst,
ArenaNode,
AsgContext,
AsgConvertError,
DefinitionStatement,
ImportResolver,
Input,
Scope,
Statement,
Variable,
};
use leo_ast::{Identifier, PackageAccess, PackageOrPackages, Span};
use indexmap::IndexMap;
@ -52,7 +60,7 @@ pub struct Program<'a> {
pub functions: IndexMap<String, &'a Function<'a>>,
/// Maps global constant name => global const code block.
pub global_consts: IndexMap<String, &'a GlobalConst<'a>>,
pub global_consts: IndexMap<String, &'a DefinitionStatement<'a>>,
/// Maps circuit name => circuit code block.
pub circuits: IndexMap<String, &'a Circuit<'a>>,
@ -269,25 +277,36 @@ impl<'a> Program<'a> {
scope.functions.borrow_mut().insert(name.name.clone(), function);
}
println!("Helllo? {:?}", program.global_consts);
for (name, global_const) in program.global_consts.iter() {
println!("loop over p gcs name {}", name);
global_const
.variable_names
.iter()
.map(|variable_name| assert!(name.contains(&variable_name.identifier.name)));
.for_each(|variable_name| assert!(name.contains(&variable_name.identifier.name)));
// TODO re-enable
// let gc = GlobalConst::init(scope, global_const)?;
// scope.global_consts.borrow_mut().insert(name.name.clone(), gc);
let gc = <&Statement<'a>>::from_ast(scope, global_const, None)?;
if let Statement::Definition(gc) = gc {
scope.global_consts.borrow_mut().insert(name.clone(), gc);
// let split = gc.split();
// for (var_name, statement) in split.iter() {
// scope.global_consts.borrow_mut().insert(var_name.clone(), statement.get());
// }
}
}
// Load concrete definitions.
// TODO RE-ENABLE
let mut global_consts = IndexMap::new();
// for (name, global_const) in program.global_consts.iter() {
// assert_eq!(name.name, global_const.variable_name.identifier.name);
// let asg_global_const = *scope.global_consts.borrow().get(&name.name).unwrap();
for (name, global_const) in program.global_consts.iter() {
global_const
.variable_names
.iter()
.for_each(|variable_name| assert!(name.contains(&variable_name.identifier.name)));
let asg_global_const = *scope.global_consts.borrow().get(name).unwrap();
// global_consts.insert(name.name.clone(), asg_global_const);
// }
global_consts.insert(name.clone(), asg_global_const);
}
let mut functions = IndexMap::new();
for (name, function) in program.functions.iter() {
@ -365,7 +384,7 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
let mut all_circuits: IndexMap<String, &'a Circuit<'a>> = IndexMap::new();
let mut all_functions: IndexMap<String, &'a Function<'a>> = IndexMap::new();
let mut all_global_consts: IndexMap<String, &'a GlobalConst<'a>> = IndexMap::new();
let mut all_global_consts: IndexMap<String, &'a DefinitionStatement<'a>> = IndexMap::new();
let mut identifiers = InternalIdentifierGenerator { next: 0 };
for (_, program) in all_programs.into_iter() {
for (name, circuit) in program.circuits.iter() {
@ -383,11 +402,11 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
all_functions.insert(identifier, *function);
}
// TODO RE-ENABLE
// for (name, global_const) in program.global_consts.iter() {
// let identifier = format!("{}{}", identifiers.next().unwrap(), name);
// global_const.variable.borrow_mut().name.name = identifier.clone();
// all_global_consts.insert(identifier, *global_const);
// }
for (name, global_const) in program.global_consts.iter() {
let identifier = format!("{}{}", identifiers.next().unwrap(), name);
// global_const.variable.borrow_mut().name.name = identifier.clone();
all_global_consts.insert(identifier, *global_const);
}
}
leo_ast::Program {
@ -412,12 +431,20 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
.into_iter()
.map(|(_, circuit)| (circuit.name.borrow().clone(), circuit.into()))
.collect(),
global_consts: IndexMap::new(),
// TODO re-enable
// all_global_consts
// .into_iter()
// .map(|(_, global_const)| (global_const.variable.borrow().name.clone(), global_const.into()))
// .collect(),
global_consts: all_global_consts
.into_iter()
.map(|(_, global_const)| {
(
global_const
.variables
.iter()
.fold("".to_string(), |joined, variable_name| {
format!("{}, {}", joined, variable_name.borrow().name.name)
}),
global_const.into(),
)
})
.collect(),
}
}
@ -437,13 +464,21 @@ impl<'a> Into<leo_ast::Program> for &Program<'a> {
.iter()
.map(|(_, function)| (function.name.borrow().clone(), (*function).into()))
.collect(),
global_consts: IndexMap::new(),
// TODO re-enable
// self
// .global_consts
// .iter()
// .map(|(_, global_const)| (global_const.variable.borrow().name.clone(), (*global_const).into()))
// .collect(),
global_consts: self
.global_consts
.iter()
.map(|(_, global_const)| {
(
global_const
.variables
.iter()
.fold("".to_string(), |joined, variable_name| {
format!("{}, {}", joined, variable_name.borrow().name.name)
}),
(*global_const).into(),
)
})
.collect(),
}
}
}

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{AsgContext, AsgConvertError, Circuit, Function, Input, Type, Variable};
use crate::{AsgContext, AsgConvertError, Circuit, DefinitionStatement, Function, Input, Type, Variable};
use indexmap::IndexMap;
use std::cell::{Cell, RefCell};
@ -44,7 +44,7 @@ pub struct Scope<'a> {
/// Maps global constant name => global const code block.
/// TODO fixs
pub global_consts: RefCell<IndexMap<String, String>>,
pub global_consts: RefCell<IndexMap<String, &'a DefinitionStatement<'a>>>,
/// Maps circuit name => circuit.
pub circuits: RefCell<IndexMap<String, &'a Circuit<'a>>>,
@ -62,6 +62,7 @@ impl<'a> Scope<'a> {
/// If there is no parent scope, then `None` is returned.
///
pub fn resolve_variable(&self, name: &str) -> Option<&'a Variable<'a>> {
println!("rv n {}", name);
if let Some(resolved) = self.variables.borrow().get(name) {
Some(*resolved)
}

View File

@ -39,6 +39,22 @@ pub struct DefinitionStatement<'a> {
pub value: Cell<&'a Expression<'a>>,
}
impl<'a> DefinitionStatement<'a> {
pub fn split(&self) -> Vec<(String, Self)> {
self.variables
.iter()
.map(|variable| {
(variable.borrow().name.name.clone(), DefinitionStatement {
parent: self.parent.clone(),
span: self.span.clone(),
variables: vec![variable],
value: self.value.clone(),
})
})
.collect()
}
}
impl<'a> Node for DefinitionStatement<'a> {
fn span(&self) -> Option<&Span> {
self.span.as_ref()

View File

@ -477,8 +477,16 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
functions.insert(self.reduce_identifier(identifier)?, self.reduce_function(function)?);
}
self.reducer
.reduce_program(program, inputs, imports, circuits, functions)
// TODO reduce gcs
self.reducer.reduce_program(
program,
inputs,
imports,
circuits,
functions,
program.global_consts.clone(),
)
}
pub fn reduce_function_input_variable(

View File

@ -444,6 +444,7 @@ pub trait ReconstructingReducer {
imports: Vec<ImportStatement>,
circuits: IndexMap<Identifier, Circuit>,
functions: IndexMap<Identifier, Function>,
global_consts: IndexMap<String, DefinitionStatement>,
) -> Result<Program, CanonicalizeError> {
Ok(Program {
name: program.name.clone(),
@ -451,7 +452,7 @@ pub trait ReconstructingReducer {
imports,
circuits,
functions,
global_consts: IndexMap::new(),
global_consts,
})
}

View File

@ -34,9 +34,8 @@ pub fn generate_constraints<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSy
let mut resolved_program = ConstrainedProgram::<F, G>::new(program.clone());
for (_, global_const) in program.global_consts.iter() {
let value = resolved_program.enforce_expression(cs, global_const.value.get())?;
// TODO re-enable
// resolved_program.store_global_const(global_const, value);
println!("Yo");
resolved_program.enforce_definition_statement(cs, global_const)?;
}
let main = {

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::errors::{ExpressionError, FunctionError, ImportError, OutputBytesError, OutputFileError};
use crate::errors::{ExpressionError, FunctionError, ImportError, OutputBytesError, OutputFileError, StatementError};
use leo_asg::{AsgConvertError, FormattedError};
use leo_ast::{CanonicalizeError, LeoError};
use leo_imports::ImportParserError;
@ -83,6 +83,9 @@ pub enum CompilerError {
#[error("{}", _0)]
CanonicalizeError(#[from] CanonicalizeError),
#[error("{}", _0)]
StatementError(#[from] StatementError),
}
impl LeoError for CompilerError {

View File

@ -1,31 +0,0 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
//! Stores all defined names in a compiled Leo program.
use crate::{program::ConstrainedProgram, value::ConstrainedValue, GroupType};
use leo_asg::GlobalConst;
// TODO remove
// use snarkvm_models::curves::PrimeField;
// impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
// pub fn store_global_const(&mut self, global_const: &GlobalConst, value: ConstrainedValue<'a, F, G>) {
// let variable = global_const.variable.borrow();
// self.store(variable.id, value);
// }
// }

View File

@ -1,18 +0,0 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
pub mod global_const;
pub use self::global_const::*;

View File

@ -42,9 +42,6 @@ pub use expression::*;
pub mod function;
pub use function::*;
pub mod global_const;
pub use self::global_const::*;
pub mod output;
pub use output::*;

View File

@ -1,45 +0,0 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{
ast::Rule,
common::{Const, LineEnd, Variables},
expressions::Expression,
SpanDef,
};
use pest::Span;
use pest_ast::FromPest;
use serde::Serialize;
use std::fmt;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::global_const))]
pub struct GlobalConst<'ast> {
pub const_keyword: Const,
pub variables: Variables<'ast>,
pub expression: Expression<'ast>,
pub line_end: LineEnd,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for GlobalConst<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "let {} = {};", self.variables, self.expression)
}
}

View File

@ -1,20 +0,0 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
// #![allow(clippy::module_inception)]
pub mod global_const;
pub use global_const::*;

View File

@ -59,9 +59,10 @@ impl ParserContext {
let variable_names = statement
.variable_names
.iter()
.fold("".to_string(), |joined, variable_name| {
format!("{}, {}", joined, variable_name.identifier.name)
});
.map(|variable_name| variable_name.identifier.name.clone())
.collect::<Vec<String>>()
.join(",");
println!("definition VN {}", variable_names);
global_consts.insert(variable_names, statement);
}
_ => {