Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 62 additions & 114 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ version = "3.1.1"
version = "0.10.9"

[workspace.dependencies.snarkvm]
version = "4.4.0"
#path = "./../snarkvm"
git = "https://github.com/ProvableHQ/snarkVM.git"
branch = "struct-namespace-squashed"
features = [ "test_consensus_heights" ]

[workspace.dependencies.tempfile]
Expand Down
5 changes: 2 additions & 3 deletions compiler/ast/src/common/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ use leo_span::Symbol;
use indexmap::{IndexMap, IndexSet};
use std::{fmt::Debug, hash::Hash, rc::Rc};

/// A composite dependency graph.
/// The `Vec<Symbol>` is to the absolute path to each composite
pub type CompositeGraph = DiGraph<Vec<Symbol>>;
/// A struct dependency graph.
pub type CompositeGraph = DiGraph<Location>;

/// A call graph.
pub type CallGraph = DiGraph<Location>;
Expand Down
9 changes: 8 additions & 1 deletion compiler/ast/src/expressions/composite_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pub struct CompositeExpression {
/// N.B. Any functions or member constants in the composite definition
/// are excluded from this list.
pub members: Vec<CompositeFieldInitializer>,
/// The external program that this composite is defined in.
pub program: Option<Symbol>,
/// A span from `name` to `}`.
pub span: Span,
/// The ID of the node.
Expand All @@ -66,7 +68,12 @@ pub struct CompositeExpression {

impl fmt::Display for CompositeExpression {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.path)?;
if let Some(program) = self.program.as_ref() {
write!(f, "{}.aleo/{}", program, self.path)?;
} else {
write!(f, "{}", self.path)?;
}

if !self.const_arguments.is_empty() {
write!(f, "::[{}]", self.const_arguments.iter().format(", "))?;
}
Expand Down
16 changes: 11 additions & 5 deletions compiler/ast/src/expressions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{Identifier, IntegerType, Intrinsic, Node, NodeBuilder, NodeID, Path, Type};
use crate::{Identifier, IntegerType, Intrinsic, Location, Node, NodeBuilder, NodeID, Path, Type};
use leo_span::{Span, Symbol};

use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -388,7 +388,8 @@ impl Expression {
ty: &Type,
span: Span,
node_builder: &NodeBuilder,
composite_lookup: &dyn Fn(&[Symbol]) -> Vec<(Symbol, Type)>,
current_program: Symbol,
composite_lookup: &dyn Fn(&Location) -> Vec<(Symbol, Type)>,
) -> Option<Self> {
let id = node_builder.next_id();

Expand Down Expand Up @@ -444,13 +445,17 @@ impl Expression {
// Composite types
Type::Composite(composite_type) => {
let path = &composite_type.path;
let members = composite_lookup(&path.absolute_path());
let members = composite_lookup(&Location::new(
composite_type.program.unwrap_or(current_program),
path.absolute_path(),
));

let composite_members = members
.into_iter()
.map(|(symbol, member_type)| {
let member_id = node_builder.next_id();
let zero_expr = Self::zero(&member_type, span, node_builder, composite_lookup)?;
let zero_expr =
Self::zero(&member_type, span, node_builder, current_program, composite_lookup)?;

Some(CompositeFieldInitializer {
span,
Expand All @@ -465,6 +470,7 @@ impl Expression {
span,
id,
path: path.clone(),
program: composite_type.program,
const_arguments: composite_type.const_arguments.clone(),
members: composite_members,
}))
Expand All @@ -474,7 +480,7 @@ impl Expression {
Type::Array(array_type) => {
let element_ty = &array_type.element_type;

let element_expr = Self::zero(element_ty, span, node_builder, composite_lookup)?;
let element_expr = Self::zero(element_ty, span, node_builder, current_program, composite_lookup)?;

Some(Expression::Repeat(
RepeatExpression { span, id, expr: element_expr, count: *array_type.length.clone() }.into(),
Expand Down
2 changes: 2 additions & 0 deletions compiler/ast/src/interpreter_value/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,13 @@ pub fn evaluate_intrinsic(
_ => crate::halt_no_span2!("expected array for deserialization"),
};
let get_struct_fail = |_: &SvmIdentifier| anyhow::bail!("structs are not supported");
let get_external_struct_fail = |_: &SvmLocator| anyhow::bail!("structs are not supported");
let value = snarkvm::synthesizer::program::evaluate_deserialize(
variant,
&bits,
&type_.to_snarkvm()?,
&get_struct_fail,
&get_external_struct_fail,
)?;
Ok(value.into())
};
Expand Down
28 changes: 22 additions & 6 deletions compiler/ast/src/interpreter_value/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use snarkvm::prelude::{
pub(crate) use snarkvm::prelude::{
Identifier as SvmIdentifierParam,
Literal as SvmLiteralParam,
Locator as SvmLocatorParam,
Plaintext,
Signature as SvmSignature,
TestnetV0,
Expand All @@ -61,6 +62,7 @@ pub(crate) type ProgramID = ProgramIDParam<CurrentNetwork>;
pub(crate) type SvmPlaintext = Plaintext<CurrentNetwork>;
pub(crate) type SvmLiteral = SvmLiteralParam<CurrentNetwork>;
pub(crate) type SvmIdentifier = SvmIdentifierParam<CurrentNetwork>;
pub(crate) type SvmLocator = SvmLocatorParam<CurrentNetwork>;
pub(crate) type Group = SvmGroup<CurrentNetwork>;
pub(crate) type Field = SvmField<CurrentNetwork>;
pub(crate) type Scalar = SvmScalar<CurrentNetwork>;
Expand Down Expand Up @@ -827,8 +829,9 @@ impl Value {
&self,
span: Span,
node_builder: &NodeBuilder,
current_program: Symbol,
ty: &Type,
struct_lookup: &dyn Fn(&[Symbol]) -> Vec<(Symbol, Type)>,
struct_lookup: &dyn Fn(&Location) -> Vec<(Symbol, Type)>,
) -> Option<Expression> {
use crate::{Literal, TupleExpression, UnitExpression};

Expand All @@ -850,15 +853,15 @@ impl Value {
elements: vec
.iter()
.zip(tuple_type.elements())
.map(|(val, ty)| val.to_expression(span, node_builder, ty, struct_lookup))
.map(|(val, ty)| val.to_expression(span, node_builder, current_program, ty, struct_lookup))
.collect::<Option<Vec<_>>>()?,
}
.into()
}
ValueVariants::Unsuffixed(s) => Literal::unsuffixed(s.clone(), span, id).into(),
ValueVariants::Svm(value) => match value {
SvmValueParam::Plaintext(plaintext) => {
plaintext_to_expression(plaintext, span, node_builder, ty, &struct_lookup)?
plaintext_to_expression(plaintext, span, node_builder, current_program, ty, &struct_lookup)?
}
SvmValueParam::Record(..) => return None,
SvmValueParam::Future(..) => return None,
Expand All @@ -876,8 +879,9 @@ fn plaintext_to_expression(
plaintext: &SvmPlaintext,
span: Span,
node_builder: &NodeBuilder,
current_program: Symbol,
ty: &Type,
struct_lookup: &dyn Fn(&[Symbol]) -> Vec<(Symbol, Type)>,
struct_lookup: &dyn Fn(&Location) -> Vec<(Symbol, Type)>,
) -> Option<Expression> {
use crate::{ArrayExpression, CompositeExpression, CompositeFieldInitializer, Identifier, IntegerType, Literal};

Expand Down Expand Up @@ -925,14 +929,16 @@ fn plaintext_to_expression(
return None;
};
let symbols = composite_type.path.as_symbols();
let iter_members = struct_lookup(&symbols);
let iter_members =
struct_lookup(&Location::new(composite_type.program.unwrap_or(current_program), symbols));
CompositeExpression {
span,
id,
path: composite_type.path.clone(),
// If we were able to construct a Value, the const arguments must have already been resolved
// and inserted appropriately.
const_arguments: Vec::new(),
program: None, // not an external struct.
members: iter_members
.into_iter()
.map(|(sym, ty)| {
Expand All @@ -946,6 +952,7 @@ fn plaintext_to_expression(
index_map.get(&svm_identifier)?,
span,
node_builder,
current_program,
&ty,
&struct_lookup,
)?),
Expand All @@ -964,7 +971,16 @@ fn plaintext_to_expression(
id,
elements: vec
.iter()
.map(|pt| plaintext_to_expression(pt, span, node_builder, &array_ty.element_type, &struct_lookup))
.map(|pt| {
plaintext_to_expression(
pt,
span,
node_builder,
current_program,
&array_ty.element_type,
&struct_lookup,
)
})
.collect::<Option<Vec<_>>>()?,
}
.into()
Expand Down
12 changes: 12 additions & 0 deletions compiler/ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,18 @@ impl AsRef<Program> for Ast {
}
}

/// Produced set of bytecodes
pub struct CompiledPrograms {
pub primary_bytecode: String,
pub import_bytecodes: Vec<Bytecode>,
}

/// Bytecode for a single program.
pub struct Bytecode {
pub program_name: String,
pub bytecode: String,
}

/// Helper function to recursively filter keys from AST JSON
pub fn remove_key_from_json(value: serde_json::Value, key: &str) -> serde_json::Value {
match value {
Expand Down
6 changes: 6 additions & 0 deletions compiler/ast/src/passes/consumer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ pub trait ProgramConsumer {
fn consume_program(&mut self, input: Program) -> Self::Output;
}

/// A Consumer trait for a stub in the the AST.
pub trait StubConsumer {
type Output;
fn consume_stub(&mut self, input: Stub) -> Self::Output;
}

/// A Consumer trait for modules in the AST.
pub trait ModuleConsumer {
type Output;
Expand Down
27 changes: 15 additions & 12 deletions compiler/ast/src/passes/reconstructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,18 +560,16 @@ pub trait AstReconstructor {
/// A Reconstructor trait for the program represented by the AST.
pub trait ProgramReconstructor: AstReconstructor {
fn reconstruct_program(&mut self, input: Program) -> Program {
let stubs = input.stubs.into_iter().map(|(id, stub)| (id, self.reconstruct_stub(stub))).collect();
let program_scopes =
input.program_scopes.into_iter().map(|(id, scope)| (id, self.reconstruct_program_scope(scope))).collect();
Program {
imports: input.imports,
stubs: input.stubs.into_iter().map(|(id, stub)| (id, self.reconstruct_stub(stub))).collect(),
modules: input.modules.into_iter().map(|(id, module)| (id, self.reconstruct_module(module))).collect(),
program_scopes,
}
let modules = input.modules.into_iter().map(|(id, module)| (id, self.reconstruct_module(module))).collect();

Program { modules, imports: input.imports, stubs, program_scopes }
}

fn reconstruct_stub(&mut self, input: Stub) -> Stub {
Stub {
fn reconstruct_aleo_program(&mut self, input: AleoProgram) -> AleoProgram {
AleoProgram {
imports: input.imports,
stub_id: input.stub_id,
consts: input.consts,
Expand All @@ -582,6 +580,15 @@ pub trait ProgramReconstructor: AstReconstructor {
}
}

fn reconstruct_stub(&mut self, input: Stub) -> Stub {
match input {
Stub::FromLeo { program, parents } => Stub::FromLeo { program: self.reconstruct_program(program), parents },
Stub::FromAleo { program, parents } => {
Stub::FromAleo { program: self.reconstruct_aleo_program(program), parents }
}
}
}

fn reconstruct_program_scope(&mut self, input: ProgramScope) -> ProgramScope {
ProgramScope {
program_id: input.program_id,
Expand Down Expand Up @@ -679,10 +686,6 @@ pub trait ProgramReconstructor: AstReconstructor {
}
}

fn reconstruct_import(&mut self, input: Program) -> Program {
self.reconstruct_program(input)
}

fn reconstruct_mapping(&mut self, input: Mapping) -> Mapping {
Mapping {
key_type: self.reconstruct_type(input.key_type).0,
Expand Down
15 changes: 9 additions & 6 deletions compiler/ast/src/passes/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,15 @@ pub trait ProgramVisitor: AstVisitor {
input.stubs.values().for_each(|stub| self.visit_stub(stub));
}

fn visit_aleo_program(&mut self, _input: &AleoProgram) {}

fn visit_stub(&mut self, input: &Stub) {
match input {
Stub::FromLeo { program, .. } => self.visit_program(program),
Stub::FromAleo { program, .. } => self.visit_aleo_program(program),
}
}

fn visit_program_scope(&mut self, input: &ProgramScope) {
input.consts.iter().for_each(|(_, c)| self.visit_const(c));
input.composites.iter().for_each(|(_, c)| self.visit_composite(c));
Expand All @@ -343,12 +352,6 @@ pub trait ProgramVisitor: AstVisitor {
input.functions.iter().for_each(|(_, c)| self.visit_function(c));
}

fn visit_stub(&mut self, _input: &Stub) {}

fn visit_import(&mut self, input: &Program) {
self.visit_program(input)
}

fn visit_composite(&mut self, input: &Composite) {
input.const_parameters.iter().for_each(|input| self.visit_type(&input.type_));
input.members.iter().for_each(|member| self.visit_type(&member.type_));
Expand Down
22 changes: 1 addition & 21 deletions compiler/ast/src/program/program_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

//! A Leo program scope consists of const, composite, function, and mapping definitions.

use crate::{Composite, ConstDeclaration, Constructor, Function, Indent, Mapping, ProgramId, StorageVariable, Stub};
use crate::{Composite, ConstDeclaration, Constructor, Function, Indent, Mapping, ProgramId, StorageVariable};

use leo_span::{Span, Symbol};
use serde::{Deserialize, Serialize};
Expand All @@ -43,26 +43,6 @@ pub struct ProgramScope {
pub span: Span,
}

impl From<Stub> for ProgramScope {
fn from(stub: Stub) -> Self {
Self {
program_id: stub.stub_id,
consts: stub.consts,
composites: stub.composites,
mappings: stub.mappings,
storage_variables: Vec::new(), // stubs don't have storage variables
functions: stub
.functions
.into_iter()
.map(|(symbol, function)| (symbol, Function::from(function)))
.collect(),
// A program scope constructed from a stub does not need a constructor, since they are not externally callable.
constructor: None,
span: stub.span,
}
}
}

impl fmt::Display for ProgramScope {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "program {} {{", self.program_id)?;
Expand Down
Loading