AST refactor

This commit is contained in:
evan-schott 2024-03-04 16:59:28 -08:00
parent c516db61f0
commit 8e67cfbf2a
12 changed files with 45 additions and 101 deletions

View File

@ -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))
}
}

View File

@ -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::*;

View File

@ -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,
}

View File

@ -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) {}

View File

@ -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,

View File

@ -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
}
}

View File

@ -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};

View File

@ -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(","))

View File

@ -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,
}
);

View File

@ -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: (),

View File

@ -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,

View File

@ -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())