mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-18 07:11:53 +03:00
basic use case works, need to clean up, and test more advanced use cases
This commit is contained in:
parent
0b22e77301
commit
f7314625ff
@ -14,7 +14,18 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{AsgConvertError, Circuit, Expression, Function, PartialType, Scope, Span, Statement, Variable};
|
use crate::{
|
||||||
|
AsgConvertError,
|
||||||
|
Circuit,
|
||||||
|
Expression,
|
||||||
|
Function,
|
||||||
|
GlobalConst,
|
||||||
|
PartialType,
|
||||||
|
Scope,
|
||||||
|
Span,
|
||||||
|
Statement,
|
||||||
|
Variable,
|
||||||
|
};
|
||||||
|
|
||||||
/// A node in the abstract semantic graph.
|
/// A node in the abstract semantic graph.
|
||||||
pub trait Node {
|
pub trait Node {
|
||||||
@ -38,4 +49,5 @@ pub enum ArenaNode<'a> {
|
|||||||
Variable(Variable<'a>),
|
Variable(Variable<'a>),
|
||||||
Circuit(Circuit<'a>),
|
Circuit(Circuit<'a>),
|
||||||
Function(Function<'a>),
|
Function(Function<'a>),
|
||||||
|
GlobalConst(GlobalConst<'a>),
|
||||||
}
|
}
|
||||||
|
@ -14,24 +14,94 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{AsgConvertError, ExpressionStatement, Identifier, Node, Scope, Span, Type};
|
use crate::{
|
||||||
|
AsgConvertError,
|
||||||
|
Expression,
|
||||||
|
ExpressionNode,
|
||||||
|
FromAst,
|
||||||
|
InnerVariable,
|
||||||
|
Node,
|
||||||
|
Scope,
|
||||||
|
Span,
|
||||||
|
Statement,
|
||||||
|
Variable,
|
||||||
|
};
|
||||||
|
|
||||||
use uuid::Uuid;
|
use std::cell::{Cell, RefCell};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Define<'a> {
|
pub struct GlobalConst<'a> {
|
||||||
pub id: Uuid,
|
pub parent: Cell<Option<&'a Statement<'a>>>,
|
||||||
pub name: Identifier,
|
pub span: Option<Span>,
|
||||||
pub expression: ExpressionStatement<'a>,
|
pub variable: &'a Variable<'a>,
|
||||||
|
pub value: Cell<&'a Expression<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PartialEq for Define<'a> {
|
impl<'a> Node for GlobalConst<'a> {
|
||||||
fn eq(&self, other: &Define) -> bool {
|
fn span(&self) -> Option<&Span> {
|
||||||
if self.name != other.name {
|
self.span.as_ref()
|
||||||
return false;
|
|
||||||
}
|
|
||||||
self.id == other.id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Eq for Define<'a> {}
|
impl<'a> GlobalConst<'a> {
|
||||||
|
pub(super) fn init(
|
||||||
|
scope: &'a Scope<'a>,
|
||||||
|
global_const: &leo_ast::GlobalConst,
|
||||||
|
) -> Result<&'a GlobalConst<'a>, AsgConvertError> {
|
||||||
|
let type_ = global_const
|
||||||
|
.type_
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| scope.resolve_ast_type(&x))
|
||||||
|
.transpose()?;
|
||||||
|
|
||||||
|
let value = <&Expression<'a>>::from_ast(scope, &global_const.value, type_.clone().map(Into::into))?;
|
||||||
|
|
||||||
|
let type_ = type_.or_else(|| value.get_type());
|
||||||
|
|
||||||
|
let variable = scope.alloc_variable(RefCell::new(InnerVariable {
|
||||||
|
id: uuid::Uuid::new_v4(),
|
||||||
|
name: global_const.variable_name.identifier.clone(),
|
||||||
|
type_: type_.ok_or_else(|| {
|
||||||
|
AsgConvertError::unresolved_type(&global_const.variable_name.identifier.name, &global_const.span)
|
||||||
|
})?,
|
||||||
|
mutable: global_const.variable_name.mutable,
|
||||||
|
const_: false,
|
||||||
|
declaration: crate::VariableDeclaration::Definition,
|
||||||
|
references: vec![],
|
||||||
|
assignments: vec![],
|
||||||
|
}));
|
||||||
|
|
||||||
|
//TODO add scope onto this for reference other global consts?
|
||||||
|
let global_const = scope.alloc_global_const(GlobalConst {
|
||||||
|
parent: Cell::new(None),
|
||||||
|
span: Some(global_const.span.clone()),
|
||||||
|
variable,
|
||||||
|
value: Cell::new(value),
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(global_const)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Into<leo_ast::GlobalConst> for &GlobalConst<'a> {
|
||||||
|
fn into(self) -> leo_ast::GlobalConst {
|
||||||
|
let mut type_ = None::<leo_ast::Type>;
|
||||||
|
let variable = self.variable.borrow();
|
||||||
|
let variable_name = leo_ast::VariableName {
|
||||||
|
mutable: variable.mutable,
|
||||||
|
identifier: variable.name.clone(),
|
||||||
|
span: variable.name.span.clone(),
|
||||||
|
};
|
||||||
|
if type_.is_none() {
|
||||||
|
type_ = Some((&variable.type_.clone()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
leo_ast::GlobalConst {
|
||||||
|
declaration_type: leo_ast::Declare::Let,
|
||||||
|
variable_name,
|
||||||
|
type_,
|
||||||
|
value: self.value.get().into(),
|
||||||
|
span: self.span.clone().unwrap_or_default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -55,11 +55,13 @@ pub struct InternalProgram<'a> {
|
|||||||
/// Maps function name => function code block.
|
/// Maps function name => function code block.
|
||||||
pub functions: IndexMap<String, &'a Function<'a>>,
|
pub functions: IndexMap<String, &'a Function<'a>>,
|
||||||
|
|
||||||
|
/// Maps global constant name => global const code block.
|
||||||
|
pub global_consts: IndexMap<String, &'a GlobalConst<'a>>,
|
||||||
|
|
||||||
/// Maps circuit name => circuit code block.
|
/// Maps circuit name => circuit code block.
|
||||||
pub circuits: IndexMap<String, &'a Circuit<'a>>,
|
pub circuits: IndexMap<String, &'a Circuit<'a>>,
|
||||||
|
|
||||||
// pub global_consts: IndexMap<String, (Identifier, &'a ExpressionStatement<'a>)>,
|
// pub global_consts: IndexMap<String, (Identifier, &'a ExpressionStatement<'a>)>,
|
||||||
|
|
||||||
/// Bindings for names and additional program context.
|
/// Bindings for names and additional program context.
|
||||||
pub scope: &'a Scope<'a>,
|
pub scope: &'a Scope<'a>,
|
||||||
}
|
}
|
||||||
@ -179,6 +181,8 @@ impl<'a> InternalProgram<'a> {
|
|||||||
|
|
||||||
let mut imported_functions: IndexMap<String, &'a Function<'a>> = IndexMap::new();
|
let mut imported_functions: IndexMap<String, &'a Function<'a>> = IndexMap::new();
|
||||||
let mut imported_circuits: IndexMap<String, &'a Circuit<'a>> = IndexMap::new();
|
let mut imported_circuits: IndexMap<String, &'a Circuit<'a>> = IndexMap::new();
|
||||||
|
//TODO
|
||||||
|
let imported_global_consts: IndexMap<String, &'a GlobalConst<'a>> = IndexMap::new();
|
||||||
|
|
||||||
// Prepare locally relevant scope of imports.
|
// Prepare locally relevant scope of imports.
|
||||||
for (package, symbol, span) in imported_symbols.into_iter() {
|
for (package, symbol, span) in imported_symbols.into_iter() {
|
||||||
@ -226,9 +230,9 @@ impl<'a> InternalProgram<'a> {
|
|||||||
circuit_self: Cell::new(None),
|
circuit_self: Cell::new(None),
|
||||||
variables: RefCell::new(IndexMap::new()),
|
variables: RefCell::new(IndexMap::new()),
|
||||||
functions: RefCell::new(imported_functions),
|
functions: RefCell::new(imported_functions),
|
||||||
|
global_consts: RefCell::new(imported_global_consts),
|
||||||
circuits: RefCell::new(imported_circuits),
|
circuits: RefCell::new(imported_circuits),
|
||||||
function: Cell::new(None),
|
function: Cell::new(None),
|
||||||
// global_consts: RefCell::new(Vec::new()),
|
|
||||||
input: Cell::new(None),
|
input: Cell::new(None),
|
||||||
})) {
|
})) {
|
||||||
ArenaNode::Scope(c) => c,
|
ArenaNode::Scope(c) => c,
|
||||||
@ -243,7 +247,7 @@ impl<'a> InternalProgram<'a> {
|
|||||||
circuit_self: Cell::new(None),
|
circuit_self: Cell::new(None),
|
||||||
variables: RefCell::new(IndexMap::new()),
|
variables: RefCell::new(IndexMap::new()),
|
||||||
functions: RefCell::new(IndexMap::new()),
|
functions: RefCell::new(IndexMap::new()),
|
||||||
// global_consts: RefCell(vec![]),
|
global_consts: RefCell::new(IndexMap::new()),
|
||||||
circuits: RefCell::new(IndexMap::new()),
|
circuits: RefCell::new(IndexMap::new()),
|
||||||
function: Cell::new(None),
|
function: Cell::new(None),
|
||||||
});
|
});
|
||||||
@ -271,6 +275,23 @@ impl<'a> InternalProgram<'a> {
|
|||||||
scope.functions.borrow_mut().insert(name.name.clone(), function);
|
scope.functions.borrow_mut().insert(name.name.clone(), function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (name, global_const) in program.global_consts.iter() {
|
||||||
|
assert_eq!(name.name, global_const.variable_name.identifier.name);
|
||||||
|
let gc = GlobalConst::init(scope, global_const)?;
|
||||||
|
scope.global_consts.borrow_mut().insert(name.name.clone(), gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
//TODO?
|
||||||
|
// asg_global_const.fill_from_ast(global_const)?;
|
||||||
|
|
||||||
|
global_consts.insert(name.name.clone(), asg_global_const);
|
||||||
|
}
|
||||||
|
|
||||||
// Load concrete definitions.
|
// Load concrete definitions.
|
||||||
let mut test_functions = IndexMap::new();
|
let mut test_functions = IndexMap::new();
|
||||||
for (name, test_function) in program.tests.iter() {
|
for (name, test_function) in program.tests.iter() {
|
||||||
@ -302,19 +323,14 @@ impl<'a> InternalProgram<'a> {
|
|||||||
circuits.insert(name.name.clone(), asg_circuit);
|
circuits.insert(name.name.clone(), asg_circuit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// let global_consts = vec![];
|
|
||||||
for (global_const) in program.global_consts.iter() {
|
|
||||||
// assert_eq!(name.name, define.name.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(InternalProgram {
|
Ok(InternalProgram {
|
||||||
context: arena,
|
context: arena,
|
||||||
id: Uuid::new_v4(),
|
id: Uuid::new_v4(),
|
||||||
name: program.name.clone(),
|
name: program.name.clone(),
|
||||||
test_functions,
|
test_functions,
|
||||||
functions,
|
functions,
|
||||||
|
global_consts,
|
||||||
circuits,
|
circuits,
|
||||||
// global_consts,
|
|
||||||
imported_modules: resolved_packages
|
imported_modules: resolved_packages
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(package, program)| (package.join("."), program))
|
.map(|(package, program)| (package.join("."), program))
|
||||||
@ -364,6 +380,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_circuits: IndexMap<String, &'a Circuit<'a>> = IndexMap::new();
|
||||||
let mut all_functions: IndexMap<String, &'a Function<'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_test_functions: IndexMap<String, (&'a Function<'a>, Option<Identifier>)> = IndexMap::new();
|
let mut all_test_functions: IndexMap<String, (&'a Function<'a>, Option<Identifier>)> = IndexMap::new();
|
||||||
let mut identifiers = InternalIdentifierGenerator { next: 0 };
|
let mut identifiers = InternalIdentifierGenerator { next: 0 };
|
||||||
for (_, program) in all_programs.into_iter() {
|
for (_, program) in all_programs.into_iter() {
|
||||||
@ -381,6 +398,11 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
|||||||
function.name.borrow_mut().name = identifier.clone();
|
function.name.borrow_mut().name = identifier.clone();
|
||||||
all_functions.insert(identifier, *function);
|
all_functions.insert(identifier, *function);
|
||||||
}
|
}
|
||||||
|
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, function) in program.test_functions.iter() {
|
for (name, function) in program.test_functions.iter() {
|
||||||
let identifier = format!("{}{}", identifiers.next().unwrap(), name);
|
let identifier = format!("{}{}", identifiers.next().unwrap(), name);
|
||||||
function.0.name.borrow_mut().name = identifier.clone();
|
function.0.name.borrow_mut().name = identifier.clone();
|
||||||
@ -419,7 +441,10 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, circuit)| (circuit.name.borrow().clone(), circuit.into()))
|
.map(|(_, circuit)| (circuit.name.borrow().clone(), circuit.into()))
|
||||||
.collect(),
|
.collect(),
|
||||||
global_consts: Vec::new(),
|
global_consts: all_global_consts
|
||||||
|
.into_iter()
|
||||||
|
.map(|(_, global_const)| (global_const.variable.borrow().name.clone(), global_const.into()))
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,7 +474,11 @@ impl<'a> Into<leo_ast::Program> for &InternalProgram<'a> {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
global_consts: Vec::new(),
|
global_consts: self
|
||||||
|
.global_consts
|
||||||
|
.iter()
|
||||||
|
.map(|(_, global_const)| (global_const.variable.borrow().name.clone(), (*global_const).into()))
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{ArenaNode, AsgConvertError, Circuit, Expression, Function, Input, Statement, Type, Variable};
|
use crate::{ArenaNode, AsgConvertError, Circuit, Expression, Function, GlobalConst, Input, Statement, Type, Variable};
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
@ -44,6 +44,9 @@ pub struct Scope<'a> {
|
|||||||
/// Maps function name => function.
|
/// Maps function name => function.
|
||||||
pub functions: RefCell<IndexMap<String, &'a Function<'a>>>,
|
pub functions: RefCell<IndexMap<String, &'a Function<'a>>>,
|
||||||
|
|
||||||
|
/// Maps global constant name => global const code block.
|
||||||
|
pub global_consts: RefCell<IndexMap<String, &'a GlobalConst<'a>>>,
|
||||||
|
|
||||||
/// Maps circuit name => circuit.
|
/// Maps circuit name => circuit.
|
||||||
pub circuits: RefCell<IndexMap<String, &'a Circuit<'a>>>,
|
pub circuits: RefCell<IndexMap<String, &'a Circuit<'a>>>,
|
||||||
|
|
||||||
@ -95,6 +98,13 @@ impl<'a> Scope<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn alloc_global_const(&'a self, global_const: GlobalConst<'a>) -> &'a mut GlobalConst<'a> {
|
||||||
|
match self.arena.alloc(ArenaNode::GlobalConst(global_const)) {
|
||||||
|
ArenaNode::GlobalConst(e) => e,
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a reference to the variable corresponding to the name.
|
/// Returns a reference to the variable corresponding to the name.
|
||||||
///
|
///
|
||||||
@ -104,6 +114,8 @@ impl<'a> Scope<'a> {
|
|||||||
pub fn resolve_variable(&self, name: &str) -> Option<&'a Variable<'a>> {
|
pub fn resolve_variable(&self, name: &str) -> Option<&'a Variable<'a>> {
|
||||||
if let Some(resolved) = self.variables.borrow().get(name) {
|
if let Some(resolved) = self.variables.borrow().get(name) {
|
||||||
Some(*resolved)
|
Some(*resolved)
|
||||||
|
} else if let Some(resolved) = self.global_consts.borrow().get(name) {
|
||||||
|
Some(resolved.variable)
|
||||||
} else if let Some(scope) = self.parent_scope.get() {
|
} else if let Some(scope) = self.parent_scope.get() {
|
||||||
scope.resolve_variable(name)
|
scope.resolve_variable(name)
|
||||||
} else {
|
} else {
|
||||||
@ -205,6 +217,7 @@ impl<'a> Scope<'a> {
|
|||||||
variables: RefCell::new(IndexMap::new()),
|
variables: RefCell::new(IndexMap::new()),
|
||||||
functions: RefCell::new(IndexMap::new()),
|
functions: RefCell::new(IndexMap::new()),
|
||||||
circuits: RefCell::new(IndexMap::new()),
|
circuits: RefCell::new(IndexMap::new()),
|
||||||
|
global_consts: RefCell::new(IndexMap::new()),
|
||||||
function: Cell::new(None),
|
function: Cell::new(None),
|
||||||
input: Cell::new(None),
|
input: Cell::new(None),
|
||||||
})
|
})
|
||||||
|
@ -14,8 +14,13 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{Expression, Node, Span, statements::{Declare, VariableName}, Type};
|
use crate::{
|
||||||
use leo_grammar::global_consts::GlobalConst as GrammarGlobalConst;
|
statements::{Declare, VariableName},
|
||||||
|
Expression,
|
||||||
|
Node,
|
||||||
|
Span,
|
||||||
|
Type,
|
||||||
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -23,7 +28,7 @@ use std::fmt;
|
|||||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||||
pub struct GlobalConst {
|
pub struct GlobalConst {
|
||||||
pub declaration_type: Declare,
|
pub declaration_type: Declare,
|
||||||
pub variable_names: Vec<VariableName>,
|
pub variable_name: VariableName,
|
||||||
pub type_: Option<Type>,
|
pub type_: Option<Type>,
|
||||||
pub value: Expression,
|
pub value: Expression,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
@ -31,21 +36,7 @@ pub struct GlobalConst {
|
|||||||
|
|
||||||
impl fmt::Display for GlobalConst {
|
impl fmt::Display for GlobalConst {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{} ", self.declaration_type)?;
|
write!(f, "{} {}", self.declaration_type, self.variable_name)?;
|
||||||
if self.variable_names.len() == 1 {
|
|
||||||
// mut a
|
|
||||||
write!(f, "{}", self.variable_names[0])?;
|
|
||||||
} else {
|
|
||||||
// (a, mut b)
|
|
||||||
let names = self
|
|
||||||
.variable_names
|
|
||||||
.iter()
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(",");
|
|
||||||
|
|
||||||
write!(f, "({})", names)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.type_.is_some() {
|
if self.type_.is_some() {
|
||||||
write!(f, ": {}", self.type_.as_ref().unwrap())?;
|
write!(f, ": {}", self.type_.as_ref().unwrap())?;
|
||||||
@ -54,27 +45,6 @@ impl fmt::Display for GlobalConst {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> From<GrammarGlobalConst<'ast>> for GlobalConst {
|
|
||||||
fn from(statement: GrammarGlobalConst<'ast>) -> Self {
|
|
||||||
let variable_names = statement
|
|
||||||
.variables
|
|
||||||
.names
|
|
||||||
.into_iter()
|
|
||||||
.map(VariableName::from)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let type_ = statement.variables.type_.map(Type::from);
|
|
||||||
|
|
||||||
GlobalConst {
|
|
||||||
declaration_type: Declare::Const,
|
|
||||||
variable_names,
|
|
||||||
type_,
|
|
||||||
value: Expression::from(statement.expression),
|
|
||||||
span: Span::from(statement.span),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Node for GlobalConst {
|
impl Node for GlobalConst {
|
||||||
fn span(&self) -> &Span {
|
fn span(&self) -> &Span {
|
||||||
&self.span
|
&self.span
|
||||||
|
123
ast/src/global_consts/global_consts.rs
Normal file
123
ast/src/global_consts/global_consts.rs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// 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::{
|
||||||
|
statements::{Declare, VariableName},
|
||||||
|
Expression,
|
||||||
|
GlobalConst,
|
||||||
|
Node,
|
||||||
|
Span,
|
||||||
|
Type,
|
||||||
|
};
|
||||||
|
use leo_grammar::global_consts::GlobalConst as GrammarGlobalConst;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GlobalConsts {
|
||||||
|
pub declaration_type: Declare,
|
||||||
|
pub variable_names: Vec<VariableName>,
|
||||||
|
pub type_: Option<Type>,
|
||||||
|
pub value: Expression,
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GlobalConsts {
|
||||||
|
pub fn into_global_const(self) -> Vec<GlobalConst> {
|
||||||
|
let mut global_consts = vec![];
|
||||||
|
let mut types: Vec<Option<Type>> = vec![];
|
||||||
|
|
||||||
|
if self.type_.is_some() {
|
||||||
|
match self.type_.clone().unwrap() {
|
||||||
|
Type::Tuple(types_old) => {
|
||||||
|
for type_ in &types_old {
|
||||||
|
types.push(Some(type_.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => types.push(self.type_.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, variable_name) in self.variable_names.iter().enumerate() {
|
||||||
|
global_consts.push(GlobalConst {
|
||||||
|
declaration_type: self.declaration_type.clone(),
|
||||||
|
variable_name: variable_name.clone(),
|
||||||
|
type_: types.get(i).unwrap_or(&None).clone(),
|
||||||
|
value: self.value.clone(),
|
||||||
|
span: self.span.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
global_consts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for GlobalConsts {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{} ", self.declaration_type)?;
|
||||||
|
if self.variable_names.len() == 1 {
|
||||||
|
// mut a
|
||||||
|
write!(f, "{}", self.variable_names[0])?;
|
||||||
|
} else {
|
||||||
|
// (a, mut b)
|
||||||
|
let names = self
|
||||||
|
.variable_names
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(",");
|
||||||
|
|
||||||
|
write!(f, "({})", names)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.type_.is_some() {
|
||||||
|
write!(f, ": {}", self.type_.as_ref().unwrap())?;
|
||||||
|
}
|
||||||
|
write!(f, " = {};", self.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast> From<GrammarGlobalConst<'ast>> for GlobalConsts {
|
||||||
|
fn from(global_const: GrammarGlobalConst<'ast>) -> Self {
|
||||||
|
let variable_names = global_const
|
||||||
|
.variables
|
||||||
|
.names
|
||||||
|
.into_iter()
|
||||||
|
.map(VariableName::from)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let type_ = global_const.variables.type_.map(Type::from);
|
||||||
|
|
||||||
|
GlobalConsts {
|
||||||
|
declaration_type: Declare::Const,
|
||||||
|
variable_names,
|
||||||
|
type_,
|
||||||
|
value: Expression::from(global_const.expression),
|
||||||
|
span: Span::from(global_const.span),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Node for GlobalConsts {
|
||||||
|
fn span(&self) -> &Span {
|
||||||
|
&self.span
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_span(&mut self, span: Span) {
|
||||||
|
self.span = span;
|
||||||
|
}
|
||||||
|
}
|
@ -16,3 +16,6 @@
|
|||||||
|
|
||||||
pub mod global_const;
|
pub mod global_const;
|
||||||
pub use global_const::*;
|
pub use global_const::*;
|
||||||
|
|
||||||
|
pub mod global_consts;
|
||||||
|
pub use global_consts::*;
|
||||||
|
@ -20,10 +20,11 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
load_annotation,
|
load_annotation,
|
||||||
Circuit,
|
Circuit,
|
||||||
GlobalConst,
|
|
||||||
DeprecatedError,
|
DeprecatedError,
|
||||||
Function,
|
Function,
|
||||||
FunctionInput,
|
FunctionInput,
|
||||||
|
GlobalConst,
|
||||||
|
GlobalConsts,
|
||||||
Identifier,
|
Identifier,
|
||||||
ImportStatement,
|
ImportStatement,
|
||||||
TestFunction,
|
TestFunction,
|
||||||
@ -41,7 +42,7 @@ pub struct Program {
|
|||||||
pub expected_input: Vec<FunctionInput>,
|
pub expected_input: Vec<FunctionInput>,
|
||||||
pub imports: Vec<ImportStatement>,
|
pub imports: Vec<ImportStatement>,
|
||||||
pub circuits: IndexMap<Identifier, Circuit>,
|
pub circuits: IndexMap<Identifier, Circuit>,
|
||||||
pub global_consts: Vec<GlobalConst>,
|
pub global_consts: IndexMap<Identifier, GlobalConst>,
|
||||||
pub functions: IndexMap<Identifier, Function>,
|
pub functions: IndexMap<Identifier, Function>,
|
||||||
pub tests: IndexMap<Identifier, TestFunction>,
|
pub tests: IndexMap<Identifier, TestFunction>,
|
||||||
}
|
}
|
||||||
@ -78,7 +79,7 @@ impl<'ast> Program {
|
|||||||
pub fn from(program_name: &str, program_ast: &File<'ast>) -> Result<Self, DeprecatedError> {
|
pub fn from(program_name: &str, program_ast: &File<'ast>) -> Result<Self, DeprecatedError> {
|
||||||
let mut imports = vec![];
|
let mut imports = vec![];
|
||||||
let mut circuits = IndexMap::new();
|
let mut circuits = IndexMap::new();
|
||||||
let mut global_consts = vec![];
|
let mut global_consts = IndexMap::new();
|
||||||
let mut functions = IndexMap::new();
|
let mut functions = IndexMap::new();
|
||||||
let mut tests = IndexMap::new();
|
let mut tests = IndexMap::new();
|
||||||
let mut expected_input = vec![];
|
let mut expected_input = vec![];
|
||||||
@ -98,7 +99,10 @@ impl<'ast> Program {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
Definition::GlobalConst(global_const) => {
|
Definition::GlobalConst(global_const) => {
|
||||||
global_consts.push(GlobalConst::from(global_const));
|
let global_const_vec = GlobalConsts::from(global_const).into_global_const();
|
||||||
|
for gc in global_const_vec {
|
||||||
|
global_consts.insert(gc.variable_name.identifier.clone(), gc);
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Definition::Function(function_def) => {
|
Definition::Function(function_def) => {
|
||||||
@ -149,7 +153,7 @@ impl Program {
|
|||||||
expected_input: vec![],
|
expected_input: vec![],
|
||||||
imports: vec![],
|
imports: vec![],
|
||||||
circuits: IndexMap::new(),
|
circuits: IndexMap::new(),
|
||||||
global_consts: vec![],
|
global_consts: IndexMap::new(),
|
||||||
functions: IndexMap::new(),
|
functions: IndexMap::new(),
|
||||||
tests: IndexMap::new(),
|
tests: IndexMap::new(),
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,13 @@ pub fn generate_constraints<'a, F: PrimeField, G: GroupType<F>, CS: ConstraintSy
|
|||||||
let program = asg.as_repr();
|
let program = asg.as_repr();
|
||||||
let mut resolved_program = ConstrainedProgram::<F, G>::new(program.clone());
|
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())
|
||||||
|
.unwrap();
|
||||||
|
resolved_program.store_global_const(global_const, value);
|
||||||
|
}
|
||||||
|
|
||||||
let main = {
|
let main = {
|
||||||
let program = program;
|
let program = program;
|
||||||
program.functions.get("main").cloned()
|
program.functions.get("main").cloned()
|
||||||
|
@ -26,6 +26,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
|||||||
pub fn evaluate_ref(&mut self, variable_ref: &VariableRef) -> Result<ConstrainedValue<'a, F, G>, ExpressionError> {
|
pub fn evaluate_ref(&mut self, variable_ref: &VariableRef) -> Result<ConstrainedValue<'a, F, G>, ExpressionError> {
|
||||||
// Evaluate the identifier name in the current function scope
|
// Evaluate the identifier name in the current function scope
|
||||||
let variable = variable_ref.variable.borrow();
|
let variable = variable_ref.variable.borrow();
|
||||||
|
|
||||||
let result_value = if let Some(value) = self.get(&variable.id) {
|
let result_value = if let Some(value) = self.get(&variable.id) {
|
||||||
value.clone()
|
value.clone()
|
||||||
} else {
|
} else {
|
||||||
|
30
compiler/src/global_const/global_const.rs
Normal file
30
compiler/src/global_const/global_const.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// 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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
18
compiler/src/global_const/mod.rs
Normal file
18
compiler/src/global_const/mod.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// 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::*;
|
@ -41,6 +41,9 @@ pub use self::expression::*;
|
|||||||
pub mod function;
|
pub mod function;
|
||||||
pub use self::function::*;
|
pub use self::function::*;
|
||||||
|
|
||||||
|
pub mod global_const;
|
||||||
|
pub use self::global_const::*;
|
||||||
|
|
||||||
pub mod output;
|
pub mod output;
|
||||||
pub use self::output::*;
|
pub use self::output::*;
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ast::Rule,
|
ast::Rule,
|
||||||
circuits::Circuit,
|
circuits::Circuit,
|
||||||
global_consts::GlobalConst,
|
|
||||||
definitions::{AnnotatedDefinition, Deprecated},
|
definitions::{AnnotatedDefinition, Deprecated},
|
||||||
functions::Function,
|
functions::Function,
|
||||||
|
global_consts::GlobalConst,
|
||||||
imports::Import,
|
imports::Import,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user