mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-26 02:53:08 +03:00
Adds ASG struct, updates ASG to support debug
This commit is contained in:
parent
f80c3d236a
commit
1b99c42470
@ -22,6 +22,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArrayAccessExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -21,6 +21,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArrayInitExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -22,6 +22,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArrayInlineExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -22,6 +22,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArrayRangeAccessExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -22,6 +22,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BinaryExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -36,6 +36,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -36,6 +36,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CircuitAccessExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -36,6 +36,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CircuitInitExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -34,6 +34,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Constant {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -66,6 +66,7 @@ use crate::{AsgConvertError, ConstValue, FromAst, Node, PartialType, Scope, Span
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Expression {
|
||||
VariableRef(VariableRef),
|
||||
Constant(Constant),
|
||||
|
@ -21,6 +21,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TernaryExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -21,6 +21,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TupleAccessExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -21,6 +21,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TupleInitExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -22,6 +22,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnaryExpression {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -37,6 +37,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VariableRef {
|
||||
pub parent: RefCell<Option<Weak<Expression>>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -23,7 +23,7 @@ use std::{
|
||||
};
|
||||
|
||||
/// Stores program input values as asg nodes.
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Input {
|
||||
pub registers: Arc<CircuitBody>,
|
||||
pub state: Arc<CircuitBody>,
|
||||
|
@ -67,9 +67,9 @@ pub use type_::*;
|
||||
pub mod variable;
|
||||
pub use variable::*;
|
||||
|
||||
pub use leo_ast::{Identifier, Span};
|
||||
pub use leo_ast::{Ast, Identifier, Span};
|
||||
|
||||
use std::path::Path;
|
||||
use std::{cell::RefCell, path::Path, sync::Arc};
|
||||
|
||||
/// The abstract semantic graph (ASG) for a Leo program.
|
||||
///
|
||||
@ -77,42 +77,41 @@ use std::path::Path;
|
||||
/// These data types form a graph that begins from a [`Program`] type node.
|
||||
///
|
||||
/// A new [`Asg`] can be created from an [`Ast`] generated in the `ast` module.
|
||||
// #[derive(Debug, Eq, PartialEq)]
|
||||
// pub struct Asg {
|
||||
// asg: InnerProgram,
|
||||
// }
|
||||
//
|
||||
// impl Asg {
|
||||
// /// Creates a new asg from a given ast tree and import resolver.
|
||||
// pub fn new<T: ImportResolver + 'static>(
|
||||
// content: leo_ast::Program,
|
||||
// resolver: &mut T,
|
||||
// ) -> Result<Program, AsgConvertError> {
|
||||
// InnerProgram::new(&content, resolver)
|
||||
// }
|
||||
//
|
||||
// /// Returns a reference to the inner program ast representation.
|
||||
// pub fn into_repr(self) -> Program {
|
||||
// self.asg
|
||||
// }
|
||||
// }
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Asg {
|
||||
asg: Arc<RefCell<InternalProgram>>,
|
||||
}
|
||||
|
||||
pub fn load_ast<T: AsRef<Path>, Y: AsRef<str>>(path: T, content: Y) -> Result<leo_ast::Program, AsgConvertError> {
|
||||
impl Asg {
|
||||
/// Creates a new ASG from a given AST and import resolver.
|
||||
pub fn new<T: ImportResolver + 'static>(ast: &Ast, resolver: &mut T) -> Result<Self, AsgConvertError> {
|
||||
Ok(Self {
|
||||
asg: InternalProgram::new(&ast.as_repr(), resolver)?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the internal program ASG representation.
|
||||
pub fn as_repr(&self) -> Arc<RefCell<InternalProgram>> {
|
||||
self.asg.clone()
|
||||
}
|
||||
|
||||
// /// Serializes the ast into a JSON string.
|
||||
// pub fn to_json_string(&self) -> Result<String, serde_json::Error> {
|
||||
// serde_json::to_string_pretty(&self.asg)
|
||||
// }
|
||||
//
|
||||
// /// Deserializes the JSON string into a ast.
|
||||
// pub fn from_json_string(json: &str) -> Result<Self, serde_json::Error> {
|
||||
// let ast: Program = serde_json::from_str(json)?;
|
||||
// Ok(Self { ast })
|
||||
// }
|
||||
}
|
||||
|
||||
// TODO (howardwu): Remove this.
|
||||
pub fn load_asg<T: ImportResolver + 'static>(content: &str, resolver: &mut T) -> Result<Program, AsgConvertError> {
|
||||
// Parses the Leo file and constructs a grammar ast.
|
||||
let ast = leo_grammar::Grammar::new(path.as_ref(), content.as_ref())
|
||||
let ast = leo_grammar::Grammar::new(&Path::new("input.leo"), content.as_ref())
|
||||
.map_err(|e| AsgConvertError::InternalError(format!("ast: {:?}", e)))?;
|
||||
|
||||
// Parses the pest ast and constructs a Leo ast.
|
||||
Ok(leo_ast::Ast::new("load_ast", &ast)?.into_repr())
|
||||
}
|
||||
|
||||
pub fn load_asg_from_ast<T: ImportResolver + 'static>(
|
||||
content: leo_ast::Program,
|
||||
resolver: &mut T,
|
||||
) -> Result<Program, AsgConvertError> {
|
||||
InternalProgram::new(&content, resolver)
|
||||
}
|
||||
|
||||
pub fn load_asg<T: ImportResolver + 'static>(content: &str, resolver: &mut T) -> Result<Program, AsgConvertError> {
|
||||
InternalProgram::new(&load_ast("input.leo", content)?, resolver)
|
||||
InternalProgram::new(leo_ast::Ast::new("load_ast", &ast)?.as_repr(), resolver)
|
||||
}
|
||||
|
@ -14,12 +14,12 @@
|
||||
// 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/>.
|
||||
|
||||
//todo: we should merge this with core
|
||||
// TODO (protryon): We should merge this with core
|
||||
|
||||
use crate::{AsgConvertError, Program};
|
||||
|
||||
// todo: make asg deep copy so we can cache resolved core modules
|
||||
// todo: figure out how to do headers without bogus returns
|
||||
// TODO (protryon): Make asg deep copy so we can cache resolved core modules
|
||||
// TODO (protryon): Figure out how to do headers without bogus returns
|
||||
|
||||
pub fn resolve_core_module(module: &str) -> Result<Option<Program>, AsgConvertError> {
|
||||
match module {
|
||||
|
@ -23,16 +23,19 @@ use std::{
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CircuitMemberBody {
|
||||
Variable(Type),
|
||||
Function(Arc<FunctionBody>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CircuitMember {
|
||||
Variable(WeakType),
|
||||
Function(Arc<Function>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Circuit {
|
||||
pub id: Uuid,
|
||||
pub name: RefCell<Identifier>,
|
||||
@ -51,6 +54,7 @@ impl PartialEq for Circuit {
|
||||
}
|
||||
impl Eq for Circuit {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CircuitBody {
|
||||
pub scope: Scope,
|
||||
pub span: Option<Span>,
|
||||
|
@ -38,13 +38,14 @@ use std::{
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum FunctionQualifier {
|
||||
SelfRef,
|
||||
MutSelfRef,
|
||||
Static,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Function {
|
||||
pub id: Uuid,
|
||||
pub name: RefCell<Identifier>,
|
||||
@ -66,6 +67,7 @@ impl PartialEq for Function {
|
||||
}
|
||||
impl Eq for Function {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionBody {
|
||||
pub span: Option<Span>,
|
||||
pub function: Arc<Function>,
|
||||
|
@ -32,7 +32,7 @@ use std::{cell::RefCell, sync::Arc};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Stores the Leo program abstract semantic graph (ASG).
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InternalProgram {
|
||||
/// The unique id of the program.
|
||||
pub id: Uuid,
|
||||
@ -111,21 +111,21 @@ fn resolve_import_package_access(
|
||||
}
|
||||
|
||||
impl InternalProgram {
|
||||
/// Returns a new Leo program asg from the given Leo program ast and imports.
|
||||
/// Returns a new Leo program ASG from the given Leo program AST and its imports.
|
||||
///
|
||||
/// stages:
|
||||
/// Stages:
|
||||
/// 1. resolve imports into super scope
|
||||
/// 2. finalize declared types
|
||||
/// 3. finalize declared functions
|
||||
/// 4. resolve all asg nodes
|
||||
///
|
||||
pub fn new<T: ImportResolver + 'static>(
|
||||
value: &leo_ast::Program,
|
||||
program: &leo_ast::Program,
|
||||
import_resolver: &mut T,
|
||||
) -> Result<Program, AsgConvertError> {
|
||||
// Recursively extract imported symbols.
|
||||
let mut imported_symbols: Vec<(Vec<String>, ImportSymbol, Span)> = vec![];
|
||||
for import in value.imports.iter() {
|
||||
for import in program.imports.iter() {
|
||||
resolve_import_package(&mut imported_symbols, vec![], &import.package);
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ impl InternalProgram {
|
||||
|
||||
// Prepare header-like scope entries.
|
||||
let mut proto_circuits = IndexMap::new();
|
||||
for (name, circuit) in value.circuits.iter() {
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = Circuit::init(circuit);
|
||||
|
||||
@ -234,7 +234,7 @@ impl InternalProgram {
|
||||
function: None,
|
||||
}));
|
||||
|
||||
for (name, circuit) in value.circuits.iter() {
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = proto_circuits.get(&name.name).unwrap();
|
||||
|
||||
@ -242,7 +242,7 @@ impl InternalProgram {
|
||||
}
|
||||
|
||||
let mut proto_test_functions = IndexMap::new();
|
||||
for (name, test_function) in value.tests.iter() {
|
||||
for (name, test_function) in program.tests.iter() {
|
||||
assert_eq!(name.name, test_function.function.identifier.name);
|
||||
let function = Arc::new(Function::from_ast(&scope, &test_function.function)?);
|
||||
|
||||
@ -250,7 +250,7 @@ impl InternalProgram {
|
||||
}
|
||||
|
||||
let mut proto_functions = IndexMap::new();
|
||||
for (name, function) in value.functions.iter() {
|
||||
for (name, function) in program.functions.iter() {
|
||||
assert_eq!(name.name, function.identifier.name);
|
||||
let asg_function = Arc::new(Function::from_ast(&scope, function)?);
|
||||
|
||||
@ -263,7 +263,7 @@ impl InternalProgram {
|
||||
|
||||
// Load concrete definitions.
|
||||
let mut test_functions = IndexMap::new();
|
||||
for (name, test_function) in value.tests.iter() {
|
||||
for (name, test_function) in program.tests.iter() {
|
||||
assert_eq!(name.name, test_function.function.identifier.name);
|
||||
let function = proto_test_functions.get(&name.name).unwrap();
|
||||
|
||||
@ -278,7 +278,7 @@ impl InternalProgram {
|
||||
}
|
||||
|
||||
let mut functions = IndexMap::new();
|
||||
for (name, function) in value.functions.iter() {
|
||||
for (name, function) in program.functions.iter() {
|
||||
assert_eq!(name.name, function.identifier.name);
|
||||
let asg_function = proto_functions.get(&name.name).unwrap();
|
||||
|
||||
@ -289,7 +289,7 @@ impl InternalProgram {
|
||||
}
|
||||
|
||||
let mut circuits = IndexMap::new();
|
||||
for (name, circuit) in value.circuits.iter() {
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
assert_eq!(name.name, circuit.circuit_name.name);
|
||||
let asg_circuit = proto_circuits.get(&name.name).unwrap();
|
||||
let body = Arc::new(CircuitBody::from_ast(&scope, circuit, asg_circuit.clone())?);
|
||||
@ -300,7 +300,7 @@ impl InternalProgram {
|
||||
|
||||
Ok(Arc::new(RefCell::new(InternalProgram {
|
||||
id: Uuid::new_v4(),
|
||||
name: value.name.clone(),
|
||||
name: program.name.clone(),
|
||||
test_functions,
|
||||
functions,
|
||||
circuits,
|
||||
@ -332,7 +332,7 @@ impl Iterator for InternalIdentifierGenerator {
|
||||
Some(out)
|
||||
}
|
||||
}
|
||||
/// Returns an ast from the given asg program.
|
||||
/// Returns an AST from the given ASG program.
|
||||
pub fn reform_ast(program: &Program) -> leo_ast::Program {
|
||||
let mut all_programs: IndexMap<String, Program> = IndexMap::new();
|
||||
let mut program_stack = program.borrow().imported_modules.clone();
|
||||
@ -395,13 +395,10 @@ pub fn reform_ast(program: &Program) -> leo_ast::Program {
|
||||
tests: all_test_functions
|
||||
.into_iter()
|
||||
.map(|(_, (function, ident))| {
|
||||
(
|
||||
function.function.name.borrow().clone(),
|
||||
leo_ast::TestFunction {
|
||||
function: function.function.as_ref().into(),
|
||||
input_file: ident,
|
||||
},
|
||||
)
|
||||
(function.function.name.borrow().clone(), leo_ast::TestFunction {
|
||||
function: function.function.as_ref().into(),
|
||||
input_file: ident,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
functions: all_functions
|
||||
@ -445,13 +442,10 @@ impl Into<leo_ast::Program> for &InternalProgram {
|
||||
.test_functions
|
||||
.iter()
|
||||
.map(|(_, function)| {
|
||||
(
|
||||
function.0.function.name.borrow().clone(),
|
||||
leo_ast::TestFunction {
|
||||
function: function.0.function.as_ref().into(),
|
||||
input_file: function.1.clone(),
|
||||
},
|
||||
)
|
||||
(function.0.function.name.borrow().clone(), leo_ast::TestFunction {
|
||||
function: function.0.function.as_ref().into(),
|
||||
input_file: function.1.clone(),
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ use std::{cell::RefCell, sync::Arc};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// An abstract data type that track the current bindings for variables, functions, and circuits.
|
||||
#[derive(Debug)]
|
||||
pub struct InnerScope {
|
||||
/// The unique id of the scope.
|
||||
pub id: Uuid,
|
||||
|
@ -37,6 +37,7 @@ use leo_ast::AssigneeAccess as AstAssigneeAccess;
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AssignAccess {
|
||||
ArrayRange(Option<Arc<Expression>>, Option<Arc<Expression>>),
|
||||
ArrayIndex(Arc<Expression>),
|
||||
@ -44,6 +45,7 @@ pub enum AssignAccess {
|
||||
Member(Identifier),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssignStatement {
|
||||
pub parent: Option<Weak<Statement>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -18,6 +18,7 @@ use crate::{AsgConvertError, FromAst, InnerScope, Node, PartialType, Scope, Span
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BlockStatement {
|
||||
pub parent: Option<Weak<Statement>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -18,6 +18,7 @@ use crate::{AsgConvertError, BlockStatement, Expression, FromAst, Node, PartialT
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConditionalStatement {
|
||||
pub parent: Option<Weak<Statement>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -19,7 +19,8 @@ use leo_ast::ConsoleFunction as AstConsoleFunction;
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
//todo: refactor to not require/depend on span
|
||||
// TODO (protryon): Refactor to not require/depend on span
|
||||
#[derive(Debug)]
|
||||
pub struct FormattedString {
|
||||
pub string: String,
|
||||
pub containers: Vec<Span>,
|
||||
@ -27,6 +28,7 @@ pub struct FormattedString {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ConsoleFunction {
|
||||
Assert(Arc<Expression>),
|
||||
Debug(FormattedString),
|
||||
@ -34,6 +36,7 @@ pub enum ConsoleFunction {
|
||||
Log(FormattedString),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConsoleStatement {
|
||||
pub parent: Option<Weak<Statement>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -34,6 +34,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DefinitionStatement {
|
||||
pub parent: Option<Weak<Statement>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -18,6 +18,7 @@ use crate::{AsgConvertError, Expression, FromAst, Node, PartialType, Scope, Span
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExpressionStatement {
|
||||
pub parent: Option<Weak<Statement>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -35,6 +35,7 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IterationStatement {
|
||||
pub parent: Option<Weak<Statement>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -46,6 +46,7 @@ use crate::{AsgConvertError, FromAst, Node, PartialType, Scope, Span};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Statement {
|
||||
Return(ReturnStatement),
|
||||
Definition(DefinitionStatement),
|
||||
|
@ -18,6 +18,7 @@ use crate::{AsgConvertError, Expression, FromAst, Node, PartialType, Scope, Span
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReturnStatement {
|
||||
pub parent: Option<Weak<Statement>>,
|
||||
pub span: Option<Span>,
|
||||
|
@ -22,8 +22,8 @@ use std::{
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
/// A type in an asg.
|
||||
#[derive(Clone, PartialEq)]
|
||||
/// A type in an ASG.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Type {
|
||||
// Data types
|
||||
Address,
|
||||
@ -38,13 +38,13 @@ pub enum Type {
|
||||
Circuit(Arc<Circuit>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum WeakType {
|
||||
Type(Type), // circuit not allowed
|
||||
Circuit(Weak<Circuit>),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum PartialType {
|
||||
Type(Type), // non-array or tuple
|
||||
Integer(Option<IntegerType>, Option<IntegerType>), // specific, context-specific
|
||||
|
@ -24,7 +24,7 @@ use std::{
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Specifies how a program variable was declared.
|
||||
#[derive(PartialEq)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum VariableDeclaration {
|
||||
Definition,
|
||||
IterationDefinition,
|
||||
@ -33,6 +33,7 @@ pub enum VariableDeclaration {
|
||||
}
|
||||
|
||||
/// Stores information on a program variable.
|
||||
#[derive(Debug)]
|
||||
pub struct InnerVariable {
|
||||
pub id: Uuid,
|
||||
pub name: Identifier,
|
||||
|
@ -15,16 +15,28 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_asg::*;
|
||||
use leo_ast::Ast;
|
||||
use leo_grammar::Grammar;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
mod fail;
|
||||
mod pass;
|
||||
|
||||
fn load_asg(content: &str) -> Result<Program, AsgConvertError> {
|
||||
leo_asg::load_asg(content, &mut NullImportResolver)
|
||||
const TESTING_FILEPATH: &str = "input.leo";
|
||||
const TESTING_PROGRAM_NAME: &str = "test_program";
|
||||
|
||||
fn load_asg(program_string: &str) -> Result<Program, AsgConvertError> {
|
||||
load_asg_imports(program_string, &mut NullImportResolver)
|
||||
}
|
||||
|
||||
fn load_asg_imports<T: ImportResolver + 'static>(content: &str, imports: &mut T) -> Result<Program, AsgConvertError> {
|
||||
leo_asg::load_asg(content, imports)
|
||||
fn load_asg_imports<T: ImportResolver + 'static>(
|
||||
program_string: &str,
|
||||
imports: &mut T,
|
||||
) -> Result<Program, AsgConvertError> {
|
||||
let grammar = Grammar::new(Path::new(&TESTING_FILEPATH), program_string)?;
|
||||
let ast = Ast::new(TESTING_PROGRAM_NAME, &grammar)?;
|
||||
InternalProgram::new(&ast.as_repr(), imports)
|
||||
}
|
||||
|
||||
fn mocked_resolver() -> MockedImportResolver {
|
||||
|
@ -15,6 +15,10 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::load_asg;
|
||||
use leo_ast::Ast;
|
||||
use leo_grammar::Grammar;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn test_basic() {
|
||||
@ -73,14 +77,19 @@ fn test_imports() {
|
||||
console.assert(foo() == 1u32);
|
||||
}
|
||||
"#;
|
||||
|
||||
let test_import_grammar = Grammar::new(Path::new("test-import.leo"), test_import).unwrap();
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string(&crate::load_ast("test-import.leo", test_import).unwrap()).unwrap()
|
||||
serde_json::to_string(Ast::new("test-import", &test_import_grammar).unwrap().as_repr()).unwrap()
|
||||
);
|
||||
|
||||
let test_grammar = Grammar::new(Path::new("test.leo"), program_string).unwrap();
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string(&crate::load_ast("test.leo", program_string).unwrap()).unwrap()
|
||||
serde_json::to_string(Ast::new("test", &test_grammar).unwrap().as_repr()).unwrap()
|
||||
);
|
||||
|
||||
let asg = crate::load_asg_imports(program_string, &mut imports).unwrap();
|
||||
let reformed_ast = leo_asg::reform_ast(&asg);
|
||||
println!("{}", serde_json::to_string(&reformed_ast).unwrap());
|
||||
|
@ -83,8 +83,8 @@ impl Ast {
|
||||
}
|
||||
|
||||
/// Returns a reference to the inner program AST representation.
|
||||
pub fn into_repr(self) -> Program {
|
||||
self.ast
|
||||
pub fn as_repr(&self) -> &Program {
|
||||
&self.ast
|
||||
}
|
||||
|
||||
/// Serializes the ast into a JSON string.
|
||||
|
@ -44,7 +44,7 @@ fn test_serialize() {
|
||||
};
|
||||
|
||||
// Serializes the ast into JSON format.
|
||||
let serialized_ast: Program = serde_json::from_value(serde_json::to_value(ast.into_repr()).unwrap()).unwrap();
|
||||
let serialized_ast: Program = serde_json::from_value(serde_json::to_value(ast.as_repr()).unwrap()).unwrap();
|
||||
|
||||
// Load the expected ast.
|
||||
let expected: Program = serde_json::from_str(include_str!("expected_leo_ast.json")).unwrap();
|
||||
|
@ -19,15 +19,17 @@
|
||||
use crate::{
|
||||
constraints::{generate_constraints, generate_test_constraints},
|
||||
errors::CompilerError,
|
||||
GroupType, OutputBytes, OutputFile,
|
||||
GroupType,
|
||||
OutputBytes,
|
||||
OutputFile,
|
||||
};
|
||||
use leo_asg::Asg;
|
||||
use leo_ast::{Ast, Input, MainInput, Program};
|
||||
use leo_grammar::Grammar;
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
use leo_state::verify_local_data_commitment;
|
||||
|
||||
use leo_asg::Program as AsgProgram;
|
||||
use snarkvm_dpc::{base_dpc::instantiated::Components, SystemParameters};
|
||||
use snarkvm_errors::gadgets::SynthesisError;
|
||||
use snarkvm_models::{
|
||||
@ -50,7 +52,7 @@ pub struct Compiler<F: Field + PrimeField, G: GroupType<F>> {
|
||||
output_directory: PathBuf,
|
||||
program: Program,
|
||||
program_input: Input,
|
||||
asg: Option<AsgProgram>,
|
||||
asg: Option<Asg>,
|
||||
_engine: PhantomData<F>,
|
||||
_group: PhantomData<G>,
|
||||
}
|
||||
@ -182,12 +184,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
let core_ast = Ast::new(&self.program_name, &grammar)?;
|
||||
|
||||
// Store the main program file.
|
||||
self.program = core_ast.into_repr();
|
||||
self.program = core_ast.as_repr().clone();
|
||||
|
||||
tracing::debug!("Program parsing complete\n{:#?}", self.program);
|
||||
|
||||
// Create a new symbol table from the program, imported_programs, and program_input.
|
||||
let asg = leo_asg::InternalProgram::new(&self.program, &mut leo_imports::ImportParser::default())?;
|
||||
let asg = Asg::new(&core_ast, &mut leo_imports::ImportParser::default())?;
|
||||
|
||||
tracing::debug!("ASG generation complete");
|
||||
|
||||
@ -201,7 +203,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
/// Synthesizes the circuit with program input to verify correctness.
|
||||
///
|
||||
pub fn compile_constraints<CS: ConstraintSystem<F>>(&self, cs: &mut CS) -> Result<OutputBytes, CompilerError> {
|
||||
generate_constraints::<F, G, CS>(cs, self.asg.as_ref().unwrap(), &self.program_input).map_err(|mut error| {
|
||||
generate_constraints::<F, G, CS>(cs, &self.asg.as_ref().unwrap(), &self.program_input).map_err(|mut error| {
|
||||
error.set_path(&self.main_file_path);
|
||||
error
|
||||
})
|
||||
@ -212,7 +214,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
///
|
||||
pub fn compile_test_constraints(self, input_pairs: InputPairs) -> Result<(u32, u32), CompilerError> {
|
||||
generate_test_constraints::<F, G>(
|
||||
self.asg.as_ref().unwrap(),
|
||||
&self.asg.as_ref().unwrap(),
|
||||
input_pairs,
|
||||
&self.main_file_path,
|
||||
&self.output_directory,
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Generates R1CS constraints for a compiled Leo program.
|
||||
|
||||
use crate::{errors::CompilerError, ConstrainedProgram, GroupType, OutputBytes, OutputFile};
|
||||
use leo_asg::Program;
|
||||
use leo_asg::Asg;
|
||||
use leo_ast::Input;
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
@ -30,9 +30,10 @@ use std::path::Path;
|
||||
|
||||
pub fn generate_constraints<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
cs: &mut CS,
|
||||
program: &Program,
|
||||
asg: &Asg,
|
||||
input: &Input,
|
||||
) -> Result<OutputBytes, CompilerError> {
|
||||
let program = asg.as_repr();
|
||||
let mut resolved_program = ConstrainedProgram::<F, G>::new(program.clone());
|
||||
|
||||
let main = {
|
||||
@ -50,11 +51,12 @@ pub fn generate_constraints<F: Field + PrimeField, G: GroupType<F>, CS: Constrai
|
||||
}
|
||||
|
||||
pub fn generate_test_constraints<F: Field + PrimeField, G: GroupType<F>>(
|
||||
program: &Program,
|
||||
asg: &Asg,
|
||||
input: InputPairs,
|
||||
main_file_path: &Path,
|
||||
output_directory: &Path,
|
||||
) -> Result<(u32, u32), CompilerError> {
|
||||
let program = asg.as_repr();
|
||||
let mut resolved_program = ConstrainedProgram::<F, G>::new(program.clone());
|
||||
let program_name = program.borrow().name.clone();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user