mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-23 23:23:50 +03:00
merge master, clean up reducer and directors
This commit is contained in:
commit
bddcef732f
@ -1,6 +1,6 @@
|
||||
# leo add (w/o login) & remove
|
||||
|
||||
$LEO new my-app && cd my-app
|
||||
$LEO new my-app && cd my-app || exit 1
|
||||
$LEO add howard/silly-sudoku
|
||||
$LEO remove silly-sudoku
|
||||
$LEO clean
|
||||
|
@ -1,4 +1,5 @@
|
||||
mkdir hello-world && cd hello-world || exit 1
|
||||
$LEO init
|
||||
ls -la
|
||||
mkdir hello-world
|
||||
cd hello-world
|
||||
$LEO init || exit 1
|
||||
ls -la hello-world
|
||||
$LEO run
|
||||
|
52
Cargo.lock
generated
52
Cargo.lock
generated
@ -4,9 +4,9 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "abnf"
|
||||
version = "0.10.1"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb23c378acfcb46052bd7d1a6119d8d608d4c12ac6c72cb1d9c4e85bc2cb2bb7"
|
||||
checksum = "fd8863e7db43447ad50376e19b0549343b72ad45cbd394b3fc8fe3ede961facc"
|
||||
dependencies = [
|
||||
"abnf-core",
|
||||
"nom 6.1.2",
|
||||
@ -2572,9 +2572,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-algorithms"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "472ed062cdd1f54076312dd34e5fb56bd585c80c12209045f4b5bbbd368e9000"
|
||||
checksum = "bdf8ca73d429824090b96f751846e37e539f24c527f1f1ce0254984ade6d17b2"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"derivative",
|
||||
@ -2595,9 +2595,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-curves"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdfdfa3aa137f64a7f49df03393e5d0269f133ca8c8c79e569cb3bb13181aeb2"
|
||||
checksum = "64610b135b8b1152439d5dfa4f745515933366082f08651961344aa0bb5abfca"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"rand",
|
||||
@ -2611,9 +2611,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-derives"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a2ba967601ff2534adbc6a71a691be4285e61c83d23d54a59824f8fa80f6038"
|
||||
checksum = "46c9829b6e2023b4c7c4d6c55e88fe755dd997171a6c9c063b75c28161d04326"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
@ -2624,9 +2624,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-dpc"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff4cb55898089843ba44b9f96448dcb2badcc1ce12daa8d7365d4e41513e37bc"
|
||||
checksum = "491ae936e24e17c358d112ff8638b260500b5a982ecefc804861e28b5279f552"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base58",
|
||||
@ -2650,9 +2650,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-fields"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca9ea954196e76fe8968fb99eced7ccf08f901ab22747c4c489bda6674a7cb39"
|
||||
checksum = "8c49c69d02df11be58e07f626c9d6f5804c6dd4ccf42e425f2be8d79fe6e5bb7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"derivative",
|
||||
@ -2665,9 +2665,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-gadgets"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdda42a0a6484d9f008801a8a4d494a69a4db3f7b317057a8cc3c6e4b3ef6884"
|
||||
checksum = "bd6f9ac2a166d926e1755a06fdae21ce40ce6164c75c89120401b8d78f3b7ba4"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"digest 0.9.0",
|
||||
@ -2682,9 +2682,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-objects"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e20d13db49cedc147df06c4a6f2dd727ea25640bdf50b876f40005331767a68f"
|
||||
checksum = "9bd9779ec6ab9211f34a6ba25566feb575a396f4c41cc0e002ec2d48d7560a2a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -2703,9 +2703,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-parameters"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d35fa1819d803e45b4e99fe822e6981f177716f5384eef27245b5f6ed59a8305"
|
||||
checksum = "98378f612206fc7dd44a26f4e345bd1f3ba51bd325acad1e5cc3785d14750ec5"
|
||||
dependencies = [
|
||||
"curl",
|
||||
"hex",
|
||||
@ -2716,15 +2716,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-profiler"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7834d57af37a31f2f280f08b61d07a04a9a4b7720819b06ca325da32a5a925f5"
|
||||
checksum = "b2460ac01c25f79f5ea306e4de82a1d4105e811f868206b4fd31c0c9b62a3d7b"
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-r1cs"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0838118f276e7bb673cbf3741f4966c56861aaff399a46d343fc98c12851d9eb"
|
||||
checksum = "a3a0d54b15802976aff7522765dd29d5733f338612449629cc57c5a4a4d51f05"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fxhash",
|
||||
@ -2737,9 +2737,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-storage"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a42d92a817502878f315cc264704fa2a3d563755f16186316d8177ea685769af"
|
||||
checksum = "1d76881939f008d7bba4c8cc4118d29567b5c71908ad66bef9880f8aa7c52881"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -2758,9 +2758,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-utilities"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5598f7f71c8aaf4fc267b5b420b2440a4d86c9243cecd57ff0af5c366217e5cc"
|
||||
checksum = "c763843fa67a3aa4ce68173c8cd96b4f04aaa135a5792bc051c36eec0fe1cd73"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"rand",
|
||||
|
10
Cargo.toml
10
Cargo.toml
@ -69,23 +69,23 @@ path = "./synthesizer"
|
||||
version = "1.2.3"
|
||||
|
||||
[dependencies.snarkvm-algorithms]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
#default-features = false
|
||||
|
||||
[dependencies.snarkvm-curves]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-gadgets]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-r1cs]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-utilities]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
|
||||
[dependencies.anyhow]
|
||||
version = "1.0"
|
||||
|
@ -172,6 +172,13 @@ impl AsgConvertError {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn duplicate_function_definition(name: &str, span: &Span) -> Self {
|
||||
Self::new_from_span(
|
||||
format!("a function named \"{}\" already exists in this scope", name),
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn index_into_non_tuple(name: &str, span: &Span) -> Self {
|
||||
Self::new_from_span(format!("failed to index into non-tuple '{}'", name), span)
|
||||
}
|
||||
|
@ -266,7 +266,13 @@ impl<'a> Program<'a> {
|
||||
|
||||
asg_function.fill_from_ast(function)?;
|
||||
|
||||
functions.insert(name.name.to_string(), asg_function);
|
||||
let name = name.name.to_string();
|
||||
|
||||
if functions.contains_key(&name) {
|
||||
return Err(AsgConvertError::duplicate_function_definition(&name, &function.span));
|
||||
}
|
||||
|
||||
functions.insert(name, asg_function);
|
||||
}
|
||||
|
||||
let mut circuits = IndexMap::new();
|
||||
|
@ -25,13 +25,19 @@ use crate::*;
|
||||
pub struct Canonicalizer {
|
||||
// If we are in a circuit keep track of the circuit name.
|
||||
circuit_name: Option<Identifier>,
|
||||
in_circuit: bool,
|
||||
}
|
||||
|
||||
impl Default for Canonicalizer {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
circuit_name: None,
|
||||
in_circuit: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Canonicalizer {
|
||||
pub fn default() -> Self {
|
||||
Self { circuit_name: None }
|
||||
}
|
||||
|
||||
fn is_self_type(&mut self, type_option: Option<&Type>) -> bool {
|
||||
matches!(type_option, Some(Type::SelfType))
|
||||
}
|
||||
@ -380,13 +386,15 @@ impl Canonicalizer {
|
||||
}
|
||||
|
||||
impl ReconstructingReducer for Canonicalizer {
|
||||
fn reduce_type(
|
||||
&mut self,
|
||||
_type_: &Type,
|
||||
new: Type,
|
||||
in_circuit: bool,
|
||||
span: &Span,
|
||||
) -> Result<Type, CanonicalizeError> {
|
||||
fn in_circuit(&self) -> bool {
|
||||
self.in_circuit
|
||||
}
|
||||
|
||||
fn swap_in_circuit(&mut self) {
|
||||
self.in_circuit = !self.in_circuit;
|
||||
}
|
||||
|
||||
fn reduce_type(&mut self, _type_: &Type, new: Type, span: &Span) -> Result<Type, CanonicalizeError> {
|
||||
match new {
|
||||
Type::Array(type_, mut dimensions) => {
|
||||
if dimensions.is_zero() {
|
||||
@ -407,7 +415,7 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
|
||||
Ok(array)
|
||||
}
|
||||
Type::SelfType if !in_circuit => Err(CanonicalizeError::big_self_outside_of_circuit(span)),
|
||||
Type::SelfType if !self.in_circuit => Err(CanonicalizeError::big_self_outside_of_circuit(span)),
|
||||
_ => Ok(new.clone()),
|
||||
}
|
||||
}
|
||||
@ -416,7 +424,6 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
&mut self,
|
||||
array_init: &ArrayInitExpression,
|
||||
element: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<ArrayInitExpression, CanonicalizeError> {
|
||||
if array_init.dimensions.is_zero() {
|
||||
return Err(CanonicalizeError::invalid_array_dimension_size(&array_init.span));
|
||||
@ -466,7 +473,6 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
assign: &AssignStatement,
|
||||
assignee: Assignee,
|
||||
value: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<AssignStatement, CanonicalizeError> {
|
||||
match value {
|
||||
Expression::Value(value_expr) if assign.operation != AssignOperation::Assign => {
|
||||
@ -545,7 +551,6 @@ impl ReconstructingReducer for Canonicalizer {
|
||||
input: Vec<FunctionInput>,
|
||||
output: Option<Type>,
|
||||
block: Block,
|
||||
_in_circuit: bool,
|
||||
) -> Result<Function, CanonicalizeError> {
|
||||
let new_output = match output {
|
||||
None => Some(Type::Tuple(vec![])),
|
||||
|
@ -22,15 +22,11 @@ use indexmap::IndexMap;
|
||||
|
||||
pub struct ReconstructingDirector<R: ReconstructingReducer> {
|
||||
reducer: R,
|
||||
in_circuit: bool,
|
||||
}
|
||||
|
||||
impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
pub fn new(reducer: R) -> Self {
|
||||
Self {
|
||||
reducer,
|
||||
in_circuit: false,
|
||||
}
|
||||
Self { reducer }
|
||||
}
|
||||
|
||||
pub fn reduce_type(&mut self, type_: &Type, span: &Span) -> Result<Type, CanonicalizeError> {
|
||||
@ -48,7 +44,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
_ => type_.clone(),
|
||||
};
|
||||
|
||||
self.reducer.reduce_type(type_, new, self.in_circuit, span)
|
||||
self.reducer.reduce_type(type_, new, span)
|
||||
}
|
||||
|
||||
// Expressions
|
||||
@ -84,7 +80,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
Expression::Call(call) => Expression::Call(self.reduce_call(&call)?),
|
||||
};
|
||||
|
||||
self.reducer.reduce_expression(expression, new, self.in_circuit)
|
||||
self.reducer.reduce_expression(expression, new)
|
||||
}
|
||||
|
||||
pub fn reduce_identifier(&mut self, identifier: &Identifier) -> Result<Identifier, CanonicalizeError> {
|
||||
@ -119,15 +115,13 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
let left = self.reduce_expression(&binary.left)?;
|
||||
let right = self.reduce_expression(&binary.right)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_binary(binary, left, right, binary.op.clone(), self.in_circuit)
|
||||
self.reducer.reduce_binary(binary, left, right, binary.op.clone())
|
||||
}
|
||||
|
||||
pub fn reduce_unary(&mut self, unary: &UnaryExpression) -> Result<UnaryExpression, CanonicalizeError> {
|
||||
let inner = self.reduce_expression(&unary.inner)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_unary(unary, inner, unary.op.clone(), self.in_circuit)
|
||||
self.reducer.reduce_unary(unary, inner, unary.op.clone())
|
||||
}
|
||||
|
||||
pub fn reduce_ternary(&mut self, ternary: &TernaryExpression) -> Result<TernaryExpression, CanonicalizeError> {
|
||||
@ -135,15 +129,14 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
let if_true = self.reduce_expression(&ternary.if_true)?;
|
||||
let if_false = self.reduce_expression(&ternary.if_false)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_ternary(ternary, condition, if_true, if_false, self.in_circuit)
|
||||
self.reducer.reduce_ternary(ternary, condition, if_true, if_false)
|
||||
}
|
||||
|
||||
pub fn reduce_cast(&mut self, cast: &CastExpression) -> Result<CastExpression, CanonicalizeError> {
|
||||
let inner = self.reduce_expression(&cast.inner)?;
|
||||
let target_type = self.reduce_type(&cast.target_type, &cast.span)?;
|
||||
|
||||
self.reducer.reduce_cast(cast, inner, target_type, self.in_circuit)
|
||||
self.reducer.reduce_cast(cast, inner, target_type)
|
||||
}
|
||||
|
||||
pub fn reduce_array_inline(
|
||||
@ -164,8 +157,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
elements.push(reduced_element);
|
||||
}
|
||||
|
||||
self.reducer
|
||||
.reduce_array_inline(array_inline, elements, self.in_circuit)
|
||||
self.reducer.reduce_array_inline(array_inline, elements)
|
||||
}
|
||||
|
||||
pub fn reduce_array_init(
|
||||
@ -174,7 +166,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
) -> Result<ArrayInitExpression, CanonicalizeError> {
|
||||
let element = self.reduce_expression(&array_init.element)?;
|
||||
|
||||
self.reducer.reduce_array_init(array_init, element, self.in_circuit)
|
||||
self.reducer.reduce_array_init(array_init, element)
|
||||
}
|
||||
|
||||
pub fn reduce_array_access(
|
||||
@ -184,8 +176,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
let array = self.reduce_expression(&array_access.array)?;
|
||||
let index = self.reduce_expression(&array_access.index)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_array_access(array_access, array, index, self.in_circuit)
|
||||
self.reducer.reduce_array_access(array_access, array, index)
|
||||
}
|
||||
|
||||
pub fn reduce_array_range_access(
|
||||
@ -205,7 +196,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
.transpose()?;
|
||||
|
||||
self.reducer
|
||||
.reduce_array_range_access(array_range_access, array, left, right, self.in_circuit)
|
||||
.reduce_array_range_access(array_range_access, array, left, right)
|
||||
}
|
||||
|
||||
pub fn reduce_tuple_init(
|
||||
@ -217,7 +208,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
elements.push(self.reduce_expression(element)?);
|
||||
}
|
||||
|
||||
self.reducer.reduce_tuple_init(tuple_init, elements, self.in_circuit)
|
||||
self.reducer.reduce_tuple_init(tuple_init, elements)
|
||||
}
|
||||
|
||||
pub fn reduce_tuple_access(
|
||||
@ -226,7 +217,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
) -> Result<TupleAccessExpression, CanonicalizeError> {
|
||||
let tuple = self.reduce_expression(&tuple_access.tuple)?;
|
||||
|
||||
self.reducer.reduce_tuple_access(tuple_access, tuple, self.in_circuit)
|
||||
self.reducer.reduce_tuple_access(tuple_access, tuple)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_implied_variable_definition(
|
||||
@ -241,7 +232,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
.transpose()?;
|
||||
|
||||
self.reducer
|
||||
.reduce_circuit_implied_variable_definition(variable, identifier, expression, self.in_circuit)
|
||||
.reduce_circuit_implied_variable_definition(variable, identifier, expression)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_init(
|
||||
@ -255,8 +246,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
members.push(self.reduce_circuit_implied_variable_definition(member)?);
|
||||
}
|
||||
|
||||
self.reducer
|
||||
.reduce_circuit_init(circuit_init, name, members, self.in_circuit)
|
||||
self.reducer.reduce_circuit_init(circuit_init, name, members)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_member_access(
|
||||
@ -267,7 +257,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
let name = self.reduce_identifier(&circuit_member_access.name)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_circuit_member_access(circuit_member_access, circuit, name, self.in_circuit)
|
||||
.reduce_circuit_member_access(circuit_member_access, circuit, name)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_static_fn_access(
|
||||
@ -278,7 +268,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
let name = self.reduce_identifier(&circuit_static_fn_access.name)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_circuit_static_fn_access(circuit_static_fn_access, circuit, name, self.in_circuit)
|
||||
.reduce_circuit_static_fn_access(circuit_static_fn_access, circuit, name)
|
||||
}
|
||||
|
||||
pub fn reduce_call(&mut self, call: &CallExpression) -> Result<CallExpression, CanonicalizeError> {
|
||||
@ -289,7 +279,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
arguments.push(self.reduce_expression(argument)?);
|
||||
}
|
||||
|
||||
self.reducer.reduce_call(call, function, arguments, self.in_circuit)
|
||||
self.reducer.reduce_call(call, function, arguments)
|
||||
}
|
||||
|
||||
// Statements
|
||||
@ -305,14 +295,13 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
Statement::Block(block) => Statement::Block(self.reduce_block(&block)?),
|
||||
};
|
||||
|
||||
self.reducer.reduce_statement(statement, new, self.in_circuit)
|
||||
self.reducer.reduce_statement(statement, new)
|
||||
}
|
||||
|
||||
pub fn reduce_return(&mut self, return_statement: &ReturnStatement) -> Result<ReturnStatement, CanonicalizeError> {
|
||||
let expression = self.reduce_expression(&return_statement.expression)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_return(return_statement, expression, self.in_circuit)
|
||||
self.reducer.reduce_return(return_statement, expression)
|
||||
}
|
||||
|
||||
pub fn reduce_variable_name(&mut self, variable_name: &VariableName) -> Result<VariableName, CanonicalizeError> {
|
||||
@ -338,8 +327,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
|
||||
let value = self.reduce_expression(&definition.value)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_definition(definition, variable_names, type_, value, self.in_circuit)
|
||||
self.reducer.reduce_definition(definition, variable_names, type_, value)
|
||||
}
|
||||
|
||||
pub fn reduce_assignee_access(&mut self, access: &AssigneeAccess) -> Result<AssigneeAccess, CanonicalizeError> {
|
||||
@ -355,7 +343,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
_ => access.clone(),
|
||||
};
|
||||
|
||||
self.reducer.reduce_assignee_access(access, new, self.in_circuit)
|
||||
self.reducer.reduce_assignee_access(access, new)
|
||||
}
|
||||
|
||||
pub fn reduce_assignee(&mut self, assignee: &Assignee) -> Result<Assignee, CanonicalizeError> {
|
||||
@ -366,15 +354,14 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
accesses.push(self.reduce_assignee_access(access)?);
|
||||
}
|
||||
|
||||
self.reducer
|
||||
.reduce_assignee(assignee, identifier, accesses, self.in_circuit)
|
||||
self.reducer.reduce_assignee(assignee, identifier, accesses)
|
||||
}
|
||||
|
||||
pub fn reduce_assign(&mut self, assign: &AssignStatement) -> Result<AssignStatement, CanonicalizeError> {
|
||||
let assignee = self.reduce_assignee(&assign.assignee)?;
|
||||
let value = self.reduce_expression(&assign.value)?;
|
||||
|
||||
self.reducer.reduce_assign(assign, assignee, value, self.in_circuit)
|
||||
self.reducer.reduce_assign(assign, assignee, value)
|
||||
}
|
||||
|
||||
pub fn reduce_conditional(
|
||||
@ -389,8 +376,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
.map(|condition| self.reduce_statement(condition))
|
||||
.transpose()?;
|
||||
|
||||
self.reducer
|
||||
.reduce_conditional(conditional, condition, block, next, self.in_circuit)
|
||||
self.reducer.reduce_conditional(conditional, condition, block, next)
|
||||
}
|
||||
|
||||
pub fn reduce_iteration(
|
||||
@ -402,8 +388,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
let stop = self.reduce_expression(&iteration.stop)?;
|
||||
let block = self.reduce_block(&iteration.block)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_iteration(iteration, variable, start, stop, block, self.in_circuit)
|
||||
self.reducer.reduce_iteration(iteration, variable, start, stop, block)
|
||||
}
|
||||
|
||||
pub fn reduce_console(
|
||||
@ -433,8 +418,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
}
|
||||
};
|
||||
|
||||
self.reducer
|
||||
.reduce_console(console_function_call, function, self.in_circuit)
|
||||
self.reducer.reduce_console(console_function_call, function)
|
||||
}
|
||||
|
||||
pub fn reduce_expression_statement(
|
||||
@ -442,8 +426,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
expression: &ExpressionStatement,
|
||||
) -> Result<ExpressionStatement, CanonicalizeError> {
|
||||
let inner_expression = self.reduce_expression(&expression.expression)?;
|
||||
self.reducer
|
||||
.reduce_expression_statement(expression, inner_expression, self.in_circuit)
|
||||
self.reducer.reduce_expression_statement(expression, inner_expression)
|
||||
}
|
||||
|
||||
pub fn reduce_block(&mut self, block: &Block) -> Result<Block, CanonicalizeError> {
|
||||
@ -452,7 +435,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
statements.push(self.reduce_statement(statement)?);
|
||||
}
|
||||
|
||||
self.reducer.reduce_block(block, statements, self.in_circuit)
|
||||
self.reducer.reduce_block(block, statements)
|
||||
}
|
||||
|
||||
// Program
|
||||
@ -468,9 +451,11 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
}
|
||||
|
||||
let mut circuits = IndexMap::new();
|
||||
self.reducer.swap_in_circuit();
|
||||
for (identifier, circuit) in program.circuits.iter() {
|
||||
circuits.insert(self.reduce_identifier(identifier)?, self.reduce_circuit(circuit)?);
|
||||
}
|
||||
self.reducer.swap_in_circuit();
|
||||
|
||||
let mut functions = IndexMap::new();
|
||||
for (identifier, function) in program.functions.iter() {
|
||||
@ -488,8 +473,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
let identifier = self.reduce_identifier(&variable.identifier)?;
|
||||
let type_ = self.reduce_type(&variable.type_, &variable.span)?;
|
||||
|
||||
self.reducer
|
||||
.reduce_function_input_variable(variable, identifier, type_, self.in_circuit)
|
||||
self.reducer.reduce_function_input_variable(variable, identifier, type_)
|
||||
}
|
||||
|
||||
pub fn reduce_function_input(&mut self, input: &FunctionInput) -> Result<FunctionInput, CanonicalizeError> {
|
||||
@ -500,7 +484,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
_ => input.clone(),
|
||||
};
|
||||
|
||||
self.reducer.reduce_function_input(input, new, self.in_circuit)
|
||||
self.reducer.reduce_function_input(input, new)
|
||||
}
|
||||
|
||||
pub fn reduce_package_or_packages(
|
||||
@ -533,7 +517,6 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
&mut self,
|
||||
circuit_member: &CircuitMember,
|
||||
) -> Result<CircuitMember, CanonicalizeError> {
|
||||
self.in_circuit = !self.in_circuit;
|
||||
let new = match circuit_member {
|
||||
CircuitMember::CircuitVariable(identifier, type_) => CircuitMember::CircuitVariable(
|
||||
self.reduce_identifier(&identifier)?,
|
||||
@ -543,7 +526,6 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
CircuitMember::CircuitFunction(self.reduce_function(&function)?)
|
||||
}
|
||||
};
|
||||
self.in_circuit = !self.in_circuit;
|
||||
|
||||
self.reducer.reduce_circuit_member(circuit_member, new)
|
||||
}
|
||||
@ -586,14 +568,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
|
||||
let block = self.reduce_block(&function.block)?;
|
||||
|
||||
self.reducer.reduce_function(
|
||||
function,
|
||||
identifier,
|
||||
annotations,
|
||||
inputs,
|
||||
output,
|
||||
block,
|
||||
self.in_circuit,
|
||||
)
|
||||
self.reducer
|
||||
.reduce_function(function, identifier, annotations, inputs, output, block)
|
||||
}
|
||||
}
|
||||
|
@ -20,13 +20,10 @@ use indexmap::IndexMap;
|
||||
// Needed to fix clippy bug.
|
||||
#[allow(clippy::redundant_closure)]
|
||||
pub trait ReconstructingReducer {
|
||||
fn reduce_type(
|
||||
&mut self,
|
||||
_type_: &Type,
|
||||
new: Type,
|
||||
_in_circuit: bool,
|
||||
_span: &Span,
|
||||
) -> Result<Type, CanonicalizeError> {
|
||||
fn in_circuit(&self) -> bool;
|
||||
fn swap_in_circuit(&mut self);
|
||||
|
||||
fn reduce_type(&mut self, _type_: &Type, new: Type, _span: &Span) -> Result<Type, CanonicalizeError> {
|
||||
Ok(new)
|
||||
}
|
||||
|
||||
@ -35,7 +32,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
_expression: &Expression,
|
||||
new: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<Expression, CanonicalizeError> {
|
||||
Ok(new)
|
||||
}
|
||||
@ -77,7 +73,6 @@ pub trait ReconstructingReducer {
|
||||
left: Expression,
|
||||
right: Expression,
|
||||
op: BinaryOperation,
|
||||
_in_circuit: bool,
|
||||
) -> Result<BinaryExpression, CanonicalizeError> {
|
||||
Ok(BinaryExpression {
|
||||
left: Box::new(left),
|
||||
@ -92,7 +87,6 @@ pub trait ReconstructingReducer {
|
||||
unary: &UnaryExpression,
|
||||
inner: Expression,
|
||||
op: UnaryOperation,
|
||||
_in_circuit: bool,
|
||||
) -> Result<UnaryExpression, CanonicalizeError> {
|
||||
Ok(UnaryExpression {
|
||||
inner: Box::new(inner),
|
||||
@ -107,7 +101,6 @@ pub trait ReconstructingReducer {
|
||||
condition: Expression,
|
||||
if_true: Expression,
|
||||
if_false: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<TernaryExpression, CanonicalizeError> {
|
||||
Ok(TernaryExpression {
|
||||
condition: Box::new(condition),
|
||||
@ -122,7 +115,6 @@ pub trait ReconstructingReducer {
|
||||
cast: &CastExpression,
|
||||
inner: Expression,
|
||||
target_type: Type,
|
||||
_in_circuit: bool,
|
||||
) -> Result<CastExpression, CanonicalizeError> {
|
||||
Ok(CastExpression {
|
||||
inner: Box::new(inner),
|
||||
@ -135,7 +127,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
array_inline: &ArrayInlineExpression,
|
||||
elements: Vec<SpreadOrExpression>,
|
||||
_in_circuit: bool,
|
||||
) -> Result<ArrayInlineExpression, CanonicalizeError> {
|
||||
Ok(ArrayInlineExpression {
|
||||
elements,
|
||||
@ -147,7 +138,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
array_init: &ArrayInitExpression,
|
||||
element: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<ArrayInitExpression, CanonicalizeError> {
|
||||
Ok(ArrayInitExpression {
|
||||
element: Box::new(element),
|
||||
@ -161,7 +151,6 @@ pub trait ReconstructingReducer {
|
||||
array_access: &ArrayAccessExpression,
|
||||
array: Expression,
|
||||
index: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<ArrayAccessExpression, CanonicalizeError> {
|
||||
Ok(ArrayAccessExpression {
|
||||
array: Box::new(array),
|
||||
@ -176,7 +165,6 @@ pub trait ReconstructingReducer {
|
||||
array: Expression,
|
||||
left: Option<Expression>,
|
||||
right: Option<Expression>,
|
||||
_in_circuit: bool,
|
||||
) -> Result<ArrayRangeAccessExpression, CanonicalizeError> {
|
||||
Ok(ArrayRangeAccessExpression {
|
||||
array: Box::new(array),
|
||||
@ -190,7 +178,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
tuple_init: &TupleInitExpression,
|
||||
elements: Vec<Expression>,
|
||||
_in_circuit: bool,
|
||||
) -> Result<TupleInitExpression, CanonicalizeError> {
|
||||
Ok(TupleInitExpression {
|
||||
elements,
|
||||
@ -202,7 +189,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
tuple_access: &TupleAccessExpression,
|
||||
tuple: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<TupleAccessExpression, CanonicalizeError> {
|
||||
Ok(TupleAccessExpression {
|
||||
tuple: Box::new(tuple),
|
||||
@ -216,7 +202,6 @@ pub trait ReconstructingReducer {
|
||||
_variable: &CircuitImpliedVariableDefinition,
|
||||
identifier: Identifier,
|
||||
expression: Option<Expression>,
|
||||
_in_circuit: bool,
|
||||
) -> Result<CircuitImpliedVariableDefinition, CanonicalizeError> {
|
||||
Ok(CircuitImpliedVariableDefinition { identifier, expression })
|
||||
}
|
||||
@ -226,7 +211,6 @@ pub trait ReconstructingReducer {
|
||||
circuit_init: &CircuitInitExpression,
|
||||
name: Identifier,
|
||||
members: Vec<CircuitImpliedVariableDefinition>,
|
||||
_in_circuit: bool,
|
||||
) -> Result<CircuitInitExpression, CanonicalizeError> {
|
||||
Ok(CircuitInitExpression {
|
||||
name,
|
||||
@ -240,7 +224,6 @@ pub trait ReconstructingReducer {
|
||||
circuit_member_access: &CircuitMemberAccessExpression,
|
||||
circuit: Expression,
|
||||
name: Identifier,
|
||||
_in_circuit: bool,
|
||||
) -> Result<CircuitMemberAccessExpression, CanonicalizeError> {
|
||||
Ok(CircuitMemberAccessExpression {
|
||||
circuit: Box::new(circuit),
|
||||
@ -254,7 +237,6 @@ pub trait ReconstructingReducer {
|
||||
circuit_static_fn_access: &CircuitStaticFunctionAccessExpression,
|
||||
circuit: Expression,
|
||||
name: Identifier,
|
||||
_in_circuit: bool,
|
||||
) -> Result<CircuitStaticFunctionAccessExpression, CanonicalizeError> {
|
||||
Ok(CircuitStaticFunctionAccessExpression {
|
||||
circuit: Box::new(circuit),
|
||||
@ -268,7 +250,6 @@ pub trait ReconstructingReducer {
|
||||
call: &CallExpression,
|
||||
function: Expression,
|
||||
arguments: Vec<Expression>,
|
||||
_in_circuit: bool,
|
||||
) -> Result<CallExpression, CanonicalizeError> {
|
||||
Ok(CallExpression {
|
||||
function: Box::new(function),
|
||||
@ -278,12 +259,7 @@ pub trait ReconstructingReducer {
|
||||
}
|
||||
|
||||
// Statements
|
||||
fn reduce_statement(
|
||||
&mut self,
|
||||
_statement: &Statement,
|
||||
new: Statement,
|
||||
_in_circuit: bool,
|
||||
) -> Result<Statement, CanonicalizeError> {
|
||||
fn reduce_statement(&mut self, _statement: &Statement, new: Statement) -> Result<Statement, CanonicalizeError> {
|
||||
Ok(new)
|
||||
}
|
||||
|
||||
@ -291,7 +267,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
return_statement: &ReturnStatement,
|
||||
expression: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<ReturnStatement, CanonicalizeError> {
|
||||
Ok(ReturnStatement {
|
||||
expression,
|
||||
@ -317,7 +292,6 @@ pub trait ReconstructingReducer {
|
||||
variable_names: Vec<VariableName>,
|
||||
type_: Option<Type>,
|
||||
value: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<DefinitionStatement, CanonicalizeError> {
|
||||
Ok(DefinitionStatement {
|
||||
declaration_type: definition.declaration_type.clone(),
|
||||
@ -332,7 +306,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
_access: &AssigneeAccess,
|
||||
new: AssigneeAccess,
|
||||
_in_circuit: bool,
|
||||
) -> Result<AssigneeAccess, CanonicalizeError> {
|
||||
Ok(new)
|
||||
}
|
||||
@ -342,7 +315,6 @@ pub trait ReconstructingReducer {
|
||||
assignee: &Assignee,
|
||||
identifier: Identifier,
|
||||
accesses: Vec<AssigneeAccess>,
|
||||
_in_circuit: bool,
|
||||
) -> Result<Assignee, CanonicalizeError> {
|
||||
Ok(Assignee {
|
||||
identifier,
|
||||
@ -356,7 +328,6 @@ pub trait ReconstructingReducer {
|
||||
assign: &AssignStatement,
|
||||
assignee: Assignee,
|
||||
value: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<AssignStatement, CanonicalizeError> {
|
||||
Ok(AssignStatement {
|
||||
operation: assign.operation.clone(),
|
||||
@ -372,7 +343,6 @@ pub trait ReconstructingReducer {
|
||||
condition: Expression,
|
||||
block: Block,
|
||||
statement: Option<Statement>,
|
||||
_in_circuit: bool,
|
||||
) -> Result<ConditionalStatement, CanonicalizeError> {
|
||||
Ok(ConditionalStatement {
|
||||
condition,
|
||||
@ -389,7 +359,6 @@ pub trait ReconstructingReducer {
|
||||
start: Expression,
|
||||
stop: Expression,
|
||||
block: Block,
|
||||
_in_circuit: bool,
|
||||
) -> Result<IterationStatement, CanonicalizeError> {
|
||||
Ok(IterationStatement {
|
||||
variable,
|
||||
@ -404,7 +373,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
console: &ConsoleStatement,
|
||||
function: ConsoleFunction,
|
||||
_in_circuit: bool,
|
||||
) -> Result<ConsoleStatement, CanonicalizeError> {
|
||||
Ok(ConsoleStatement {
|
||||
function,
|
||||
@ -416,7 +384,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
expression_statement: &ExpressionStatement,
|
||||
expression: Expression,
|
||||
_in_circuit: bool,
|
||||
) -> Result<ExpressionStatement, CanonicalizeError> {
|
||||
Ok(ExpressionStatement {
|
||||
expression,
|
||||
@ -424,12 +391,7 @@ pub trait ReconstructingReducer {
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_block(
|
||||
&mut self,
|
||||
block: &Block,
|
||||
statements: Vec<Statement>,
|
||||
_in_circuit: bool,
|
||||
) -> Result<Block, CanonicalizeError> {
|
||||
fn reduce_block(&mut self, block: &Block, statements: Vec<Statement>) -> Result<Block, CanonicalizeError> {
|
||||
Ok(Block {
|
||||
statements,
|
||||
span: block.span.clone(),
|
||||
@ -459,7 +421,6 @@ pub trait ReconstructingReducer {
|
||||
variable: &FunctionInputVariable,
|
||||
identifier: Identifier,
|
||||
type_: Type,
|
||||
_in_circuit: bool,
|
||||
) -> Result<FunctionInputVariable, CanonicalizeError> {
|
||||
Ok(FunctionInputVariable {
|
||||
identifier,
|
||||
@ -474,7 +435,6 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
_input: &FunctionInput,
|
||||
new: FunctionInput,
|
||||
_in_circuit: bool,
|
||||
) -> Result<FunctionInput, CanonicalizeError> {
|
||||
Ok(new)
|
||||
}
|
||||
@ -536,7 +496,6 @@ pub trait ReconstructingReducer {
|
||||
input: Vec<FunctionInput>,
|
||||
output: Option<Type>,
|
||||
block: Block,
|
||||
_in_circuit: bool,
|
||||
) -> Result<Function, CanonicalizeError> {
|
||||
Ok(Function {
|
||||
identifier,
|
||||
|
@ -53,27 +53,27 @@ version = "1.2.3"
|
||||
version = "0.4"
|
||||
|
||||
[dependencies.snarkvm-curves]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-fields]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-dpc]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-gadgets]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-r1cs]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-utilities]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
|
||||
[dependencies.bincode]
|
||||
version = "1.3"
|
||||
@ -114,7 +114,7 @@ version = "0.3"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.snarkvm-algorithms]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.tempfile]
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use leo_ast::{FormattedError, LeoError, Span};
|
||||
|
||||
use snarkvm_gadgets::errors::SignedIntegerError;
|
||||
use snarkvm_gadgets::errors::{SignedIntegerError, UnsignedIntegerError};
|
||||
use snarkvm_r1cs::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@ -38,6 +38,15 @@ impl IntegerError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn unsigned(error: UnsignedIntegerError, span: &Span) -> Self {
|
||||
let message = format!(
|
||||
"integer operation failed due to the unsigned integer error `{:?}`",
|
||||
error
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn synthesis(error: SynthesisError, span: &Span) -> Self {
|
||||
let message = format!("integer operation failed due to the synthesis error `{}`", error);
|
||||
|
||||
|
@ -98,16 +98,11 @@ use tendril::StrTendril;
|
||||
pub struct CombineAstAsgDirector<R: ReconstructingReducer> {
|
||||
ast_reducer: R,
|
||||
options: CompilerOptions,
|
||||
in_circuit: bool,
|
||||
}
|
||||
|
||||
impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
pub fn new(ast_reducer: R, options: CompilerOptions) -> Self {
|
||||
Self {
|
||||
ast_reducer,
|
||||
options,
|
||||
in_circuit: false,
|
||||
}
|
||||
Self { ast_reducer, options }
|
||||
}
|
||||
|
||||
pub fn reduce_type(&mut self, ast: &AstType, asg: &AsgType, span: &Span) -> Result<AstType, CanonicalizeError> {
|
||||
@ -138,7 +133,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
_ => ast.clone(),
|
||||
};
|
||||
|
||||
self.ast_reducer.reduce_type(ast, new, self.in_circuit, span)
|
||||
self.ast_reducer.reduce_type(ast, new, span)
|
||||
}
|
||||
|
||||
pub fn reduce_expression(
|
||||
@ -197,7 +192,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
_ => ast.clone(),
|
||||
};
|
||||
|
||||
self.ast_reducer.reduce_expression(ast, new, self.in_circuit)
|
||||
self.ast_reducer.reduce_expression(ast, new)
|
||||
}
|
||||
|
||||
pub fn reduce_array_access(
|
||||
@ -208,7 +203,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
let array = self.reduce_expression(&ast.array, asg.array.get())?;
|
||||
let index = self.reduce_expression(&ast.index, asg.index.get())?;
|
||||
|
||||
self.ast_reducer.reduce_array_access(ast, array, index, self.in_circuit)
|
||||
self.ast_reducer.reduce_array_access(ast, array, index)
|
||||
}
|
||||
|
||||
pub fn reduce_array_init(
|
||||
@ -218,7 +213,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
) -> Result<AstArrayInitExpression, CanonicalizeError> {
|
||||
let element = self.reduce_expression(&ast.element, asg.element.get())?;
|
||||
|
||||
self.ast_reducer.reduce_array_init(ast, element, self.in_circuit)
|
||||
self.ast_reducer.reduce_array_init(ast, element)
|
||||
}
|
||||
|
||||
pub fn reduce_array_inline(
|
||||
@ -240,7 +235,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
elements.push(reduced_element);
|
||||
}
|
||||
|
||||
self.ast_reducer.reduce_array_inline(ast, elements, self.in_circuit)
|
||||
self.ast_reducer.reduce_array_inline(ast, elements)
|
||||
}
|
||||
|
||||
pub fn reduce_array_range_access(
|
||||
@ -258,8 +253,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
_ => None,
|
||||
};
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_array_range_access(ast, array, left, right, self.in_circuit)
|
||||
self.ast_reducer.reduce_array_range_access(ast, array, left, right)
|
||||
}
|
||||
|
||||
pub fn reduce_binary(
|
||||
@ -270,8 +264,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
let left = self.reduce_expression(&ast.left, asg.left.get())?;
|
||||
let right = self.reduce_expression(&ast.right, asg.right.get())?;
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_binary(ast, left, right, ast.op.clone(), self.in_circuit)
|
||||
self.ast_reducer.reduce_binary(ast, left, right, ast.op.clone())
|
||||
}
|
||||
|
||||
pub fn reduce_call(
|
||||
@ -289,8 +282,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
arguments.push(self.reduce_expression(ast_arg, asg_arg.get())?);
|
||||
}
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_call(ast, *ast.function.clone(), arguments, self.in_circuit)
|
||||
self.ast_reducer.reduce_call(ast, *ast.function.clone(), arguments)
|
||||
}
|
||||
|
||||
pub fn reduce_cast(
|
||||
@ -301,7 +293,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
let inner = self.reduce_expression(&ast.inner, &asg.inner.get())?;
|
||||
let target_type = self.reduce_type(&ast.target_type, &asg.target_type, &ast.span)?;
|
||||
|
||||
self.ast_reducer.reduce_cast(ast, inner, target_type, self.in_circuit)
|
||||
self.ast_reducer.reduce_cast(ast, inner, target_type)
|
||||
}
|
||||
|
||||
pub fn reduce_constant(
|
||||
@ -333,7 +325,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
// does it matter?
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_circuit_member_access(ast, *ast.circuit.clone(), ast.name.clone(), self.in_circuit)
|
||||
.reduce_circuit_member_access(ast, *ast.circuit.clone(), ast.name.clone())
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_static_fn_access(
|
||||
@ -348,7 +340,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
// does it matter?
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_circuit_static_fn_access(ast, *ast.circuit.clone(), ast.name.clone(), self.in_circuit)
|
||||
.reduce_circuit_static_fn_access(ast, *ast.circuit.clone(), ast.name.clone())
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_implied_variable_definition(
|
||||
@ -362,12 +354,8 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
.map(|ast_expr| self.reduce_expression(ast_expr, asg))
|
||||
.transpose()?;
|
||||
|
||||
self.ast_reducer.reduce_circuit_implied_variable_definition(
|
||||
ast,
|
||||
ast.identifier.clone(),
|
||||
expression,
|
||||
self.in_circuit,
|
||||
)
|
||||
self.ast_reducer
|
||||
.reduce_circuit_implied_variable_definition(ast, ast.identifier.clone(), expression)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_init(
|
||||
@ -380,8 +368,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
members.push(self.reduce_circuit_implied_variable_definition(ast_member, asg_member.1.get())?);
|
||||
}
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_circuit_init(ast, ast.name.clone(), members, self.in_circuit)
|
||||
self.ast_reducer.reduce_circuit_init(ast, ast.name.clone(), members)
|
||||
}
|
||||
|
||||
pub fn reduce_ternary(
|
||||
@ -393,8 +380,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
let if_true = self.reduce_expression(&ast.if_true, asg.if_true.get())?;
|
||||
let if_false = self.reduce_expression(&ast.if_false, asg.if_false.get())?;
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_ternary(ast, condition, if_true, if_false, self.in_circuit)
|
||||
self.ast_reducer.reduce_ternary(ast, condition, if_true, if_false)
|
||||
}
|
||||
|
||||
pub fn reduce_tuple_access(
|
||||
@ -404,7 +390,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
) -> Result<AstTupleAccessExpression, CanonicalizeError> {
|
||||
let tuple = self.reduce_expression(&ast.tuple, asg.tuple_ref.get())?;
|
||||
|
||||
self.ast_reducer.reduce_tuple_access(ast, tuple, self.in_circuit)
|
||||
self.ast_reducer.reduce_tuple_access(ast, tuple)
|
||||
}
|
||||
|
||||
pub fn reduce_tuple_init(
|
||||
@ -418,7 +404,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
elements.push(element);
|
||||
}
|
||||
|
||||
self.ast_reducer.reduce_tuple_init(ast, elements, self.in_circuit)
|
||||
self.ast_reducer.reduce_tuple_init(ast, elements)
|
||||
}
|
||||
|
||||
pub fn reduce_unary(
|
||||
@ -428,8 +414,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
) -> Result<AstUnaryExpression, CanonicalizeError> {
|
||||
let inner = self.reduce_expression(&ast.inner, asg.inner.get())?;
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_unary(ast, inner, ast.op.clone(), self.in_circuit)
|
||||
self.ast_reducer.reduce_unary(ast, inner, ast.op.clone())
|
||||
}
|
||||
|
||||
pub fn reduce_variable_ref(
|
||||
@ -480,7 +465,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
_ => ast_statement.clone(),
|
||||
};
|
||||
|
||||
self.ast_reducer.reduce_statement(ast_statement, new, self.in_circuit)
|
||||
self.ast_reducer.reduce_statement(ast_statement, new)
|
||||
}
|
||||
|
||||
pub fn reduce_assign_access(
|
||||
@ -508,7 +493,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
_ => ast.clone(),
|
||||
};
|
||||
|
||||
self.ast_reducer.reduce_assignee_access(ast, new, self.in_circuit)
|
||||
self.ast_reducer.reduce_assignee_access(ast, new)
|
||||
}
|
||||
|
||||
pub fn reduce_assignee(&mut self, ast: &Assignee, asg: &[AsgAssignAccess]) -> Result<Assignee, CanonicalizeError> {
|
||||
@ -517,8 +502,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
accesses.push(self.reduce_assign_access(ast_access, asg_access)?);
|
||||
}
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_assignee(ast, ast.identifier.clone(), accesses, self.in_circuit)
|
||||
self.ast_reducer.reduce_assignee(ast, ast.identifier.clone(), accesses)
|
||||
}
|
||||
|
||||
pub fn reduce_assign(
|
||||
@ -529,7 +513,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
let assignee = self.reduce_assignee(&ast.assignee, &asg.target_accesses)?;
|
||||
let value = self.reduce_expression(&ast.value, asg.value.get())?;
|
||||
|
||||
self.ast_reducer.reduce_assign(ast, assignee, value, self.in_circuit)
|
||||
self.ast_reducer.reduce_assign(ast, assignee, value)
|
||||
}
|
||||
|
||||
pub fn reduce_block(
|
||||
@ -542,7 +526,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
statements.push(self.reduce_statement(ast_statement, asg_statement.get())?);
|
||||
}
|
||||
|
||||
self.ast_reducer.reduce_block(ast, statements, self.in_circuit)
|
||||
self.ast_reducer.reduce_block(ast, statements)
|
||||
}
|
||||
|
||||
pub fn reduce_conditional(
|
||||
@ -563,8 +547,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
_ => None,
|
||||
};
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_conditional(ast, condition, block, next, self.in_circuit)
|
||||
self.ast_reducer.reduce_conditional(ast, condition, block, next)
|
||||
}
|
||||
|
||||
pub fn reduce_console(
|
||||
@ -600,7 +583,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
_ => ast.function.clone(),
|
||||
};
|
||||
|
||||
self.ast_reducer.reduce_console(ast, function, self.in_circuit)
|
||||
self.ast_reducer.reduce_console(ast, function)
|
||||
}
|
||||
|
||||
pub fn reduce_definition(
|
||||
@ -638,7 +621,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
let value = self.reduce_expression(&ast.value, asg.value.get())?;
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_definition(ast, ast.variable_names.clone(), type_, value, self.in_circuit)
|
||||
.reduce_definition(ast, ast.variable_names.clone(), type_, value)
|
||||
}
|
||||
|
||||
pub fn reduce_expression_statement(
|
||||
@ -647,8 +630,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
asg: &AsgExpressionStatement,
|
||||
) -> Result<AstExpressionStatement, CanonicalizeError> {
|
||||
let inner_expression = self.reduce_expression(&ast.expression, asg.expression.get())?;
|
||||
self.ast_reducer
|
||||
.reduce_expression_statement(ast, inner_expression, self.in_circuit)
|
||||
self.ast_reducer.reduce_expression_statement(ast, inner_expression)
|
||||
}
|
||||
|
||||
pub fn reduce_iteration(
|
||||
@ -666,7 +648,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
}
|
||||
|
||||
self.ast_reducer
|
||||
.reduce_iteration(ast, ast.variable.clone(), start, stop, block, self.in_circuit)
|
||||
.reduce_iteration(ast, ast.variable.clone(), start, stop, block)
|
||||
}
|
||||
|
||||
pub fn reduce_return(
|
||||
@ -676,7 +658,7 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
) -> Result<AstReturnStatement, CanonicalizeError> {
|
||||
let expression = self.reduce_expression(&ast.expression, asg.expression.get())?;
|
||||
|
||||
self.ast_reducer.reduce_return(ast, expression, self.in_circuit)
|
||||
self.ast_reducer.reduce_return(ast, expression)
|
||||
}
|
||||
|
||||
pub fn reduce_program(
|
||||
@ -684,10 +666,12 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
ast: &leo_ast::Program,
|
||||
asg: &leo_asg::Program,
|
||||
) -> Result<leo_ast::Program, leo_ast::CanonicalizeError> {
|
||||
self.ast_reducer.swap_in_circuit();
|
||||
let mut circuits = IndexMap::new();
|
||||
for ((ast_ident, ast_circuit), (_asg_ident, asg_circuit)) in ast.circuits.iter().zip(&asg.circuits) {
|
||||
circuits.insert(ast_ident.clone(), self.reduce_circuit(ast_circuit, asg_circuit)?);
|
||||
}
|
||||
self.ast_reducer.swap_in_circuit();
|
||||
|
||||
let mut functions = IndexMap::new();
|
||||
for ((ast_ident, ast_function), (_asg_ident, asg_function)) in ast.functions.iter().zip(&asg.functions) {
|
||||
@ -729,7 +713,6 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
ast.input.clone(),
|
||||
output,
|
||||
block,
|
||||
self.in_circuit,
|
||||
)
|
||||
}
|
||||
|
||||
@ -738,7 +721,6 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
ast: &AstCircuitMember,
|
||||
asg: &AsgCircuitMember,
|
||||
) -> Result<AstCircuitMember, CanonicalizeError> {
|
||||
self.in_circuit = !self.in_circuit;
|
||||
let new = match (ast, asg) {
|
||||
(AstCircuitMember::CircuitVariable(identifier, ast_type), AsgCircuitMember::Variable(asg_type)) => {
|
||||
AstCircuitMember::CircuitVariable(
|
||||
@ -751,7 +733,6 @@ impl<R: ReconstructingReducer> CombineAstAsgDirector<R> {
|
||||
}
|
||||
_ => ast.clone(),
|
||||
};
|
||||
self.in_circuit = !self.in_circuit;
|
||||
|
||||
self.ast_reducer.reduce_circuit_member(ast, new)
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ use crate::{
|
||||
GroupType,
|
||||
IndicatorAndConstrainedValue,
|
||||
Integer,
|
||||
IntegerTrait,
|
||||
StatementResult,
|
||||
};
|
||||
use leo_asg::IterationStatement;
|
||||
|
@ -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::AddressError, ConstrainedValue, GroupType};
|
||||
use crate::{errors::AddressError, ConstrainedValue, GroupType, IntegerTrait};
|
||||
use leo_ast::{InputValue, Span};
|
||||
|
||||
use snarkvm_dpc::{account::AccountAddress, base_dpc::instantiated::Components};
|
||||
@ -24,7 +24,7 @@ use snarkvm_gadgets::traits::utilities::{
|
||||
boolean::Boolean,
|
||||
eq::{ConditionalEqGadget, EqGadget, EvaluateEqGadget},
|
||||
select::CondSelectGadget,
|
||||
uint::{UInt, UInt8},
|
||||
uint::UInt8,
|
||||
};
|
||||
use snarkvm_r1cs::{Assignment, ConstraintSystem, SynthesisError};
|
||||
use snarkvm_utilities::ToBytes;
|
||||
|
@ -28,10 +28,10 @@ use snarkvm_gadgets::traits::utilities::{
|
||||
eq::{ConditionalEqGadget, EqGadget, EvaluateEqGadget},
|
||||
int::{Int128, Int16, Int32, Int64, Int8},
|
||||
select::CondSelectGadget,
|
||||
uint::*,
|
||||
uint::{Sub as UIntSub, *},
|
||||
};
|
||||
use snarkvm_r1cs::{ConstraintSystem, SynthesisError};
|
||||
use std::fmt;
|
||||
use std::{convert::TryInto, fmt};
|
||||
|
||||
/// An integer type enum wrapping the integer value.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
|
||||
@ -83,7 +83,7 @@ impl Integer {
|
||||
|
||||
pub fn get_bits(&self) -> Vec<Boolean> {
|
||||
let integer = self;
|
||||
match_integer!(integer => integer.get_bits())
|
||||
match_integer!(integer => integer.to_bits_le())
|
||||
}
|
||||
|
||||
// pub fn get_bits_typed(&self) -> (Vec<Boolean>, IntegerType) {
|
||||
@ -113,7 +113,7 @@ impl Integer {
|
||||
|
||||
pub fn to_usize(&self) -> Option<usize> {
|
||||
let unsigned_integer = self;
|
||||
match_unsigned_integer!(unsigned_integer => unsigned_integer.get_index())
|
||||
match_unsigned_integer!(unsigned_integer => unsigned_integer.value.map(|num| num.try_into().ok()).flatten())
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> IntegerType {
|
||||
|
@ -14,41 +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 snarkvm_gadgets::traits::utilities::{
|
||||
boolean::Boolean,
|
||||
int::{Int128, Int16, Int32, Int64, Int8},
|
||||
uint::{UInt128, UInt16, UInt32, UInt64, UInt8},
|
||||
};
|
||||
use std::{convert::TryInto, fmt::Debug};
|
||||
|
||||
pub trait IntegerTrait: Sized + Clone + Debug {
|
||||
fn get_value(&self) -> Option<String>;
|
||||
|
||||
fn get_index(&self) -> Option<usize>;
|
||||
|
||||
fn get_bits(&self) -> Vec<Boolean>;
|
||||
}
|
||||
|
||||
macro_rules! integer_trait_impl {
|
||||
($($gadget: ident)*) => ($(
|
||||
impl IntegerTrait for $gadget {
|
||||
fn get_value(&self) -> Option<String> {
|
||||
self.value.map(|num| num.to_string())
|
||||
}
|
||||
|
||||
fn get_index(&self) -> Option<usize> {
|
||||
self.value.map(|num| num.try_into().ok()).flatten()
|
||||
}
|
||||
|
||||
fn get_bits(&self) -> Vec<Boolean> {
|
||||
self.bits.clone()
|
||||
}
|
||||
}
|
||||
|
||||
)*)
|
||||
}
|
||||
|
||||
integer_trait_impl!(UInt8 UInt16 UInt32 UInt64 UInt128 Int8 Int16 Int32 Int64 Int128);
|
||||
pub use snarkvm_gadgets::traits::utilities::integer::Integer as IntegerTrait;
|
||||
|
||||
/// Useful macros to avoid duplicating `match` constructions.
|
||||
#[macro_export]
|
||||
@ -125,19 +91,19 @@ macro_rules! match_integers_span {
|
||||
(($a: ident, $b: ident), $span: ident => $expression:expr) => {
|
||||
match ($a, $b) {
|
||||
(Integer::U8($a), Integer::U8($b)) => {
|
||||
Some(Integer::U8($expression.map_err(|e| IntegerError::synthesis(e, $span))?))
|
||||
Some(Integer::U8($expression.map_err(|e| IntegerError::unsigned(e, $span))?))
|
||||
}
|
||||
(Integer::U16($a), Integer::U16($b)) => {
|
||||
Some(Integer::U16($expression.map_err(|e| IntegerError::unsigned(e, $span))?))
|
||||
}
|
||||
(Integer::U32($a), Integer::U32($b)) => {
|
||||
Some(Integer::U32($expression.map_err(|e| IntegerError::unsigned(e, $span))?))
|
||||
}
|
||||
(Integer::U64($a), Integer::U64($b)) => {
|
||||
Some(Integer::U64($expression.map_err(|e| IntegerError::unsigned(e, $span))?))
|
||||
}
|
||||
(Integer::U16($a), Integer::U16($b)) => Some(Integer::U16(
|
||||
$expression.map_err(|e| IntegerError::synthesis(e, $span))?,
|
||||
)),
|
||||
(Integer::U32($a), Integer::U32($b)) => Some(Integer::U32(
|
||||
$expression.map_err(|e| IntegerError::synthesis(e, $span))?,
|
||||
)),
|
||||
(Integer::U64($a), Integer::U64($b)) => Some(Integer::U64(
|
||||
$expression.map_err(|e| IntegerError::synthesis(e, $span))?,
|
||||
)),
|
||||
(Integer::U128($a), Integer::U128($b)) => Some(Integer::U128(
|
||||
$expression.map_err(|e| IntegerError::synthesis(e, $span))?,
|
||||
$expression.map_err(|e| IntegerError::unsigned(e, $span))?,
|
||||
)),
|
||||
|
||||
(Integer::I8($a), Integer::I8($b)) => {
|
||||
|
7
compiler/tests/function/duplicate_definition.leo
Normal file
7
compiler/tests/function/duplicate_definition.leo
Normal file
@ -0,0 +1,7 @@
|
||||
function main() {
|
||||
console.log("{}", 1u8);
|
||||
}
|
||||
|
||||
function main() {
|
||||
console.log("{}", 2u8);
|
||||
}
|
@ -211,3 +211,11 @@ fn test_array_params_direct_call() {
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_duplicate_function_definition() {
|
||||
let program_string = include_str!("duplicate_definition.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_asg_error(error);
|
||||
}
|
||||
|
@ -14,5 +14,5 @@ keywords = [
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
abnf = "0.10.1"
|
||||
abnf = "0.10.2"
|
||||
anyhow = "1.0"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,6 @@
|
||||
; Leo Library
|
||||
;
|
||||
; Copyright (C) 2021 Aleo Systems Inc.
|
||||
;
|
||||
; Author: Alessandro Coglio (acoglio on GitHub)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@ -20,7 +18,7 @@
|
||||
|
||||
; Note that this CR LF requirement only applies to the grammar files themselves.
|
||||
; It does not apply to the lines of the languages described by the grammar.
|
||||
; ABNF grammar may describe any kinds of languages,
|
||||
; ABNF grammars may describe any kind of languages,
|
||||
; with any kind of line terminators,
|
||||
; or even without line terminators at all (e.g. for "binary" languages).
|
||||
|
||||
@ -29,29 +27,23 @@
|
||||
; Introduction
|
||||
; ------------
|
||||
|
||||
; This file contains an initial draft of
|
||||
; a complete ABNF (Augmented Backus-Naur Form) grammar of Leo.
|
||||
; This file contains an ABNF (Augmented Backus-Naur Form) grammar of Leo.
|
||||
; Background on ABNF is provided later in this file.
|
||||
|
||||
; The initial motivation for creating an ABNF grammar of Leo was that
|
||||
; we have a formally verified parser of ABNF grammars
|
||||
; This grammar provides an official definition of the syntax of Leo
|
||||
; that is both human-readable and machine-readable.
|
||||
; It will be part of an upcoming Leo language reference.
|
||||
; It may also be used to generate parser tests at some point.
|
||||
|
||||
; We are also using this grammar
|
||||
; as part of a mathematical formalization of the Leo language,
|
||||
; which we are developing in the ACL2 theorem prover
|
||||
; and which we plan to publish at some point.
|
||||
; In particular, we have used a formally verified parser of ABNF grammars
|
||||
; (at https://github.com/acl2/acl2/tree/master/books/kestrel/abnf;
|
||||
; also see the paper at https://www.kestrel.edu/people/coglio/vstte18.pdf)
|
||||
; which we have used to parse this ABNF grammar of Leo
|
||||
; into a formal representation, in the ACL2 theorem prover,
|
||||
; of the Leo concrete syntax.
|
||||
; The parsing of this grammar file into an ACL2 representation
|
||||
; happens every time the ACL2 formalization of Leo is built.
|
||||
|
||||
; In addition to that initial motivation,
|
||||
; this ABNF grammar has now the additional and primary purpose of
|
||||
; providing an official definition of the syntax of Leo
|
||||
; that is both human-readable and machine-readable.
|
||||
; This grammar will be part of the (upcoming) Leo language reference,
|
||||
; of the Leo Language Formal Specification
|
||||
; (i.e. the LaTeX document in the leo-semantics repo),
|
||||
; and of the ACL2 formalization of Leo (which was the initial motivation).
|
||||
; It has also been suggested that it may be used to generate tests.
|
||||
; to parse this grammar into a formal representation of the Leo concrete syntax
|
||||
; and to validate that the grammar satisfies certain consistency properties.
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@ -59,13 +51,10 @@
|
||||
; ------------------
|
||||
|
||||
; ABNF is an Internet standard:
|
||||
; see https://www.rfc-editor.org/info/rfc5234
|
||||
; and https://www.rfc-editor.org/info/rfc7405.
|
||||
; see RFC 5234 at https://www.rfc-editor.org/info/rfc5234
|
||||
; and RFC 7405 at https://www.rfc-editor.org/info/rfc7405.
|
||||
; It is used to specify the syntax of JSON, HTTP, and other standards.
|
||||
|
||||
; The following is copied (and "un-LaTeX'd") from the aforementioned paper
|
||||
; (at https://www.kestrel.edu/people/coglio/vstte18.pdf).
|
||||
|
||||
; ABNF adds conveniences and makes slight modifications
|
||||
; to Backus-Naur Form (BNF),
|
||||
; without going beyond context-free grammars.
|
||||
@ -82,15 +71,15 @@
|
||||
; and denotes them via:
|
||||
; (i) binary, decimal, or hexadecimal sequences,
|
||||
; e.g. %b1.11.1010, %d1.3.10, and %x.1.3.A
|
||||
; all denote the string '1 3 10';
|
||||
; all denote the sequence of terminals '1 3 10';
|
||||
; (ii) binary, decimal, or hexadecimal ranges,
|
||||
; e.g. %x30-39 denotes any string 'n' with 48 <= n <= 57
|
||||
; (an ASCII digit);
|
||||
; e.g. %x30-39 denotes any singleton sequence of terminals
|
||||
; 'n' with 48 <= n <= 57 (an ASCII digit);
|
||||
; (iii) case-sensitive ASCII strings,
|
||||
; e.g. %s"Ab" denotes the string '65 98';
|
||||
; e.g. %s"Ab" denotes the sequence of terminals '65 98';
|
||||
; and (iv) case-insensitive ASCII strings,
|
||||
; e.g. %i"ab", or just "ab", denotes
|
||||
; any string among
|
||||
; any sequence of terminals among
|
||||
; '65 66',
|
||||
; '65 98',
|
||||
; '97 66', and
|
||||
@ -114,7 +103,7 @@
|
||||
; Repetition prefixes have precedence over juxtapositions,
|
||||
; which have precedence over /.
|
||||
; Round brackets group things and override the aforementioned precedence rules,
|
||||
; e.g. *(WSP / CRLF WSP) denotes strings
|
||||
; e.g. *(WSP / CRLF WSP) denotes sequences of terminals
|
||||
; obtained by repeating, zero or more times,
|
||||
; either (i) a WSP or (ii) a CRLF followed by a WSP.
|
||||
; Square brackets also group things but make them optional,
|
||||
@ -141,49 +130,42 @@
|
||||
; Structure
|
||||
; ---------
|
||||
|
||||
; Language specifications often define the syntax of their languages via
|
||||
; This ABNF grammar consists of two (sub-)grammars:
|
||||
; (i) a lexical grammar that describes how
|
||||
; sequence of characters are parsed into tokens, and
|
||||
; (ii) a syntactic grammar that described how
|
||||
; tokens are parsed into expressions, statements, etc.
|
||||
; (The adjectives 'lexical' and 'syntactic' are
|
||||
; the ones used in the Java language specification;
|
||||
; other terms may be used by other languages,
|
||||
; but the essence is similar.)
|
||||
; The situation is sometimes more complex,
|
||||
; with multiple passes (e.g. Unicode escape processing in Java),
|
||||
; but the division between lexical and syntactic (in the sense above) stands.
|
||||
; The adjectives 'lexical' and 'syntactic' are
|
||||
; the same ones used in the Java language reference,
|
||||
; for instance;
|
||||
; alternative terms may be used in other languages,
|
||||
; but the separation into these two components is quite common
|
||||
; (the situation is sometimes a bit more complex, with multiple passes,
|
||||
; e.g. Unicode escape processing in Java).
|
||||
|
||||
; In the aforementioned language specifications,
|
||||
; both the lexical and syntactic grammars
|
||||
; are normally written in a context-free grammar notation,
|
||||
; augmented with natural language that may assert, for instance,
|
||||
; that tokenization always takes the longest sequence that constitutes a token.
|
||||
|
||||
; This dual structure appears to be motivated by the fact that
|
||||
; This separation enables
|
||||
; concerns of white space, line endings, etc.
|
||||
; can be handled by the lexical grammar,
|
||||
; allowing the syntactic grammar to focus on the more important structure.
|
||||
; Handling both aspects in a single context-free grammar may be unwieldy,
|
||||
; to be handled by the lexical grammar,
|
||||
; with the syntactic grammar focused on the more important structure.
|
||||
; Handling both aspects in a single grammar may be unwieldy,
|
||||
; so having two grammars provides more clarity and readability.
|
||||
|
||||
; In contrast, PEG (Parsing Expression Grammar) formalisms like Pest
|
||||
; naturally embody a procedural interpretation
|
||||
; that can handle white space and tokenization in just one manageable grammar.
|
||||
; However, this procedural interpretaion may be sometimes
|
||||
; less clear and readable to humans than context-free rules.
|
||||
; Indeed, context-free grammar are commonly used to documentat languages.
|
||||
|
||||
; ABNF is a context-free grammar notation,
|
||||
; with no procedural interpretation,
|
||||
; and therefore it makes sense to define
|
||||
; separate lexical and syntactic ABNF grammars for Leo.
|
||||
; Conceptually, the two grammars define two subsequent processing phases,
|
||||
; ABNF is a context-free grammar notation, with no procedural interpretation.
|
||||
; The two grammars conceptually define two subsequent processing phases,
|
||||
; as detailed below.
|
||||
; However, a parser implementation does not need to perform
|
||||
; two strictly separate phases (in fact, it typically does not),
|
||||
; so long as it produces the same final result.
|
||||
|
||||
; The grammar is accompanied by some extra-grammatical requirements,
|
||||
; which are not conveniently expressible in a context-free grammar like ABNF.
|
||||
; These requirements are needed to make the grammar unambiguous,
|
||||
; i.e. to ensure that, for each sequence of terminals,
|
||||
; there is exactly one parse tree for that sequence terminals
|
||||
; that satisfies not only the grammar rules
|
||||
; but also the extra-grammatical requirements.
|
||||
; These requirements are expressed as comments in this file.
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Operator Precedence
|
||||
@ -205,8 +187,9 @@
|
||||
; / additive-expression "+" multiplicative-expression
|
||||
; / additive-expression "-" multiplicative-expression
|
||||
;
|
||||
; this rule tells us that the additive operators '+' and '-' have
|
||||
; lower precedence than the multiplicative operators '*' and '/',
|
||||
; These rules tell us
|
||||
; that the additive operators '+' and '-' have lower precedence
|
||||
; than the multiplicative operators '*' and '/',
|
||||
; and that both the additive and multiplicative operators associate to the left.
|
||||
; This may be best understood via the examples given below.
|
||||
|
||||
@ -261,14 +244,14 @@
|
||||
; Naming Convention
|
||||
; -----------------
|
||||
|
||||
; For this ABNF grammar, we choose nonterminal names
|
||||
; This ABNF grammar uses nonterminal names
|
||||
; that consist of complete English words, separated by dashes,
|
||||
; and that describe the construct the way it is in English.
|
||||
; For instance, we use the name 'conditional-statement'
|
||||
; to describe conditional statements.
|
||||
|
||||
; At the same time, we attempt to establish
|
||||
; a precise and "official" nomenclature for the Leo constructs,
|
||||
; At the same time, this grammar establishes
|
||||
; a precise and official nomenclature for the Leo constructs,
|
||||
; by way of the nonterminal names that define their syntax.
|
||||
; For instance, the rule
|
||||
;
|
||||
@ -286,19 +269,21 @@
|
||||
; is the fact that, as discussed above,
|
||||
; we write the grammar rules in a way that determines
|
||||
; the relative precedence and the associativity of expression operators,
|
||||
; and that therefore we have rules like
|
||||
; and therefore we have rules like
|
||||
;
|
||||
; unary-expression = primary-expression
|
||||
; / "!" unary-expression
|
||||
; / "-" unary-expression
|
||||
;
|
||||
; In order to allow the recursion of the rule to stop,
|
||||
; we need to regard, in the grammar, a primary expression as a unary expression.
|
||||
; we need to regard, in the grammar, a primary expression as a unary expression
|
||||
; (i.e. a primary expression is also a unary expression in the grammar;
|
||||
; but note that the opposite is not true).
|
||||
; However, this is just a grammatical artifact:
|
||||
; ontologically, a primary expression is not really a unary expression,
|
||||
; because a unary expression is one that consists of
|
||||
; a unary operator and an operand sub-expression.
|
||||
; These terminological "exceptions" should be easy to identify in the rules.
|
||||
; These terminological exceptions should be easy to identify in the rules.
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@ -310,11 +295,12 @@
|
||||
; which are numbers in the range form 0 to 10FFFFh.
|
||||
; These are captured by the ABNF rule 'character' below.
|
||||
|
||||
; The lexical grammar defines how, conceptually,
|
||||
; The lexical grammar defines how, at least conceptually,
|
||||
; the sequence of characters is turned into
|
||||
; a sequence of tokens, comments, and whitespaces.
|
||||
; a sequence of tokens, comments, and whitespaces:
|
||||
; these entities are all defined by the grammar rules below.
|
||||
|
||||
; As stated, the lexical grammar is ambiguous.
|
||||
; As stated, the lexical grammar alone is ambiguous.
|
||||
; For example, the sequence of characters '**' (i.e. two stars)
|
||||
; could be equally parsed as two '*' symbol tokens or one '**' symbol token
|
||||
; (see rule for 'symbol' below).
|
||||
@ -329,10 +315,6 @@
|
||||
; the longest possible sequence of characters is always parsed.
|
||||
; This way, '**' must be parsed as one '**' symbol token,
|
||||
; and '<CR><LF>' must be parsed as one line terminator.
|
||||
; (We should formalize this requirement,
|
||||
; along with the other extra-grammatical requirements given below,
|
||||
; and formally prove that they indeed make
|
||||
; the lexical grammar of Leo unambiguous.)
|
||||
|
||||
; As mentioned above, a character is any Unicode code point.
|
||||
; This grammar does not say how those are encoded in files (e.g. UTF-8):
|
||||
@ -371,7 +353,8 @@ not-star-or-slash = %x0-29 / %x2B-2E / %x30-10FFFF ; anything but * or /
|
||||
; a line feed,
|
||||
; or a carriage return immediately followed by a line feed.
|
||||
; Note that the latter combination constitutes a single line terminator,
|
||||
; according to the extra-grammatical rule of the longest sequence.
|
||||
; according to the extra-grammatical requirement of the longest sequence,
|
||||
; described above.
|
||||
|
||||
newline = line-feed / carriage-return / carriage-return line-feed
|
||||
|
||||
@ -381,13 +364,13 @@ whitespace = space / horizontal-tab / newline
|
||||
|
||||
; There are two kinds of comments in Leo, as in other languages.
|
||||
; One is block comments of the form '/* ... */',
|
||||
; and the other is end-of-line comments '// ...'.
|
||||
; and the other is end-of-line comments of the form '// ...'.
|
||||
; The first kind start at '/*' and end at the first '*/',
|
||||
; possibly spanning multiple (partial) lines;
|
||||
; they do no nest.
|
||||
; these do no nest.
|
||||
; The second kind start at '//' and extend till the end of the line.
|
||||
; The rules about comments given below are similar to
|
||||
; the ones used in the Java language specification.
|
||||
; the ones used in the Java language reference.
|
||||
|
||||
comment = block-comment / end-of-line-comment
|
||||
|
||||
@ -469,9 +452,9 @@ package-name = 1*( lowercase-letter / digit )
|
||||
|
||||
address = %s"aleo1" 58( lowercase-letter / digit )
|
||||
|
||||
; A format string is a sequence of characters, other than double quote,
|
||||
; A formatted string is a sequence of characters, other than double quote,
|
||||
; surrounded by double quotes.
|
||||
; Within a format string, substrings '{}' are distinguished as containers
|
||||
; Within a formatted string, sub-strings '{}' are distinguished as containers
|
||||
; (these are the ones that may be matched with values
|
||||
; whose textual representation replaces the containers
|
||||
; in the printed string).
|
||||
@ -484,12 +467,12 @@ address = %s"aleo1" 58( lowercase-letter / digit )
|
||||
formatted-string-container = "{}"
|
||||
|
||||
formatted-string = double-quote
|
||||
*( not-double-quote / formatted-string-container )
|
||||
double-quote
|
||||
*( not-double-quote / formatted-string-container )
|
||||
double-quote
|
||||
|
||||
; Here is (part of this ABNF comment),
|
||||
; an alternative way to specify format strings,
|
||||
; which captures the extra-grammatical requirement above in the grammar
|
||||
; an alternative way to specify formatted strings,
|
||||
; which captures the extra-grammatical requirement above in the grammar,
|
||||
; but is more complicated:
|
||||
;
|
||||
; not-double-quote-or-open-brace = %x0-22 / %x24-7A / %x7C-10FFFF
|
||||
@ -497,27 +480,25 @@ formatted-string = double-quote
|
||||
; not-double-quote-or-close-brace = %x0-22 / %x24-7C / %x7E-10FFFF
|
||||
;
|
||||
; formatted-string-element = not-double-quote-or-open-brace
|
||||
; / "{" not-double-quote-or-close-brace
|
||||
; / formatted-string-container
|
||||
; / "{" not-double-quote-or-close-brace
|
||||
; / formatted-string-container
|
||||
;
|
||||
; formatted-string = double-quote *formatted-string-element double-quote
|
||||
;
|
||||
; It is not immediately clear which approach is better; there are tradeoffs.
|
||||
; Regardless, we should choose one eventually.
|
||||
; We may choose to adopt this one in future revisions of the grammar.
|
||||
|
||||
; Annotations are built out of names and arguments, which are tokens.
|
||||
; Two names are currently supported.
|
||||
; An argument is a sequence of one or more letters, digits, and underscores.
|
||||
; Annotations have names, which are identifiers immediately preceded by '@'.
|
||||
|
||||
annotation-name = "@" identifier
|
||||
|
||||
; A natural (number) is a sequence of one or more digits.
|
||||
; Note that we allow leading zeros, e.g. '007'.
|
||||
; We allow leading zeros, e.g. '007'.
|
||||
|
||||
natural = 1*digit
|
||||
|
||||
; An integer (number) is either a natural or its negation.
|
||||
; Note that we also allow leading zeros in negative numbers, e.g. '-007'.
|
||||
; We allow leading zeros also in negative numbers, e.g. '-007'.
|
||||
|
||||
integer = [ "-" ] natural
|
||||
|
||||
@ -554,7 +535,9 @@ boolean-literal = %s"true" / %s"false"
|
||||
|
||||
address-literal = %s"address" "(" address ")"
|
||||
|
||||
; The ones above are all the literals, as defined by the following rule.
|
||||
; The ones above are all the atomic literals
|
||||
; (in the sense that they are tokens, without whitespace allowed in them),
|
||||
; as defined by the following rule.
|
||||
|
||||
atomic-literal = untyped-literal
|
||||
/ unsigned-literal
|
||||
@ -568,14 +551,14 @@ atomic-literal = untyped-literal
|
||||
; it remains to define tokens for non-alphanumeric symbols such as "+" and "(".
|
||||
; Different programming languages used different terminologies for these,
|
||||
; e.g. operators, separators, punctuators, etc.
|
||||
; Here we use 'symbol', for all of them, but we can do something different.
|
||||
; Here we use 'symbol', for all of them.
|
||||
; We also include a token consisting of
|
||||
; a closing parenthesis immediately followed by 'group':
|
||||
; as defined in the syntactic grammar,
|
||||
; this is the final part of an affine group literal.
|
||||
; Even though it includes letters,
|
||||
; this is the final part of an affine group literal;
|
||||
; even though it includes letters,
|
||||
; it seems appropriate to still consider it a symbol,
|
||||
; particularly since it starts with a symbol.
|
||||
; particularly since it starts with a proper symbol.
|
||||
|
||||
; We could give names to all of these symbols,
|
||||
; via rules such as
|
||||
@ -648,7 +631,7 @@ group-type = %s"group"
|
||||
arithmetic-type = integer-type / field-type / group-type
|
||||
|
||||
; The arithmetic types, along with the boolean and address types,
|
||||
; form the scalar types, i.e. the ones whose values do not contain (sub)values.
|
||||
; form the scalar types, i.e. the ones whose values do not contain (sub-)values.
|
||||
|
||||
boolean-type = %s"bool"
|
||||
|
||||
@ -658,7 +641,7 @@ scalar-type = boolean-type / arithmetic-type / address-type
|
||||
|
||||
; Circuit types are denoted by identifiers and the keyword 'Self'.
|
||||
; The latter is only allowed inside a circuit definition,
|
||||
; to denote the defined circuit.
|
||||
; to denote the circuit being defined.
|
||||
|
||||
self-type = %s"Self"
|
||||
|
||||
@ -670,9 +653,8 @@ tuple-type = "(" [ type 1*( "," type ) ] ")"
|
||||
|
||||
; An array type consists of an element type
|
||||
; and an indication of dimensions.
|
||||
; There is either a single dimension (a number),
|
||||
; or a tuple of one or more dimensions
|
||||
; (we could restrict the latter to two or more dimensions).
|
||||
; There is either a single dimension,
|
||||
; or a tuple of one or more dimensions.
|
||||
|
||||
array-type = "[" type ";" array-dimensions "]"
|
||||
|
||||
@ -680,7 +662,7 @@ array-dimensions = natural
|
||||
/ "(" natural *( "," natural ) ")"
|
||||
|
||||
; Circuit, tuple, and array types form the aggregate types,
|
||||
; i.e. types whose values contain (sub)values
|
||||
; i.e. types whose values contain (sub-)values
|
||||
; (with the corner-case exception of the empty tuple value).
|
||||
|
||||
aggregate-type = tuple-type / array-type / circuit-type
|
||||
@ -689,23 +671,21 @@ aggregate-type = tuple-type / array-type / circuit-type
|
||||
|
||||
type = scalar-type / aggregate-type
|
||||
|
||||
; The lexical grammar above defines product group literals.
|
||||
; The lexical grammar given earlier defines product group literals.
|
||||
; The other kind of group literal is a pair of integer coordinates,
|
||||
; which are reduced modulo the prime to identify a point,
|
||||
; which must be on the elliptic curve.
|
||||
; It is also allowed to omit one (not both) coordinates,
|
||||
; with an indication of how to infer the missing coordinate
|
||||
; It is also allowed to omit one coordinate (not both),
|
||||
; with an indication of how to fill in the missing coordinate
|
||||
; (i.e. sign high, sign low, or inferred).
|
||||
; This is an affine group literal,
|
||||
; because it consists of affine point coordinates.
|
||||
|
||||
group-coordinate = integer / "+" / "-" / "_"
|
||||
|
||||
affine-group-literal = "(" group-coordinate "," group-coordinate ")" %s"group"
|
||||
affine-group-literal = "(" group-coordinate "," group-coordinate %s")group"
|
||||
|
||||
; A literal is either an atomic one or an affine group literal.
|
||||
; Here 'atomic' refers to being a token or not,
|
||||
; since no whitespace is allowed within a token.
|
||||
|
||||
literal = atomic-literal / affine-group-literal
|
||||
|
||||
@ -723,13 +703,12 @@ group-literal = product-group-literal / affine-group-literal
|
||||
; and the (left or right) associativity of binary operators.
|
||||
|
||||
; The primary expressions are self-contained in a way,
|
||||
; i.e. they have clear deliminations.
|
||||
; Some consist of single tokens:
|
||||
; identifiers, the keywords 'self' and 'input', and literals.
|
||||
; i.e. they have clear deliminations:
|
||||
; Some consist of single tokens,
|
||||
; while others have explicit endings.
|
||||
; Primary expressions also include parenthesized expressions,
|
||||
; i.e. any expression may be turned into a primary one
|
||||
; by putting parentheses around it.
|
||||
; The other kinds are defined and explained below.
|
||||
|
||||
primary-expression = identifier
|
||||
/ %s"self"
|
||||
@ -739,37 +718,20 @@ primary-expression = identifier
|
||||
/ tuple-expression
|
||||
/ array-expression
|
||||
/ circuit-expression
|
||||
/ function-call
|
||||
|
||||
; There are tuple expressions to construct and deconstruct tuples.
|
||||
; A construction consists of zero, two, or more component expressions.
|
||||
; A deconstruction uses a component index (zero-indexed).
|
||||
; Note that constructions are delimited by closing parentheses
|
||||
; and deconstructions are delimited by natural tokens.
|
||||
; The rule below, and similar rules for other aggregate types,
|
||||
; use the perhaps more familiar 'access',
|
||||
; but note that 'deconstruction' has a nice symmetry to 'construction';
|
||||
; the term 'destructor' has a different meaning in other languages,
|
||||
; so we may want to avoid it, but not necessarily.
|
||||
; Tuple expressions construct tuples.
|
||||
; Each consists of zero, two, or more component expressions.
|
||||
|
||||
tuple-construction = "(" [ expression 1*( "," expression ) ] ")"
|
||||
|
||||
tuple-expression = tuple-construction
|
||||
|
||||
; The are array expressions to construct and deconstruct arrays.
|
||||
; There are two kinds of constructions:
|
||||
; Array expressions construct arrays.
|
||||
; There are two kinds:
|
||||
; one lists the element expressions (at least one),
|
||||
; including spreads (via '...') which are arrays being spliced in;
|
||||
; the other repeats (the value of) a single expression
|
||||
; across one or more dimensions.
|
||||
; There are two kinds of deconstructions:
|
||||
; one selects a single element by index (zero-indexed);
|
||||
; the other selects a range via two indices,
|
||||
; the first inclusive and the second exclusive --
|
||||
; both are optional,
|
||||
; the first defaulting to 0 and the second to the array length.
|
||||
; Note that these expressions are all delimited
|
||||
; by closing square brackets.
|
||||
|
||||
array-inline-construction = "["
|
||||
array-inline-element
|
||||
@ -784,17 +746,14 @@ array-construction = array-inline-construction / array-repeat-construction
|
||||
|
||||
array-expression = array-construction
|
||||
|
||||
; There are circuit expressions to construct and deconstruct circuit values.
|
||||
; A construction lists values for all the member variables (in any order);
|
||||
; there must be at least one member variable currently.
|
||||
; Circuit expressions construct circuit values.
|
||||
; Each lists values for all the member variables (in any order);
|
||||
; there must be at least one member variable.
|
||||
; A single identifier abbreviates
|
||||
; a pair consisting of the same identifier separated by dot;
|
||||
; a pair consisting of the same identifier separated by colon;
|
||||
; note that, in the expansion, the left one denotes a member name,
|
||||
; while the right one denotes an expression (a variable),
|
||||
; so they are syntactically identical but semantically different.
|
||||
; A deconstruction selects a member variable by name.
|
||||
; Note that these expressions are delimited,
|
||||
; by closing curly braces or identifiers.
|
||||
|
||||
circuit-construction = circuit-type "{"
|
||||
circuit-inline-element *( "," circuit-inline-element )
|
||||
@ -804,30 +763,39 @@ circuit-inline-element = identifier ":" expression / identifier
|
||||
|
||||
circuit-expression = circuit-construction
|
||||
|
||||
; After primary expressions, postfix expressions have highest precedence.
|
||||
; They apply to primary expressions, and recursively to postfix expressions.
|
||||
|
||||
; There are postfix expressions to access parts of aggregate values.
|
||||
; A tuple access selects a component by index (zero-based).
|
||||
; There are two kinds of array accesses:
|
||||
; one selects a single element by index (zero-based);
|
||||
; the other selects a range via two indices,
|
||||
; the first inclusive and the second exclusive --
|
||||
; both are optional,
|
||||
; the first defaulting to 0 and the second to the array length.
|
||||
; A circuit access selects a member variable by name.
|
||||
|
||||
; Function calls are also postfix expressions.
|
||||
; There are three kinds of function calls:
|
||||
; top-level function calls,
|
||||
; instance (i.e. non-static) member function calls, and
|
||||
; static member function calls.
|
||||
; What changes is the start, but they all end in an argument list,
|
||||
; delimited by a closing parenthesis.
|
||||
; What changes is the start, but they all end in an argument list.
|
||||
|
||||
function-arguments = "(" [ expression *( "," expression ) ] ")"
|
||||
|
||||
; Postfix expressions have highest precedence.
|
||||
; They apply to primary expressions.
|
||||
; Contains access expressions for arrays, tuples, and circuits.
|
||||
; Contains function call types.
|
||||
postfix-expression = primary-expression
|
||||
/ postfix-expression "." natural
|
||||
/ postfix-expression "." identifier
|
||||
/ identifier function-arguments
|
||||
/ postfix-expression "." identifier function-arguments
|
||||
/ circuit-type "::" identifier function-arguments
|
||||
/ postfix-expression "[" expression "]"
|
||||
/ postfix-expression "[" [expression] ".." [expression] "]"
|
||||
/ postfix-expression "." natural
|
||||
/ postfix-expression "." identifier
|
||||
/ identifier function-arguments
|
||||
/ postfix-expression "." identifier function-arguments
|
||||
/ circuit-type "::" identifier function-arguments
|
||||
/ postfix-expression "[" expression "]"
|
||||
/ postfix-expression "[" [expression] ".." [expression] "]"
|
||||
|
||||
; Unary operators have the highest operator precedence.
|
||||
; They apply to postfix expressions
|
||||
; They apply to postfix expressions,
|
||||
; and recursively to unary expressions.
|
||||
|
||||
unary-expression = postfix-expression
|
||||
@ -835,7 +803,7 @@ unary-expression = postfix-expression
|
||||
/ "-" unary-expression
|
||||
|
||||
; Next in the operator precedence is casting.
|
||||
; The current rule below makes exponentiation left-associative,
|
||||
|
||||
cast-expression = unary-expression
|
||||
/ cast-expression %s"as" type
|
||||
|
||||
@ -843,7 +811,6 @@ cast-expression = unary-expression
|
||||
; following mathematical practice.
|
||||
; The current rule below makes exponentiation left-associative,
|
||||
; i.e. 'a ** b ** c' must be parsed as '(a ** b) ** c'.
|
||||
; This is easy to change if we want it to be right-associative instead.
|
||||
|
||||
exponential-expression = cast-expression
|
||||
/ exponential-expression "**" cast-expression
|
||||
@ -869,8 +836,8 @@ ordering-expression = additive-expression
|
||||
/ additive-expression "<=" additive-expression
|
||||
/ additive-expression ">=" additive-expression
|
||||
|
||||
; Equalities return booleans but may also operate on boolean,
|
||||
; so we make them left-associative.
|
||||
; Equalities return booleans but may also operate on booleans;
|
||||
; the rule below makes them left-associative.
|
||||
|
||||
equality-expression = ordering-expression
|
||||
/ equality-expression "==" ordering-expression
|
||||
@ -889,11 +856,11 @@ disjunctive-expression = conjunctive-expression
|
||||
; Finally we have conditional expressions.
|
||||
|
||||
conditional-expression = disjunctive-expression
|
||||
/ conditional-expression
|
||||
/ conditional-expression
|
||||
"?" expression
|
||||
":" conditional-expression
|
||||
|
||||
; These are all the expressions.
|
||||
; Those above are all the expressions.
|
||||
; Recall that conditional expressions
|
||||
; may be disjunctive expressions,
|
||||
; which may be conjunctive expressions,
|
||||
@ -901,9 +868,8 @@ conditional-expression = disjunctive-expression
|
||||
|
||||
expression = conditional-expression
|
||||
|
||||
; There are various kinds of statements,
|
||||
; including blocks, which are
|
||||
; possibly empty sequences of statements surounded by curly braces.
|
||||
; There are various kinds of statements, including blocks.
|
||||
; Blocks are possibly empty sequences of statements surrounded by curly braces.
|
||||
|
||||
statement = expression-statement
|
||||
/ return-statement
|
||||
@ -916,13 +882,13 @@ statement = expression-statement
|
||||
|
||||
block = "{" *statement "}"
|
||||
|
||||
; An expression (that returns the empty tuple)
|
||||
; An expression (that must return the empty tuple, as semantically required)
|
||||
; can be turned into a statement by appending a semicolon.
|
||||
|
||||
expression-statement = expression ";"
|
||||
|
||||
; A return statement always takes an expression,
|
||||
; and does not end with a semicolon (but we may want to change that).
|
||||
; and does not end with a semicolon.
|
||||
|
||||
return-statement = %s"return" expression
|
||||
|
||||
@ -943,7 +909,7 @@ identifier-or-identifiers = identifier
|
||||
; (which together form a branch).
|
||||
; It may stop there, or it may continue with an alternative block,
|
||||
; or possibly with another conditional statement, forming a chain.
|
||||
; Note that we require blocks in all branches, not merely statements.
|
||||
; Note that blocks are required in all branches, not merely statements.
|
||||
|
||||
branch = %s"if" expression block
|
||||
|
||||
@ -970,10 +936,10 @@ assignment-statement = expression assignment-operator expression ";"
|
||||
; The call may be an assertion or a print command.
|
||||
; The former takes an expression (which must be boolean) as argument.
|
||||
; The latter takes either no argument,
|
||||
; or a format string followed by expressions,
|
||||
; whose number must match the number of containers '{}' in the format string.
|
||||
; or a formatted string followed by expressions,
|
||||
; whose number must match the number of containers '{}' in the formatted string.
|
||||
; Note that the console function names are identifiers, not keywords.
|
||||
; There are three kind of printing.
|
||||
; There are three kinds of print commands.
|
||||
|
||||
console-statement = %s"console" "." console-call
|
||||
|
||||
@ -989,23 +955,19 @@ print-arguments = "(" [ formatted-string *( "," expression ) ] ")"
|
||||
print-call = print-function print-arguments
|
||||
|
||||
; An annotation consists of an annotation name (which starts with '@')
|
||||
; with optional annotation arguments.
|
||||
; with optional annotation arguments, which are identifiers.
|
||||
; Note that no parentheses are used if there are no arguments.
|
||||
|
||||
annotation = annotation-name
|
||||
[ "(" identifier *( "," identifier ) ")" ]
|
||||
|
||||
; A function declaration defines a function.
|
||||
; This could be called 'function-definition' instead,
|
||||
; but see the comments about the 'declaration' rule below.
|
||||
; The output type is optional (it defaults to the empty tuple type).
|
||||
; The output type is optional, defaulting to the empty tuple type.
|
||||
; In general, a function input consists of an identifier and a type,
|
||||
; with an optional 'const' modifier.
|
||||
; However, functions inside circuits
|
||||
; may start with a 'mut self' or 'self' parameter,
|
||||
; which may be the only parameter in fact.
|
||||
; Furthermore, any function may end with an 'input' parameter,
|
||||
; which may be the only parameter in fact.
|
||||
; Additionally, functions inside circuits
|
||||
; may start with a 'mut self' or 'const self' or 'self' parameter.
|
||||
; Furthermore, any function may end with an 'input' parameter.
|
||||
|
||||
function-declaration = *annotation %s"function" identifier
|
||||
"(" [ function-parameters ] ")" [ "->" type ]
|
||||
@ -1016,7 +978,7 @@ function-parameters = self-parameter [ "," input-parameter ]
|
||||
/ function-inputs [ "," input-parameter ]
|
||||
/ input-parameter
|
||||
|
||||
self-parameter = [%s"mut"] %s"self"
|
||||
self-parameter = [ %s"mut" / %s"const" ] %s"self"
|
||||
|
||||
function-inputs = function-input *( "," function-input )
|
||||
|
||||
@ -1026,8 +988,6 @@ input-parameter = %s"input"
|
||||
|
||||
; A circuit member variable declaration consists of an identifier and a type.
|
||||
; A circuit member function declaration consists of a function declaration.
|
||||
; We could call these 'member-definition' etc.,
|
||||
; but see the comments about the 'declaration' rule below.
|
||||
|
||||
member-declaration = member-variable-declaration
|
||||
/ member-function-declaration
|
||||
@ -1036,9 +996,8 @@ member-variable-declaration = identifier ":" type
|
||||
|
||||
member-function-declaration = function-declaration
|
||||
|
||||
; A circuit declaration defines a circuit type. It is straightforward.
|
||||
; This could be called 'circuit-definition' instead,
|
||||
; but see the comments about the 'declaration' rule below.
|
||||
; A circuit declaration defines a circuit type,
|
||||
; as consisting of member variables and functions.
|
||||
|
||||
circuit-declaration = *annotation %s"circuit" identifier
|
||||
"{" member-declaration *( "," member-declaration ) "}"
|
||||
@ -1051,7 +1010,7 @@ circuit-declaration = *annotation %s"circuit" identifier
|
||||
; or a parenthesized list of package paths,
|
||||
; which are "fan out" of the initial path.
|
||||
; Note that we allow the last element of the parenthesized list
|
||||
; to be followed by a comma, presumably for convenience.
|
||||
; to be followed by a comma, for convenience.
|
||||
|
||||
import-declaration = %s"import" package-path
|
||||
|
||||
@ -1061,12 +1020,6 @@ package-path = "*"
|
||||
/ "(" package-path *( "," package-path ) [","] ")"
|
||||
|
||||
; Finally, we define a file as a sequence of zero or more declarations.
|
||||
; This is why we used 'function-declaration' and 'circuit-declaration'
|
||||
; instead of 'function-definition' and 'ciruit-definition':
|
||||
; this way, they are all declarations of some sort.
|
||||
; An import declaration cannot really called an import definition,
|
||||
; because it does not define anything.
|
||||
; But we may revisit this, and use 'definition' instead of 'declaration'.
|
||||
|
||||
declaration = import-declaration
|
||||
/ function-declaration
|
||||
|
@ -198,13 +198,10 @@ fn main() -> Result<()> {
|
||||
// Take Leo ABNF grammar file.
|
||||
let grammar = include_str!("../abnf-grammar.txt");
|
||||
|
||||
// A. Coglio's proposal for %s syntax for case-sensitive statements has not been implemented
|
||||
// in this library, so we need to remove all occurrences of %s in the grammar file.
|
||||
// Link to this proposal: https://www.kestrel.edu/people/coglio/vstte18.pdf
|
||||
let grammar = &str::replace(grammar, "%s", "");
|
||||
|
||||
// Parse ABNF to get list of all definitions.
|
||||
let parsed = abnf::rulelist(grammar).map_err(|e| {
|
||||
// Rust ABNF does not provide support for `%s` (case sensitive strings, part of
|
||||
// the standard); so we need to remove all occurrences before parsing.
|
||||
let parsed = abnf::rulelist(&str::replace(grammar, "%s", "")).map_err(|e| {
|
||||
eprintln!("{}", &e);
|
||||
anyhow::anyhow!(e)
|
||||
})?;
|
||||
|
@ -45,7 +45,7 @@ impl Command for Build {
|
||||
tracing::span!(tracing::Level::INFO, "Build")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ impl Command for Clean {
|
||||
tracing::span!(tracing::Level::INFO, "Cleaning")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ impl Command for Deploy {
|
||||
tracing::span!(tracing::Level::INFO, "Deploy")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ impl Command for Init {
|
||||
tracing::span!(tracing::Level::INFO, "Initializing")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ impl Command for Lint {
|
||||
tracing::span!(tracing::Level::INFO, "Linting")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -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::context::{get_context, Context};
|
||||
use crate::context::Context;
|
||||
|
||||
use anyhow::Result;
|
||||
use std::time::Instant;
|
||||
@ -72,11 +72,6 @@ pub trait Command {
|
||||
/// this field may be left empty.
|
||||
type Output;
|
||||
|
||||
/// Returns the project context, which is defined as the current directory.
|
||||
fn context(&self) -> Result<Context> {
|
||||
get_context()
|
||||
}
|
||||
|
||||
/// Adds a span to the logger via `tracing::span`.
|
||||
/// Because of the specifics of the macro implementation, it is not possible
|
||||
/// to set the span name with a non-literal i.e. a dynamic variable even if this
|
||||
@ -86,7 +81,7 @@ pub trait Command {
|
||||
}
|
||||
|
||||
/// Runs the prelude and returns the Input of the current command.
|
||||
fn prelude(&self) -> Result<Self::Input>
|
||||
fn prelude(&self, context: Context) -> Result<Self::Input>
|
||||
where
|
||||
Self: std::marker::Sized;
|
||||
|
||||
@ -98,11 +93,11 @@ pub trait Command {
|
||||
|
||||
/// A wrapper around the `apply` method.
|
||||
/// This function sets up tracing, timing, and the context.
|
||||
fn execute(self) -> Result<Self::Output>
|
||||
fn execute(self, context: Context) -> Result<Self::Output>
|
||||
where
|
||||
Self: std::marker::Sized,
|
||||
{
|
||||
let input = self.prelude()?;
|
||||
let input = self.prelude(context.clone())?;
|
||||
|
||||
// Create the span for this command.
|
||||
let span = self.log_span();
|
||||
@ -110,8 +105,6 @@ pub trait Command {
|
||||
|
||||
// Calculate the execution time for this command.
|
||||
let timer = Instant::now();
|
||||
|
||||
let context = self.context()?;
|
||||
let out = self.apply(context, input);
|
||||
|
||||
drop(span);
|
||||
@ -127,10 +120,10 @@ pub trait Command {
|
||||
/// Executes command but empty the result. Comes in handy where there's a
|
||||
/// need to make match arms compatible while keeping implementation-specific
|
||||
/// output possible. Errors however are all of the type Error
|
||||
fn try_execute(self) -> Result<()>
|
||||
fn try_execute(self, context: Context) -> Result<()>
|
||||
where
|
||||
Self: std::marker::Sized,
|
||||
{
|
||||
self.execute().map(|_| Ok(()))?
|
||||
self.execute(context).map(|_| Ok(()))?
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ impl Command for New {
|
||||
tracing::span!(tracing::Level::INFO, "New")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ impl Command for Add {
|
||||
tracing::span!(tracing::Level::INFO, "Adding")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ impl Command for Clone {
|
||||
tracing::span!(tracing::Level::INFO, "Cloning")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ impl Command for Login {
|
||||
tracing::span!(tracing::Level::INFO, "Login")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ impl Command for Logout {
|
||||
tracing::span!(tracing::Level::INFO, "Logout")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,8 @@ impl Command for Publish {
|
||||
type Output = Option<String>;
|
||||
|
||||
/// Build program before publishing
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
(Build {}).execute()
|
||||
fn prelude(&self, context: Context) -> Result<Self::Input> {
|
||||
(Build {}).execute(context)
|
||||
}
|
||||
|
||||
fn apply(self, context: Context, _input: Self::Input) -> Result<Self::Output> {
|
||||
|
@ -37,7 +37,7 @@ impl Command for Remove {
|
||||
tracing::span!(tracing::Level::INFO, "Removing")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -45,9 +45,9 @@ impl Command for Prove {
|
||||
tracing::span!(tracing::Level::INFO, "Proving")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, context: Context) -> Result<Self::Input> {
|
||||
let skip_key_check = self.skip_key_check;
|
||||
(Setup { skip_key_check }).execute()
|
||||
(Setup { skip_key_check }).execute(context)
|
||||
}
|
||||
|
||||
fn apply(self, context: Context, input: Self::Input) -> Result<Self::Output> {
|
||||
|
@ -40,9 +40,9 @@ impl Command for Run {
|
||||
tracing::span!(tracing::Level::INFO, "Verifying")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, context: Context) -> Result<Self::Input> {
|
||||
let skip_key_check = self.skip_key_check;
|
||||
(Prove { skip_key_check }).execute()
|
||||
(Prove { skip_key_check }).execute(context)
|
||||
}
|
||||
|
||||
fn apply(self, _context: Context, input: Self::Input) -> Result<Self::Output> {
|
||||
|
@ -49,8 +49,8 @@ impl Command for Setup {
|
||||
tracing::span!(tracing::Level::INFO, "Setup")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
(Build {}).execute()
|
||||
fn prelude(&self, context: Context) -> Result<Self::Input> {
|
||||
(Build {}).execute(context)
|
||||
}
|
||||
|
||||
fn apply(self, context: Context, input: Self::Input) -> Result<Self::Output> {
|
||||
|
@ -47,7 +47,7 @@ impl Command for Test {
|
||||
tracing::span!(tracing::Level::INFO, "Test")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ impl Command for Update {
|
||||
tracing::span!(tracing::Level::INFO, "Updating")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -43,11 +43,11 @@ impl Command for Watch {
|
||||
tracing::span!(tracing::Level::INFO, "Watching")
|
||||
}
|
||||
|
||||
fn prelude(&self) -> Result<Self::Input> {
|
||||
fn prelude(&self, _: Context) -> Result<Self::Input> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn apply(self, _context: Context, _: Self::Input) -> Result<Self::Output> {
|
||||
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
|
||||
let (tx, rx) = channel();
|
||||
let mut watcher = watcher(tx, Duration::from_secs(self.interval)).unwrap();
|
||||
|
||||
@ -64,7 +64,7 @@ impl Command for Watch {
|
||||
match rx.recv() {
|
||||
// See changes on the write event
|
||||
Ok(DebouncedEvent::Write(_write)) => {
|
||||
match (Build {}).execute() {
|
||||
match (Build {}).execute(context.clone()) {
|
||||
Ok(_output) => {
|
||||
tracing::info!("Built successfully");
|
||||
}
|
||||
|
61
leo/main.rs
61
leo/main.rs
@ -39,21 +39,29 @@ use commands::{
|
||||
};
|
||||
|
||||
use anyhow::Error;
|
||||
use std::process::exit;
|
||||
use std::{path::PathBuf, process::exit};
|
||||
use structopt::{clap::AppSettings, StructOpt};
|
||||
|
||||
/// CLI Arguments entry point - includes global parameters and subcommands
|
||||
#[derive(StructOpt, Debug)]
|
||||
#[structopt(name = "leo", author = "The Aleo Team <hello@aleo.org>", setting = AppSettings::ColoredHelp)]
|
||||
struct Opt {
|
||||
#[structopt(short, long, help = "Print additional information for debugging")]
|
||||
#[structopt(short, global = true, help = "Print additional information for debugging")]
|
||||
debug: bool,
|
||||
|
||||
#[structopt(short, long, help = "Suppress CLI output")]
|
||||
#[structopt(short, global = true, help = "Suppress CLI output")]
|
||||
quiet: bool,
|
||||
|
||||
#[structopt(subcommand)]
|
||||
command: CommandOpts,
|
||||
|
||||
#[structopt(
|
||||
long,
|
||||
global = true,
|
||||
help = "Optional path to Leo program root folder",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
///Leo compiler and package manager
|
||||
@ -170,38 +178,45 @@ enum CommandOpts {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// read command line arguments
|
||||
// Read command line arguments.
|
||||
let opt = Opt::from_args();
|
||||
|
||||
if !opt.quiet {
|
||||
// init logger with optional debug flag
|
||||
// Init logger with optional debug flag.
|
||||
logger::init_logger("leo", match opt.debug {
|
||||
false => 1,
|
||||
true => 2,
|
||||
});
|
||||
}
|
||||
|
||||
// Get custom root folder and create context for it.
|
||||
// If not specified, default context will be created in cwd.
|
||||
let context = handle_error(match opt.path {
|
||||
Some(path) => context::create_context(path),
|
||||
None => context::get_context(),
|
||||
});
|
||||
|
||||
handle_error(match opt.command {
|
||||
CommandOpts::Init { command } => command.try_execute(),
|
||||
CommandOpts::New { command } => command.try_execute(),
|
||||
CommandOpts::Build { command } => command.try_execute(),
|
||||
CommandOpts::Setup { command } => command.try_execute(),
|
||||
CommandOpts::Prove { command } => command.try_execute(),
|
||||
CommandOpts::Test { command } => command.try_execute(),
|
||||
CommandOpts::Run { command } => command.try_execute(),
|
||||
CommandOpts::Clean { command } => command.try_execute(),
|
||||
CommandOpts::Watch { command } => command.try_execute(),
|
||||
CommandOpts::Update { command } => command.try_execute(),
|
||||
CommandOpts::Init { command } => command.try_execute(context),
|
||||
CommandOpts::New { command } => command.try_execute(context),
|
||||
CommandOpts::Build { command } => command.try_execute(context),
|
||||
CommandOpts::Setup { command } => command.try_execute(context),
|
||||
CommandOpts::Prove { command } => command.try_execute(context),
|
||||
CommandOpts::Test { command } => command.try_execute(context),
|
||||
CommandOpts::Run { command } => command.try_execute(context),
|
||||
CommandOpts::Clean { command } => command.try_execute(context),
|
||||
CommandOpts::Watch { command } => command.try_execute(context),
|
||||
CommandOpts::Update { command } => command.try_execute(context),
|
||||
|
||||
CommandOpts::Add { command } => command.try_execute(),
|
||||
CommandOpts::Clone { command } => command.try_execute(),
|
||||
CommandOpts::Login { command } => command.try_execute(),
|
||||
CommandOpts::Logout { command } => command.try_execute(),
|
||||
CommandOpts::Publish { command } => command.try_execute(),
|
||||
CommandOpts::Remove { command } => command.try_execute(),
|
||||
CommandOpts::Add { command } => command.try_execute(context),
|
||||
CommandOpts::Clone { command } => command.try_execute(context),
|
||||
CommandOpts::Login { command } => command.try_execute(context),
|
||||
CommandOpts::Logout { command } => command.try_execute(context),
|
||||
CommandOpts::Publish { command } => command.try_execute(context),
|
||||
CommandOpts::Remove { command } => command.try_execute(context),
|
||||
|
||||
CommandOpts::Lint { command } => command.try_execute(),
|
||||
CommandOpts::Deploy { command } => command.try_execute(),
|
||||
CommandOpts::Lint { command } => command.try_execute(context),
|
||||
CommandOpts::Deploy { command } => command.try_execute(context),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -68,10 +68,16 @@ impl Package {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the first character is not a number.
|
||||
if previous.is_numeric() {
|
||||
tracing::error!("Project names cannot begin with a number");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Iterate and check that the package name is valid.
|
||||
for current in package_name.chars() {
|
||||
// Check that the package name is lowercase.
|
||||
if !current.is_ascii_lowercase() && current != '-' {
|
||||
if current.is_ascii_uppercase() && current != '-' {
|
||||
tracing::error!("Project names must be all lowercase");
|
||||
return false;
|
||||
}
|
||||
@ -267,6 +273,8 @@ mod tests {
|
||||
assert!(Package::is_package_name_valid("foo"));
|
||||
assert!(Package::is_package_name_valid("foo-bar"));
|
||||
assert!(Package::is_package_name_valid("foo-bar-baz"));
|
||||
assert!(Package::is_package_name_valid("foo1"));
|
||||
assert!(Package::is_package_name_valid("foo-1"));
|
||||
|
||||
assert!(!Package::is_package_name_valid(""));
|
||||
assert!(!Package::is_package_name_valid("-"));
|
||||
@ -279,5 +287,6 @@ mod tests {
|
||||
assert!(!Package::is_package_name_valid("foo*bar"));
|
||||
assert!(!Package::is_package_name_valid("foo,bar"));
|
||||
assert!(!Package::is_package_name_valid("foo_bar"));
|
||||
assert!(!Package::is_package_name_valid("1-foo"));
|
||||
}
|
||||
}
|
||||
|
@ -26,19 +26,19 @@ path = "../ast"
|
||||
version = "1.2.3"
|
||||
|
||||
[dependencies.snarkvm-algorithms]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
#default-features = false
|
||||
|
||||
[dependencies.snarkvm-curves]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-dpc]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-utilities]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.6.2"
|
||||
@ -54,7 +54,7 @@ version = "0.3"
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.snarkvm-storage]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
|
||||
[dev-dependencies.rand_core]
|
||||
version = "0.6.2"
|
||||
|
@ -18,19 +18,19 @@ license = "GPL-3.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies.snarkvm-curves]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-fields]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-gadgets]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.snarkvm-r1cs]
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.num-bigint]
|
||||
|
Loading…
Reference in New Issue
Block a user