mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-22 22:44:47 +03:00
AST refactor
This commit is contained in:
parent
c516db61f0
commit
8e67cfbf2a
@ -21,13 +21,13 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Location {
|
||||
pub program: Symbol,
|
||||
pub name: Symbol,
|
||||
pub function: Symbol,
|
||||
}
|
||||
|
||||
impl Location {
|
||||
// Create new Location instance.
|
||||
pub fn new(program: Symbol, name: Symbol) -> Location {
|
||||
Location { program, name }
|
||||
Location { program, function: name }
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ impl Serialize for Location {
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&format!("{}/{}", self.program, self.name))
|
||||
serializer.serialize_str(&format!("{}/{}", self.program, self.function))
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pub mod location;
|
||||
pub use location::*;
|
||||
|
||||
pub mod identifier;
|
||||
pub use identifier::*;
|
||||
|
||||
@ -29,5 +32,4 @@ pub mod node_builder;
|
||||
pub use node_builder::*;
|
||||
|
||||
pub mod static_string;
|
||||
|
||||
pub use static_string::*;
|
||||
|
@ -48,6 +48,7 @@ pub trait ExpressionReconstructor {
|
||||
AccessExpression::AssociatedConstant(constant) => self.reconstruct_associated_constant(constant),
|
||||
AccessExpression::AssociatedFunction(function) => self.reconstruct_associated_function(function),
|
||||
AccessExpression::Member(member) => self.reconstruct_member_access(member),
|
||||
AccessExpression::MethodCall(call) => self.reconstruct_method_call(call),
|
||||
AccessExpression::Tuple(tuple) => self.reconstruct_tuple_access(tuple),
|
||||
}
|
||||
}
|
||||
@ -101,6 +102,19 @@ pub trait ExpressionReconstructor {
|
||||
)
|
||||
}
|
||||
|
||||
fn reconstruct_method_call(&mut self, input: MethodCall) -> (Expression, Self::AdditionalOutput) {
|
||||
(
|
||||
Expression::Access(AccessExpression::MethodCall(MethodCall {
|
||||
receiver: input.receiver,
|
||||
arguments: input.arguments.into_iter().map(|arg| self.reconstruct_expression(arg).0).collect(),
|
||||
span: input.span,
|
||||
id: input.id,
|
||||
name: input.name,
|
||||
})),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn reconstruct_tuple_access(&mut self, input: TupleAccess) -> (Expression, Self::AdditionalOutput) {
|
||||
(
|
||||
Expression::Access(AccessExpression::Tuple(TupleAccess {
|
||||
@ -397,9 +411,6 @@ pub trait StatementReconstructor: ExpressionReconstructor {
|
||||
(
|
||||
Statement::Return(ReturnStatement {
|
||||
expression: self.reconstruct_expression(input.expression).0,
|
||||
finalize_arguments: input.finalize_arguments.map(|arguments| {
|
||||
arguments.into_iter().map(|argument| self.reconstruct_expression(argument).0).collect()
|
||||
}),
|
||||
span: input.span,
|
||||
id: input.id,
|
||||
}),
|
||||
@ -459,21 +470,13 @@ pub trait ProgramReconstructor: StatementReconstructor {
|
||||
fn reconstruct_function(&mut self, input: Function) -> Function {
|
||||
Function {
|
||||
annotations: input.annotations,
|
||||
is_async: input.is_async,
|
||||
variant: input.variant,
|
||||
identifier: input.identifier,
|
||||
input: input.input,
|
||||
output: input.output,
|
||||
output_type: input.output_type,
|
||||
block: self.reconstruct_block(input.block).0,
|
||||
finalize: input.finalize.map(|finalize| Finalize {
|
||||
identifier: finalize.identifier,
|
||||
input: finalize.input,
|
||||
output: finalize.output,
|
||||
output_type: finalize.output_type,
|
||||
block: self.reconstruct_block(finalize.block).0,
|
||||
span: finalize.span,
|
||||
id: finalize.id,
|
||||
}),
|
||||
span: input.span,
|
||||
id: input.id,
|
||||
}
|
||||
|
@ -210,11 +210,6 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
||||
|
||||
fn visit_return(&mut self, input: &'a ReturnStatement) {
|
||||
self.visit_expression(&input.expression, &Default::default());
|
||||
if let Some(arguments) = &input.finalize_arguments {
|
||||
arguments.iter().for_each(|argument| {
|
||||
self.visit_expression(argument, &Default::default());
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,9 +243,6 @@ pub trait ProgramVisitor<'a>: StatementVisitor<'a> {
|
||||
|
||||
fn visit_function(&mut self, input: &'a Function) {
|
||||
self.visit_block(&input.block);
|
||||
if let Some(finalize) = &input.finalize {
|
||||
self.visit_block(&finalize.block);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_function_stub(&mut self, _input: &'a FunctionStub) {}
|
||||
|
@ -24,6 +24,7 @@ use crate::{
|
||||
FutureType,
|
||||
Identifier,
|
||||
Input,
|
||||
Location,
|
||||
Mode,
|
||||
Node,
|
||||
NodeID,
|
||||
@ -35,7 +36,7 @@ use crate::{
|
||||
};
|
||||
use leo_span::{sym, Span, Symbol};
|
||||
|
||||
use crate::{stub::future_stub::FutureStub, Type::Composite};
|
||||
use crate::Type::Composite;
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use snarkvm::{
|
||||
@ -60,7 +61,7 @@ pub struct FunctionStub {
|
||||
/// The function identifier, e.g., `foo` in `function foo(...) { ... }`.
|
||||
pub identifier: Identifier,
|
||||
/// Ordered list of futures inputted to finalize.
|
||||
pub future_stubs: Vec<FutureStub>,
|
||||
pub future_locations: Vec<Location>,
|
||||
/// The function's input parameters.
|
||||
pub input: Vec<Input>,
|
||||
/// The function's output declarations.
|
||||
@ -111,7 +112,7 @@ impl FunctionStub {
|
||||
is_async,
|
||||
variant,
|
||||
identifier,
|
||||
future_stubs: Vec::new(),
|
||||
future_locations: Vec::new(),
|
||||
input,
|
||||
output,
|
||||
output_type,
|
||||
@ -218,7 +219,7 @@ impl FunctionStub {
|
||||
is_async: function.finalize_logic().is_some(),
|
||||
variant: Variant::Transition,
|
||||
identifier: Identifier::from(function.name()),
|
||||
future_stubs: Vec::new(),
|
||||
future_locations: Vec::new(),
|
||||
input: function
|
||||
.inputs()
|
||||
.iter()
|
||||
@ -281,11 +282,11 @@ impl FunctionStub {
|
||||
is_async: true,
|
||||
variant: Variant::Transition,
|
||||
identifier: Identifier::new(name, Default::default()),
|
||||
future_stubs: function
|
||||
future_locations: function
|
||||
.inputs()
|
||||
.iter()
|
||||
.filter_map(|input| match input.value_type() {
|
||||
ValueType::Future(val) => Some(FutureStub::new(
|
||||
ValueType::Future(val) => Some(Location::new(
|
||||
Identifier::from(val.program_id().name()).name,
|
||||
Identifier::from(val.resource()).name,
|
||||
)),
|
||||
@ -303,7 +304,7 @@ impl FunctionStub {
|
||||
identifier: Identifier::new(Symbol::intern(&format!("a{}", index + 1)), Default::default()),
|
||||
mode: Mode::Public,
|
||||
type_: match input.finalize_type() {
|
||||
PlaintextFinalizeType(val) => Type::from_snarkvm(&val, name),
|
||||
PlaintextFinalizeType(val) => Type::from_snarkvm(val, name),
|
||||
FutureFinalizeType(_) => Type::Future(Default::default()),
|
||||
},
|
||||
span: Default::default(),
|
||||
@ -359,7 +360,7 @@ impl FunctionStub {
|
||||
is_async: false,
|
||||
variant: Variant::Standard,
|
||||
identifier: Identifier::from(closure.name()),
|
||||
future_stubs: Vec::new(),
|
||||
future_locations: Vec::new(),
|
||||
input: closure
|
||||
.inputs()
|
||||
.iter()
|
||||
@ -395,7 +396,7 @@ impl From<Function> for FunctionStub {
|
||||
is_async: function.is_async,
|
||||
variant: function.variant,
|
||||
identifier: function.identifier,
|
||||
future_stubs: Vec::new(),
|
||||
future_locations: Vec::new(),
|
||||
input: function.input,
|
||||
output: function.output,
|
||||
output_type: function.output_type,
|
||||
|
@ -1,55 +0,0 @@
|
||||
// Copyright (C) 2019-2023 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_span::Symbol;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A future stub definition.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct FutureStub {
|
||||
program: Symbol,
|
||||
function: Symbol,
|
||||
}
|
||||
|
||||
impl PartialEq for FutureStub {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.program == other.program && self.function == other.function
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FutureStub {}
|
||||
|
||||
impl FutureStub {
|
||||
/// Initialize a new future stub.
|
||||
pub fn new(program: Symbol, function: Symbol) -> Self {
|
||||
FutureStub { program, function }
|
||||
}
|
||||
|
||||
pub fn to_key(&self) -> (Symbol, Symbol) {
|
||||
(self.program, self.function)
|
||||
}
|
||||
|
||||
/// Get the program.
|
||||
pub fn program(&self) -> Symbol {
|
||||
self.program
|
||||
}
|
||||
|
||||
/// Get the function.
|
||||
pub fn function(&self) -> Symbol {
|
||||
self.function
|
||||
}
|
||||
}
|
@ -19,9 +19,6 @@
|
||||
pub mod function_stub;
|
||||
pub use function_stub::*;
|
||||
|
||||
pub mod future_stub;
|
||||
pub use future_stub;
|
||||
|
||||
use crate::{Composite, ConstDeclaration, Identifier, Mapping, NodeID, ProgramId};
|
||||
use leo_span::{Span, Symbol};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -14,13 +14,14 @@
|
||||
// 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::{TupleType, Type};
|
||||
use crate::{Type};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// A future type consisting of the type of the inputs.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Default)]
|
||||
pub struct FutureType {
|
||||
// Optional type specification of inputs.
|
||||
pub inputs: Vec<Type>,
|
||||
@ -38,11 +39,7 @@ impl FutureType {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FutureType {
|
||||
fn default() -> Self {
|
||||
Self { inputs: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for crate::FutureType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Future<{}>", self.inputs.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","))
|
||||
|
@ -152,4 +152,11 @@ create_messages!(
|
||||
msg: format!("There are two mismatched definitions of struct `{struct_}`."),
|
||||
help: Some("Duplicate definitions of structs are required to use external structs, but each field's name and type must match exactly.".to_string()),
|
||||
}
|
||||
|
||||
@backtraced
|
||||
function_not_found {
|
||||
args: (func: impl Display),
|
||||
msg: format!("function `{func}` not found"),
|
||||
help: None,
|
||||
}
|
||||
);
|
||||
|
@ -772,7 +772,7 @@ create_messages!(
|
||||
@formatted
|
||||
async_function_must_return_single_future {
|
||||
args: (),
|
||||
msg: "An async function must only a single output, and it must be a future.".to_string(),
|
||||
msg: "An async function must have only a single output, and it must be a future.".to_string(),
|
||||
help: Some("Example: `async function foo() -> Future {...}`".to_string()),
|
||||
}
|
||||
|
||||
@ -923,7 +923,7 @@ create_messages!(
|
||||
msg: "Cannot return a value in an async function block.".to_string(),
|
||||
help: Some("Async functions execute on-chain. Since async transitions call async functions, and async transitions execute offline, it would be impossible for the async function to be able to return on-chain state to the transition function.".to_string()),
|
||||
}
|
||||
|
||||
|
||||
@formatted
|
||||
async_transition_missing_future_to_return {
|
||||
args: (),
|
||||
|
@ -89,7 +89,7 @@ fn new_compiler(handler: &Handler) -> Compiler<'_> {
|
||||
PathBuf::from(String::new()),
|
||||
PathBuf::from(String::new()),
|
||||
Some(CompilerOptions {
|
||||
build: BuildOptions { dce_enabled: true },
|
||||
build: BuildOptions { dce_enabled: true, conditional_block_max_depth: 10, disable_conditional_branch_type_checking: false },
|
||||
output: OutputOptions {
|
||||
symbol_table_spans_enabled: false,
|
||||
initial_symbol_table: false,
|
||||
|
@ -70,7 +70,7 @@ pub fn disassemble<N: Network, Instruction: InstructionTrait<N>, Command: Comman
|
||||
.functions()
|
||||
.iter()
|
||||
.filter_map(|(id, function)| match function.finalize_logic() {
|
||||
Some(f) => {
|
||||
Some(_f) => {
|
||||
let name = Symbol::intern(&format!(
|
||||
"finalize/{}",
|
||||
Symbol::intern(&Identifier::from(id).name.to_string())
|
||||
|
Loading…
Reference in New Issue
Block a user