mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-26 19:51:52 +03:00
Merge pull request #2536 from AleoHQ/design/unique-node-ids
[Design] Parsing produces unique node IDs.
This commit is contained in:
commit
0cccdda67e
@ -52,9 +52,9 @@ pub struct Identifier {
|
||||
simple_node_impl!(Identifier);
|
||||
|
||||
impl Identifier {
|
||||
/// Constructs a new identifier with `name` and a default span.
|
||||
pub fn new(name: Symbol) -> Self {
|
||||
Self { name, span: Span::default(), id: NodeID::default() }
|
||||
/// Constructs a new identifier with `name` and `id` and a default span.
|
||||
pub fn new(name: Symbol, id: NodeID) -> Self {
|
||||
Self { name, span: Span::default(), id }
|
||||
}
|
||||
|
||||
/// Check if the Identifier name matches the other name.
|
||||
@ -100,6 +100,7 @@ impl Serialize for Identifier {
|
||||
let mut key: BTreeMap<String, String> = BTreeMap::new();
|
||||
key.insert("name".to_string(), self.name.to_string());
|
||||
key.insert("span".to_string(), to_json_string(&self.span)?);
|
||||
key.insert("id".to_string(), to_json_string(&self.id)?);
|
||||
|
||||
// Convert the serialized object into a string for use as a key.
|
||||
serializer.serialize_str(&to_json_string(&key)?)
|
||||
|
@ -24,6 +24,10 @@ pub mod positive_number;
|
||||
pub use positive_number::*;
|
||||
|
||||
pub mod node;
|
||||
|
||||
pub mod node_builder;
|
||||
pub use node_builder::*;
|
||||
|
||||
pub mod static_string;
|
||||
|
||||
pub use static_string::*;
|
||||
|
@ -19,7 +19,6 @@ use leo_span::Span;
|
||||
/// A node ID.
|
||||
// Development Note:
|
||||
// A `NodeID` must implement: `Copy`, `Default`, among others.
|
||||
// TODO (@d0cd): Replace use of `NodeID::default()` with unique IDs in the rest of the codebase.
|
||||
pub type NodeID = usize;
|
||||
|
||||
/// A node in the AST.
|
||||
|
67
compiler/ast/src/common/node_builder.rs
Normal file
67
compiler/ast/src/common/node_builder.rs
Normal file
@ -0,0 +1,67 @@
|
||||
// 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 crate::NodeID;
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
/// A counter that produces sequentially increasing `NodeID`s.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NodeBuilder {
|
||||
/// The inner counter.
|
||||
/// `RefCell` is used here to avoid `&mut` all over the compiler.
|
||||
inner: RefCell<NodeBuilderInner>,
|
||||
}
|
||||
|
||||
impl NodeBuilder {
|
||||
/// Returns a new `NodeCounter` with the given `NodeID` as the starting value.
|
||||
pub fn new(next: NodeID) -> Self {
|
||||
Self { inner: RefCell::new(NodeBuilderInner::new(next)) }
|
||||
}
|
||||
|
||||
/// Returns the next `NodeID` and increments the internal state.
|
||||
pub fn next_id(&self) -> NodeID {
|
||||
self.inner.borrow_mut().next_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for NodeBuilder {
|
||||
fn default() -> Self {
|
||||
Self::new(0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains the actual data for `Handler`.
|
||||
/// Modeled this way to afford an API using interior mutability.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NodeBuilderInner {
|
||||
/// The next `NodeID`.
|
||||
next: NodeID,
|
||||
}
|
||||
|
||||
impl NodeBuilderInner {
|
||||
/// Returns a new `NodeCounter` with the given `NodeID` as the starting value.
|
||||
pub fn new(next: NodeID) -> Self {
|
||||
Self { next }
|
||||
}
|
||||
|
||||
/// Returns the next `NodeID` and increments the internal state.
|
||||
pub fn next_id(&mut self) -> NodeID {
|
||||
let next = self.next;
|
||||
self.next += 1;
|
||||
next
|
||||
}
|
||||
}
|
@ -42,14 +42,21 @@ pub struct Finalize {
|
||||
|
||||
impl Finalize {
|
||||
/// Create a new finalize block.
|
||||
pub fn new(identifier: Identifier, input: Vec<Input>, output: Vec<Output>, block: Block, span: Span) -> Self {
|
||||
pub fn new(
|
||||
identifier: Identifier,
|
||||
input: Vec<Input>,
|
||||
output: Vec<Output>,
|
||||
block: Block,
|
||||
span: Span,
|
||||
id: NodeID,
|
||||
) -> Self {
|
||||
let output_type = match output.len() {
|
||||
0 => Type::Unit,
|
||||
1 => output[0].type_(),
|
||||
_ => Type::Tuple(Tuple(output.iter().map(|output| output.type_()).collect())),
|
||||
};
|
||||
|
||||
Self { identifier, input, output, output_type, block, span, id: NodeID::default() }
|
||||
Self { identifier, input, output, output_type, block, span, id }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@ impl Function {
|
||||
block: Block,
|
||||
finalize: Option<Finalize>,
|
||||
span: Span,
|
||||
id: NodeID,
|
||||
) -> Self {
|
||||
// Determine the output type of the function
|
||||
let get_output_type = |output: &Output| match &output {
|
||||
@ -102,18 +103,7 @@ impl Function {
|
||||
_ => Type::Tuple(Tuple(output.iter().map(|output| get_output_type(output)).collect())),
|
||||
};
|
||||
|
||||
Function {
|
||||
annotations,
|
||||
variant,
|
||||
identifier,
|
||||
input,
|
||||
output,
|
||||
output_type,
|
||||
block,
|
||||
finalize,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
}
|
||||
Function { annotations, variant, identifier, input, output, output_type, block, finalize, span, id }
|
||||
}
|
||||
|
||||
/// Returns function name.
|
||||
|
@ -73,8 +73,8 @@ pub enum Statement {
|
||||
|
||||
impl Statement {
|
||||
/// Returns a dummy statement made from an empty block `{}`.
|
||||
pub fn dummy(span: Span) -> Self {
|
||||
Self::Block(Block { statements: Vec::new(), span, id: NodeID::default() })
|
||||
pub fn dummy(span: Span, id: NodeID) -> Self {
|
||||
Self::Block(Block { statements: Vec::new(), span, id })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -893,28 +893,29 @@ impl TryFrom<&Literal> for Value {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Value> for Literal {
|
||||
fn from(v: Value) -> Self {
|
||||
impl Literal {
|
||||
#[allow(unused)]
|
||||
fn from_value(v: Value, id: NodeID) -> Self {
|
||||
use Value::*;
|
||||
match v {
|
||||
Input(_, _) => todo!("We need to test if this is hittable"),
|
||||
Address(v, span) => Literal::Address(v, span, NodeID::default()),
|
||||
Boolean(v, span) => Literal::Boolean(v, span, NodeID::default()),
|
||||
Address(v, span) => Literal::Address(v, span, id),
|
||||
Boolean(v, span) => Literal::Boolean(v, span, id),
|
||||
Struct(_ident, _values) => todo!("We need to test if this is hittable"),
|
||||
Field(v, span) => Literal::Field(v, span, NodeID::default()),
|
||||
Field(v, span) => Literal::Field(v, span, id),
|
||||
Group(v) => Literal::Group(v),
|
||||
I8(v, span) => Literal::Integer(IntegerType::I8, v.to_string(), span, NodeID::default()),
|
||||
I16(v, span) => Literal::Integer(IntegerType::I16, v.to_string(), span, NodeID::default()),
|
||||
I32(v, span) => Literal::Integer(IntegerType::I32, v.to_string(), span, NodeID::default()),
|
||||
I64(v, span) => Literal::Integer(IntegerType::I64, v.to_string(), span, NodeID::default()),
|
||||
I128(v, span) => Literal::Integer(IntegerType::I128, v.to_string(), span, NodeID::default()),
|
||||
U8(v, span) => Literal::Integer(IntegerType::U8, v.to_string(), span, NodeID::default()),
|
||||
U16(v, span) => Literal::Integer(IntegerType::U16, v.to_string(), span, NodeID::default()),
|
||||
U32(v, span) => Literal::Integer(IntegerType::U32, v.to_string(), span, NodeID::default()),
|
||||
U64(v, span) => Literal::Integer(IntegerType::U64, v.to_string(), span, NodeID::default()),
|
||||
U128(v, span) => Literal::Integer(IntegerType::U128, v.to_string(), span, NodeID::default()),
|
||||
Scalar(v, span) => Literal::Scalar(v, span, NodeID::default()),
|
||||
String(v, span) => Literal::String(v, span, NodeID::default()),
|
||||
I8(v, span) => Literal::Integer(IntegerType::I8, v.to_string(), span, id),
|
||||
I16(v, span) => Literal::Integer(IntegerType::I16, v.to_string(), span, id),
|
||||
I32(v, span) => Literal::Integer(IntegerType::I32, v.to_string(), span, id),
|
||||
I64(v, span) => Literal::Integer(IntegerType::I64, v.to_string(), span, id),
|
||||
I128(v, span) => Literal::Integer(IntegerType::I128, v.to_string(), span, id),
|
||||
U8(v, span) => Literal::Integer(IntegerType::U8, v.to_string(), span, id),
|
||||
U16(v, span) => Literal::Integer(IntegerType::U16, v.to_string(), span, id),
|
||||
U32(v, span) => Literal::Integer(IntegerType::U32, v.to_string(), span, id),
|
||||
U64(v, span) => Literal::Integer(IntegerType::U64, v.to_string(), span, id),
|
||||
U128(v, span) => Literal::Integer(IntegerType::U128, v.to_string(), span, id),
|
||||
Scalar(v, span) => Literal::Scalar(v, span, id),
|
||||
String(v, span) => Literal::String(v, span, id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,8 @@
|
||||
//! The compiler for Leo programs.
|
||||
//!
|
||||
//! The [`Compiler`] type compiles Leo programs into R1CS circuits.
|
||||
use leo_ast::Program;
|
||||
pub use leo_ast::{Ast, InputAst};
|
||||
use leo_ast::{NodeBuilder, Program};
|
||||
use leo_errors::{emitter::Handler, CompilerError, Result};
|
||||
pub use leo_passes::SymbolTable;
|
||||
use leo_passes::*;
|
||||
@ -48,6 +48,10 @@ pub struct Compiler<'a> {
|
||||
pub input_ast: Option<InputAst>,
|
||||
/// Options configuring compilation.
|
||||
compiler_options: CompilerOptions,
|
||||
/// The `NodeCounter` used to generate sequentially increasing `NodeID`s.
|
||||
node_builder: NodeBuilder,
|
||||
/// The `Assigner` is used to construct (unique) assignment statements.
|
||||
assigner: Assigner,
|
||||
}
|
||||
|
||||
impl<'a> Compiler<'a> {
|
||||
@ -60,6 +64,8 @@ impl<'a> Compiler<'a> {
|
||||
output_directory: PathBuf,
|
||||
compiler_options: Option<CompilerOptions>,
|
||||
) -> Self {
|
||||
let node_builder = NodeBuilder::default();
|
||||
let assigner = Assigner::default();
|
||||
Self {
|
||||
handler,
|
||||
main_file_path,
|
||||
@ -69,6 +75,8 @@ impl<'a> Compiler<'a> {
|
||||
ast: Ast::new(Program::default()),
|
||||
input_ast: None,
|
||||
compiler_options: compiler_options.unwrap_or_default(),
|
||||
node_builder,
|
||||
assigner,
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +100,7 @@ impl<'a> Compiler<'a> {
|
||||
let prg_sf = with_session_globals(|s| s.source_map.new_source(program_string, name));
|
||||
|
||||
// Use the parser to construct the abstract syntax tree (ast).
|
||||
self.ast = leo_parser::parse_ast(self.handler, &prg_sf.src, prg_sf.start_pos)?;
|
||||
self.ast = leo_parser::parse_ast(self.handler, &self.node_builder, &prg_sf.src, prg_sf.start_pos)?;
|
||||
|
||||
// If the program is imported, then check that the name of its program scope matches the file name.
|
||||
// Note that parsing enforces that there is exactly one program scope in a file.
|
||||
@ -132,7 +140,8 @@ impl<'a> Compiler<'a> {
|
||||
.map_err(|e| CompilerError::file_read_error(&input_file_path, e))?;
|
||||
|
||||
// Parse and serialize it.
|
||||
let input_ast = leo_parser::parse_input(self.handler, &input_sf.src, input_sf.start_pos)?;
|
||||
let input_ast =
|
||||
leo_parser::parse_input(self.handler, &self.node_builder, &input_sf.src, input_sf.start_pos)?;
|
||||
if self.compiler_options.output.initial_ast {
|
||||
// Write the input AST snapshot post parsing.
|
||||
if self.compiler_options.output.spans_enabled {
|
||||
@ -166,7 +175,8 @@ impl<'a> Compiler<'a> {
|
||||
|
||||
/// Runs the loop unrolling pass.
|
||||
pub fn loop_unrolling_pass(&mut self, symbol_table: SymbolTable) -> Result<SymbolTable> {
|
||||
let (ast, symbol_table) = Unroller::do_pass((std::mem::take(&mut self.ast), self.handler, symbol_table))?;
|
||||
let (ast, symbol_table) =
|
||||
Unroller::do_pass((std::mem::take(&mut self.ast), self.handler, &self.node_builder, symbol_table))?;
|
||||
self.ast = ast;
|
||||
|
||||
if self.compiler_options.output.unrolled_ast {
|
||||
@ -177,45 +187,50 @@ impl<'a> Compiler<'a> {
|
||||
}
|
||||
|
||||
/// Runs the static single assignment pass.
|
||||
pub fn static_single_assignment_pass(&mut self, symbol_table: &SymbolTable) -> Result<Assigner> {
|
||||
let (ast, assigner) = StaticSingleAssigner::do_pass((std::mem::take(&mut self.ast), symbol_table))?;
|
||||
self.ast = ast;
|
||||
pub fn static_single_assignment_pass(&mut self, symbol_table: &SymbolTable) -> Result<()> {
|
||||
self.ast = StaticSingleAssigner::do_pass((
|
||||
std::mem::take(&mut self.ast),
|
||||
&self.node_builder,
|
||||
&self.assigner,
|
||||
symbol_table,
|
||||
))?;
|
||||
|
||||
if self.compiler_options.output.ssa_ast {
|
||||
self.write_ast_to_json("ssa_ast.json")?;
|
||||
}
|
||||
|
||||
Ok(assigner)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Runs the flattening pass.
|
||||
pub fn flattening_pass(&mut self, symbol_table: &SymbolTable, assigner: Assigner) -> Result<Assigner> {
|
||||
let (ast, assigner) = Flattener::do_pass((std::mem::take(&mut self.ast), symbol_table, assigner))?;
|
||||
self.ast = ast;
|
||||
pub fn flattening_pass(&mut self, symbol_table: &SymbolTable) -> Result<()> {
|
||||
self.ast =
|
||||
Flattener::do_pass((std::mem::take(&mut self.ast), symbol_table, &self.node_builder, &self.assigner))?;
|
||||
|
||||
if self.compiler_options.output.flattened_ast {
|
||||
self.write_ast_to_json("flattened_ast.json")?;
|
||||
}
|
||||
|
||||
Ok(assigner)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Runs the function inlining pass.
|
||||
pub fn function_inlining_pass(&mut self, call_graph: &CallGraph, assigner: Assigner) -> Result<Assigner> {
|
||||
let (ast, assigner) = FunctionInliner::do_pass((std::mem::take(&mut self.ast), call_graph, assigner))?;
|
||||
pub fn function_inlining_pass(&mut self, call_graph: &CallGraph) -> Result<()> {
|
||||
let ast =
|
||||
FunctionInliner::do_pass((std::mem::take(&mut self.ast), &self.node_builder, call_graph, &self.assigner))?;
|
||||
self.ast = ast;
|
||||
|
||||
if self.compiler_options.output.inlined_ast {
|
||||
self.write_ast_to_json("inlined_ast.json")?;
|
||||
}
|
||||
|
||||
Ok(assigner)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Runs the dead code elimination pass.
|
||||
pub fn dead_code_elimination_pass(&mut self) -> Result<()> {
|
||||
if self.compiler_options.build.dce_enabled {
|
||||
self.ast = DeadCodeEliminator::do_pass(std::mem::take(&mut self.ast))?;
|
||||
self.ast = DeadCodeEliminator::do_pass((std::mem::take(&mut self.ast), &self.node_builder))?;
|
||||
}
|
||||
|
||||
if self.compiler_options.output.dce_ast {
|
||||
@ -243,12 +258,11 @@ impl<'a> Compiler<'a> {
|
||||
// TODO: Make this pass optional.
|
||||
let st = self.loop_unrolling_pass(st)?;
|
||||
|
||||
// TODO: Make this pass optional.
|
||||
let assigner = self.static_single_assignment_pass(&st)?;
|
||||
self.static_single_assignment_pass(&st)?;
|
||||
|
||||
let assigner = self.flattening_pass(&st, assigner)?;
|
||||
self.flattening_pass(&st)?;
|
||||
|
||||
let _ = self.function_inlining_pass(&call_graph, assigner)?;
|
||||
self.function_inlining_pass(&call_graph)?;
|
||||
|
||||
self.dead_code_elimination_pass()?;
|
||||
|
||||
|
352
compiler/compiler/tests/utilities/check_unique_node_ids.rs
Normal file
352
compiler/compiler/tests/utilities/check_unique_node_ids.rs
Normal file
@ -0,0 +1,352 @@
|
||||
// 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_ast::*;
|
||||
|
||||
use std::{collections::HashSet, marker::PhantomData};
|
||||
|
||||
/// A utility that checks that each node in the AST has a unique `NodeID`.
|
||||
pub struct CheckUniqueNodeIds<'a> {
|
||||
/// The set of `NodeID`s that have been seen.
|
||||
seen: HashSet<NodeID>,
|
||||
_phantom: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> CheckUniqueNodeIds<'a> {
|
||||
/// Creates a new `CheckUniqueNodeId`.
|
||||
pub fn new() -> Self {
|
||||
Self { seen: HashSet::new(), _phantom: PhantomData }
|
||||
}
|
||||
|
||||
/// Checks that the given `NodeID` has not been seen before.
|
||||
pub fn check(&mut self, id: NodeID) {
|
||||
if !self.seen.insert(id) {
|
||||
panic!("Duplicate NodeID found in the AST: {}", id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks that the given `Type` has a unique `NodeID`.
|
||||
pub fn check_ty(&mut self, ty: &'a Type) {
|
||||
match ty {
|
||||
Type::Identifier(identifier) => self.visit_identifier(identifier, &Default::default()),
|
||||
Type::Mapping(mapping) => {
|
||||
self.check_ty(&mapping.key);
|
||||
self.check_ty(&mapping.value);
|
||||
}
|
||||
Type::Tuple(tuple) => {
|
||||
for ty in &tuple.0 {
|
||||
self.check_ty(ty);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExpressionVisitor<'a> for CheckUniqueNodeIds<'a> {
|
||||
type AdditionalInput = ();
|
||||
type Output = ();
|
||||
|
||||
fn visit_access(&mut self, input: &'a AccessExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
match input {
|
||||
AccessExpression::AssociatedConstant(AssociatedConstant { ty, name, id, .. }) => {
|
||||
self.check_ty(ty);
|
||||
self.visit_identifier(name, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
AccessExpression::AssociatedFunction(AssociatedFunction { ty, name, arguments, id, .. }) => {
|
||||
self.check_ty(ty);
|
||||
self.visit_identifier(name, &Default::default());
|
||||
for argument in arguments {
|
||||
self.visit_expression(argument, &Default::default());
|
||||
}
|
||||
self.check(*id);
|
||||
}
|
||||
AccessExpression::Member(MemberAccess { inner, name, id, .. }) => {
|
||||
self.visit_expression(inner, &Default::default());
|
||||
self.visit_identifier(name, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
AccessExpression::Tuple(TupleAccess { tuple, id, .. }) => {
|
||||
self.visit_expression(tuple, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_binary(&mut self, input: &'a BinaryExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
let BinaryExpression { left, right, id, .. } = input;
|
||||
self.visit_expression(left, &Default::default());
|
||||
self.visit_expression(right, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
|
||||
fn visit_call(&mut self, input: &'a CallExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
let CallExpression { function, arguments, external, id, .. } = input;
|
||||
self.visit_expression(function, &Default::default());
|
||||
for argument in arguments {
|
||||
self.visit_expression(argument, &Default::default());
|
||||
}
|
||||
if let Some(external) = external {
|
||||
self.visit_expression(external, &Default::default());
|
||||
}
|
||||
self.check(*id);
|
||||
}
|
||||
|
||||
fn visit_cast(&mut self, input: &'a CastExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
let CastExpression { expression, type_, id, .. } = input;
|
||||
self.visit_expression(expression, &Default::default());
|
||||
self.check_ty(type_);
|
||||
self.check(*id);
|
||||
}
|
||||
|
||||
fn visit_struct_init(&mut self, input: &'a StructExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
let StructExpression { name, members, id, .. } = input;
|
||||
self.visit_identifier(name, &Default::default());
|
||||
for StructVariableInitializer { identifier, expression, id, .. } in members {
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
if let Some(expression) = expression {
|
||||
self.visit_expression(expression, &Default::default());
|
||||
}
|
||||
self.check(*id);
|
||||
}
|
||||
self.check(*id);
|
||||
}
|
||||
|
||||
fn visit_err(&mut self, input: &'a ErrExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
self.check(input.id);
|
||||
}
|
||||
|
||||
fn visit_identifier(&mut self, input: &'a Identifier, _: &Self::AdditionalInput) -> Self::Output {
|
||||
self.check(input.id)
|
||||
}
|
||||
|
||||
fn visit_literal(&mut self, input: &'a Literal, _: &Self::AdditionalInput) -> Self::Output {
|
||||
self.check(input.id())
|
||||
}
|
||||
|
||||
fn visit_ternary(&mut self, input: &'a TernaryExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
let TernaryExpression { condition, if_true, if_false, id, .. } = input;
|
||||
self.visit_expression(condition, &Default::default());
|
||||
self.visit_expression(if_true, &Default::default());
|
||||
self.visit_expression(if_false, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
|
||||
fn visit_tuple(&mut self, input: &'a TupleExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
let TupleExpression { elements, id, .. } = input;
|
||||
for element in elements {
|
||||
self.visit_expression(element, &Default::default());
|
||||
}
|
||||
self.check(*id);
|
||||
}
|
||||
|
||||
fn visit_unary(&mut self, input: &'a UnaryExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
let UnaryExpression { receiver, id, .. } = input;
|
||||
self.visit_expression(receiver, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
|
||||
fn visit_unit(&mut self, input: &'a UnitExpression, _: &Self::AdditionalInput) -> Self::Output {
|
||||
self.check(input.id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> StatementVisitor<'a> for CheckUniqueNodeIds<'a> {
|
||||
fn visit_assert(&mut self, input: &'a AssertStatement) {
|
||||
match &input.variant {
|
||||
AssertVariant::Assert(expr) => self.visit_expression(expr, &Default::default()),
|
||||
AssertVariant::AssertEq(left, right) | AssertVariant::AssertNeq(left, right) => {
|
||||
self.visit_expression(left, &Default::default());
|
||||
self.visit_expression(right, &Default::default())
|
||||
}
|
||||
};
|
||||
self.check(input.id)
|
||||
}
|
||||
|
||||
fn visit_assign(&mut self, input: &'a AssignStatement) {
|
||||
self.visit_expression(&input.place, &Default::default());
|
||||
self.visit_expression(&input.value, &Default::default());
|
||||
self.check(input.id)
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, input: &'a Block) {
|
||||
input.statements.iter().for_each(|stmt| self.visit_statement(stmt));
|
||||
self.check(input.id)
|
||||
}
|
||||
|
||||
fn visit_conditional(&mut self, input: &'a ConditionalStatement) {
|
||||
self.visit_expression(&input.condition, &Default::default());
|
||||
self.visit_block(&input.then);
|
||||
if let Some(stmt) = input.otherwise.as_ref() {
|
||||
self.visit_statement(stmt);
|
||||
}
|
||||
self.check(input.id)
|
||||
}
|
||||
|
||||
fn visit_console(&mut self, input: &'a ConsoleStatement) {
|
||||
match &input.function {
|
||||
ConsoleFunction::Assert(expr) => {
|
||||
self.visit_expression(expr, &Default::default());
|
||||
}
|
||||
ConsoleFunction::AssertEq(left, right) => {
|
||||
self.visit_expression(left, &Default::default());
|
||||
self.visit_expression(right, &Default::default());
|
||||
}
|
||||
ConsoleFunction::AssertNeq(left, right) => {
|
||||
self.visit_expression(left, &Default::default());
|
||||
self.visit_expression(right, &Default::default());
|
||||
}
|
||||
};
|
||||
self.check(input.id)
|
||||
}
|
||||
|
||||
fn visit_definition(&mut self, input: &'a DefinitionStatement) {
|
||||
self.visit_expression(&input.place, &Default::default());
|
||||
self.check_ty(&input.type_);
|
||||
self.visit_expression(&input.value, &Default::default());
|
||||
self.check(input.id)
|
||||
}
|
||||
|
||||
fn visit_expression_statement(&mut self, input: &'a ExpressionStatement) {
|
||||
self.visit_expression(&input.expression, &Default::default());
|
||||
self.check(input.id)
|
||||
}
|
||||
|
||||
fn visit_iteration(&mut self, input: &'a IterationStatement) {
|
||||
self.visit_identifier(&input.variable, &Default::default());
|
||||
self.check_ty(&input.type_);
|
||||
self.visit_expression(&input.start, &Default::default());
|
||||
self.visit_expression(&input.stop, &Default::default());
|
||||
self.visit_block(&input.block);
|
||||
self.check(input.id)
|
||||
}
|
||||
|
||||
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());
|
||||
})
|
||||
}
|
||||
self.check(input.id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ProgramVisitor<'a> for CheckUniqueNodeIds<'a> {
|
||||
fn visit_struct(&mut self, input: &'a Struct) {
|
||||
let Struct { identifier, members, id, .. } = input;
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
for Member { identifier, type_, id, .. } in members {
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
self.check_ty(type_);
|
||||
self.check(*id);
|
||||
}
|
||||
self.check(*id);
|
||||
}
|
||||
|
||||
fn visit_mapping(&mut self, input: &'a Mapping) {
|
||||
let Mapping { identifier, key_type, value_type, id, .. } = input;
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
self.check_ty(key_type);
|
||||
self.check_ty(value_type);
|
||||
self.check(*id);
|
||||
}
|
||||
|
||||
fn visit_function(&mut self, input: &'a Function) {
|
||||
let Function { annotations, identifier, input, output, block, finalize, id, .. } = input;
|
||||
// Check the annotations.
|
||||
for Annotation { identifier, id, .. } in annotations {
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
// Check the function name.
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
// Check the inputs.
|
||||
for in_ in input {
|
||||
match in_ {
|
||||
Input::Internal(FunctionInput { identifier, type_, id, .. }) => {
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
self.check_ty(type_);
|
||||
self.check(*id);
|
||||
}
|
||||
Input::External(External { identifier, program_name, record, id, .. }) => {
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
self.visit_identifier(program_name, &Default::default());
|
||||
self.visit_identifier(record, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check the outputs.
|
||||
for out in output {
|
||||
match out {
|
||||
Output::Internal(FunctionOutput { type_, id, .. }) => {
|
||||
self.check_ty(type_);
|
||||
self.check(*id);
|
||||
}
|
||||
Output::External(External { identifier, program_name, record, id, .. }) => {
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
self.visit_identifier(program_name, &Default::default());
|
||||
self.visit_identifier(record, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check the function body.
|
||||
self.visit_block(block);
|
||||
// Check the finalize block.
|
||||
if let Some(Finalize { identifier, input, output, block, id, .. }) = finalize {
|
||||
// Check the finalize name.
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
// Check the inputs.
|
||||
for in_ in input {
|
||||
match in_ {
|
||||
Input::Internal(FunctionInput { identifier, type_, id, .. }) => {
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
self.check_ty(type_);
|
||||
self.check(*id);
|
||||
}
|
||||
Input::External(External { identifier, program_name, record, id, .. }) => {
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
self.visit_identifier(program_name, &Default::default());
|
||||
self.visit_identifier(record, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check the outputs.
|
||||
for out in output {
|
||||
match out {
|
||||
Output::Internal(FunctionOutput { type_, id, .. }) => {
|
||||
self.check_ty(type_);
|
||||
self.check(*id);
|
||||
}
|
||||
Output::External(External { identifier, program_name, record, id, .. }) => {
|
||||
self.visit_identifier(identifier, &Default::default());
|
||||
self.visit_identifier(program_name, &Default::default());
|
||||
self.visit_identifier(record, &Default::default());
|
||||
self.check(*id);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check the function body.
|
||||
self.visit_block(block);
|
||||
self.check(*id);
|
||||
}
|
||||
self.check(*id);
|
||||
}
|
||||
}
|
@ -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/>.
|
||||
|
||||
mod check_unique_node_ids;
|
||||
use check_unique_node_ids::*;
|
||||
|
||||
use leo_compiler::{BuildOptions, Compiler, CompilerOptions};
|
||||
use leo_errors::{
|
||||
emitter::{Buffer, Emitter, Handler},
|
||||
@ -27,6 +30,7 @@ use leo_test_framework::{test::TestConfig, Test};
|
||||
|
||||
use snarkvm::prelude::*;
|
||||
|
||||
use leo_ast::ProgramVisitor;
|
||||
use snarkvm::{file::Manifest, package::Package};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
@ -144,6 +148,8 @@ pub fn parse_program<'a>(
|
||||
let name = cwd.map_or_else(|| FileName::Custom("compiler-test".into()), FileName::Real);
|
||||
compiler.parse_program_from_string(program_string, name)?;
|
||||
|
||||
CheckUniqueNodeIds::new().visit_program(&compiler.ast.ast);
|
||||
|
||||
Ok(compiler)
|
||||
}
|
||||
|
||||
@ -211,15 +217,19 @@ pub fn temp_dir() -> PathBuf {
|
||||
pub fn compile_and_process<'a>(parsed: &'a mut Compiler<'a>) -> Result<String, LeoError> {
|
||||
let st = parsed.symbol_table_pass()?;
|
||||
|
||||
CheckUniqueNodeIds::new().visit_program(&parsed.ast.ast);
|
||||
|
||||
let (st, struct_graph, call_graph) = parsed.type_checker_pass(st)?;
|
||||
|
||||
CheckUniqueNodeIds::new().visit_program(&parsed.ast.ast);
|
||||
|
||||
let st = parsed.loop_unrolling_pass(st)?;
|
||||
|
||||
let assigner = parsed.static_single_assignment_pass(&st)?;
|
||||
parsed.static_single_assignment_pass(&st)?;
|
||||
|
||||
let assigner = parsed.flattening_pass(&st, assigner)?;
|
||||
parsed.flattening_pass(&st)?;
|
||||
|
||||
let _ = parsed.function_inlining_pass(&call_graph, assigner)?;
|
||||
parsed.function_inlining_pass(&call_graph)?;
|
||||
|
||||
parsed.dead_code_elimination_pass()?;
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
use leo_ast::NodeBuilder;
|
||||
use leo_errors::{emitter::Handler, Result};
|
||||
use leo_span::symbol::create_session_if_not_set_then;
|
||||
|
||||
@ -45,7 +46,9 @@ fn main() -> Result<(), String> {
|
||||
let input_string = s.source_map.load_file(&opt.input_path).expect("failed to open an input file");
|
||||
|
||||
Handler::with(|handler| {
|
||||
let input = leo_parser::parse_program_inputs(handler, &input_string.src, input_string.start_pos)?;
|
||||
let node_builder = NodeBuilder::default();
|
||||
let input =
|
||||
leo_parser::parse_program_inputs(handler, &node_builder, &input_string.src, input_string.start_pos)?;
|
||||
input.to_json_string()
|
||||
})
|
||||
.map_err(|e| e.to_string())
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
use leo_ast::Ast;
|
||||
use leo_ast::{Ast, NodeBuilder};
|
||||
use leo_errors::emitter::Handler;
|
||||
use leo_span::symbol::create_session_if_not_set_then;
|
||||
|
||||
@ -47,7 +47,8 @@ fn main() -> Result<(), String> {
|
||||
let code = s.source_map.load_file(&opt.input_path).expect("failed to open file");
|
||||
|
||||
Handler::with(|h| {
|
||||
let ast = leo_parser::parse_ast(h, &code.src, code.start_pos)?;
|
||||
let node_builder = NodeBuilder::default();
|
||||
let ast = leo_parser::parse_ast(h, &node_builder, &code.src, code.start_pos)?;
|
||||
let json = Ast::to_json_string(&ast)?;
|
||||
println!("{json}");
|
||||
Ok(json)
|
||||
|
@ -31,20 +31,26 @@ pub(crate) use tokenizer::*;
|
||||
pub mod parser;
|
||||
pub use parser::*;
|
||||
|
||||
use leo_ast::{input::InputData, Ast, ProgramInput};
|
||||
use leo_ast::{input::InputData, Ast, NodeBuilder, ProgramInput};
|
||||
use leo_errors::{emitter::Handler, Result};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
/// Creates a new AST from a given file path and source code text.
|
||||
pub fn parse_ast(handler: &Handler, source: &str, start_pos: BytePos) -> Result<Ast> {
|
||||
Ok(Ast::new(parser::parse(handler, source, start_pos)?))
|
||||
pub fn parse_ast(handler: &Handler, node_builder: &NodeBuilder, source: &str, start_pos: BytePos) -> Result<Ast> {
|
||||
Ok(Ast::new(parser::parse(handler, node_builder, source, start_pos)?))
|
||||
}
|
||||
|
||||
/// Parses program inputs from the input file path
|
||||
pub fn parse_program_inputs(handler: &Handler, input_string: &str, start_pos: BytePos) -> Result<InputData> {
|
||||
let program_input: ProgramInput = parser::parse_input(handler, input_string, start_pos)?.try_into()?;
|
||||
pub fn parse_program_inputs(
|
||||
handler: &Handler,
|
||||
node_builder: &NodeBuilder,
|
||||
input_string: &str,
|
||||
start_pos: BytePos,
|
||||
) -> Result<InputData> {
|
||||
let program_input: ProgramInput =
|
||||
parser::parse_input(handler, node_builder, input_string, start_pos)?.try_into()?;
|
||||
|
||||
Ok(InputData { program_input })
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ use std::{fmt::Display, mem};
|
||||
pub(crate) struct ParserContext<'a> {
|
||||
/// Handler used to side-channel emit errors from the parser.
|
||||
pub(crate) handler: &'a Handler,
|
||||
/// Counter used to generate unique node ids.
|
||||
pub(crate) node_builder: &'a NodeBuilder,
|
||||
/// All un-bumped tokens.
|
||||
tokens: Vec<SpannedToken>,
|
||||
/// The current token, i.e., if `p.tokens = ['3', *, '4']`,
|
||||
@ -46,7 +48,7 @@ const DUMMY_EOF: SpannedToken = SpannedToken { token: Token::Eof, span: Span::du
|
||||
|
||||
impl<'a> ParserContext<'a> {
|
||||
/// Returns a new [`ParserContext`] type given a vector of tokens.
|
||||
pub fn new(handler: &'a Handler, mut tokens: Vec<SpannedToken>) -> Self {
|
||||
pub fn new(handler: &'a Handler, node_builder: &'a NodeBuilder, mut tokens: Vec<SpannedToken>) -> Self {
|
||||
// Strip out comments.
|
||||
tokens.retain(|x| !matches!(x.token, Token::CommentLine(_) | Token::CommentBlock(_)));
|
||||
// For performance we reverse so that we get cheap `.pop()`s.
|
||||
@ -55,6 +57,7 @@ impl<'a> ParserContext<'a> {
|
||||
let token = SpannedToken::dummy();
|
||||
let mut p = Self {
|
||||
handler,
|
||||
node_builder,
|
||||
disallow_struct_construction: false,
|
||||
allow_identifier_underscores: false,
|
||||
prev_token: token.clone(),
|
||||
@ -131,7 +134,7 @@ impl<'a> ParserContext<'a> {
|
||||
/// At the previous token, return and make an identifier with `name`.
|
||||
fn mk_ident_prev(&self, name: Symbol) -> Identifier {
|
||||
let span = self.prev_token.span;
|
||||
Identifier { name, span, id: NodeID::default() }
|
||||
Identifier { name, span, id: self.node_builder.next_id() }
|
||||
}
|
||||
|
||||
/// Eats the next token if its an identifier and returns it.
|
||||
|
@ -15,11 +15,9 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
|
||||
use leo_errors::{ParserError, Result};
|
||||
|
||||
use leo_span::{sym, Symbol};
|
||||
|
||||
use snarkvm_console::{account::Address, network::Testnet3};
|
||||
|
||||
const INT_TYPES: &[Token] = &[
|
||||
@ -75,20 +73,20 @@ impl ParserContext<'_> {
|
||||
condition: Box::new(expr),
|
||||
if_true: Box::new(if_true),
|
||||
if_false: Box::new(if_false),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
/// Constructs a binary expression `left op right`.
|
||||
fn bin_expr(left: Expression, right: Expression, op: BinaryOperation) -> Expression {
|
||||
fn bin_expr(node_builder: &NodeBuilder, left: Expression, right: Expression, op: BinaryOperation) -> Expression {
|
||||
Expression::Binary(BinaryExpression {
|
||||
span: left.span() + right.span(),
|
||||
op,
|
||||
left: Box::new(left),
|
||||
right: Box::new(right),
|
||||
id: NodeID::default(),
|
||||
id: node_builder.next_id(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -101,7 +99,7 @@ impl ParserContext<'_> {
|
||||
) -> Result<Expression> {
|
||||
let mut expr = f(self)?;
|
||||
while let Some(op) = self.eat_bin_op(tokens) {
|
||||
expr = Self::bin_expr(expr, f(self)?, op);
|
||||
expr = Self::bin_expr(self.node_builder, expr, f(self)?, op);
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
@ -156,7 +154,7 @@ impl ParserContext<'_> {
|
||||
let mut expr = self.parse_bitwise_exclusive_or_expression()?;
|
||||
if let Some(op) = self.eat_bin_op(&[Token::Lt, Token::LtEq, Token::Gt, Token::GtEq]) {
|
||||
let right = self.parse_bitwise_exclusive_or_expression()?;
|
||||
expr = Self::bin_expr(expr, right, op);
|
||||
expr = Self::bin_expr(self.node_builder, expr, right, op);
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
@ -169,7 +167,7 @@ impl ParserContext<'_> {
|
||||
let mut expr = self.parse_ordering_expression()?;
|
||||
if let Some(op) = self.eat_bin_op(&[Token::Eq, Token::NotEq]) {
|
||||
let right = self.parse_ordering_expression()?;
|
||||
expr = Self::bin_expr(expr, right, op);
|
||||
expr = Self::bin_expr(self.node_builder, expr, right, op);
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
@ -239,7 +237,12 @@ impl ParserContext<'_> {
|
||||
if self.eat(&Token::As) {
|
||||
let (type_, end_span) = self.parse_primitive_type()?;
|
||||
let span = expr.span() + end_span;
|
||||
expr = Expression::Cast(CastExpression { expression: Box::new(expr), type_, span, id: NodeID::default() });
|
||||
expr = Expression::Cast(CastExpression {
|
||||
expression: Box::new(expr),
|
||||
type_,
|
||||
span,
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(expr)
|
||||
@ -308,7 +311,7 @@ impl ParserContext<'_> {
|
||||
span: op_span + inner.span(),
|
||||
op,
|
||||
receiver: Box::new(inner),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
}
|
||||
|
||||
@ -325,7 +328,12 @@ impl ParserContext<'_> {
|
||||
|
||||
if let (true, Some(op)) = (args.is_empty(), UnaryOperation::from_symbol(method.name)) {
|
||||
// Found an unary operator and the argument list is empty.
|
||||
Ok(Expression::Unary(UnaryExpression { span, op, receiver: Box::new(receiver), id: NodeID::default() }))
|
||||
Ok(Expression::Unary(UnaryExpression {
|
||||
span,
|
||||
op,
|
||||
receiver: Box::new(receiver),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
} else if let (1, Some(op)) = (args.len(), BinaryOperation::from_symbol(method.name)) {
|
||||
// Found a binary operator and the argument list contains a single argument.
|
||||
Ok(Expression::Binary(BinaryExpression {
|
||||
@ -333,7 +341,7 @@ impl ParserContext<'_> {
|
||||
op,
|
||||
left: Box::new(receiver),
|
||||
right: Box::new(args.swap_remove(0)),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
} else {
|
||||
// Attempt to parse the method call as a mapping operation.
|
||||
@ -345,7 +353,7 @@ impl ParserContext<'_> {
|
||||
| (1, Some(CoreFunction::MappingContains)) => {
|
||||
// Found an instance of `<mapping>.get`, `<mapping>.get_or_use`, `<mapping>.set`, `<mapping>.remove`, or `<mapping>.contains`.
|
||||
Ok(Expression::Access(AccessExpression::AssociatedFunction(AssociatedFunction {
|
||||
ty: Type::Identifier(Identifier::new(sym::Mapping)),
|
||||
ty: Type::Identifier(Identifier::new(sym::Mapping, self.node_builder.next_id())),
|
||||
name: method,
|
||||
arguments: {
|
||||
let mut arguments = vec![receiver];
|
||||
@ -353,13 +361,13 @@ impl ParserContext<'_> {
|
||||
arguments
|
||||
},
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})))
|
||||
}
|
||||
_ => {
|
||||
// Either an invalid unary/binary operator, or more arguments given.
|
||||
self.emit_err(ParserError::invalid_method_call(receiver, method, args.len(), span));
|
||||
Ok(Expression::Err(ErrExpression { span, id: NodeID::default() }))
|
||||
Ok(Expression::Err(ErrExpression { span, id: self.node_builder.next_id() }))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -389,7 +397,7 @@ impl ParserContext<'_> {
|
||||
ty: type_,
|
||||
name: member_name,
|
||||
arguments: args,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})
|
||||
} else {
|
||||
// Return the struct constant.
|
||||
@ -397,7 +405,7 @@ impl ParserContext<'_> {
|
||||
span: module_name.span() + member_name.span(),
|
||||
ty: type_,
|
||||
name: member_name,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})
|
||||
}))
|
||||
}
|
||||
@ -425,7 +433,7 @@ impl ParserContext<'_> {
|
||||
tuple: Box::new(expr),
|
||||
index,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
} else if self.eat(&Token::Leo) {
|
||||
// Eat an external function call.
|
||||
@ -441,7 +449,7 @@ impl ParserContext<'_> {
|
||||
function: Box::new(Expression::Identifier(name)),
|
||||
external: Some(Box::new(expr)),
|
||||
arguments,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
} else {
|
||||
// Parse identifier name.
|
||||
@ -456,7 +464,7 @@ impl ParserContext<'_> {
|
||||
span: expr.span() + name.span(),
|
||||
inner: Box::new(expr),
|
||||
name,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -475,7 +483,7 @@ impl ParserContext<'_> {
|
||||
function: Box::new(expr),
|
||||
external: None,
|
||||
arguments,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
}
|
||||
// Check if next token is a dot to see if we are calling recursive method.
|
||||
@ -497,7 +505,7 @@ impl ParserContext<'_> {
|
||||
|
||||
match elements.len() {
|
||||
// If the tuple expression is empty, return a `UnitExpression`.
|
||||
0 => Ok(Expression::Unit(UnitExpression { span, id: NodeID::default() })),
|
||||
0 => Ok(Expression::Unit(UnitExpression { span, id: self.node_builder.next_id() })),
|
||||
1 => match trailing {
|
||||
// If there is one element in the tuple but no trailing comma, e.g `(foo)`, return the element.
|
||||
false => Ok(elements.swap_remove(0)),
|
||||
@ -506,7 +514,7 @@ impl ParserContext<'_> {
|
||||
},
|
||||
// Otherwise, return a tuple expression.
|
||||
// Note: This is the only place where `TupleExpression` is constructed in the parser.
|
||||
_ => Ok(Expression::Tuple(TupleExpression { elements, span, id: NodeID::default() })),
|
||||
_ => Ok(Expression::Tuple(TupleExpression { elements, span, id: self.node_builder.next_id() })),
|
||||
}
|
||||
}
|
||||
|
||||
@ -554,7 +562,8 @@ impl ParserContext<'_> {
|
||||
let end_span = check_ahead(dist, &Token::Group)?;
|
||||
dist += 1; // Standing at `)` so advance one for 'group'.
|
||||
|
||||
let gt = GroupTuple { span: start_span + &end_span, x: first_gc, y: second_gc, id: NodeID::default() };
|
||||
let gt =
|
||||
GroupTuple { span: start_span + &end_span, x: first_gc, y: second_gc, id: self.node_builder.next_id() };
|
||||
|
||||
// Eat everything so that this isn't just peeking.
|
||||
for _ in 0..dist {
|
||||
@ -572,7 +581,10 @@ impl ParserContext<'_> {
|
||||
let identifier = if self.allow_identifier_underscores && self.eat(&Token::Underscore) {
|
||||
// Allow `_nonce` for struct records.
|
||||
let identifier_without_underscore = self.expect_identifier()?;
|
||||
Identifier::new(Symbol::intern(&format!("_{}", identifier_without_underscore.name)))
|
||||
Identifier::new(
|
||||
Symbol::intern(&format!("_{}", identifier_without_underscore.name)),
|
||||
self.node_builder.next_id(),
|
||||
)
|
||||
} else {
|
||||
self.expect_identifier()?
|
||||
};
|
||||
@ -586,7 +598,7 @@ impl ParserContext<'_> {
|
||||
(None, identifier.span)
|
||||
};
|
||||
|
||||
Ok(StructVariableInitializer { identifier, expression, id: NodeID::default(), span })
|
||||
Ok(StructVariableInitializer { identifier, expression, id: self.node_builder.next_id(), span })
|
||||
}
|
||||
|
||||
/// Returns an [`Expression`] AST node if the next tokens represent a
|
||||
@ -600,7 +612,7 @@ impl ParserContext<'_> {
|
||||
span: identifier.span + end,
|
||||
name: identifier,
|
||||
members,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -628,7 +640,7 @@ impl ParserContext<'_> {
|
||||
// Literal followed by `field`, e.g., `42field`.
|
||||
Some(Token::Field) => {
|
||||
assert_no_whitespace("field")?;
|
||||
Expression::Literal(Literal::Field(value, full_span, NodeID::default()))
|
||||
Expression::Literal(Literal::Field(value, full_span, self.node_builder.next_id()))
|
||||
}
|
||||
// Literal followed by `group`, e.g., `42group`.
|
||||
Some(Token::Group) => {
|
||||
@ -636,34 +648,36 @@ impl ParserContext<'_> {
|
||||
Expression::Literal(Literal::Group(Box::new(GroupLiteral::Single(
|
||||
value,
|
||||
full_span,
|
||||
NodeID::default(),
|
||||
self.node_builder.next_id(),
|
||||
))))
|
||||
}
|
||||
// Literal followed by `scalar` e.g., `42scalar`.
|
||||
Some(Token::Scalar) => {
|
||||
assert_no_whitespace("scalar")?;
|
||||
Expression::Literal(Literal::Scalar(value, full_span, NodeID::default()))
|
||||
Expression::Literal(Literal::Scalar(value, full_span, self.node_builder.next_id()))
|
||||
}
|
||||
// Literal followed by other type suffix, e.g., `42u8`.
|
||||
Some(suffix) => {
|
||||
assert_no_whitespace(&suffix.to_string())?;
|
||||
let int_ty = Self::token_to_int_type(suffix).expect("unknown int type token");
|
||||
Expression::Literal(Literal::Integer(int_ty, value, full_span, NodeID::default()))
|
||||
Expression::Literal(Literal::Integer(int_ty, value, full_span, self.node_builder.next_id()))
|
||||
}
|
||||
None => return Err(ParserError::implicit_values_not_allowed(value, span).into()),
|
||||
}
|
||||
}
|
||||
Token::True => Expression::Literal(Literal::Boolean(true, span, NodeID::default())),
|
||||
Token::False => Expression::Literal(Literal::Boolean(false, span, NodeID::default())),
|
||||
Token::True => Expression::Literal(Literal::Boolean(true, span, self.node_builder.next_id())),
|
||||
Token::False => Expression::Literal(Literal::Boolean(false, span, self.node_builder.next_id())),
|
||||
Token::AddressLit(address_string) => {
|
||||
if address_string.parse::<Address<Testnet3>>().is_err() {
|
||||
self.emit_err(ParserError::invalid_address_lit(&address_string, span));
|
||||
}
|
||||
Expression::Literal(Literal::Address(address_string, span, NodeID::default()))
|
||||
Expression::Literal(Literal::Address(address_string, span, self.node_builder.next_id()))
|
||||
}
|
||||
Token::StaticString(value) => {
|
||||
Expression::Literal(Literal::String(value, span, self.node_builder.next_id()))
|
||||
}
|
||||
Token::StaticString(value) => Expression::Literal(Literal::String(value, span, NodeID::default())),
|
||||
Token::Identifier(name) => {
|
||||
let ident = Identifier { name, span, id: NodeID::default() };
|
||||
let ident = Identifier { name, span, id: self.node_builder.next_id() };
|
||||
if !self.disallow_struct_construction && self.check(&Token::LeftCurly) {
|
||||
// Parse struct and records inits as struct expressions.
|
||||
// Enforce struct or record type later at type checking.
|
||||
@ -673,12 +687,16 @@ impl ParserContext<'_> {
|
||||
}
|
||||
}
|
||||
Token::SelfLower => {
|
||||
Expression::Identifier(Identifier { name: sym::SelfLower, span, id: NodeID::default() })
|
||||
Expression::Identifier(Identifier { name: sym::SelfLower, span, id: self.node_builder.next_id() })
|
||||
}
|
||||
Token::Block => Expression::Identifier(Identifier { name: sym::block, span, id: NodeID::default() }),
|
||||
t if crate::type_::TYPE_TOKENS.contains(&t) => {
|
||||
Expression::Identifier(Identifier { name: t.keyword_to_symbol().unwrap(), span, id: NodeID::default() })
|
||||
Token::Block => {
|
||||
Expression::Identifier(Identifier { name: sym::block, span, id: self.node_builder.next_id() })
|
||||
}
|
||||
t if crate::type_::TYPE_TOKENS.contains(&t) => Expression::Identifier(Identifier {
|
||||
name: t.keyword_to_symbol().unwrap(),
|
||||
span,
|
||||
id: self.node_builder.next_id(),
|
||||
}),
|
||||
token => {
|
||||
return Err(ParserError::unexpected_str(token, "expression", span).into());
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ impl ParserContext<'_> {
|
||||
let prg_sf = with_session_globals(|s| s.source_map.new_source(&program_string, name));
|
||||
|
||||
// Use the parser to construct the imported abstract syntax tree (ast).
|
||||
let program_ast = parse_ast(self.handler, &prg_sf.src, prg_sf.start_pos)?;
|
||||
let program_ast = parse_ast(self.handler, self.node_builder, &prg_sf.src, prg_sf.start_pos)?;
|
||||
|
||||
Ok((import_name.name, (program_ast.into_repr(), start + end)))
|
||||
}
|
||||
@ -223,7 +223,7 @@ impl ParserContext<'_> {
|
||||
|
||||
let (identifier, type_, span) = self.parse_typed_ident()?;
|
||||
|
||||
Ok(Member { mode, identifier, type_, span, id: NodeID::default() })
|
||||
Ok(Member { mode, identifier, type_, span, id: self.node_builder.next_id() })
|
||||
}
|
||||
|
||||
/// Parses a struct or record definition, e.g., `struct Foo { ... }` or `record Foo { ... }`.
|
||||
@ -240,7 +240,7 @@ impl ParserContext<'_> {
|
||||
members,
|
||||
is_record,
|
||||
span: start + end,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -253,7 +253,13 @@ impl ParserContext<'_> {
|
||||
self.expect(&Token::BigArrow)?;
|
||||
let (value_type, _) = self.parse_type()?;
|
||||
let end = self.expect(&Token::Semicolon)?;
|
||||
Ok((identifier.name, Mapping { identifier, key_type, value_type, span: start + end, id: NodeID::default() }))
|
||||
Ok((identifier.name, Mapping {
|
||||
identifier,
|
||||
key_type,
|
||||
value_type,
|
||||
span: start + end,
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
}
|
||||
|
||||
// TODO: Return a span associated with the mode.
|
||||
@ -309,7 +315,7 @@ impl ParserContext<'_> {
|
||||
program_name: external,
|
||||
record,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
} else {
|
||||
let type_ = self.parse_type()?.0;
|
||||
@ -319,7 +325,7 @@ impl ParserContext<'_> {
|
||||
mode,
|
||||
type_,
|
||||
span: name.span,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -329,7 +335,7 @@ impl ParserContext<'_> {
|
||||
// TODO: Could this span be made more accurate?
|
||||
let mode = self.parse_mode()?;
|
||||
let (type_, span) = self.parse_type()?;
|
||||
Ok(FunctionOutput { mode, type_, span, id: NodeID::default() })
|
||||
Ok(FunctionOutput { mode, type_, span, id: self.node_builder.next_id() })
|
||||
}
|
||||
|
||||
/// Returns a [`Output`] AST node if the next tokens represent a function output.
|
||||
@ -352,11 +358,11 @@ impl ParserContext<'_> {
|
||||
span = span + self.prev_token.span;
|
||||
|
||||
Ok(Output::External(External {
|
||||
identifier: Identifier::new(Symbol::intern("dummy")),
|
||||
identifier: Identifier::new(Symbol::intern("dummy"), self.node_builder.next_id()),
|
||||
program_name: external,
|
||||
record,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
} else {
|
||||
Ok(Output::Internal(self.parse_function_output()?))
|
||||
@ -373,7 +379,7 @@ impl ParserContext<'_> {
|
||||
let start = self.expect(&Token::At)?;
|
||||
let identifier = match self.token.token {
|
||||
Token::Program => {
|
||||
Identifier { name: sym::program, span: self.expect(&Token::Program)?, id: NodeID::default() }
|
||||
Identifier { name: sym::program, span: self.expect(&Token::Program)?, id: self.node_builder.next_id() }
|
||||
}
|
||||
_ => self.expect_identifier()?,
|
||||
};
|
||||
@ -383,7 +389,7 @@ impl ParserContext<'_> {
|
||||
// Check that there is no whitespace in between the `@` symbol and identifier.
|
||||
match identifier.span.hi.0 - start.lo.0 > 1 + identifier.name.to_string().len() as u32 {
|
||||
true => Err(ParserError::space_in_annotation(span).into()),
|
||||
false => Ok(Annotation { identifier, span, id: NodeID::default() }),
|
||||
false => Ok(Annotation { identifier, span, id: self.node_builder.next_id() }),
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,12 +462,25 @@ impl ParserContext<'_> {
|
||||
let block = self.parse_block()?;
|
||||
let span = start + block.span;
|
||||
|
||||
Some(Finalize::new(identifier, input, output, block, span))
|
||||
Some(Finalize::new(identifier, input, output, block, span, self.node_builder.next_id()))
|
||||
}
|
||||
};
|
||||
|
||||
let span = start + block.span;
|
||||
Ok((name.name, Function::new(annotations, variant, name, inputs, output, block, finalize, span)))
|
||||
Ok((
|
||||
name.name,
|
||||
Function::new(
|
||||
annotations,
|
||||
variant,
|
||||
name,
|
||||
inputs,
|
||||
output,
|
||||
block,
|
||||
finalize,
|
||||
span,
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,15 +39,20 @@ mod statement;
|
||||
pub(super) mod type_;
|
||||
|
||||
/// Creates a new program from a given file path and source code text.
|
||||
pub fn parse(handler: &Handler, source: &str, start_pos: BytePos) -> Result<Program> {
|
||||
let mut tokens = ParserContext::new(handler, crate::tokenize(source, start_pos)?);
|
||||
pub fn parse(handler: &Handler, node_builder: &NodeBuilder, source: &str, start_pos: BytePos) -> Result<Program> {
|
||||
let mut tokens = ParserContext::new(handler, node_builder, crate::tokenize(source, start_pos)?);
|
||||
|
||||
tokens.parse_program()
|
||||
}
|
||||
|
||||
/// Parses an input file at the given file `path` and `source` code text.
|
||||
pub fn parse_input(handler: &Handler, source: &str, start_pos: BytePos) -> Result<InputAst> {
|
||||
let mut tokens = ParserContext::new(handler, crate::tokenize(source, start_pos)?);
|
||||
pub fn parse_input(
|
||||
handler: &Handler,
|
||||
node_builder: &NodeBuilder,
|
||||
source: &str,
|
||||
start_pos: BytePos,
|
||||
) -> Result<InputAst> {
|
||||
let mut tokens = ParserContext::new(handler, node_builder, crate::tokenize(source, start_pos)?);
|
||||
|
||||
tokens.parse_input_file()
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ impl ParserContext<'_> {
|
||||
self.expect(&Token::Semicolon)?;
|
||||
|
||||
// Return the assertion statement.
|
||||
Ok(Statement::Assert(AssertStatement { variant, span, id: NodeID::default() }))
|
||||
Ok(Statement::Assert(AssertStatement { variant, span, id: self.node_builder.next_id() }))
|
||||
}
|
||||
|
||||
/// Returns a [`AssignStatement`] AST node if the next tokens represent a assign, otherwise expects an expression statement.
|
||||
@ -115,20 +115,24 @@ impl ParserContext<'_> {
|
||||
// Construct the span for the statement.
|
||||
let span = place.span() + value.span();
|
||||
|
||||
// Construct a copy of the lhs with a unique id.
|
||||
let mut left = place.clone();
|
||||
left.set_id(self.node_builder.next_id());
|
||||
|
||||
// Simplify complex assignments into simple assignments.
|
||||
// For example, `x += 1` becomes `x = x + 1`, while simple assignments like `x = y` remain unchanged.
|
||||
let value = match operation {
|
||||
None => value,
|
||||
Some(op) => Expression::Binary(BinaryExpression {
|
||||
left: Box::new(place.clone()),
|
||||
left: Box::new(left),
|
||||
right: Box::new(value),
|
||||
op,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}),
|
||||
};
|
||||
|
||||
Ok(Statement::Assign(Box::new(AssignStatement { span, place, value, id: NodeID::default() })))
|
||||
Ok(Statement::Assign(Box::new(AssignStatement { span, place, value, id: self.node_builder.next_id() })))
|
||||
} else {
|
||||
// Check for `increment` and `decrement` statements. If found, emit a deprecation warning.
|
||||
if let Expression::Call(call_expression) = &place {
|
||||
@ -156,7 +160,7 @@ impl ParserContext<'_> {
|
||||
Ok(Statement::Expression(ExpressionStatement {
|
||||
span: place.span() + end,
|
||||
expression: place,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -166,7 +170,7 @@ impl ParserContext<'_> {
|
||||
self.parse_list(Delimiter::Brace, None, |p| p.parse_statement().map(Some)).map(|(statements, _, span)| Block {
|
||||
statements,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -177,7 +181,7 @@ impl ParserContext<'_> {
|
||||
let expression = match self.token.token {
|
||||
// If the next token is a semicolon, implicitly return a unit expression, `()`.
|
||||
Token::Semicolon | Token::Then => {
|
||||
Expression::Unit(UnitExpression { span: self.token.span, id: NodeID::default() })
|
||||
Expression::Unit(UnitExpression { span: self.token.span, id: self.node_builder.next_id() })
|
||||
}
|
||||
// Otherwise, attempt to parse an expression.
|
||||
_ => self.parse_expression()?,
|
||||
@ -200,7 +204,7 @@ impl ParserContext<'_> {
|
||||
};
|
||||
let end = self.expect(&Token::Semicolon)?;
|
||||
let span = start + end;
|
||||
Ok(ReturnStatement { span, expression, finalize_arguments: finalize_args, id: NodeID::default() })
|
||||
Ok(ReturnStatement { span, expression, finalize_arguments: finalize_args, id: self.node_builder.next_id() })
|
||||
}
|
||||
|
||||
/// Returns a [`ConditionalStatement`] AST node if the next tokens represent a conditional statement.
|
||||
@ -225,7 +229,7 @@ impl ParserContext<'_> {
|
||||
condition: expr,
|
||||
then: body,
|
||||
otherwise: next,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -256,7 +260,7 @@ impl ParserContext<'_> {
|
||||
stop_value: Default::default(),
|
||||
inclusive: false,
|
||||
block,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -300,14 +304,14 @@ impl ParserContext<'_> {
|
||||
Default::default(),
|
||||
ConsoleFunction::Assert(Expression::Err(ErrExpression {
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})),
|
||||
)
|
||||
}
|
||||
};
|
||||
self.expect(&Token::Semicolon)?;
|
||||
|
||||
Ok(ConsoleStatement { span: keyword + span, function, id: NodeID::default() })
|
||||
Ok(ConsoleStatement { span: keyword + span, function, id: self.node_builder.next_id() })
|
||||
}
|
||||
|
||||
/// Returns a [`DefinitionStatement`] AST node if the next tokens represent a definition statement.
|
||||
@ -335,7 +339,7 @@ impl ParserContext<'_> {
|
||||
place,
|
||||
type_,
|
||||
value,
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{tokenizer, ParserContext, SpannedToken};
|
||||
|
||||
use leo_ast::Statement;
|
||||
use leo_ast::{NodeBuilder, NodeID, Statement};
|
||||
use leo_errors::{emitter::Handler, LeoError};
|
||||
use leo_span::{
|
||||
source_map::FileName,
|
||||
@ -67,7 +67,8 @@ fn with_handler<T>(
|
||||
logic: impl FnOnce(&mut ParserContext<'_>) -> Result<T, LeoError>,
|
||||
) -> Result<T, String> {
|
||||
let (handler, buf) = Handler::new_with_buf();
|
||||
let mut tokens = ParserContext::new(&handler, tokens);
|
||||
let node_builder = NodeBuilder::default();
|
||||
let mut tokens = ParserContext::new(&handler, &node_builder, tokens);
|
||||
let parsed = handler
|
||||
.extend_if_error(logic(&mut tokens))
|
||||
.map_err(|_| buf.extract_errs().to_string() + &buf.extract_warnings().to_string())?;
|
||||
@ -117,7 +118,7 @@ impl Namespace for ParseStatementNamespace {
|
||||
create_session_if_not_set_then(|s| {
|
||||
let tokenizer = tokenize(test, s)?;
|
||||
if all_are_comments(&tokenizer) {
|
||||
return Ok(yaml_or_fail(Statement::dummy(Span::default())));
|
||||
return Ok(yaml_or_fail(Statement::dummy(Span::default(), NodeID::default())));
|
||||
}
|
||||
with_handler(tokenizer, |p| p.parse_statement()).map(yaml_or_fail)
|
||||
})
|
||||
|
@ -16,41 +16,53 @@
|
||||
|
||||
use leo_ast::{AssignStatement, Expression, Identifier, NodeID, Statement};
|
||||
use leo_span::Symbol;
|
||||
use std::fmt::Display;
|
||||
|
||||
use std::{cell::RefCell, fmt::Display};
|
||||
|
||||
/// A struct used to create assignment statements.
|
||||
#[derive(Default)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Assigner {
|
||||
/// A strictly increasing counter, used to ensure that new variable names are unique.
|
||||
pub(crate) counter: usize,
|
||||
/// The inner counter.
|
||||
/// `RefCell` is used here to avoid `&mut` all over the compiler.
|
||||
inner: RefCell<AssignerInner>,
|
||||
}
|
||||
|
||||
impl Assigner {
|
||||
/// Return a new unique `Symbol` from a `&str`.
|
||||
pub(crate) fn unique_symbol(&mut self, arg: impl Display, separator: impl Display) -> Symbol {
|
||||
pub fn unique_symbol(&self, arg: impl Display, separator: impl Display) -> Symbol {
|
||||
self.inner.borrow_mut().unique_symbol(arg, separator)
|
||||
}
|
||||
|
||||
/// Constructs the assignment statement `place = expr;`.
|
||||
/// This function should be the only place where `AssignStatement`s are constructed.
|
||||
pub fn simple_assign_statement(&self, identifier: Identifier, value: Expression, id: NodeID) -> Statement {
|
||||
self.inner.borrow_mut().simple_assign_statement(identifier, value, id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains the actual data for `Assigner`.
|
||||
/// Modeled this way to afford an API using interior mutability.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct AssignerInner {
|
||||
/// A strictly increasing counter, used to ensure that new variable names are unique.
|
||||
pub(crate) counter: usize,
|
||||
}
|
||||
|
||||
impl AssignerInner {
|
||||
/// Return a new unique `Symbol` from a `&str`.
|
||||
fn unique_symbol(&mut self, arg: impl Display, separator: impl Display) -> Symbol {
|
||||
self.counter += 1;
|
||||
Symbol::intern(&format!("{}{}{}", arg, separator, self.counter - 1))
|
||||
}
|
||||
|
||||
/// Constructs the assignment statement `place = expr;`.
|
||||
/// This function should be the only place where `AssignStatement`s are constructed.
|
||||
pub(crate) fn simple_assign_statement(&mut self, identifier: Identifier, value: Expression) -> Statement {
|
||||
fn simple_assign_statement(&mut self, identifier: Identifier, value: Expression, id: NodeID) -> Statement {
|
||||
Statement::Assign(Box::new(AssignStatement {
|
||||
place: Expression::Identifier(identifier),
|
||||
value,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Constructs a simple assign statement for `expr` with a unique name.
|
||||
/// For example, `expr` is transformed into `$var$0 = expr;`.
|
||||
pub(crate) fn unique_simple_assign_statement(&mut self, expr: Expression) -> (Identifier, Statement) {
|
||||
// Create a new variable for the expression.
|
||||
let name = self.unique_symbol("$var", "$");
|
||||
|
||||
let place = Identifier { name, span: Default::default(), id: NodeID::default() };
|
||||
|
||||
(place, self.simple_assign_statement(place, expr))
|
||||
}
|
||||
}
|
||||
|
@ -14,21 +14,23 @@
|
||||
// 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_ast::NodeBuilder;
|
||||
use leo_span::Symbol;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DeadCodeEliminator {
|
||||
pub struct DeadCodeEliminator<'a> {
|
||||
/// A counter to generate unique node IDs.
|
||||
pub(crate) node_builder: &'a NodeBuilder,
|
||||
/// The set of used variables in the current function body.
|
||||
pub(crate) used_variables: IndexSet<Symbol>,
|
||||
/// Whether or not the variables are necessary.
|
||||
pub(crate) is_necessary: bool,
|
||||
}
|
||||
|
||||
impl DeadCodeEliminator {
|
||||
impl<'a> DeadCodeEliminator<'a> {
|
||||
/// Initializes a new `DeadCodeEliminator`.
|
||||
pub fn new() -> Self {
|
||||
Self { used_variables: Default::default(), is_necessary: false }
|
||||
pub fn new(node_builder: &'a NodeBuilder) -> Self {
|
||||
Self { node_builder, used_variables: Default::default(), is_necessary: false }
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ use leo_ast::{
|
||||
ExpressionReconstructor,
|
||||
Identifier,
|
||||
MemberAccess,
|
||||
NodeID,
|
||||
StructExpression,
|
||||
StructVariableInitializer,
|
||||
TupleAccess,
|
||||
@ -31,7 +30,7 @@ use leo_ast::{
|
||||
};
|
||||
use leo_span::sym;
|
||||
|
||||
impl ExpressionReconstructor for DeadCodeEliminator {
|
||||
impl ExpressionReconstructor for DeadCodeEliminator<'_> {
|
||||
type AdditionalOutput = ();
|
||||
|
||||
/// Reconstructs the components of an access expression.
|
||||
@ -58,7 +57,7 @@ impl ExpressionReconstructor for DeadCodeEliminator {
|
||||
.map(|arg| self.reconstruct_expression(arg).0)
|
||||
.collect(),
|
||||
span: function.span,
|
||||
id: NodeID::default(),
|
||||
id: function.id,
|
||||
});
|
||||
// Unset `self.is_necessary`.
|
||||
self.is_necessary = false;
|
||||
@ -68,13 +67,13 @@ impl ExpressionReconstructor for DeadCodeEliminator {
|
||||
inner: Box::new(self.reconstruct_expression(*member.inner).0),
|
||||
name: member.name,
|
||||
span: member.span,
|
||||
id: NodeID::default(),
|
||||
id: member.id,
|
||||
}),
|
||||
AccessExpression::Tuple(tuple) => AccessExpression::Tuple(TupleAccess {
|
||||
tuple: Box::new(self.reconstruct_expression(*tuple.tuple).0),
|
||||
index: tuple.index,
|
||||
span: tuple.span,
|
||||
id: NodeID::default(),
|
||||
id: tuple.id,
|
||||
}),
|
||||
AccessExpression::AssociatedConstant(constant) => AccessExpression::AssociatedConstant(constant),
|
||||
}),
|
||||
@ -99,11 +98,11 @@ impl ExpressionReconstructor for DeadCodeEliminator {
|
||||
None => unreachable!("Static single assignment ensures that the expression always exists."),
|
||||
},
|
||||
span: member.span,
|
||||
id: NodeID::default(),
|
||||
id: member.id,
|
||||
})
|
||||
.collect(),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
|
@ -16,9 +16,9 @@
|
||||
|
||||
use crate::DeadCodeEliminator;
|
||||
|
||||
use leo_ast::{Finalize, Function, NodeID, ProgramReconstructor, StatementReconstructor};
|
||||
use leo_ast::{Finalize, Function, ProgramReconstructor, StatementReconstructor};
|
||||
|
||||
impl ProgramReconstructor for DeadCodeEliminator {
|
||||
impl ProgramReconstructor for DeadCodeEliminator<'_> {
|
||||
fn reconstruct_function(&mut self, input: Function) -> Function {
|
||||
// Reset the state of the dead code eliminator.
|
||||
self.used_variables.clear();
|
||||
@ -43,7 +43,7 @@ impl ProgramReconstructor for DeadCodeEliminator {
|
||||
output_type: finalize.output_type,
|
||||
block,
|
||||
span: finalize.span,
|
||||
id: NodeID::default(),
|
||||
id: finalize.id,
|
||||
}
|
||||
});
|
||||
|
||||
@ -57,7 +57,7 @@ impl ProgramReconstructor for DeadCodeEliminator {
|
||||
block,
|
||||
finalize,
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,13 +29,12 @@ use leo_ast::{
|
||||
ExpressionReconstructor,
|
||||
ExpressionStatement,
|
||||
IterationStatement,
|
||||
NodeID,
|
||||
ReturnStatement,
|
||||
Statement,
|
||||
StatementReconstructor,
|
||||
};
|
||||
|
||||
impl StatementReconstructor for DeadCodeEliminator {
|
||||
impl StatementReconstructor for DeadCodeEliminator<'_> {
|
||||
fn reconstruct_assert(&mut self, input: AssertStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
// Set the `is_necessary` flag.
|
||||
self.is_necessary = true;
|
||||
@ -52,7 +51,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
}
|
||||
},
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
});
|
||||
|
||||
// Unset the `is_necessary` flag.
|
||||
@ -92,7 +91,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
place: input.place,
|
||||
value: self.reconstruct_expression(input.value).0,
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
|
||||
// Unset the `is_necessary` flag.
|
||||
@ -101,7 +100,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
(statement, Default::default())
|
||||
}
|
||||
// Otherwise, we can eliminate it.
|
||||
false => (Statement::dummy(Default::default()), Default::default()),
|
||||
false => (Statement::dummy(Default::default(), self.node_builder.next_id()), Default::default()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +113,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
// Reverse the direction of `statements`.
|
||||
statements.reverse();
|
||||
|
||||
(Block { statements, span: block.span, id: NodeID::default() }, Default::default())
|
||||
(Block { statements, span: block.span, id: block.id }, Default::default())
|
||||
}
|
||||
|
||||
/// Flattening removes conditional statements from the program.
|
||||
@ -145,7 +144,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
let statement = Statement::Expression(ExpressionStatement {
|
||||
expression: self.reconstruct_call(expression).0,
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
});
|
||||
|
||||
// Unset the `is_necessary` flag.
|
||||
@ -161,14 +160,14 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
.reconstruct_access(AccessExpression::AssociatedFunction(associated_function))
|
||||
.0,
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
// Any other expression is dead code, since they do not have side effects.
|
||||
// Note: array access expressions will have side effects and need to be handled here.
|
||||
_ => (Statement::dummy(Default::default()), Default::default()),
|
||||
_ => (Statement::dummy(Default::default(), self.node_builder.next_id()), Default::default()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,7 +187,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
arguments.into_iter().map(|argument| self.reconstruct_expression(argument).0).collect()
|
||||
}),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
});
|
||||
|
||||
// Unset the `is_necessary` flag.
|
||||
|
@ -60,15 +60,15 @@ pub use dead_code_eliminator::*;
|
||||
|
||||
use crate::Pass;
|
||||
|
||||
use leo_ast::{Ast, ProgramReconstructor};
|
||||
use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
|
||||
use leo_errors::Result;
|
||||
|
||||
impl Pass for DeadCodeEliminator {
|
||||
type Input = Ast;
|
||||
impl<'a> Pass for DeadCodeEliminator<'a> {
|
||||
type Input = (Ast, &'a NodeBuilder);
|
||||
type Output = Result<Ast>;
|
||||
|
||||
fn do_pass(ast: Self::Input) -> Self::Output {
|
||||
let mut reconstructor = DeadCodeEliminator::new();
|
||||
fn do_pass((ast, node_builder): Self::Input) -> Self::Output {
|
||||
let mut reconstructor = DeadCodeEliminator::new(node_builder);
|
||||
let program = reconstructor.reconstruct_program(ast.into_repr());
|
||||
|
||||
Ok(Ast::new(program))
|
||||
|
@ -24,7 +24,6 @@ use leo_ast::{
|
||||
ExpressionReconstructor,
|
||||
Member,
|
||||
MemberAccess,
|
||||
NodeID,
|
||||
Statement,
|
||||
StructExpression,
|
||||
StructVariableInitializer,
|
||||
@ -52,14 +51,14 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
.map(|arg| self.reconstruct_expression(arg).0)
|
||||
.collect(),
|
||||
span: function.span,
|
||||
id: NodeID::default(),
|
||||
id: function.id,
|
||||
}))
|
||||
}
|
||||
AccessExpression::Member(member) => Expression::Access(AccessExpression::Member(MemberAccess {
|
||||
inner: Box::new(self.reconstruct_expression(*member.inner).0),
|
||||
name: member.name,
|
||||
span: member.span,
|
||||
id: NodeID::default(),
|
||||
id: member.id,
|
||||
})),
|
||||
AccessExpression::Tuple(tuple) => {
|
||||
// Reconstruct the tuple expression.
|
||||
@ -99,14 +98,11 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
identifier: member.identifier,
|
||||
expression: Some(expr),
|
||||
span: member.span,
|
||||
id: NodeID::default(),
|
||||
id: member.id,
|
||||
});
|
||||
}
|
||||
|
||||
(
|
||||
Expression::Struct(StructExpression { name: input.name, members, span: input.span, id: NodeID::default() }),
|
||||
statements,
|
||||
)
|
||||
(Expression::Struct(StructExpression { name: input.name, members, span: input.span, id: input.id }), statements)
|
||||
}
|
||||
|
||||
/// Reconstructs ternary expressions over tuples and structs, accumulating any statements that are generated.
|
||||
@ -150,7 +146,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
if_true: Box::new(if_true),
|
||||
if_false: Box::new(if_false),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
});
|
||||
|
||||
// Accumulate any statements generated.
|
||||
@ -165,7 +161,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
})
|
||||
.collect(),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
(tuple, statements)
|
||||
}
|
||||
@ -200,16 +196,16 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
inner: Box::new(Expression::Access(AccessExpression::Member(first.clone()))),
|
||||
name: *identifier,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))),
|
||||
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||
inner: Box::new(Expression::Access(AccessExpression::Member(second.clone()))),
|
||||
name: *identifier,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
|
||||
// Accumulate any statements generated.
|
||||
@ -223,7 +219,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
identifier: *identifier,
|
||||
expression: Some(Expression::Identifier(result)),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@ -232,7 +228,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
name: first_member_struct.identifier,
|
||||
members,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
|
||||
// Accumulate any statements generated.
|
||||
@ -265,7 +261,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
if_true: Box::new(if_true),
|
||||
if_false: Box::new(if_false),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
|
||||
// Accumulate the new assignment statement.
|
||||
@ -296,16 +292,16 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
inner: Box::new(Expression::Identifier(first)),
|
||||
name: *identifier,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))),
|
||||
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
|
||||
inner: Box::new(Expression::Identifier(second)),
|
||||
name: *identifier,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
|
||||
// Accumulate any statements generated.
|
||||
@ -319,7 +315,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
identifier: *identifier,
|
||||
expression: Some(Expression::Identifier(result)),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@ -328,7 +324,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
name: first_struct.identifier,
|
||||
members,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
|
||||
// Accumulate any statements generated.
|
||||
@ -358,7 +354,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
if_true: Box::new(Expression::Tuple(first_tuple.clone())),
|
||||
if_false: Box::new(Expression::Tuple(second_tuple.clone())),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
})
|
||||
}
|
||||
// Otherwise, create a new intermediate assignment for the ternary expression are return the assigned variable.
|
||||
@ -378,7 +374,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
if_true: Box::new(if_true),
|
||||
if_false: Box::new(if_false),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
|
||||
// Accumulate the new assignment statement.
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::Flattener;
|
||||
|
||||
use leo_ast::{Finalize, Function, NodeID, ProgramReconstructor, StatementReconstructor, Type};
|
||||
use leo_ast::{Finalize, Function, ProgramReconstructor, StatementReconstructor, Type};
|
||||
|
||||
impl ProgramReconstructor for Flattener<'_> {
|
||||
/// Flattens a function's body and finalize block, if it exists.
|
||||
@ -47,7 +47,7 @@ impl ProgramReconstructor for Flattener<'_> {
|
||||
output_type: finalize.output_type,
|
||||
block,
|
||||
span: finalize.span,
|
||||
id: NodeID::default(),
|
||||
id: finalize.id,
|
||||
}
|
||||
});
|
||||
|
||||
@ -78,7 +78,7 @@ impl ProgramReconstructor for Flattener<'_> {
|
||||
block,
|
||||
finalize,
|
||||
span: function.span,
|
||||
id: NodeID::default(),
|
||||
id: function.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ use leo_ast::{
|
||||
Identifier,
|
||||
IterationStatement,
|
||||
Node,
|
||||
NodeID,
|
||||
ReturnStatement,
|
||||
Statement,
|
||||
StatementReconstructor,
|
||||
@ -70,7 +69,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
// Flatten the arguments of the assert statement.
|
||||
let assert = AssertStatement {
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
variant: match input.variant {
|
||||
AssertVariant::Assert(expression) => {
|
||||
let (expression, additional_statements) = self.reconstruct_expression(expression);
|
||||
@ -104,17 +103,17 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
Some(guard) => (
|
||||
Statement::Assert(AssertStatement {
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
variant: AssertVariant::Assert(Expression::Binary(BinaryExpression {
|
||||
op: BinaryOperation::Or,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
// Take the logical negation of the guard.
|
||||
left: Box::new(Expression::Unary(UnaryExpression {
|
||||
op: UnaryOperation::Not,
|
||||
receiver: Box::new(guard),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})),
|
||||
right: Box::new(match assert.variant {
|
||||
// If the assert statement is an `assert`, use the expression as is.
|
||||
@ -125,7 +124,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
op: BinaryOperation::Eq,
|
||||
right: Box::new(right),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}),
|
||||
// If the assert statement is an `assert_ne`, construct a new inequality expression.
|
||||
AssertVariant::AssertNeq(left, right) => Expression::Binary(BinaryExpression {
|
||||
@ -133,7 +132,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
op: BinaryOperation::Neq,
|
||||
right: Box::new(right),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}),
|
||||
}),
|
||||
})),
|
||||
@ -155,7 +154,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
(Expression::Identifier(identifier), Expression::Tuple(tuple)) => {
|
||||
self.tuples.insert(identifier.name, tuple);
|
||||
// Note that tuple assignments are removed from the AST.
|
||||
(Statement::dummy(Default::default()), statements)
|
||||
(Statement::dummy(Default::default(), self.node_builder.next_id()), statements)
|
||||
}
|
||||
// If the lhs is an identifier and the rhs is an identifier that is a tuple, then add it to `self.tuples`.
|
||||
(Expression::Identifier(lhs_identifier), Expression::Identifier(rhs_identifier))
|
||||
@ -165,7 +164,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
// Note that the `unwrap` is safe since the match arm checks that the entry exists.
|
||||
self.tuples.insert(lhs_identifier.name, self.tuples.get(&rhs_identifier.name).unwrap().clone());
|
||||
// Note that tuple assignments are removed from the AST.
|
||||
(Statement::dummy(Default::default()), statements)
|
||||
(Statement::dummy(Default::default(), self.node_builder.next_id()), statements)
|
||||
}
|
||||
// If the lhs is an identifier and the rhs is a function call that produces a tuple, then add it to `self.tuples`.
|
||||
(Expression::Identifier(lhs_identifier), Expression::Call(call)) => {
|
||||
@ -187,6 +186,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
.map(|(i, type_)| {
|
||||
let identifier = Identifier::new(
|
||||
self.assigner.unique_symbol(lhs_identifier.name, format!("$index${i}$")),
|
||||
self.node_builder.next_id(),
|
||||
);
|
||||
|
||||
// If the output type is a struct, add it to `self.structs`.
|
||||
@ -198,7 +198,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
})
|
||||
.collect(),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
};
|
||||
// Add the `tuple_expression` to `self.tuples`.
|
||||
self.tuples.insert(lhs_identifier.name, tuple_expression.clone());
|
||||
@ -208,7 +208,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
place: Expression::Tuple(tuple_expression),
|
||||
value: Expression::Call(call),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})),
|
||||
statements,
|
||||
)
|
||||
@ -224,7 +224,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
place: Expression::Identifier(lhs_identifier),
|
||||
value: Expression::Call(call),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})),
|
||||
statements,
|
||||
)
|
||||
@ -274,14 +274,14 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
place: Expression::Identifier(lhs_identifier),
|
||||
value,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})),
|
||||
statements,
|
||||
)
|
||||
}
|
||||
(Expression::Identifier(identifier), expression) => {
|
||||
self.update_structs(&identifier, &expression);
|
||||
(self.assigner.simple_assign_statement(identifier, expression), statements)
|
||||
(self.assigner.simple_assign_statement(identifier, expression, self.node_builder.next_id()), statements)
|
||||
}
|
||||
// If the lhs is a tuple and the rhs is a function call, then return the reconstructed statement.
|
||||
(Expression::Tuple(tuple), Expression::Call(call)) => {
|
||||
@ -315,7 +315,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
place: Expression::Tuple(tuple),
|
||||
value: Expression::Call(call),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})),
|
||||
statements,
|
||||
)
|
||||
@ -333,11 +333,11 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
place: lhs,
|
||||
value: rhs,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
},
|
||||
));
|
||||
(Statement::dummy(Default::default()), statements)
|
||||
(Statement::dummy(Default::default(), self.node_builder.next_id()), statements)
|
||||
}
|
||||
// If the lhs is a tuple and the rhs is an identifier that is a tuple, create a new assign statement for each tuple element.
|
||||
(Expression::Tuple(lhs_tuple), Expression::Identifier(identifier))
|
||||
@ -358,10 +358,10 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
place: lhs,
|
||||
value: rhs,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})));
|
||||
}
|
||||
(Statement::dummy(Default::default()), statements)
|
||||
(Statement::dummy(Default::default(), self.node_builder.next_id()), statements)
|
||||
}
|
||||
// If the lhs of an assignment is a tuple, then the rhs can be one of the following:
|
||||
// - A function call that produces a tuple. (handled above)
|
||||
@ -388,7 +388,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
statements.push(reconstructed_statement);
|
||||
}
|
||||
|
||||
(Block { span: block.span, statements, id: NodeID::default() }, Default::default())
|
||||
(Block { span: block.span, statements, id: self.node_builder.next_id() }, Default::default())
|
||||
}
|
||||
|
||||
/// Flatten a conditional statement into a list of statements.
|
||||
@ -411,7 +411,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
op: UnaryOperation::Not,
|
||||
receiver: Box::new(conditional.condition.clone()),
|
||||
span: conditional.condition.span(),
|
||||
id: NodeID::default(),
|
||||
id: conditional.condition.id(),
|
||||
}));
|
||||
|
||||
// Reconstruct the otherwise-block and accumulate it constituent statements.
|
||||
@ -424,7 +424,7 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
self.condition_stack.pop();
|
||||
};
|
||||
|
||||
(Statement::dummy(Default::default()), statements)
|
||||
(Statement::dummy(Default::default(), self.node_builder.next_id()), statements)
|
||||
}
|
||||
|
||||
fn reconstruct_console(&mut self, _: ConsoleStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
@ -458,13 +458,13 @@ impl StatementReconstructor for Flattener<'_> {
|
||||
span: input.span,
|
||||
expression: Expression::Tuple(tuple),
|
||||
finalize_arguments: input.finalize_arguments,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
}
|
||||
// Otherwise, add the expression directly.
|
||||
_ => self.returns.push((guard, input)),
|
||||
};
|
||||
|
||||
(Statement::dummy(Default::default()), Default::default())
|
||||
(Statement::dummy(Default::default(), self.node_builder.next_id()), Default::default())
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use leo_ast::{
|
||||
ExpressionReconstructor,
|
||||
Identifier,
|
||||
Member,
|
||||
NodeID,
|
||||
NodeBuilder,
|
||||
ReturnStatement,
|
||||
Statement,
|
||||
TernaryExpression,
|
||||
@ -39,8 +39,10 @@ use indexmap::IndexMap;
|
||||
pub struct Flattener<'a> {
|
||||
/// The symbol table associated with the program.
|
||||
pub(crate) symbol_table: &'a SymbolTable,
|
||||
/// A counter used to generate unique node IDs.
|
||||
pub(crate) node_builder: &'a NodeBuilder,
|
||||
/// A struct used to construct (unique) assignment statements.
|
||||
pub(crate) assigner: Assigner,
|
||||
pub(crate) assigner: &'a Assigner,
|
||||
/// The set of variables that are structs.
|
||||
pub(crate) structs: IndexMap<Symbol, Symbol>,
|
||||
/// A stack of condition `Expression`s visited up to the current point in the AST.
|
||||
@ -55,9 +57,10 @@ pub struct Flattener<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Flattener<'a> {
|
||||
pub(crate) fn new(symbol_table: &'a SymbolTable, assigner: Assigner) -> Self {
|
||||
pub(crate) fn new(symbol_table: &'a SymbolTable, node_builder: &'a NodeBuilder, assigner: &'a Assigner) -> Self {
|
||||
Self {
|
||||
symbol_table,
|
||||
node_builder,
|
||||
assigner,
|
||||
structs: IndexMap::new(),
|
||||
condition_stack: Vec::new(),
|
||||
@ -83,7 +86,7 @@ impl<'a> Flattener<'a> {
|
||||
left: Box::new(acc),
|
||||
right: Box::new(condition),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})
|
||||
}))
|
||||
}
|
||||
@ -114,14 +117,14 @@ impl<'a> Flattener<'a> {
|
||||
let place = Identifier {
|
||||
name: self.assigner.unique_symbol(prefix, "$"),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
};
|
||||
let (value, stmts) = self.reconstruct_ternary(TernaryExpression {
|
||||
condition: Box::new(guard),
|
||||
if_true: Box::new(if_true),
|
||||
if_false: Box::new(if_false),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
statements.extend(stmts);
|
||||
|
||||
@ -186,7 +189,13 @@ impl<'a> Flattener<'a> {
|
||||
|
||||
/// A wrapper around `assigner.unique_simple_assign_statement` that updates `self.structs`.
|
||||
pub(crate) fn unique_simple_assign_statement(&mut self, expr: Expression) -> (Identifier, Statement) {
|
||||
let (place, statement) = self.assigner.unique_simple_assign_statement(expr);
|
||||
// Create a new variable for the expression.
|
||||
let name = self.assigner.unique_symbol("$var", "$");
|
||||
// Construct the lhs of the assignment.
|
||||
let place = Identifier { name, span: Default::default(), id: self.node_builder.next_id() };
|
||||
// Construct the assignment statement.
|
||||
let statement = self.assigner.simple_assign_statement(place, expr, self.node_builder.next_id());
|
||||
|
||||
match &statement {
|
||||
Statement::Assign(assign) => {
|
||||
self.update_structs(&place, &assign.value);
|
||||
@ -199,7 +208,7 @@ impl<'a> Flattener<'a> {
|
||||
/// A wrapper around `assigner.simple_assign_statement` that updates `self.structs`.
|
||||
pub(crate) fn simple_assign_statement(&mut self, lhs: Identifier, rhs: Expression) -> Statement {
|
||||
self.update_structs(&lhs, &rhs);
|
||||
self.assigner.simple_assign_statement(lhs, rhs)
|
||||
self.assigner.simple_assign_statement(lhs, rhs, self.node_builder.next_id())
|
||||
}
|
||||
|
||||
/// Folds a list of return statements into a single return statement and adds the produced statements to the block.
|
||||
@ -254,7 +263,7 @@ impl<'a> Flattener<'a> {
|
||||
expression,
|
||||
finalize_arguments,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -61,17 +61,17 @@ pub use flattener::*;
|
||||
|
||||
use crate::{Assigner, Pass, SymbolTable};
|
||||
|
||||
use leo_ast::{Ast, ProgramReconstructor};
|
||||
use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
|
||||
use leo_errors::Result;
|
||||
|
||||
impl<'a> Pass for Flattener<'a> {
|
||||
type Input = (Ast, &'a SymbolTable, Assigner);
|
||||
type Output = Result<(Ast, Assigner)>;
|
||||
type Input = (Ast, &'a SymbolTable, &'a NodeBuilder, &'a Assigner);
|
||||
type Output = Result<Ast>;
|
||||
|
||||
fn do_pass((ast, st, assigner): Self::Input) -> Self::Output {
|
||||
let mut reconstructor = Flattener::new(st, assigner);
|
||||
fn do_pass((ast, st, node_builder, assigner): Self::Input) -> Self::Output {
|
||||
let mut reconstructor = Flattener::new(st, node_builder, assigner);
|
||||
let program = reconstructor.reconstruct_program(ast.into_repr());
|
||||
|
||||
Ok((Ast::new(program), reconstructor.assigner))
|
||||
Ok(Ast::new(program))
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ use leo_ast::{
|
||||
ExpressionReconstructor,
|
||||
Identifier,
|
||||
IterationStatement,
|
||||
NodeID,
|
||||
ProgramReconstructor,
|
||||
Statement,
|
||||
StatementReconstructor,
|
||||
@ -36,15 +35,15 @@ use leo_span::Symbol;
|
||||
// TODO: Generalize the functionality of this reconstructor to be used in other passes.
|
||||
/// An `AssignmentRenamer` renames the left-hand side of all assignment statements in an AST node.
|
||||
/// The new names are propagated to all following identifiers.
|
||||
pub struct AssignmentRenamer {
|
||||
pub assigner: Assigner,
|
||||
pub struct AssignmentRenamer<'a> {
|
||||
pub assigner: &'a Assigner,
|
||||
pub rename_table: RenameTable,
|
||||
pub is_lhs: bool,
|
||||
}
|
||||
|
||||
impl AssignmentRenamer {
|
||||
impl<'a> AssignmentRenamer<'a> {
|
||||
/// Initialize a new `AssignmentRenamer`.
|
||||
pub fn new(assigner: Assigner) -> Self {
|
||||
pub fn new(assigner: &'a Assigner) -> Self {
|
||||
Self { assigner, rename_table: RenameTable::new(None), is_lhs: false }
|
||||
}
|
||||
|
||||
@ -61,7 +60,7 @@ impl AssignmentRenamer {
|
||||
}
|
||||
}
|
||||
|
||||
impl ExpressionReconstructor for AssignmentRenamer {
|
||||
impl ExpressionReconstructor for AssignmentRenamer<'_> {
|
||||
type AdditionalOutput = ();
|
||||
|
||||
/// Rename the identifier if it is the left-hand side of an assignment, otherwise look up for a new name in the internal rename table.
|
||||
@ -80,7 +79,7 @@ impl ExpressionReconstructor for AssignmentRenamer {
|
||||
false => *self.rename_table.lookup(input.name).unwrap_or(&input.name),
|
||||
};
|
||||
|
||||
(Expression::Identifier(Identifier { name, span: input.span, id: NodeID::default() }), Default::default())
|
||||
(Expression::Identifier(Identifier { name, span: input.span, id: input.id }), Default::default())
|
||||
}
|
||||
|
||||
/// Rename the variable initializers in the struct expression.
|
||||
@ -100,18 +99,18 @@ impl ExpressionReconstructor for AssignmentRenamer {
|
||||
),
|
||||
},
|
||||
span: member.span,
|
||||
id: NodeID::default(),
|
||||
id: member.id,
|
||||
})
|
||||
.collect(),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl StatementReconstructor for AssignmentRenamer {
|
||||
impl StatementReconstructor for AssignmentRenamer<'_> {
|
||||
/// Rename the left-hand side of the assignment statement.
|
||||
fn reconstruct_assign(&mut self, input: AssignStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
// First rename the right-hand-side of the assignment.
|
||||
@ -124,7 +123,7 @@ impl StatementReconstructor for AssignmentRenamer {
|
||||
self.is_lhs = false;
|
||||
|
||||
(
|
||||
Statement::Assign(Box::new(AssignStatement { place, value, span: input.span, id: NodeID::default() })),
|
||||
Statement::Assign(Box::new(AssignStatement { place, value, span: input.span, id: input.id })),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
@ -150,4 +149,4 @@ impl StatementReconstructor for AssignmentRenamer {
|
||||
}
|
||||
}
|
||||
|
||||
impl ProgramReconstructor for AssignmentRenamer {}
|
||||
impl ProgramReconstructor for AssignmentRenamer<'_> {}
|
||||
|
@ -16,24 +16,27 @@
|
||||
|
||||
use crate::{Assigner, AssignmentRenamer, CallGraph};
|
||||
|
||||
use leo_ast::Function;
|
||||
use leo_ast::{Function, NodeBuilder};
|
||||
use leo_span::Symbol;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
pub struct FunctionInliner<'a> {
|
||||
/// A counter used to create unique NodeIDs.
|
||||
pub(crate) node_builder: &'a NodeBuilder,
|
||||
/// The call graph for the program.
|
||||
pub(crate) call_graph: &'a CallGraph,
|
||||
/// A wrapper around an Assigner used to create unique variable assignments.
|
||||
pub(crate) assignment_renamer: AssignmentRenamer,
|
||||
pub(crate) assignment_renamer: AssignmentRenamer<'a>,
|
||||
/// A map of reconstructed functions in the current program scope.
|
||||
pub(crate) reconstructed_functions: IndexMap<Symbol, Function>,
|
||||
}
|
||||
|
||||
impl<'a> FunctionInliner<'a> {
|
||||
/// Initializes a new `FunctionInliner`.
|
||||
pub fn new(call_graph: &'a CallGraph, assigner: Assigner) -> Self {
|
||||
pub fn new(node_builder: &'a NodeBuilder, call_graph: &'a CallGraph, assigner: &'a Assigner) -> Self {
|
||||
Self {
|
||||
node_builder,
|
||||
call_graph,
|
||||
assignment_renamer: AssignmentRenamer::new(assigner),
|
||||
reconstructed_functions: Default::default(),
|
||||
|
@ -21,7 +21,6 @@ use leo_ast::{
|
||||
Expression,
|
||||
ExpressionReconstructor,
|
||||
Identifier,
|
||||
NodeID,
|
||||
ReturnStatement,
|
||||
Statement,
|
||||
StatementReconstructor,
|
||||
@ -90,7 +89,7 @@ impl ExpressionReconstructor for FunctionInliner<'_> {
|
||||
_ => unreachable!("This branch checks that the last statement is a return statement."),
|
||||
}
|
||||
}
|
||||
_ => Expression::Unit(UnitExpression { span: Default::default(), id: NodeID::default() }),
|
||||
_ => Expression::Unit(UnitExpression { span: Default::default(), id: self.node_builder.next_id() }),
|
||||
};
|
||||
|
||||
(result, inlined_statements)
|
||||
|
@ -26,7 +26,6 @@ use leo_ast::{
|
||||
ExpressionReconstructor,
|
||||
ExpressionStatement,
|
||||
IterationStatement,
|
||||
NodeID,
|
||||
Statement,
|
||||
StatementReconstructor,
|
||||
};
|
||||
@ -44,14 +43,14 @@ impl StatementReconstructor for FunctionInliner<'_> {
|
||||
place: lhs,
|
||||
value: rhs,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
}));
|
||||
(Statement::dummy(Default::default()), statements)
|
||||
(Statement::dummy(Default::default(), self.node_builder.next_id()), statements)
|
||||
}
|
||||
|
||||
(place, value) => (
|
||||
Statement::Assign(Box::new(AssignStatement { place, value, span: input.span, id: NodeID::default() })),
|
||||
Statement::Assign(Box::new(AssignStatement { place, value, span: input.span, id: input.id })),
|
||||
statements,
|
||||
),
|
||||
}
|
||||
@ -67,7 +66,7 @@ impl StatementReconstructor for FunctionInliner<'_> {
|
||||
statements.push(reconstructed_statement);
|
||||
}
|
||||
|
||||
(Block { span: block.span, statements, id: NodeID::default() }, Default::default())
|
||||
(Block { span: block.span, statements, id: block.id }, Default::default())
|
||||
}
|
||||
|
||||
/// Flattening removes conditional statements from the program.
|
||||
@ -93,8 +92,8 @@ impl StatementReconstructor for FunctionInliner<'_> {
|
||||
|
||||
// If the resulting expression is a unit expression, return a dummy statement.
|
||||
let statement = match expression {
|
||||
Expression::Unit(_) => Statement::dummy(Default::default()),
|
||||
_ => Statement::Expression(ExpressionStatement { expression, span: input.span, id: NodeID::default() }),
|
||||
Expression::Unit(_) => Statement::dummy(Default::default(), self.node_builder.next_id()),
|
||||
_ => Statement::Expression(ExpressionStatement { expression, span: input.span, id: input.id }),
|
||||
};
|
||||
|
||||
(statement, additional_statements)
|
||||
|
@ -66,17 +66,17 @@ pub use function_inliner::*;
|
||||
|
||||
use crate::{Assigner, CallGraph, Pass};
|
||||
|
||||
use leo_ast::{Ast, ProgramReconstructor};
|
||||
use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
|
||||
use leo_errors::Result;
|
||||
|
||||
impl<'a> Pass for FunctionInliner<'a> {
|
||||
type Input = (Ast, &'a CallGraph, Assigner);
|
||||
type Output = Result<(Ast, Assigner)>;
|
||||
type Input = (Ast, &'a NodeBuilder, &'a CallGraph, &'a Assigner);
|
||||
type Output = Result<Ast>;
|
||||
|
||||
fn do_pass((ast, call_graph, assigner): Self::Input) -> Self::Output {
|
||||
let mut reconstructor = FunctionInliner::new(call_graph, assigner);
|
||||
fn do_pass((ast, node_builder, call_graph, assigner): Self::Input) -> Self::Output {
|
||||
let mut reconstructor = FunctionInliner::new(node_builder, call_graph, assigner);
|
||||
let program = reconstructor.reconstruct_program(ast.into_repr());
|
||||
|
||||
Ok((Ast::new(program), reconstructor.assignment_renamer.assigner))
|
||||
Ok(Ast::new(program))
|
||||
}
|
||||
}
|
||||
|
@ -31,15 +31,15 @@ pub use unroll_statement::*;
|
||||
|
||||
use crate::{Pass, SymbolTable};
|
||||
|
||||
use leo_ast::{Ast, ProgramReconstructor};
|
||||
use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
|
||||
use leo_errors::{emitter::Handler, Result};
|
||||
|
||||
impl<'a> Pass for Unroller<'a> {
|
||||
type Input = (Ast, &'a Handler, SymbolTable);
|
||||
type Input = (Ast, &'a Handler, &'a NodeBuilder, SymbolTable);
|
||||
type Output = Result<(Ast, SymbolTable)>;
|
||||
|
||||
fn do_pass((ast, handler, st): Self::Input) -> Self::Output {
|
||||
let mut reconstructor = Self::new(st, handler);
|
||||
fn do_pass((ast, handler, node_builder, st): Self::Input) -> Self::Output {
|
||||
let mut reconstructor = Self::new(st, handler, node_builder);
|
||||
let program = reconstructor.reconstruct_program(ast.into_repr());
|
||||
handler.last_err().map_err(|e| *e)?;
|
||||
|
||||
|
@ -47,7 +47,7 @@ impl ProgramReconstructor for Unroller<'_> {
|
||||
output_type: finalize.output_type,
|
||||
block,
|
||||
span: finalize.span,
|
||||
id: NodeID::default(),
|
||||
id: finalize.id,
|
||||
}
|
||||
});
|
||||
|
||||
@ -62,7 +62,7 @@ impl ProgramReconstructor for Unroller<'_> {
|
||||
block,
|
||||
finalize,
|
||||
span: function.span,
|
||||
id: NodeID::default(),
|
||||
id: function.id,
|
||||
};
|
||||
|
||||
// Exit the function's scope.
|
||||
|
@ -30,7 +30,7 @@ impl StatementReconstructor for Unroller<'_> {
|
||||
let block = Block {
|
||||
statements: input.statements.into_iter().map(|s| self.reconstruct_statement(s).0).collect(),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
};
|
||||
|
||||
// Exit the block scope.
|
||||
|
@ -22,7 +22,7 @@ use leo_ast::{
|
||||
IntegerType,
|
||||
IterationStatement,
|
||||
Literal,
|
||||
NodeID,
|
||||
NodeBuilder,
|
||||
Statement,
|
||||
StatementReconstructor,
|
||||
Type,
|
||||
@ -41,13 +41,15 @@ pub struct Unroller<'a> {
|
||||
pub(crate) scope_index: usize,
|
||||
/// An error handler used for any errors found during unrolling.
|
||||
pub(crate) handler: &'a Handler,
|
||||
/// A counter used to generate unique node IDs.
|
||||
pub(crate) node_builder: &'a NodeBuilder,
|
||||
/// Are we in the midst of unrolling a loop?
|
||||
pub(crate) is_unrolling: bool,
|
||||
}
|
||||
|
||||
impl<'a> Unroller<'a> {
|
||||
pub(crate) fn new(symbol_table: SymbolTable, handler: &'a Handler) -> Self {
|
||||
Self { symbol_table: RefCell::new(symbol_table), scope_index: 0, handler, is_unrolling: false }
|
||||
pub(crate) fn new(symbol_table: SymbolTable, handler: &'a Handler, node_builder: &'a NodeBuilder) -> Self {
|
||||
Self { symbol_table: RefCell::new(symbol_table), scope_index: 0, handler, node_builder, is_unrolling: false }
|
||||
}
|
||||
|
||||
/// Returns the index of the current scope.
|
||||
@ -86,7 +88,7 @@ impl<'a> Unroller<'a> {
|
||||
Ok(val_as_u128) => Ok(val_as_u128),
|
||||
Err(err) => {
|
||||
self.handler.emit_err(err);
|
||||
Err(Statement::dummy(input.span))
|
||||
Err(Statement::dummy(input.span, self.node_builder.next_id()))
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -128,7 +130,7 @@ impl<'a> Unroller<'a> {
|
||||
iter.map(|iteration_count| self.unroll_single_iteration(&input, iteration_count)).collect()
|
||||
}
|
||||
},
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
});
|
||||
|
||||
// Exit the scope of the loop body.
|
||||
@ -148,36 +150,66 @@ impl<'a> Unroller<'a> {
|
||||
|
||||
// Reconstruct `iteration_count` as a `Literal`.
|
||||
let value = match input.type_ {
|
||||
Type::Integer(IntegerType::I8) => {
|
||||
Literal::Integer(IntegerType::I8, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::I16) => {
|
||||
Literal::Integer(IntegerType::I16, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::I32) => {
|
||||
Literal::Integer(IntegerType::I32, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::I64) => {
|
||||
Literal::Integer(IntegerType::I64, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::I128) => {
|
||||
Literal::Integer(IntegerType::I128, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U8) => {
|
||||
Literal::Integer(IntegerType::U8, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U16) => {
|
||||
Literal::Integer(IntegerType::U16, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U32) => {
|
||||
Literal::Integer(IntegerType::U32, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U64) => {
|
||||
Literal::Integer(IntegerType::U64, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U128) => {
|
||||
Literal::Integer(IntegerType::U128, iteration_count.to_string(), Default::default(), NodeID::default())
|
||||
}
|
||||
Type::Integer(IntegerType::I8) => Literal::Integer(
|
||||
IntegerType::I8,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
Type::Integer(IntegerType::I16) => Literal::Integer(
|
||||
IntegerType::I16,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
Type::Integer(IntegerType::I32) => Literal::Integer(
|
||||
IntegerType::I32,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
Type::Integer(IntegerType::I64) => Literal::Integer(
|
||||
IntegerType::I64,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
Type::Integer(IntegerType::I128) => Literal::Integer(
|
||||
IntegerType::I128,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
Type::Integer(IntegerType::U8) => Literal::Integer(
|
||||
IntegerType::U8,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
Type::Integer(IntegerType::U16) => Literal::Integer(
|
||||
IntegerType::U16,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
Type::Integer(IntegerType::U32) => Literal::Integer(
|
||||
IntegerType::U32,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
Type::Integer(IntegerType::U64) => Literal::Integer(
|
||||
IntegerType::U64,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
Type::Integer(IntegerType::U128) => Literal::Integer(
|
||||
IntegerType::U128,
|
||||
iteration_count.to_string(),
|
||||
Default::default(),
|
||||
self.node_builder.next_id(),
|
||||
),
|
||||
_ => unreachable!(
|
||||
"The iteration variable must be an integer type. This should be enforced by type checking."
|
||||
),
|
||||
@ -191,7 +223,7 @@ impl<'a> Unroller<'a> {
|
||||
value: Expression::Literal(value),
|
||||
span: Default::default(),
|
||||
place: Expression::Identifier(input.variable),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})
|
||||
.0,
|
||||
];
|
||||
@ -201,7 +233,7 @@ impl<'a> Unroller<'a> {
|
||||
statements.push(self.reconstruct_statement(s).0);
|
||||
});
|
||||
|
||||
let block = Statement::Block(Block { statements, span: input.block.span, id: NodeID::default() });
|
||||
let block = Statement::Block(Block { statements, span: input.block.span, id: input.block.id });
|
||||
|
||||
self.is_unrolling = prior_is_unrolling;
|
||||
|
||||
|
@ -61,17 +61,17 @@ pub use static_single_assigner::*;
|
||||
|
||||
use crate::{Assigner, Pass, SymbolTable};
|
||||
|
||||
use leo_ast::{Ast, ProgramConsumer};
|
||||
use leo_ast::{Ast, NodeBuilder, ProgramConsumer};
|
||||
use leo_errors::Result;
|
||||
|
||||
impl<'a> Pass for StaticSingleAssigner<'a> {
|
||||
type Input = (Ast, &'a SymbolTable);
|
||||
type Output = Result<(Ast, Assigner)>;
|
||||
type Input = (Ast, &'a NodeBuilder, &'a Assigner, &'a SymbolTable);
|
||||
type Output = Result<Ast>;
|
||||
|
||||
fn do_pass((ast, symbol_table): Self::Input) -> Self::Output {
|
||||
let mut consumer = StaticSingleAssigner::new(symbol_table);
|
||||
fn do_pass((ast, node_builder, assigner, symbol_table): Self::Input) -> Self::Output {
|
||||
let mut consumer = StaticSingleAssigner::new(node_builder, symbol_table, assigner);
|
||||
let program = consumer.consume_program(ast.into_repr());
|
||||
|
||||
Ok((Ast::new(program), consumer.assigner))
|
||||
Ok(Ast::new(program))
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ use leo_ast::{
|
||||
Identifier,
|
||||
Literal,
|
||||
MemberAccess,
|
||||
NodeID,
|
||||
Statement,
|
||||
Struct,
|
||||
StructExpression,
|
||||
@ -65,7 +64,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
})
|
||||
.collect(),
|
||||
span: function.span,
|
||||
id: NodeID::default(),
|
||||
id: function.id,
|
||||
}),
|
||||
statements,
|
||||
)
|
||||
@ -85,7 +84,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
inner: Box::new(expr),
|
||||
name: member.name,
|
||||
span: member.span,
|
||||
id: NodeID::default(),
|
||||
id: member.id,
|
||||
}),
|
||||
statements,
|
||||
)
|
||||
@ -97,14 +96,14 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
tuple: Box::new(expr),
|
||||
index: tuple.index,
|
||||
span: tuple.span,
|
||||
id: NodeID::default(),
|
||||
id: tuple.id,
|
||||
}),
|
||||
statements,
|
||||
)
|
||||
}
|
||||
expr => (expr, Vec::new()),
|
||||
};
|
||||
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Access(expr));
|
||||
let (place, statement) = self.unique_simple_assign_statement(Expression::Access(expr));
|
||||
statements.push(statement);
|
||||
|
||||
(Expression::Identifier(place), statements)
|
||||
@ -120,12 +119,12 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
statements.append(&mut right_statements);
|
||||
|
||||
// Construct and accumulate a unique assignment statement storing the result of the binary expression.
|
||||
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Binary(BinaryExpression {
|
||||
let (place, statement) = self.unique_simple_assign_statement(Expression::Binary(BinaryExpression {
|
||||
left: Box::new(left_expression),
|
||||
right: Box::new(right_expression),
|
||||
op: input.op,
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
statements.push(statement);
|
||||
|
||||
@ -148,14 +147,14 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
.collect();
|
||||
|
||||
// Construct and accumulate a new assignment statement for the call expression.
|
||||
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Call(CallExpression {
|
||||
let (place, statement) = self.unique_simple_assign_statement(Expression::Call(CallExpression {
|
||||
// Note that we do not rename the function name.
|
||||
function: input.function,
|
||||
// Consume the arguments.
|
||||
arguments,
|
||||
external: input.external,
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
statements.push(statement);
|
||||
|
||||
@ -168,11 +167,11 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
let (expression, mut statements) = self.consume_expression(*input.expression);
|
||||
|
||||
// Construct and accumulate a unique assignment statement storing the result of the cast expression.
|
||||
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Cast(CastExpression {
|
||||
let (place, statement) = self.unique_simple_assign_statement(Expression::Cast(CastExpression {
|
||||
expression: Box::new(expression),
|
||||
type_: input.type_,
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
statements.push(statement);
|
||||
|
||||
@ -204,7 +203,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
identifier: arg.identifier,
|
||||
expression: Some(expression),
|
||||
span: arg.span,
|
||||
id: NodeID::default(),
|
||||
id: arg.id,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@ -241,11 +240,11 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
}
|
||||
|
||||
// Construct and accumulate a new assignment statement for the struct expression.
|
||||
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Struct(StructExpression {
|
||||
let (place, statement) = self.unique_simple_assign_statement(Expression::Struct(StructExpression {
|
||||
name: input.name,
|
||||
span: input.span,
|
||||
members: reordered_members,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
statements.push(statement);
|
||||
|
||||
@ -268,7 +267,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
false => *self.rename_table.lookup(identifier.name).unwrap_or(&identifier.name),
|
||||
};
|
||||
|
||||
(Expression::Identifier(Identifier { name, span: identifier.span, id: NodeID::default() }), Default::default())
|
||||
(Expression::Identifier(Identifier { name, span: identifier.span, id: identifier.id }), Default::default())
|
||||
}
|
||||
|
||||
/// Consumes and returns the literal without making any modifications.
|
||||
@ -290,12 +289,12 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
statements.append(&mut if_false_statements);
|
||||
|
||||
// Construct and accumulate a unique assignment statement storing the result of the ternary expression.
|
||||
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Ternary(TernaryExpression {
|
||||
let (place, statement) = self.unique_simple_assign_statement(Expression::Ternary(TernaryExpression {
|
||||
condition: Box::new(cond_expr),
|
||||
if_true: Box::new(if_true_expr),
|
||||
if_false: Box::new(if_false_expr),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
statements.push(statement);
|
||||
|
||||
@ -318,10 +317,10 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
.collect();
|
||||
|
||||
// Construct and accumulate a new assignment statement for the tuple expression.
|
||||
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Tuple(TupleExpression {
|
||||
let (place, statement) = self.unique_simple_assign_statement(Expression::Tuple(TupleExpression {
|
||||
elements,
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
statements.push(statement);
|
||||
|
||||
@ -334,11 +333,11 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
let (receiver, mut statements) = self.consume_expression(*input.receiver);
|
||||
|
||||
// Construct and accumulate a new assignment statement for the unary expression.
|
||||
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Unary(UnaryExpression {
|
||||
let (place, statement) = self.unique_simple_assign_statement(Expression::Unary(UnaryExpression {
|
||||
op: input.op,
|
||||
receiver: Box::new(receiver),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
statements.push(statement);
|
||||
|
||||
|
@ -22,7 +22,6 @@ use leo_ast::{
|
||||
Function,
|
||||
FunctionConsumer,
|
||||
Member,
|
||||
NodeID,
|
||||
Program,
|
||||
ProgramConsumer,
|
||||
ProgramScope,
|
||||
@ -75,7 +74,7 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
|
||||
}
|
||||
|
||||
let block =
|
||||
Block { span: function.block.span, statements: self.consume_block(function.block), id: NodeID::default() };
|
||||
Block { span: function.block.span, id: function.block.id, statements: self.consume_block(function.block) };
|
||||
|
||||
// Remove the `RenameTable` for the function.
|
||||
self.pop();
|
||||
@ -92,8 +91,8 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
|
||||
|
||||
let block = Block {
|
||||
span: finalize.block.span,
|
||||
id: finalize.block.id,
|
||||
statements: self.consume_block(finalize.block),
|
||||
id: NodeID::default(),
|
||||
};
|
||||
|
||||
// Remove the `RenameTable` for the finalize block.
|
||||
@ -106,7 +105,7 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
|
||||
output_type: finalize.output_type,
|
||||
block,
|
||||
span: finalize.span,
|
||||
id: NodeID::default(),
|
||||
id: finalize.id,
|
||||
}
|
||||
});
|
||||
|
||||
@ -120,7 +119,7 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
|
||||
block,
|
||||
finalize,
|
||||
span: function.span,
|
||||
id: NodeID::default(),
|
||||
id: function.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ use leo_ast::{
|
||||
ExpressionStatement,
|
||||
Identifier,
|
||||
IterationStatement,
|
||||
NodeID,
|
||||
ReturnStatement,
|
||||
Statement,
|
||||
StatementConsumer,
|
||||
@ -76,7 +75,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
};
|
||||
|
||||
// Add the assert statement to the list of produced statements.
|
||||
statements.push(Statement::Assert(AssertStatement { variant, span: input.span, id: NodeID::default() }));
|
||||
statements.push(Statement::Assert(AssertStatement { variant, span: input.span, id: input.id }));
|
||||
|
||||
statements
|
||||
}
|
||||
@ -95,7 +94,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
};
|
||||
self.is_lhs = false;
|
||||
|
||||
statements.push(self.assigner.simple_assign_statement(place, value));
|
||||
statements.push(self.assigner.simple_assign_statement(place, value, self.node_builder.next_id()));
|
||||
|
||||
statements
|
||||
}
|
||||
@ -122,8 +121,8 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
// Consume the then-block.
|
||||
let then = Block {
|
||||
span: conditional.then.span,
|
||||
id: conditional.then.id,
|
||||
statements: self.consume_block(conditional.then),
|
||||
id: NodeID::default(),
|
||||
};
|
||||
|
||||
// Remove the `RenameTable` for the then-block.
|
||||
@ -136,13 +135,13 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
let otherwise = conditional.otherwise.map(|otherwise| Box::new(Statement::Block(match *otherwise {
|
||||
Statement::Block(block) => Block {
|
||||
span: block.span,
|
||||
id: block.id,
|
||||
statements: self.consume_block(block),
|
||||
id: NodeID::default(),
|
||||
},
|
||||
Statement::Conditional(conditional) => Block {
|
||||
span: conditional.span,
|
||||
id: conditional.id,
|
||||
statements: self.consume_conditional(conditional),
|
||||
id: NodeID::default()
|
||||
},
|
||||
_ => unreachable!("Type checking guarantees that the otherwise-block of a conditional statement is a block or another conditional statement."),
|
||||
})));
|
||||
@ -153,10 +152,10 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
// Add reconstructed conditional statement to the list of produced statements.
|
||||
statements.push(Statement::Conditional(ConditionalStatement {
|
||||
span: conditional.span,
|
||||
id: conditional.id,
|
||||
condition: condition.clone(),
|
||||
then,
|
||||
otherwise,
|
||||
id: NodeID::default(),
|
||||
}));
|
||||
|
||||
// Compute the write set for the variables written in the then-block or otherwise-block.
|
||||
@ -175,7 +174,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
Box::new(Expression::Identifier(Identifier {
|
||||
name,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}))
|
||||
};
|
||||
|
||||
@ -187,15 +186,16 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
if_true: create_phi_argument(&if_table, **symbol),
|
||||
if_false: create_phi_argument(&else_table, **symbol),
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
});
|
||||
|
||||
statements.extend(stmts);
|
||||
|
||||
// Create a new `AssignStatement` for the phi function.
|
||||
let assignment = self.assigner.simple_assign_statement(
|
||||
Identifier { name: new_name, span: Default::default(), id: NodeID::default() },
|
||||
Identifier { name: new_name, span: Default::default(), id: self.node_builder.next_id() },
|
||||
value,
|
||||
self.node_builder.next_id(),
|
||||
);
|
||||
|
||||
// Update the `RenameTable` with the new name of the variable.
|
||||
@ -228,7 +228,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
Expression::Identifier(identifier) => identifier,
|
||||
_ => unreachable!("`self.consume_identifier` will always return an `Identifier`."),
|
||||
};
|
||||
statements.push(self.assigner.simple_assign_statement(identifier, value));
|
||||
statements.push(self.assigner.simple_assign_statement(identifier, value, self.node_builder.next_id()));
|
||||
}
|
||||
Expression::Tuple(tuple) => {
|
||||
let elements = tuple.elements.into_iter().map(|element| {
|
||||
@ -247,11 +247,11 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
place: Expression::Tuple(TupleExpression {
|
||||
elements,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
}),
|
||||
value,
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
id: self.node_builder.next_id(),
|
||||
})));
|
||||
}
|
||||
_ => unreachable!(
|
||||
@ -291,10 +291,10 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
arguments,
|
||||
external: call.external,
|
||||
span: call.span,
|
||||
id: NodeID::default(),
|
||||
id: call.id,
|
||||
}),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
}
|
||||
Expression::Access(AccessExpression::AssociatedFunction(associated_function)) => {
|
||||
@ -308,10 +308,10 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
name: associated_function.name,
|
||||
arguments,
|
||||
span: associated_function.span,
|
||||
id: NodeID::default(),
|
||||
id: associated_function.id,
|
||||
})),
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}))
|
||||
}
|
||||
|
||||
@ -350,7 +350,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
expression,
|
||||
finalize_arguments: finalize_args,
|
||||
span: input.span,
|
||||
id: NodeID::default(),
|
||||
id: input.id,
|
||||
}));
|
||||
|
||||
statements
|
||||
|
@ -16,7 +16,11 @@
|
||||
|
||||
use crate::{Assigner, RenameTable, SymbolTable};
|
||||
|
||||
use leo_ast::{Expression, Identifier, NodeBuilder, Statement};
|
||||
|
||||
pub struct StaticSingleAssigner<'a> {
|
||||
/// A counter used to generate unique node IDs.
|
||||
pub(crate) node_builder: &'a NodeBuilder,
|
||||
/// The `SymbolTable` of the program.
|
||||
pub(crate) symbol_table: &'a SymbolTable,
|
||||
/// The `RenameTable` for the current basic block in the AST
|
||||
@ -24,13 +28,13 @@ pub struct StaticSingleAssigner<'a> {
|
||||
/// A flag to determine whether or not the traversal is on the left-hand side of a definition or an assignment.
|
||||
pub(crate) is_lhs: bool,
|
||||
/// A struct used to construct (unique) assignment statements.
|
||||
pub(crate) assigner: Assigner,
|
||||
pub(crate) assigner: &'a Assigner,
|
||||
}
|
||||
|
||||
impl<'a> StaticSingleAssigner<'a> {
|
||||
/// Initializes a new `StaticSingleAssigner` with an empty `RenameTable`.
|
||||
pub(crate) fn new(symbol_table: &'a SymbolTable) -> Self {
|
||||
Self { symbol_table, rename_table: RenameTable::new(None), is_lhs: false, assigner: Assigner::default() }
|
||||
pub(crate) fn new(node_builder: &'a NodeBuilder, symbol_table: &'a SymbolTable, assigner: &'a Assigner) -> Self {
|
||||
Self { node_builder, symbol_table, rename_table: RenameTable::new(None), is_lhs: false, assigner }
|
||||
}
|
||||
|
||||
/// Pushes a new scope, setting the current scope as the new scope's parent.
|
||||
@ -44,4 +48,23 @@ impl<'a> StaticSingleAssigner<'a> {
|
||||
let parent = self.rename_table.parent.clone().unwrap_or_default();
|
||||
core::mem::replace(&mut self.rename_table, *parent)
|
||||
}
|
||||
|
||||
/// Constructs a simple assign statement for `expr` with a unique name.
|
||||
/// For example, `expr` is transformed into `$var$0 = expr;`.
|
||||
/// The lhs is guaranteed to be unique with respect to the `Assigner`.
|
||||
pub(crate) fn unique_simple_assign_statement(&mut self, expr: Expression) -> (Identifier, Statement) {
|
||||
// Create a new variable for the expression.
|
||||
let name = self.assigner.unique_symbol("$var", "$");
|
||||
|
||||
// Create a new identifier for the variable.
|
||||
let place = Identifier { name, span: Default::default(), id: self.node_builder.next_id() };
|
||||
|
||||
// Construct the statement.
|
||||
let statement = self.assigner.simple_assign_statement(place, expr, self.node_builder.next_id());
|
||||
|
||||
// Construct the identifier to be returned. Note that it must have a unique node ID.
|
||||
let identifier = Identifier { name, span: Default::default(), id: self.node_builder.next_id() };
|
||||
|
||||
(identifier, statement)
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use super::*;
|
||||
|
||||
use leo_ast::Struct;
|
||||
use leo_ast::{NodeBuilder, Struct};
|
||||
use leo_compiler::{Compiler, CompilerOptions, InputAst, OutputOptions};
|
||||
use leo_package::{
|
||||
build::BuildDirectory,
|
||||
@ -103,6 +103,9 @@ impl Command for Build {
|
||||
// Initialize error handler
|
||||
let handler = Handler::default();
|
||||
|
||||
// Initialize a node counter.
|
||||
let node_builder = NodeBuilder::default();
|
||||
|
||||
// Fetch paths to all .leo files in the source directory.
|
||||
let source_files = SourceDirectory::files(&package_path)?;
|
||||
|
||||
@ -158,7 +161,7 @@ impl Command for Build {
|
||||
.map_err(|e| CompilerError::file_read_error(&input_file_path, e))?;
|
||||
|
||||
// TODO: This is a hack to notify the user that something is wrong with the input file. Redesign.
|
||||
leo_parser::parse_input(&handler, &input_sf.src, input_sf.start_pos)
|
||||
leo_parser::parse_input(&handler, &node_builder, &input_sf.src, input_sf.start_pos)
|
||||
.map_err(|_e| println!("Warning: Failed to parse input file"))
|
||||
.ok()
|
||||
} else {
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: aedbecdddf47324809cfe36a7329e30e0b02cb1a8e079ea3c6a1fed485eb6a23
|
||||
unrolled_ast: aedbecdddf47324809cfe36a7329e30e0b02cb1a8e079ea3c6a1fed485eb6a23
|
||||
ssa_ast: 6495fd7481d1b9490b37eb367af3f47f367d5571bed98476ba465441ffb6af52
|
||||
flattened_ast: d768a50e70e99bbbebbf391db1363d50ea42a2a64997319fe442c862eb477a12
|
||||
inlined_ast: d768a50e70e99bbbebbf391db1363d50ea42a2a64997319fe442c862eb477a12
|
||||
dce_ast: 195cdd11eab6742a8726b398d7fe1ad5b2ed170a9ef63b8da24e5c9bfed7e066
|
||||
- - initial_ast: ca70df10bc83440d704ee7f48d1fcd9add55c26ffc98a0f84f631ad65a83ec93
|
||||
unrolled_ast: ca70df10bc83440d704ee7f48d1fcd9add55c26ffc98a0f84f631ad65a83ec93
|
||||
ssa_ast: 66c5290f551b96ac177708948dd1080ddd4d00b1e3a73e33c28197e0ebdf7792
|
||||
flattened_ast: 2f37e06e70a4256eaff95d292b04aa0c72e34c84dfd7075e7997cf05ae4826a1
|
||||
inlined_ast: 2f37e06e70a4256eaff95d292b04aa0c72e34c84dfd7075e7997cf05ae4826a1
|
||||
dce_ast: 4eda0426e943afc272c16e4fb45f9cdd8d5ea97d39cb495361a71549dfbec66e
|
||||
bytecode: e434c09cee27a5dfb5a4e9e9fd26aa2ba6e7f0653fad3a4f2a7d85983ba559c9
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: e64985069c66d2678488b57ceab0026149c4ebaf1fc42ac15798fdc306f74d20
|
||||
unrolled_ast: e64985069c66d2678488b57ceab0026149c4ebaf1fc42ac15798fdc306f74d20
|
||||
ssa_ast: 073128b766cc8ea00519d7cdee4714796e631f2847db5f55b75d829101bd9552
|
||||
flattened_ast: 9b5233811932dc7004d77590063c9b7d2ff00be8bd7c7c8c81192ce5df740175
|
||||
inlined_ast: 9b5233811932dc7004d77590063c9b7d2ff00be8bd7c7c8c81192ce5df740175
|
||||
dce_ast: 9b5233811932dc7004d77590063c9b7d2ff00be8bd7c7c8c81192ce5df740175
|
||||
- - initial_ast: 6b548ac1d786b728c21d152061d7ae31e25fe8c3a93c38577a82f1c0c2ffd0b2
|
||||
unrolled_ast: 6b548ac1d786b728c21d152061d7ae31e25fe8c3a93c38577a82f1c0c2ffd0b2
|
||||
ssa_ast: f3daee14d82b5ff4064f11080deef28899853dbef55479ad86e1c6fe34cec041
|
||||
flattened_ast: 26dce66c06759444280565f35558f94c4c1550cbb589562ca7121f6651924bcc
|
||||
inlined_ast: 26dce66c06759444280565f35558f94c4c1550cbb589562ca7121f6651924bcc
|
||||
dce_ast: 26dce66c06759444280565f35558f94c4c1550cbb589562ca7121f6651924bcc
|
||||
bytecode: da1b0a83a17b801368b0a583b158d88d9d807a33000c8e89e82da123c8041aea
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 7a1afdab98a730090c3370305d8fa23a7a69f779b492288ab8bae2169b880118
|
||||
unrolled_ast: 7a1afdab98a730090c3370305d8fa23a7a69f779b492288ab8bae2169b880118
|
||||
ssa_ast: faaa8bd1f0f1f9d0c2d20cf6e8265e8db0593930bf38451509a218fdca25905a
|
||||
flattened_ast: 94377cdcfd12afd021b97302dc880bca782aeb9ea8b908dd3f8ef19e4d231e69
|
||||
inlined_ast: 94377cdcfd12afd021b97302dc880bca782aeb9ea8b908dd3f8ef19e4d231e69
|
||||
dce_ast: 94377cdcfd12afd021b97302dc880bca782aeb9ea8b908dd3f8ef19e4d231e69
|
||||
- - initial_ast: 778ee6a278f90c3c9a337517771c2c3fd31cf166c0fe38ba7e1da097ec0f81f1
|
||||
unrolled_ast: 778ee6a278f90c3c9a337517771c2c3fd31cf166c0fe38ba7e1da097ec0f81f1
|
||||
ssa_ast: 577c1fdc33f8a0182faa399d4f2a5d49f95efba574f0cf451511c3b8a447914f
|
||||
flattened_ast: 90c9589974b2fe7c5e320e4ac76a1655f4b84e60ed8ec9b8c52c9f1f29e4a682
|
||||
inlined_ast: 90c9589974b2fe7c5e320e4ac76a1655f4b84e60ed8ec9b8c52c9f1f29e4a682
|
||||
dce_ast: 90c9589974b2fe7c5e320e4ac76a1655f4b84e60ed8ec9b8c52c9f1f29e4a682
|
||||
bytecode: bde2653fac0393940c5400272e53492228206e50abb36ce080b95043003ee976
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 3e3635b9f0e8098731455f2d2b49026c90cea00d07461e7cbcaa5759bf823be4
|
||||
unrolled_ast: 3e3635b9f0e8098731455f2d2b49026c90cea00d07461e7cbcaa5759bf823be4
|
||||
ssa_ast: 21ca11c494c4f9c4e204f368e967727bda93ce65962c86935ce2fe6895197ebb
|
||||
flattened_ast: c5ebee78d83725ede5e4dce6ca0f77339b3d5dd0eb727fbf32bd6c476f569173
|
||||
inlined_ast: c5ebee78d83725ede5e4dce6ca0f77339b3d5dd0eb727fbf32bd6c476f569173
|
||||
dce_ast: c5ebee78d83725ede5e4dce6ca0f77339b3d5dd0eb727fbf32bd6c476f569173
|
||||
- - initial_ast: 853fd69f7e97be37c0f6a19994e4e9bf9ae354ff2a41c3de90d23d8f0d777884
|
||||
unrolled_ast: 853fd69f7e97be37c0f6a19994e4e9bf9ae354ff2a41c3de90d23d8f0d777884
|
||||
ssa_ast: c08b13b85d836c9a2e4d0f6fb1b20ccc60a9d1aa8cc7ca81b1448ddd2feef8e0
|
||||
flattened_ast: ebfda40c22a70c7490170c019fc22eef2552122300b28947b7c1826bc889cd1e
|
||||
inlined_ast: ebfda40c22a70c7490170c019fc22eef2552122300b28947b7c1826bc889cd1e
|
||||
dce_ast: ebfda40c22a70c7490170c019fc22eef2552122300b28947b7c1826bc889cd1e
|
||||
bytecode: c0b90b7f7e80041dc1a314c1a87290534936018fb001c6e1291266a02393c6f2
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 83a584fa8274354e7caf1b9f530ee91008fb867a341045e84f1849cd8dc88e88
|
||||
unrolled_ast: 83a584fa8274354e7caf1b9f530ee91008fb867a341045e84f1849cd8dc88e88
|
||||
ssa_ast: 999147035ff811021e9a050ec2fabecb6ff70eacbac0ca4b6c143b9105dfd28e
|
||||
flattened_ast: 0839b38833dc1b6dfcf512a031d4c6fa17de417ee965fd33963c9ed5eb0b7b01
|
||||
inlined_ast: 0839b38833dc1b6dfcf512a031d4c6fa17de417ee965fd33963c9ed5eb0b7b01
|
||||
dce_ast: 0839b38833dc1b6dfcf512a031d4c6fa17de417ee965fd33963c9ed5eb0b7b01
|
||||
- - initial_ast: ab78d2239021d6f96bbea881d9937d95e08dea46f20c122899e0b36d0446c4c1
|
||||
unrolled_ast: ab78d2239021d6f96bbea881d9937d95e08dea46f20c122899e0b36d0446c4c1
|
||||
ssa_ast: d90f0982b624f26c17177ead06ed3d48a96627dd187a8c38b134714e33f48260
|
||||
flattened_ast: 4bc298cb5533064ca61830980466ed1ed7c21a15d38bee043e3e0ed0348de182
|
||||
inlined_ast: 4bc298cb5533064ca61830980466ed1ed7c21a15d38bee043e3e0ed0348de182
|
||||
dce_ast: 4bc298cb5533064ca61830980466ed1ed7c21a15d38bee043e3e0ed0348de182
|
||||
bytecode: 134904b86b96581876c2ca0c6ead651dda0dc9f2fb6dc583400133410b7deede
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 28c909dfc3df83359c4f2f4b989329201c16e944b5c1206c0b770753cf07b60a
|
||||
unrolled_ast: 28c909dfc3df83359c4f2f4b989329201c16e944b5c1206c0b770753cf07b60a
|
||||
ssa_ast: 9a9c933d5a770b15fda13380e32bdcb72353582dc4e60db47c46ed5a95bead6f
|
||||
flattened_ast: f7a6fe164fe7eea96468302395fa5f7a78ebed2b7bab56bbee925f773c5d290d
|
||||
inlined_ast: f7a6fe164fe7eea96468302395fa5f7a78ebed2b7bab56bbee925f773c5d290d
|
||||
dce_ast: f7a6fe164fe7eea96468302395fa5f7a78ebed2b7bab56bbee925f773c5d290d
|
||||
- - initial_ast: f39f9a60bf3468977bc507347f90029d098e16e97cb8f976add9a40cd986e285
|
||||
unrolled_ast: f39f9a60bf3468977bc507347f90029d098e16e97cb8f976add9a40cd986e285
|
||||
ssa_ast: fc284c302558f32f72f8ed8186ac5114ea54a94d888de15907ad83207a02324b
|
||||
flattened_ast: 30952aa8bf4898cf653ebb094c31cee491a570a5084776082e7174bd66893293
|
||||
inlined_ast: 30952aa8bf4898cf653ebb094c31cee491a570a5084776082e7174bd66893293
|
||||
dce_ast: 30952aa8bf4898cf653ebb094c31cee491a570a5084776082e7174bd66893293
|
||||
bytecode: 56a9fa48a00d1b38b6f60a93ef2168b2c0ce9c23ba3cb7bffa40debfc1b16180
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c78718de7e86670216551ca3e1a7ff79eac984bbd7d3916efc0471fc47dac07e
|
||||
unrolled_ast: c78718de7e86670216551ca3e1a7ff79eac984bbd7d3916efc0471fc47dac07e
|
||||
ssa_ast: e5a52db1daeec16966a78bb2f7ef2449af7a7e1ff6eab67a63f24030b0d8077b
|
||||
flattened_ast: f7632dc71f1fcdb0c810dc41804d7a774f6470d667667ea4ebafaef764c37c62
|
||||
inlined_ast: f7632dc71f1fcdb0c810dc41804d7a774f6470d667667ea4ebafaef764c37c62
|
||||
dce_ast: f7632dc71f1fcdb0c810dc41804d7a774f6470d667667ea4ebafaef764c37c62
|
||||
- - initial_ast: 30edf3aaef89e9461c7fdf5a4e789edd00d7cc1b44be3387d4e0e59a70dc2e43
|
||||
unrolled_ast: 30edf3aaef89e9461c7fdf5a4e789edd00d7cc1b44be3387d4e0e59a70dc2e43
|
||||
ssa_ast: 72b1100d61b4477e324e30ad1eced22689eb3d63a2fd672c55498ff9465429b9
|
||||
flattened_ast: 2569b27d888761edf53ca6312a8844318e61f8a3ebeeefbd6571098cf8bee52c
|
||||
inlined_ast: 2569b27d888761edf53ca6312a8844318e61f8a3ebeeefbd6571098cf8bee52c
|
||||
dce_ast: 2569b27d888761edf53ca6312a8844318e61f8a3ebeeefbd6571098cf8bee52c
|
||||
bytecode: 2332d5b7ed9910dc65c885e1aeedbbde00e02d95a55caa300a9cb72456707034
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 9e871518f362d925d3a49dc805f25270f20d8b471e75dca55bd08ddd95dba0a7
|
||||
unrolled_ast: 9e871518f362d925d3a49dc805f25270f20d8b471e75dca55bd08ddd95dba0a7
|
||||
ssa_ast: 4df5ebccb2b9337d9570b8b674bf110b21f03e19eed2bd62720503675dd0ed76
|
||||
flattened_ast: 1d523dd55672a7be0a853091da70a15e24c028f0585808b60bb4d435d2e28866
|
||||
inlined_ast: 1d523dd55672a7be0a853091da70a15e24c028f0585808b60bb4d435d2e28866
|
||||
dce_ast: 1d523dd55672a7be0a853091da70a15e24c028f0585808b60bb4d435d2e28866
|
||||
- - initial_ast: 7c30d305deb563c4446176cc16a27c5407c78eea7275c6e528bf425d1b034647
|
||||
unrolled_ast: 7c30d305deb563c4446176cc16a27c5407c78eea7275c6e528bf425d1b034647
|
||||
ssa_ast: 378c785982c1014acc1383b29b8a09dbdfd7f393b8912626e154cedeb8a0a335
|
||||
flattened_ast: 152776e1ce69acad498c75211d502d36dd000025cd024771ba7b78dfa30bc824
|
||||
inlined_ast: 152776e1ce69acad498c75211d502d36dd000025cd024771ba7b78dfa30bc824
|
||||
dce_ast: 152776e1ce69acad498c75211d502d36dd000025cd024771ba7b78dfa30bc824
|
||||
bytecode: 990eee0b87d70df046bad969201ad8afabff10162eb70c00f837fde81fed4104
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 51323fd6e2305e68d3a49b1e3beff44a25962a9d2f981952270725a10fb907eb
|
||||
unrolled_ast: 51323fd6e2305e68d3a49b1e3beff44a25962a9d2f981952270725a10fb907eb
|
||||
ssa_ast: 7480cf469ca3ed640d36d8c171a975885590bbc3cfaec0805d9d8aef6cd19518
|
||||
flattened_ast: 2610072b45f28619332adf130aa46d92bb6d3e008c88e0d59c35407d7fe84a09
|
||||
inlined_ast: 2610072b45f28619332adf130aa46d92bb6d3e008c88e0d59c35407d7fe84a09
|
||||
dce_ast: a5cc2bdb045e2f9e981c12c2411f397b4af69a2aa6cb3a83b14403ce3155e8d6
|
||||
- - initial_ast: 75366768a7b2cb5b76e0aabd11f29dcec41d1a9d20c98ba227d9c784c8e0bd64
|
||||
unrolled_ast: 75366768a7b2cb5b76e0aabd11f29dcec41d1a9d20c98ba227d9c784c8e0bd64
|
||||
ssa_ast: 35c7bcdf89e7d7bd2e1d1d2ada0ab6de758f91c7160a681af8174bdd19e3c4d8
|
||||
flattened_ast: 5cd80f02b55d9aea6d5a752b6a9b0b90a84deefffd9797a2da0ffe2c5405a558
|
||||
inlined_ast: 5cd80f02b55d9aea6d5a752b6a9b0b90a84deefffd9797a2da0ffe2c5405a558
|
||||
dce_ast: a1c587fc02d556c185a43ee3ceed0be4027bbaba0c4fdd7b8939d0bb2b7907a7
|
||||
bytecode: bb260232bbd0ccede368961a31abeef5edc7e00cab3348b4b8518d4e5798a6b5
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 7cce4e768432d303e86d5d8f38ca10df9fcb641ab1bd791cfed3180594f6cea7
|
||||
unrolled_ast: 7cce4e768432d303e86d5d8f38ca10df9fcb641ab1bd791cfed3180594f6cea7
|
||||
ssa_ast: a8dcccc18c4984c95a15bc850343a4c0a6bd4de3745cee2d9dc5f204bf8d5290
|
||||
flattened_ast: dac527fa65b44faef014c5046d668bf8f4fb6731beedf04369367b546521d54f
|
||||
inlined_ast: dac527fa65b44faef014c5046d668bf8f4fb6731beedf04369367b546521d54f
|
||||
dce_ast: dac527fa65b44faef014c5046d668bf8f4fb6731beedf04369367b546521d54f
|
||||
- - initial_ast: 771493cfb3297abd1fbfda7b2cff7254f9106addefe0a8b5f489ecec1d83baa3
|
||||
unrolled_ast: 771493cfb3297abd1fbfda7b2cff7254f9106addefe0a8b5f489ecec1d83baa3
|
||||
ssa_ast: be444afe192366899792ef107676880d8f5a6f7bd7da49586d8762b2fc3fcd37
|
||||
flattened_ast: 1197ae78c9aabdcf47b4b8c21d800c7541703fef96789584fa817ebe0b8018b3
|
||||
inlined_ast: 1197ae78c9aabdcf47b4b8c21d800c7541703fef96789584fa817ebe0b8018b3
|
||||
dce_ast: 1197ae78c9aabdcf47b4b8c21d800c7541703fef96789584fa817ebe0b8018b3
|
||||
bytecode: c3a0c03f4324a6dd6baea42e664ffad91868714739e03525dcbc968582007ceb
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c45d509ec04f7f518387ad6a3e24a97631a50ab4d0cf122af78e03df5cb41328
|
||||
unrolled_ast: c45d509ec04f7f518387ad6a3e24a97631a50ab4d0cf122af78e03df5cb41328
|
||||
ssa_ast: 6aa7493d54a6eb2a5136980f379966cb25198c905c358b807c10bdb4e163de5d
|
||||
flattened_ast: 047a89ee6cdf364b877eca15cdc92954c7ba669fddd3c99fece729abcfd211e3
|
||||
inlined_ast: 047a89ee6cdf364b877eca15cdc92954c7ba669fddd3c99fece729abcfd211e3
|
||||
dce_ast: 047a89ee6cdf364b877eca15cdc92954c7ba669fddd3c99fece729abcfd211e3
|
||||
- - initial_ast: 7b2d55feccfedf17c5acaf63cbe41f3313518cdabf096c968e1104f3f5b4b869
|
||||
unrolled_ast: 7b2d55feccfedf17c5acaf63cbe41f3313518cdabf096c968e1104f3f5b4b869
|
||||
ssa_ast: af9661e5a0685e552b388ee6e48b8556d367d00721159fedf35288c442f21699
|
||||
flattened_ast: da3100e3f67e9ddaf90f4d534ac6ed5dc9897edd6fb1c95c8d27cdaecf85a7ac
|
||||
inlined_ast: da3100e3f67e9ddaf90f4d534ac6ed5dc9897edd6fb1c95c8d27cdaecf85a7ac
|
||||
dce_ast: da3100e3f67e9ddaf90f4d534ac6ed5dc9897edd6fb1c95c8d27cdaecf85a7ac
|
||||
bytecode: 3c391009be59588562aa4a34d1b00508cd253c94d35a66741962352c76a92633
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: d208faafad448ad0877c98ca0e950a6de31dd1ed12332c5475f670fda163280f
|
||||
unrolled_ast: d208faafad448ad0877c98ca0e950a6de31dd1ed12332c5475f670fda163280f
|
||||
ssa_ast: a69d601b77e30b0a5564c8c97308b6a4d377a8484dfcfc476f8ceeaa48334d98
|
||||
flattened_ast: dc6accfaa25f07245d9f7c6b281e9924fc02b3c2175eb8930f9a925e0372a694
|
||||
inlined_ast: dc6accfaa25f07245d9f7c6b281e9924fc02b3c2175eb8930f9a925e0372a694
|
||||
dce_ast: dc6accfaa25f07245d9f7c6b281e9924fc02b3c2175eb8930f9a925e0372a694
|
||||
- - initial_ast: 541f771580c270fa3c366fdea0c4aab112241afbf502c43ec0689762363c827b
|
||||
unrolled_ast: 541f771580c270fa3c366fdea0c4aab112241afbf502c43ec0689762363c827b
|
||||
ssa_ast: aaf2c7c0e099db4a5342d19b7b6e69ab4866c985b5553c53b08ff7eed8642f64
|
||||
flattened_ast: 027e8353d91ef1c45a9d3d1db3e0ee1f2224d7be3a41c18c9f86a688e85e5106
|
||||
inlined_ast: 027e8353d91ef1c45a9d3d1db3e0ee1f2224d7be3a41c18c9f86a688e85e5106
|
||||
dce_ast: 027e8353d91ef1c45a9d3d1db3e0ee1f2224d7be3a41c18c9f86a688e85e5106
|
||||
bytecode: 3ff716b96c532801f4fa5310f4eedf8f96fe15bd7db3bf087e7b64a161153945
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 6fd597b235a9ab6fa532413d5656c125639ebe5036284da78f9e5b6c69007b7d
|
||||
unrolled_ast: 6fd597b235a9ab6fa532413d5656c125639ebe5036284da78f9e5b6c69007b7d
|
||||
ssa_ast: 08bffe308901f0274b378f5b9011df8c245fc51d69856317430b78b5916f3943
|
||||
flattened_ast: e77fd9b2be65e8a05590387d093a18607cdc7130fcb42c9f48820b28285219c4
|
||||
inlined_ast: e77fd9b2be65e8a05590387d093a18607cdc7130fcb42c9f48820b28285219c4
|
||||
dce_ast: 4cdfeac49296a80c83c11ed59e1eadf21051ef9d851f58a02d42d1b61b319ed1
|
||||
- - initial_ast: 3498c564c77031239e93e2a745431ae348e48e542705524de326ac67afaad63f
|
||||
unrolled_ast: 3498c564c77031239e93e2a745431ae348e48e542705524de326ac67afaad63f
|
||||
ssa_ast: 30266684ef3db98bc60a6f6dde8cb285c9e27fe79f9581aabbd4e732c368997d
|
||||
flattened_ast: 19277e39b931d9c8c0a49e3e88a64b9f4bfca44b4a72e41bca5debc07a488b14
|
||||
inlined_ast: 19277e39b931d9c8c0a49e3e88a64b9f4bfca44b4a72e41bca5debc07a488b14
|
||||
dce_ast: 4ac699200ffa50c5304aa6f3aa5511b11e99e9fd99aa115772c4d2035cca841d
|
||||
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: bd3ad043ad61fc8636d1bd58ce0b7a47267a4984546b02a42a0fced89751be66
|
||||
unrolled_ast: bd3ad043ad61fc8636d1bd58ce0b7a47267a4984546b02a42a0fced89751be66
|
||||
ssa_ast: b64e7c6c0130cf4855985b81424843521d8694b6756c137d392e0d560045851e
|
||||
flattened_ast: ab295e2feb5d6e653270f88fe341d8a2aacd26e09a1949ae87c17440a2175b97
|
||||
inlined_ast: ab295e2feb5d6e653270f88fe341d8a2aacd26e09a1949ae87c17440a2175b97
|
||||
dce_ast: 91da30c194862277ddc99fef9ee7ec374649461eea7f89c29fcb48e7fa583c59
|
||||
- - initial_ast: e7a6e1d52af61fe36010137f56a679b20d90c0a0ba7194c343784c97f987d3ca
|
||||
unrolled_ast: e7a6e1d52af61fe36010137f56a679b20d90c0a0ba7194c343784c97f987d3ca
|
||||
ssa_ast: b7a79d5fc1992450ae222f2cb1511ae3845ec80cdb5612680610a33c18088d75
|
||||
flattened_ast: b3b30f99b0f01027ba1b16806068b888cd48b5e2f04b6760c4c2530846122dde
|
||||
inlined_ast: b3b30f99b0f01027ba1b16806068b888cd48b5e2f04b6760c4c2530846122dde
|
||||
dce_ast: d4db96add4e60f670f573c31468de00be3d5b086830efd8a5a1a5dfdfc7a011e
|
||||
bytecode: 680bee256d40c3ca4226844e73ae277e6db6af6398cab44674e421359f50cb83
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c9b0ddeb037da9e40d05ede3b7a8fb64087f2ac47fb4c1f0c0523a2e3b50cb85
|
||||
unrolled_ast: c9b0ddeb037da9e40d05ede3b7a8fb64087f2ac47fb4c1f0c0523a2e3b50cb85
|
||||
ssa_ast: be3af5d7c55442200353dee77047d0a30d8873eb25d0b7da0786fb15b074fd1e
|
||||
flattened_ast: 5a90052cf2d88212d54c987ba60339d4b5d9579d2316965a799662ecba6b4b8c
|
||||
inlined_ast: 5a90052cf2d88212d54c987ba60339d4b5d9579d2316965a799662ecba6b4b8c
|
||||
dce_ast: d8ed4af576dfa745f37cd9ca9256ab9067bf9f6e56a0dbf76523ba7b859c7ff9
|
||||
- - initial_ast: 200d406bb84a2b12a023d9aa6c9fb95035aed4fb171f4ae2bb7c0aa4fcf31bca
|
||||
unrolled_ast: 200d406bb84a2b12a023d9aa6c9fb95035aed4fb171f4ae2bb7c0aa4fcf31bca
|
||||
ssa_ast: 004d243356aafdf6cad6c8506b4fbac23a46376c1b6867f7be675aaebb3eb208
|
||||
flattened_ast: e893304f6a5a44eb53da6d25d023f705bd417429c9ff793d1a5d478284ba8f18
|
||||
inlined_ast: e893304f6a5a44eb53da6d25d023f705bd417429c9ff793d1a5d478284ba8f18
|
||||
dce_ast: badc11deb2180b86cd9908520df6099fde87669ae29c74afd724063919950622
|
||||
bytecode: 83cd9a0a063adab9de89253b1a5be0b4bbdc04a2a73a62a03fc1dd1639a4fbbf
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 0abc353cf7d65b1c1b0272dea8760b66a479cd83656397498c6e804fcc57eca9
|
||||
unrolled_ast: 0abc353cf7d65b1c1b0272dea8760b66a479cd83656397498c6e804fcc57eca9
|
||||
ssa_ast: ce832fb383ceccaaa63b629cea7da2a3bb918e891499dd0027e9eeb86aeb9a8d
|
||||
flattened_ast: 1522af9dca9861839b442c6e5e8a935d60c4fde932fba9ae125eee7f917405ab
|
||||
inlined_ast: 1522af9dca9861839b442c6e5e8a935d60c4fde932fba9ae125eee7f917405ab
|
||||
dce_ast: a221711722c11cb03087868a6670573bf17f47cf1303c75515950c3e28e86626
|
||||
- - initial_ast: 9ef072ecf82cb5748ef56540885990a387d22ab8a80fc2e2b9a76d6993f6b7b4
|
||||
unrolled_ast: 9ef072ecf82cb5748ef56540885990a387d22ab8a80fc2e2b9a76d6993f6b7b4
|
||||
ssa_ast: ba4c512a80279acd717aa42c2cba0277cf2af2e823eba66dd07f05867cad81ba
|
||||
flattened_ast: a89f2983a293f8ac22620cad50926738f987cda60e931e11de28268049470d2a
|
||||
inlined_ast: a89f2983a293f8ac22620cad50926738f987cda60e931e11de28268049470d2a
|
||||
dce_ast: 2a43b277d040dde328b04f3740ea0866eec08c66db8d28df79648e110b835602
|
||||
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 8737bb14b9811f8393e7b1214f875f6298a4cced885ff1d0b103b87c4dae42e7
|
||||
unrolled_ast: 8737bb14b9811f8393e7b1214f875f6298a4cced885ff1d0b103b87c4dae42e7
|
||||
ssa_ast: ffdef22bb99c2f24950b74419fe2a51b15dfd3efb7f1faed43f8d452fb21ad33
|
||||
flattened_ast: 207311ab56f2ec438a841db6db558c009b5a74a21a335f83b957f6dd246ca922
|
||||
inlined_ast: 207311ab56f2ec438a841db6db558c009b5a74a21a335f83b957f6dd246ca922
|
||||
dce_ast: a6fde2b969db27f40d74709909bb4eb29e5108074b39429000025549838a5273
|
||||
- - initial_ast: 3ba9621aa1e98533320d0ad870f3db063be8c640893d894d04df8951dd2e7a59
|
||||
unrolled_ast: 3ba9621aa1e98533320d0ad870f3db063be8c640893d894d04df8951dd2e7a59
|
||||
ssa_ast: d02b80b89778db49120f51e4c4458a316995070f93e4c3ba602ecd376e4fb947
|
||||
flattened_ast: 6d7698f119f99d3e022015f3b9872842dc6575bae0c421c307f3210044df51e2
|
||||
inlined_ast: 6d7698f119f99d3e022015f3b9872842dc6575bae0c421c307f3210044df51e2
|
||||
dce_ast: 870f8e40d53922c4cebc657fac8bb2b3a86429eef48114c55dbc2b8f77fa6f0e
|
||||
bytecode: 941f89f9872fc4a4cd8657d4ddc9bfe76d332e25cebfb374d29f8f9359ffb4ce
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 6b3fa8d416042367bac792f30d3b9f8b6dc91fc985f208956152b97532e26642
|
||||
unrolled_ast: 6b3fa8d416042367bac792f30d3b9f8b6dc91fc985f208956152b97532e26642
|
||||
ssa_ast: 72eebeba1f6a40149ec31a8a52d85ee72afe9997b1c25c3bfb62b1d8e01a1c5a
|
||||
flattened_ast: a994eee165bc14fc461972a8b0b45a75a1069498fc8cf5f05c72b30eb70805f3
|
||||
inlined_ast: a994eee165bc14fc461972a8b0b45a75a1069498fc8cf5f05c72b30eb70805f3
|
||||
dce_ast: 9a55f11504482e734847221e0a80a38541c9625932aa093a488d64514b660175
|
||||
- - initial_ast: 3a414491dcc55c0c7f6bc1cba6293090d19391ba67132b05cc4661fc00dac263
|
||||
unrolled_ast: 3a414491dcc55c0c7f6bc1cba6293090d19391ba67132b05cc4661fc00dac263
|
||||
ssa_ast: 76238bbd3667861ac9354f0c5a3cd1848bf871726c40622f067d7d96fea1f46f
|
||||
flattened_ast: dd2041696e3f097fe38d496f74a093f1c98323691d5410c3e083f903b3b3f056
|
||||
inlined_ast: dd2041696e3f097fe38d496f74a093f1c98323691d5410c3e083f903b3b3f056
|
||||
dce_ast: b208128a7b45a47478ab06a2d9cda30520c1477c640df9fe8238e6ecd56d4489
|
||||
bytecode: b325c77f01ed291126c9b43ecbf54280a09ad0be299ca2aa8698c77af8e4d9bb
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c4760546fc56254c08ab900e3e94f670cfd178e1e1b078f6a5ffc83cadbc1c5f
|
||||
unrolled_ast: c4760546fc56254c08ab900e3e94f670cfd178e1e1b078f6a5ffc83cadbc1c5f
|
||||
ssa_ast: 3b7100d9818103d05d90878c57bf1ec2cbeb2b60b760a35f52e0dcf74673d16a
|
||||
flattened_ast: 5b9b91bad19337793ac938989de8eb9dd0fb57d5803bd0489779d890a95546e7
|
||||
inlined_ast: 5b9b91bad19337793ac938989de8eb9dd0fb57d5803bd0489779d890a95546e7
|
||||
dce_ast: 103fcf3bfad3b6451e678b1cb6ccfe20aee7bda22d590358b07d88a3aba2a985
|
||||
- - initial_ast: 43de96dcfc2fcd80e20165a546c8f87129f5591cf1f3efc0fdace9bb5ab0c8fe
|
||||
unrolled_ast: 43de96dcfc2fcd80e20165a546c8f87129f5591cf1f3efc0fdace9bb5ab0c8fe
|
||||
ssa_ast: de4d3d7bef838786ae20d83a316bf42af23c565493261c314cc4c79c1f2c2748
|
||||
flattened_ast: 02f90df4fa62af993c497699eb0c3a336b01fa21fec3770aeae66f068c2f9172
|
||||
inlined_ast: 02f90df4fa62af993c497699eb0c3a336b01fa21fec3770aeae66f068c2f9172
|
||||
dce_ast: 2616e762228cec544ac98ce250c62297917d01bce094f8f1fc33d2e1b4518208
|
||||
bytecode: 1838804cfa5f0c1f7a9bb7ba88dc0207faa0e584b0b35bb34cce7091a9178fe9
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 48d5be1d1b3c4fb8504ce57800d53999f4a92b4899d809e727a0aec33fca028f
|
||||
unrolled_ast: 48d5be1d1b3c4fb8504ce57800d53999f4a92b4899d809e727a0aec33fca028f
|
||||
ssa_ast: 1f4e9c7d3669da233a2b67191c3d9c7fd8d5ba41f65f9256eda21c45623af813
|
||||
flattened_ast: dcef02c444b2a8482e8212aabc7af7184311ab3126ad2ca963c43488545db5d1
|
||||
inlined_ast: dcef02c444b2a8482e8212aabc7af7184311ab3126ad2ca963c43488545db5d1
|
||||
dce_ast: 9c7963fba2b84ad1c501e3626370b2e8bdab7b4e977cfecc9fe025c0f7affefc
|
||||
- - initial_ast: 6256b3aa50ff83f8f05ad31bf0505e1802368bddb66b4eed8c97b3e446d7038d
|
||||
unrolled_ast: 6256b3aa50ff83f8f05ad31bf0505e1802368bddb66b4eed8c97b3e446d7038d
|
||||
ssa_ast: efa1cfe0ddd338265bfd1dd2167f5c288dc92280eb527b1dc94faf2e163df6ea
|
||||
flattened_ast: 29d8d32740c0fecfa9a2879eb93b527f8cc9d5841a825b53e91c2401e6bd51c1
|
||||
inlined_ast: 29d8d32740c0fecfa9a2879eb93b527f8cc9d5841a825b53e91c2401e6bd51c1
|
||||
dce_ast: ae22e8b0e32bd60cdfaa5e6246deea26c520a11a0248d516cd47038193a84dcc
|
||||
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: a5ed14e8476fdff1f5fcb5f92e0b5fb2669a33eefdf537489fb73182ee608af4
|
||||
unrolled_ast: a5ed14e8476fdff1f5fcb5f92e0b5fb2669a33eefdf537489fb73182ee608af4
|
||||
ssa_ast: 079195bb127ebf4db1621c06fa8f856a4a751e7a914bddc26961541efaf8ea4c
|
||||
flattened_ast: d7a1868221f871563ef4151a5ec947f2bfc2fb9ae74eb60058134a1c3a503e0f
|
||||
inlined_ast: d7a1868221f871563ef4151a5ec947f2bfc2fb9ae74eb60058134a1c3a503e0f
|
||||
dce_ast: 55410ad47534700121ddd46363864fabe433a9442f81115b4670d7ed85ef4c2d
|
||||
- - initial_ast: d123591ffea71b5b2a30c85d4be12428fc927acca9aa52187e858990002c0a7d
|
||||
unrolled_ast: d123591ffea71b5b2a30c85d4be12428fc927acca9aa52187e858990002c0a7d
|
||||
ssa_ast: e79aa027e1c2ada8b44689fa102cf02e8370a6bbf5450b8a4d8a9b21d704d719
|
||||
flattened_ast: 481fade59dd13622963e93a4afe532c8e3975e9821fab2b1bd5386856acda3d3
|
||||
inlined_ast: 481fade59dd13622963e93a4afe532c8e3975e9821fab2b1bd5386856acda3d3
|
||||
dce_ast: 57e14ce61d022acc59902f8aa38347ae969e832fdf82e9eb0dc4f523825a4935
|
||||
bytecode: ff9bf81abae8332e89f00ebd53dda80528d7a582ade15b2fec53a88a7c5f0532
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 675fb4ead401c419a7a680811649b363a58356b524f5b08ec7f5569728c99f15
|
||||
unrolled_ast: 675fb4ead401c419a7a680811649b363a58356b524f5b08ec7f5569728c99f15
|
||||
ssa_ast: af736487218bf2fe2b1ca02a0b153b942394888de0c7aff41120f73a9153691f
|
||||
flattened_ast: af8bf4d8a2829319891ddef9c9f1f56a3e051c256a7478c6aadb478e7452f85f
|
||||
inlined_ast: af8bf4d8a2829319891ddef9c9f1f56a3e051c256a7478c6aadb478e7452f85f
|
||||
dce_ast: 83119fda7f384e060c443262a323a15c176b5dc27e74b3bcf30a1e48aa547d28
|
||||
- - initial_ast: 63bcc0bdfa7d14f170b363969c8371129b634ceefce3638c300a5aebdb4e6059
|
||||
unrolled_ast: 63bcc0bdfa7d14f170b363969c8371129b634ceefce3638c300a5aebdb4e6059
|
||||
ssa_ast: 1d201bd5994f3a34787be84a453f237a04f3d7d6ba63dcaa83fea62774d1195f
|
||||
flattened_ast: 08aabffc8a0888a1a46f6ff4a0959aaa46be5101658ca489d2ee418b0532779c
|
||||
inlined_ast: 08aabffc8a0888a1a46f6ff4a0959aaa46be5101658ca489d2ee418b0532779c
|
||||
dce_ast: 6d33bb2e76d5f2d2420844fc75556598395b6608335f15599d24f72b0551d039
|
||||
bytecode: 7cbb302c804e8dcb41c04687fe6f45aa748c5b7c0821f3825d21b424a4f89828
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 7dbd33614fc5d7ae3aecb3273e2f9cba1f36b100452b6fbe5e5d46a2e55180f9
|
||||
unrolled_ast: 7dbd33614fc5d7ae3aecb3273e2f9cba1f36b100452b6fbe5e5d46a2e55180f9
|
||||
ssa_ast: d0aa19d9713d3ca3fdec697f4cba37bc7146815af885aeec02294537ad37f006
|
||||
flattened_ast: c5337f7ef66cab33c31de5a2b79301c919995fcb0849b2e917223e466d7a9eef
|
||||
inlined_ast: c5337f7ef66cab33c31de5a2b79301c919995fcb0849b2e917223e466d7a9eef
|
||||
dce_ast: 54bf7ae36ca87deca1c38d5a40b54fce8e7c1f64f638ee0d33ca74d19cee17fb
|
||||
- - initial_ast: 1345d2b99e36401addfe556c910e2598fc9725b623eeb3a8976b87d9688cecee
|
||||
unrolled_ast: 1345d2b99e36401addfe556c910e2598fc9725b623eeb3a8976b87d9688cecee
|
||||
ssa_ast: 583bda9b3649325ae7e3e537583690f13f91d528c4b4cb52bfe6fd7f74a7de3f
|
||||
flattened_ast: 4889a973b75b4f4b584f1f298f7ebb5a34ecf3e7a312d5155db108957128bf11
|
||||
inlined_ast: 4889a973b75b4f4b584f1f298f7ebb5a34ecf3e7a312d5155db108957128bf11
|
||||
dce_ast: 674eb9bb060298f3c280e86526cc8c481cf969bc4336a7891d9c6c52f85283e7
|
||||
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 9e1265b1211819172c08be5779b2b0b7e1839a7aa9a88ab6c77243a9a1711345
|
||||
unrolled_ast: 9e1265b1211819172c08be5779b2b0b7e1839a7aa9a88ab6c77243a9a1711345
|
||||
ssa_ast: 8ad36d53ee8e5064346547ccd87488011c18fc6f902ebcb8a13a1b3cba30ba29
|
||||
flattened_ast: bdc6854d758b32202f4928c85f3861398fd11d0f6ec2bd0fac0972fd8e2e6648
|
||||
inlined_ast: bdc6854d758b32202f4928c85f3861398fd11d0f6ec2bd0fac0972fd8e2e6648
|
||||
dce_ast: 800890b1573816d74bc99385d77f42087f7ab4cc0d3c9ee99f26b0259a23b22c
|
||||
- - initial_ast: f99f7e4852b28e80f5f897fe39256e99b0fbfd98e2f3918134dd6a2b7334bf26
|
||||
unrolled_ast: f99f7e4852b28e80f5f897fe39256e99b0fbfd98e2f3918134dd6a2b7334bf26
|
||||
ssa_ast: 0b08c41beb2ce37e2b050595a1c8e6b08cb6c96df11d66d0ff914bbf079e6e05
|
||||
flattened_ast: 6aced85a3c7b2a9a2af15eb886110f1a06d7645a37ad7335f9c7b9a8e7d5e59c
|
||||
inlined_ast: 6aced85a3c7b2a9a2af15eb886110f1a06d7645a37ad7335f9c7b9a8e7d5e59c
|
||||
dce_ast: 9b879f75e7b4bdc4f38848eb131e9fa23b2c5d2cb424348f865941fe6f1f8164
|
||||
bytecode: d5ece61c3e7fb656863858b29941f7947b344a5ff1b4985ae467689f58938553
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c7d38c1c176bd8b4ee26013299187d1008aaa16acfba69945ddcdf17427fc072
|
||||
unrolled_ast: c7d38c1c176bd8b4ee26013299187d1008aaa16acfba69945ddcdf17427fc072
|
||||
ssa_ast: aae6639ac1536f7fd3273f6816dde1d280cd72042aa0942d20f3d7a2e2d770ac
|
||||
flattened_ast: d3eab777e3125479f833194c950ac92ba07e420d36d664ba3636f977e08e2ef5
|
||||
inlined_ast: d3eab777e3125479f833194c950ac92ba07e420d36d664ba3636f977e08e2ef5
|
||||
dce_ast: 0d892639f1f36263305a24bffb22c87bce630bbf0e9bc80b298946e4fa9eb046
|
||||
- - initial_ast: 02256e685ce23c6aa8b840396c992ae54d9ae9c27367a697aa790f070c39b3c0
|
||||
unrolled_ast: 02256e685ce23c6aa8b840396c992ae54d9ae9c27367a697aa790f070c39b3c0
|
||||
ssa_ast: d9b7b4ee5fcb97251e7ee9499ba7f2dca5edec7eb4e8ebdf83d4a1ea647eac64
|
||||
flattened_ast: c26d9480e3f93a232c11e55394bd44189c1911b1b3c965a76160b40415849237
|
||||
inlined_ast: c26d9480e3f93a232c11e55394bd44189c1911b1b3c965a76160b40415849237
|
||||
dce_ast: 8f4789bf300fb91a27af9ecae91d8e8e08bee6b2dab692e96b2636e006523aab
|
||||
bytecode: a80b560327138b8bb041f5a6cea148be39bc74dad6a47f45621d207b625a1424
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: a9be315a3445f9f02b64382f5506e9d367f3aeb8f4785df88ff8ac0fadedfc1e
|
||||
unrolled_ast: a9be315a3445f9f02b64382f5506e9d367f3aeb8f4785df88ff8ac0fadedfc1e
|
||||
ssa_ast: 67e4e9c88fa3c8c72856a9a59bb0e3ef9211981ee9a9eef752b1f832cac121f8
|
||||
flattened_ast: 73844e9aa33ebc6a1a878f5d83f652eb89b467c82e8f47b2190820e2b5f52ac4
|
||||
inlined_ast: 73844e9aa33ebc6a1a878f5d83f652eb89b467c82e8f47b2190820e2b5f52ac4
|
||||
dce_ast: 099e7069ae0639e7bafde9cf92773621394f5f1eabf432b12adae16c80e06605
|
||||
- - initial_ast: d39d5442a88a4991fe55cf474c159b4b017d0f11daa589649ce6e86523c8b348
|
||||
unrolled_ast: d39d5442a88a4991fe55cf474c159b4b017d0f11daa589649ce6e86523c8b348
|
||||
ssa_ast: 223b7cbbf1fc71b67697451c1aef7cd754256d78fc8cd1f79582e83b4a33f0e5
|
||||
flattened_ast: 9627cd027b2cc268dfe6bb256128812e76a36b30eddd739fce0ad0cd97b99a3b
|
||||
inlined_ast: 9627cd027b2cc268dfe6bb256128812e76a36b30eddd739fce0ad0cd97b99a3b
|
||||
dce_ast: c4423bd97d8106ae47a222f3bfeef898de82602f1d32c71cba269dd1f024c4c8
|
||||
bytecode: 319405c8fe80b59376c041f234ae2ef213e2d67b50701412411ac97294f91e69
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 864840baae360688c5aeb76a2a4af4f8928ded1b8b793a3f1e6bc2d39d3bc4c0
|
||||
unrolled_ast: 864840baae360688c5aeb76a2a4af4f8928ded1b8b793a3f1e6bc2d39d3bc4c0
|
||||
ssa_ast: 7870934dbdcf3c11a8e974011343342bb8671474ef2b48c58ae84836b3c66f79
|
||||
flattened_ast: 3c37a03f673a024359a7d233df9aa5ee0c16bcf4bf295953981005c51e4f9059
|
||||
inlined_ast: 3c37a03f673a024359a7d233df9aa5ee0c16bcf4bf295953981005c51e4f9059
|
||||
dce_ast: 9c7963fba2b84ad1c501e3626370b2e8bdab7b4e977cfecc9fe025c0f7affefc
|
||||
- - initial_ast: 287629280bb3ad4fecbaaa27c933520bc6dda9ffe8dde7bc33c3f18f38710201
|
||||
unrolled_ast: 287629280bb3ad4fecbaaa27c933520bc6dda9ffe8dde7bc33c3f18f38710201
|
||||
ssa_ast: 3136ccb3d0d91f0646259b8eeb7745afe69fdda24d3074e7b6a538d7987dc4bc
|
||||
flattened_ast: 5ed98885264a17775d880d90197480ba1643b7717349239008be263602c771f5
|
||||
inlined_ast: 5ed98885264a17775d880d90197480ba1643b7717349239008be263602c771f5
|
||||
dce_ast: ae22e8b0e32bd60cdfaa5e6246deea26c520a11a0248d516cd47038193a84dcc
|
||||
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 04653e3a6b37c90bb7c9dda51beb7cca18d2752671972ed2c22781453eee1576
|
||||
unrolled_ast: 04653e3a6b37c90bb7c9dda51beb7cca18d2752671972ed2c22781453eee1576
|
||||
ssa_ast: 6232d641a2106324612f574da221c5054bdb86f435d3c56d2b765cda6ffda6fd
|
||||
flattened_ast: 7e1f1830c9a660702409eee8b509584dc724644d8f11888b5d9767fed3e10fb8
|
||||
inlined_ast: 7e1f1830c9a660702409eee8b509584dc724644d8f11888b5d9767fed3e10fb8
|
||||
dce_ast: fe5dc920e6aa68917caf37138b4d00a11a1f9d97ffb4314591855fdf76369950
|
||||
- - initial_ast: 52e5677596cfeef742a9117e7aa7a64bcde3ae7e41380dd187b2dab1dcc98641
|
||||
unrolled_ast: 52e5677596cfeef742a9117e7aa7a64bcde3ae7e41380dd187b2dab1dcc98641
|
||||
ssa_ast: 8b693f92aab3cfff4a83af4fe5b26fd8be6ed0a0eb47056571e993c06af69d95
|
||||
flattened_ast: f5f224c3f859eacc1cab290c76c5a252fcc9471c6519b06ea839df915c372bed
|
||||
inlined_ast: f5f224c3f859eacc1cab290c76c5a252fcc9471c6519b06ea839df915c372bed
|
||||
dce_ast: 9d9f1fd4e6c00f33262e85963f3130276d1d0558c6525232864362ae39c2c710
|
||||
bytecode: 543bce9b35ef6f58454b6f690b9fae8dcf84f639acc37546ef137d8f8e60605c
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 1ed3c248a1f803e2f43ab6dd1a22847cacee6d2dfa90849281bfde139abb7815
|
||||
unrolled_ast: 1ed3c248a1f803e2f43ab6dd1a22847cacee6d2dfa90849281bfde139abb7815
|
||||
ssa_ast: ef985f04dede16998deb8e67568702ea747c92e5f815d815a87622f7b501d809
|
||||
flattened_ast: 18a771b32fe0ce395b4d0e041d9338bbfb5d822a4df3a80ae17d1ad89c545bb0
|
||||
inlined_ast: 18a771b32fe0ce395b4d0e041d9338bbfb5d822a4df3a80ae17d1ad89c545bb0
|
||||
dce_ast: e928d015f1a718a52c57eb61db26aa288c88fbd3711e7c2a310d6b1520f0d8f0
|
||||
- - initial_ast: 67b57ec0541b7afc4a18246df9a0ca364daf41f99150b4f7f4eafe0fcebb8fb0
|
||||
unrolled_ast: 67b57ec0541b7afc4a18246df9a0ca364daf41f99150b4f7f4eafe0fcebb8fb0
|
||||
ssa_ast: f0aeb009b835cd6aae86321682425cb18acf298cdd8fbf7016dfe153bc2ff793
|
||||
flattened_ast: c77ab4600a65575b90bf8678c98df0163d12e71811f2de2ab1d58af744d77080
|
||||
inlined_ast: c77ab4600a65575b90bf8678c98df0163d12e71811f2de2ab1d58af744d77080
|
||||
dce_ast: aae1ec2716070fc44bd4c9fdf8eecec7697dacca733e9d856976591d5b2c7e85
|
||||
bytecode: 5bf36355b36caa6fcd510f195c79195a7991b45e037c7d6ffe9479f3c2bb89f6
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 985487e286f41d77b95e043abaa99a700294acbdea52b026eabc1b403132d46e
|
||||
unrolled_ast: 985487e286f41d77b95e043abaa99a700294acbdea52b026eabc1b403132d46e
|
||||
ssa_ast: d5b506bf41288f39643f9c5caee3b2412ea7ea5eeec3521699cd0444c382e3b1
|
||||
flattened_ast: cccc6852933e40eaf259a903fdd11c2e74c28f8732be6d97c3e3890445c4b393
|
||||
inlined_ast: cccc6852933e40eaf259a903fdd11c2e74c28f8732be6d97c3e3890445c4b393
|
||||
dce_ast: 54bf7ae36ca87deca1c38d5a40b54fce8e7c1f64f638ee0d33ca74d19cee17fb
|
||||
- - initial_ast: eee18453add65b46525525d8015118390f91663d8587d29ac84e3fa9363901d5
|
||||
unrolled_ast: eee18453add65b46525525d8015118390f91663d8587d29ac84e3fa9363901d5
|
||||
ssa_ast: 7d374cb4d3b4fa72bbbd7e20affecc695135175216616d09342f2ded4f67d509
|
||||
flattened_ast: a92fdd0dc104b691342d7e500db97f4fbbdde10bc484f1dacfe89154aaba7532
|
||||
inlined_ast: a92fdd0dc104b691342d7e500db97f4fbbdde10bc484f1dacfe89154aaba7532
|
||||
dce_ast: 674eb9bb060298f3c280e86526cc8c481cf969bc4336a7891d9c6c52f85283e7
|
||||
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c184c3b9dea65d1c9972c6359cb266109146d9d5aeabcb5147d6a551d02edb01
|
||||
unrolled_ast: c184c3b9dea65d1c9972c6359cb266109146d9d5aeabcb5147d6a551d02edb01
|
||||
ssa_ast: 43e04c499f6a7be8b2f5cb861a86d610a124c22627b88c7c314cf581ce3b8247
|
||||
flattened_ast: bbb986a4b40aa8f7240096e02a5e0402d6c7f5bc1dc0722e85a2e118dbd0106f
|
||||
inlined_ast: bbb986a4b40aa8f7240096e02a5e0402d6c7f5bc1dc0722e85a2e118dbd0106f
|
||||
dce_ast: ba1f517261bb11624505c6c2fd49e3f04d942ef2b30d86e3c45334dbd1bbb577
|
||||
- - initial_ast: 1d6929dba9b3e998b112af31bf99aaa8b4b28fcc507837545d61a6dd20f3a699
|
||||
unrolled_ast: 1d6929dba9b3e998b112af31bf99aaa8b4b28fcc507837545d61a6dd20f3a699
|
||||
ssa_ast: 2744497abf673f6212c9186b0f12309f628297d7207673db3866c1c343102c13
|
||||
flattened_ast: bfefceec84c521d3cb070af34af675d029be7924d4634ae27e24819c8cd84d9e
|
||||
inlined_ast: bfefceec84c521d3cb070af34af675d029be7924d4634ae27e24819c8cd84d9e
|
||||
dce_ast: 5deb4f73c7178da95cb181694632fcf4e9eaf3d659e121c106812f830839fbf2
|
||||
bytecode: df6d5bbf5b971b9fbf39786a5bb74b9a26b0ddd9e9bfa501cfc4da9f260de048
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 328daa90b038066e97d5ba5393d4a943414bc500b5237357b9c9e58fc178e51a
|
||||
unrolled_ast: 328daa90b038066e97d5ba5393d4a943414bc500b5237357b9c9e58fc178e51a
|
||||
ssa_ast: 06dbcc5d9abeab1a4e1b417b3b632e14cdd85af3d6c82aebb16d74b2244780cb
|
||||
flattened_ast: cd05234ce579ddc5b36834020949acd415ce59f56a035f0109c8dd886938df20
|
||||
inlined_ast: cd05234ce579ddc5b36834020949acd415ce59f56a035f0109c8dd886938df20
|
||||
dce_ast: 495e6f6dde9ca039e6e55afeb94752bc044b74bf432b9193a7d01926d82e7bbb
|
||||
- - initial_ast: 7109d0444a1664ead2cb0e7f1bfe818ec8aba07e5c6711193026d06ee74d7258
|
||||
unrolled_ast: 7109d0444a1664ead2cb0e7f1bfe818ec8aba07e5c6711193026d06ee74d7258
|
||||
ssa_ast: 1e4ccf228090231a7d91df4145171f7a5c30bcd1d586d0837ec85d8e1f48b947
|
||||
flattened_ast: d6a3d02952c7d7d893242d9a65452ddc476c4b2394128b276107e3f1db3a1401
|
||||
inlined_ast: d6a3d02952c7d7d893242d9a65452ddc476c4b2394128b276107e3f1db3a1401
|
||||
dce_ast: 097e9ccccb137cc4dabf7663760b6307e77e0f46fa425fc6d5ef0ba401ce2886
|
||||
bytecode: 8e8ad00d8937c7ea19e29fd6e1162957946d6b2c1e90e0ab9b1a4f49a6685a02
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 52f0ede29adf2ca4701003a3cd70dc4bbe21848bc68e57ce3ac6d5978731ac96
|
||||
unrolled_ast: 52f0ede29adf2ca4701003a3cd70dc4bbe21848bc68e57ce3ac6d5978731ac96
|
||||
ssa_ast: e9397d32377b970aa46bca1fd809ba0f0845486c39ce945b151932f716b88d9c
|
||||
flattened_ast: 7eb3b7c843218b6b65feac487e6dd1e6319f0076985179c28f871b875b761169
|
||||
inlined_ast: 7eb3b7c843218b6b65feac487e6dd1e6319f0076985179c28f871b875b761169
|
||||
dce_ast: 7fbd1ac636ee91825d1346ff6003c33d2f1eb570952cecca69c68fd12540bc4e
|
||||
- - initial_ast: 91dc57e0bc7b29c3ec5eb072a66530fecdbbd065f34a435bf7c21248262c8258
|
||||
unrolled_ast: 91dc57e0bc7b29c3ec5eb072a66530fecdbbd065f34a435bf7c21248262c8258
|
||||
ssa_ast: af68e87160db0c11482eb4234ec60ebeb1e8cca4750bf0f735a24a4c9e01239a
|
||||
flattened_ast: 1cfc41ec5fd8a4734ec207c947954e42acc8336488514a28f7a21767ae8d9f11
|
||||
inlined_ast: 1cfc41ec5fd8a4734ec207c947954e42acc8336488514a28f7a21767ae8d9f11
|
||||
dce_ast: 19bfe4836913c51d8d4d72b08365f4f380d5509ab0a1335f857d0f879604371c
|
||||
bytecode: 4dceb1d3b4f77019d81c7e4d97a5866c6a50147cd8cbc417bb4b6629dc2cbf70
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 2619c8fef0b3503b1ae005f38fed58440f146962b20be560332bf395123eee74
|
||||
unrolled_ast: 2619c8fef0b3503b1ae005f38fed58440f146962b20be560332bf395123eee74
|
||||
ssa_ast: 6f7d5a0482b834872e14fb2a3ae867a6f377cfa21f3e71a17ff99ac698ad107d
|
||||
flattened_ast: 13919263c46a63382f0fb34d8c1dbbf67d1a8485b80d2ace5bd8ae50f7a85252
|
||||
inlined_ast: 13919263c46a63382f0fb34d8c1dbbf67d1a8485b80d2ace5bd8ae50f7a85252
|
||||
dce_ast: 9c7963fba2b84ad1c501e3626370b2e8bdab7b4e977cfecc9fe025c0f7affefc
|
||||
- - initial_ast: 2d03bdd0a7af6b16b102171d026c64b4b79dfad1c918f6372cadfac7a0efdf48
|
||||
unrolled_ast: 2d03bdd0a7af6b16b102171d026c64b4b79dfad1c918f6372cadfac7a0efdf48
|
||||
ssa_ast: cdbf3f51343cafafa3f5016071f94613a97ad3994b4c8dc425d11385fc61e0c9
|
||||
flattened_ast: f9a75ef76e52b50165df620dd76ab1b575737aaa9de3ec55900855f0b88d35c8
|
||||
inlined_ast: f9a75ef76e52b50165df620dd76ab1b575737aaa9de3ec55900855f0b88d35c8
|
||||
dce_ast: ae22e8b0e32bd60cdfaa5e6246deea26c520a11a0248d516cd47038193a84dcc
|
||||
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: fc696ada4c5b732d15b8f9b0ad5e7549f00cfc1da5ba57b885b66e0e6818a22a
|
||||
unrolled_ast: fc696ada4c5b732d15b8f9b0ad5e7549f00cfc1da5ba57b885b66e0e6818a22a
|
||||
ssa_ast: 18af862c907ef728a5d39f8965676dd43211350fe3a771a5f0faad51df67c3d3
|
||||
flattened_ast: fe08b7afbe25f75b31aae4a27ede152f12a7e50a6c327bdf362b13a1870984dc
|
||||
inlined_ast: fe08b7afbe25f75b31aae4a27ede152f12a7e50a6c327bdf362b13a1870984dc
|
||||
dce_ast: 1d3b448b8e1259dbeaae915175bc810a165219797bc67c7a12765996a523430a
|
||||
- - initial_ast: 2616d69193cd18db8e0af91be4314f4f4a4ac411ad6c0bb861881e8f56c5b1b1
|
||||
unrolled_ast: 2616d69193cd18db8e0af91be4314f4f4a4ac411ad6c0bb861881e8f56c5b1b1
|
||||
ssa_ast: 496dd06de809c3626d968ea3fdd7c3aa83369d7a9258c565b5582f1ac90aef56
|
||||
flattened_ast: 388802f2d2c5cd0d3debfe5e17f697e2b3b5bedcea14f2d6430fd2e8b7b380ed
|
||||
inlined_ast: 388802f2d2c5cd0d3debfe5e17f697e2b3b5bedcea14f2d6430fd2e8b7b380ed
|
||||
dce_ast: bb2b46bd36a6e76d34c3b00b4311c9e4afd2443a00c4140ad27554e9819cb16d
|
||||
bytecode: e1317e9396275ce8f73b494a3595e27bdbc563874acea6fed57c0b52da1354b3
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 35fcb3d27fefc2e41379cef05ef329b81eac0166ddd11d78f527bc4109af41e1
|
||||
unrolled_ast: 35fcb3d27fefc2e41379cef05ef329b81eac0166ddd11d78f527bc4109af41e1
|
||||
ssa_ast: e86fd5bca66aa0f8199faee9ac4dd1fbaf127b900c76aedc258a79af47415bad
|
||||
flattened_ast: 9f6a9ead21fe574985f41178303b2e49bf1697826134881eb37614e5eca94320
|
||||
inlined_ast: 9f6a9ead21fe574985f41178303b2e49bf1697826134881eb37614e5eca94320
|
||||
dce_ast: 9aa80eb712cd45a13d144358cfac8f5e8fb6f641732436b58b4c348d77ca25d5
|
||||
- - initial_ast: ea07694a29ef275c288260ee45faf738963fbf22dbaf2afea90ac3112c25e816
|
||||
unrolled_ast: ea07694a29ef275c288260ee45faf738963fbf22dbaf2afea90ac3112c25e816
|
||||
ssa_ast: ae34127a7baf411ff8717275384763a3b3d70e29cede5c4e60a37d29ee4c0cf4
|
||||
flattened_ast: 021b8e9d37ad1d3e2d60a5a8cc8acb88b3ad6fa9a32c30883ac5b8d4bd6e2f51
|
||||
inlined_ast: 021b8e9d37ad1d3e2d60a5a8cc8acb88b3ad6fa9a32c30883ac5b8d4bd6e2f51
|
||||
dce_ast: 621c04e49940033e81bd595d8f92d1009b797ac68c9f425a3c78f835c19af863
|
||||
bytecode: aee0a49b3add5225dd3e0e2343805040b94c16916e51b3405924378f62eb9f36
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c7b13b58b7ba847bc7592e6afa8f7b3a140c32cf3ec1f651165eaf1b99ec95a3
|
||||
unrolled_ast: c7b13b58b7ba847bc7592e6afa8f7b3a140c32cf3ec1f651165eaf1b99ec95a3
|
||||
ssa_ast: 3b4bcb28b9eac4e0e3e200013c61ce5fb7b5a8baca18d6c5c53535b6c586f81b
|
||||
flattened_ast: c239452165d456f374a3dc2789b07413191b90cd6b3c1f6d0a6f370440a2cdc9
|
||||
inlined_ast: c239452165d456f374a3dc2789b07413191b90cd6b3c1f6d0a6f370440a2cdc9
|
||||
dce_ast: 54bf7ae36ca87deca1c38d5a40b54fce8e7c1f64f638ee0d33ca74d19cee17fb
|
||||
- - initial_ast: 765ba1aea9966566c3a979614731b96000194f38bfb4f65ab64bff44645b1ed7
|
||||
unrolled_ast: 765ba1aea9966566c3a979614731b96000194f38bfb4f65ab64bff44645b1ed7
|
||||
ssa_ast: 6ee96a9485b5116b6866b9ba1355b68e8ba557beba3404ac41d2f058cc1d2692
|
||||
flattened_ast: 7b174ac8f24146ae7516e443447988a62ad034ed29d3baa2dc0122d237f3ae75
|
||||
inlined_ast: 7b174ac8f24146ae7516e443447988a62ad034ed29d3baa2dc0122d237f3ae75
|
||||
dce_ast: 674eb9bb060298f3c280e86526cc8c481cf969bc4336a7891d9c6c52f85283e7
|
||||
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: ede8e82829d45a29612d4478e4b573000d051b7c9a570a84088d83634b95e09b
|
||||
unrolled_ast: ede8e82829d45a29612d4478e4b573000d051b7c9a570a84088d83634b95e09b
|
||||
ssa_ast: 591cfefc44642c6b7d90cb032e8c50f106032d114d33c938de045389d81bca7e
|
||||
flattened_ast: a2192bfaf96f1e137c135cc0cfa6ffdf05d61869e9932aa8704804479d091b4c
|
||||
inlined_ast: a2192bfaf96f1e137c135cc0cfa6ffdf05d61869e9932aa8704804479d091b4c
|
||||
dce_ast: e1947d20d04cf487a713d633edd1cdf7ce783b15d09a3f8127f77592c300d61c
|
||||
- - initial_ast: 34321cdfdf6022714f37f053521ec53f6fcb6ebb60b137dceb4987454ed10cce
|
||||
unrolled_ast: 34321cdfdf6022714f37f053521ec53f6fcb6ebb60b137dceb4987454ed10cce
|
||||
ssa_ast: 13417366f95a28a70d03f4c29e1fbabfbf4d76f78774f9208082d5787b0b144e
|
||||
flattened_ast: 256c210818a74af6b696120cd16cb82aa29cec01f200006d88924825c194710b
|
||||
inlined_ast: 256c210818a74af6b696120cd16cb82aa29cec01f200006d88924825c194710b
|
||||
dce_ast: 4cf3fc9aee1f9777f05c580011cd0990c1b1280c014f0c8721e92d336db2f0d7
|
||||
bytecode: 38325ddbe5ab9363326dda92ef395e1c99e78e243d95ea4364499ccabadfd299
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: d05138b425c3a1200484d4491ef3bf4d9b62e32f9c318ad0d2f55b331b955d67
|
||||
unrolled_ast: d05138b425c3a1200484d4491ef3bf4d9b62e32f9c318ad0d2f55b331b955d67
|
||||
ssa_ast: 0b0839366e8e3bce98d91cd768911a1c9198fe8c762b9e218e4efd3abe21afa0
|
||||
flattened_ast: 02e32355b211e0c39bf8e9e1578de3ad37a48422518d7e20f70ecd67921df9be
|
||||
inlined_ast: 02e32355b211e0c39bf8e9e1578de3ad37a48422518d7e20f70ecd67921df9be
|
||||
dce_ast: d45be3fc835dad37fa8ec0b63d1931048d22f4587bcc0e6e6a18b0154cd93270
|
||||
- - initial_ast: b9b0e4422dd9613f2a2c75b7ed45f3f06d33129293cc888d9498f78d3926fb7c
|
||||
unrolled_ast: b9b0e4422dd9613f2a2c75b7ed45f3f06d33129293cc888d9498f78d3926fb7c
|
||||
ssa_ast: df5b237191728107e4ea6ef81307887a69827f268433edb6b850501528cf1279
|
||||
flattened_ast: 8ee14095f85ece807e1611d837b7beac682621eeafe72a961048ec23659ff709
|
||||
inlined_ast: 8ee14095f85ece807e1611d837b7beac682621eeafe72a961048ec23659ff709
|
||||
dce_ast: 872f2d0e342a1017ad2656eeb637661c880b17cad5013b4f21f08790f14a7f16
|
||||
bytecode: 95e421126839d599569f1a130c5852f7da8d6e40de90885f401530d8bcc18c14
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: a9be315a3445f9f02b64382f5506e9d367f3aeb8f4785df88ff8ac0fadedfc1e
|
||||
unrolled_ast: a9be315a3445f9f02b64382f5506e9d367f3aeb8f4785df88ff8ac0fadedfc1e
|
||||
ssa_ast: 67e4e9c88fa3c8c72856a9a59bb0e3ef9211981ee9a9eef752b1f832cac121f8
|
||||
flattened_ast: 73844e9aa33ebc6a1a878f5d83f652eb89b467c82e8f47b2190820e2b5f52ac4
|
||||
inlined_ast: 73844e9aa33ebc6a1a878f5d83f652eb89b467c82e8f47b2190820e2b5f52ac4
|
||||
dce_ast: 099e7069ae0639e7bafde9cf92773621394f5f1eabf432b12adae16c80e06605
|
||||
- - initial_ast: d39d5442a88a4991fe55cf474c159b4b017d0f11daa589649ce6e86523c8b348
|
||||
unrolled_ast: d39d5442a88a4991fe55cf474c159b4b017d0f11daa589649ce6e86523c8b348
|
||||
ssa_ast: 223b7cbbf1fc71b67697451c1aef7cd754256d78fc8cd1f79582e83b4a33f0e5
|
||||
flattened_ast: 9627cd027b2cc268dfe6bb256128812e76a36b30eddd739fce0ad0cd97b99a3b
|
||||
inlined_ast: 9627cd027b2cc268dfe6bb256128812e76a36b30eddd739fce0ad0cd97b99a3b
|
||||
dce_ast: c4423bd97d8106ae47a222f3bfeef898de82602f1d32c71cba269dd1f024c4c8
|
||||
bytecode: 319405c8fe80b59376c041f234ae2ef213e2d67b50701412411ac97294f91e69
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c91bd148e83d97ea9c5cad3a5663fdd82a83c3381151475090802525a7080746
|
||||
unrolled_ast: c91bd148e83d97ea9c5cad3a5663fdd82a83c3381151475090802525a7080746
|
||||
ssa_ast: 0a38c051202114aca4e5ae9a517beee7ac736361fa5b537eeb477d085b833964
|
||||
flattened_ast: 7b95230042361cc751275babf46870a3e929f88bc327a9df3a2bf46f25522b4c
|
||||
inlined_ast: 7b95230042361cc751275babf46870a3e929f88bc327a9df3a2bf46f25522b4c
|
||||
dce_ast: 25a44252c57774a9a8bac44f672307eab4918c371a39566813dce234e38ccb8c
|
||||
- - initial_ast: 5efcfb40cfb5a64bad1c44a310bb3f51ab61b709e38ac91606d17d883e72b4b6
|
||||
unrolled_ast: 5efcfb40cfb5a64bad1c44a310bb3f51ab61b709e38ac91606d17d883e72b4b6
|
||||
ssa_ast: 9c26e8a37c872a03ba1cba5b9731bb41a336f478db8bc034b0f5a43e6a95ba63
|
||||
flattened_ast: 49a348be0ec3ca2fd146a38dd1230ea1d7df75326192135b591aaf5cada8b93d
|
||||
inlined_ast: 49a348be0ec3ca2fd146a38dd1230ea1d7df75326192135b591aaf5cada8b93d
|
||||
dce_ast: 420f9dcd4362e135f7b86bc51faa0a13c9ac2d3bf02804c1c42df7fcca84d1ec
|
||||
bytecode: bd218715549602fce75a8d64df3317bee7386870f24b3d844b01c02d1960240b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: cd8360af7bce053a74c7add09ade31db66ed8b5900fcc33e4e0d4591c470e989
|
||||
unrolled_ast: cd8360af7bce053a74c7add09ade31db66ed8b5900fcc33e4e0d4591c470e989
|
||||
ssa_ast: d5b17cc240ab6f888faa6d6706de4c7d2c4402a7b6a5115b707258527205e3a6
|
||||
flattened_ast: 875b99ba07c5662ee3a25d0bb18507ca8c7d5211ee40dad9368098eba5178ebf
|
||||
inlined_ast: 875b99ba07c5662ee3a25d0bb18507ca8c7d5211ee40dad9368098eba5178ebf
|
||||
dce_ast: 8895f89492c0ca019e4372fb4f7cab7a0dc254c058dcb7b527483b597687fab7
|
||||
- - initial_ast: ae83c4c1c05e2741d112d9b37e3336450fcb65f65f550a561b96fcdb09d98a20
|
||||
unrolled_ast: ae83c4c1c05e2741d112d9b37e3336450fcb65f65f550a561b96fcdb09d98a20
|
||||
ssa_ast: 80097e52476437805c6ce471a481f15cc829a569cf52859e25abd2f2e5b6f78d
|
||||
flattened_ast: e0e5fef742a4c0df6a24323863bb46ad8f4d513da37bea680253713ac87f059b
|
||||
inlined_ast: e0e5fef742a4c0df6a24323863bb46ad8f4d513da37bea680253713ac87f059b
|
||||
dce_ast: 169c97e859427f154a255263c8f36c0d48b381be2b4c4017a7e82f0019f43ce1
|
||||
bytecode: 4b3d6980860116dfb43804924f4d2cedfb7db2d9fb783fd06b3127327e31a298
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 0a2966eef4db383661c3b4c70257eaae893bb046930cccd59f2c771d8501cb5c
|
||||
unrolled_ast: 0a2966eef4db383661c3b4c70257eaae893bb046930cccd59f2c771d8501cb5c
|
||||
ssa_ast: 3a514a3264fbd19707996f304bc43aee4d7ad24ca260c91d9751d2f14508f3c8
|
||||
flattened_ast: 66970fd4850f730a952e41ac8849536ccfc3dde5e2b3fcb571f074adb5fcf04b
|
||||
inlined_ast: 66970fd4850f730a952e41ac8849536ccfc3dde5e2b3fcb571f074adb5fcf04b
|
||||
dce_ast: 2f6696c21e443368f325ba36838dc7c03ab021e0da05abbe20d4cf639d93b126
|
||||
- - initial_ast: 54ac2e3f840659fd7b5eeb98ec7827dcfb0ee4203e8658e38664f3b659962d28
|
||||
unrolled_ast: 54ac2e3f840659fd7b5eeb98ec7827dcfb0ee4203e8658e38664f3b659962d28
|
||||
ssa_ast: be36a341befadaa69f857dab65976c6593638bc1f724785d6947adbd5c22ab35
|
||||
flattened_ast: 803a4d476a2312c115b4700073f78da88986fccfcdb4f15e5bfc9ff75e8d50b7
|
||||
inlined_ast: 803a4d476a2312c115b4700073f78da88986fccfcdb4f15e5bfc9ff75e8d50b7
|
||||
dce_ast: b9df995586996ad6e156600744e95e2e6c2fe138d14e4e6d6fdf9454083e8815
|
||||
bytecode: cf7a9eea97a35c026eeac1f4659903bec549092b56e6194f666fed520fc02b7a
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 7ed91381838f579d46d070d84489f6c909c8ffdd2b184dab9e78f78795bd97b3
|
||||
unrolled_ast: 7ed91381838f579d46d070d84489f6c909c8ffdd2b184dab9e78f78795bd97b3
|
||||
ssa_ast: 29ddcef122568413c740e761dcbdfa184feb521eb7fd7ee44c166fd55309d562
|
||||
flattened_ast: b6cfdf163495696b9579f35fe07925b4d3330c311aef4cb857618bbe8dce9791
|
||||
inlined_ast: b6cfdf163495696b9579f35fe07925b4d3330c311aef4cb857618bbe8dce9791
|
||||
dce_ast: 510d6f51ce40b821e99729f0def26529a4c6f16f01e929ca747f23d48fd6e254
|
||||
- - initial_ast: c3cde43bd5ce6bd109a485a1bf172d483f9dcac4595057fa360e07543ee690b6
|
||||
unrolled_ast: c3cde43bd5ce6bd109a485a1bf172d483f9dcac4595057fa360e07543ee690b6
|
||||
ssa_ast: 7f864ba4330a2545c21bbdbe0268fbb73371e47d1fbdaf7fff1d05e87a8236cc
|
||||
flattened_ast: d9914036faa2860c628ed5f50494f06b06d7a80f283f11a1e7c1545969c24741
|
||||
inlined_ast: d9914036faa2860c628ed5f50494f06b06d7a80f283f11a1e7c1545969c24741
|
||||
dce_ast: 2a9f1176a540d39660da33d14faa266e3795274285ccb68540b59ebfcf448320
|
||||
bytecode: d3d4c9152f574443e543ea5f0f1f0148116006c76aaaa2e014f268d7ab9d05df
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: e4528d944261a3586e66e83a22a5e4372c7a45c0a3ea689927007aa37681d6d9
|
||||
unrolled_ast: e4528d944261a3586e66e83a22a5e4372c7a45c0a3ea689927007aa37681d6d9
|
||||
ssa_ast: 8a901b31ecf54ceef87eda818276ca5fc2de348c1e84e4cf386c4e3f7b989059
|
||||
flattened_ast: d11751292a1314a84cf32c7333bc8bc412c5cc35e480d68a4a1a421110afdc0b
|
||||
inlined_ast: d11751292a1314a84cf32c7333bc8bc412c5cc35e480d68a4a1a421110afdc0b
|
||||
dce_ast: 592fabdaf4bc757afe4855bc4156f5191e76bdaa156057990234564304cbad70
|
||||
- - initial_ast: 5dd5cefd1086637c19b2aabcd0dbb3bb45b6c15e8ab8f81d462145f39228b3de
|
||||
unrolled_ast: 5dd5cefd1086637c19b2aabcd0dbb3bb45b6c15e8ab8f81d462145f39228b3de
|
||||
ssa_ast: 3e104420807e18487278b84b750ca52a086cb2f74a54df1c74d7302b76a57549
|
||||
flattened_ast: a4b78b37258e0ead4c42527345c5854b39491406a6e33eddf76c789993272f6d
|
||||
inlined_ast: a4b78b37258e0ead4c42527345c5854b39491406a6e33eddf76c789993272f6d
|
||||
dce_ast: f1e385ab26cde7676981f5b8b9996e5cd6264dbed5053d4d79dd6930febae2fa
|
||||
bytecode: 23b5c88c1d028f0b038f1005427c79779230306d235088802d5668e93117c120
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 3c01ed969e2830bbef88c1f734850dfaf83bb7429d807b446eb9b2b9c6857e64
|
||||
unrolled_ast: 3c01ed969e2830bbef88c1f734850dfaf83bb7429d807b446eb9b2b9c6857e64
|
||||
ssa_ast: 90a0ab34741185c64f0b2f051649100c1170b1f44728dc1ba27050ebf9efdd9c
|
||||
flattened_ast: 02b4f16917bd5e473d38677f9d0bc9e2c280b5951c362bc32213088d26f248d2
|
||||
inlined_ast: 02b4f16917bd5e473d38677f9d0bc9e2c280b5951c362bc32213088d26f248d2
|
||||
dce_ast: eb0931dbc9d952b1d43e219c3e912e2ebcce4248ee2278d4ef06b1583058cf3d
|
||||
- - initial_ast: 7b625bf89cb9265228bc7b13ed0f3b732e246d4f054461eda8fae457a272a5b8
|
||||
unrolled_ast: 7b625bf89cb9265228bc7b13ed0f3b732e246d4f054461eda8fae457a272a5b8
|
||||
ssa_ast: 553e9d2bb4a265c89d6fc102270d7db5b128ce9e000f50dc5f77f165cb7e5743
|
||||
flattened_ast: ad88dd2788bf38f99242519aad875ca84cdecafff7f4e6847cb8523ee7dd2e41
|
||||
inlined_ast: ad88dd2788bf38f99242519aad875ca84cdecafff7f4e6847cb8523ee7dd2e41
|
||||
dce_ast: 22badc4cb8f786aedb95733789faa02b6062a61d96db4fc206e32c6e07f182a1
|
||||
bytecode: b195e16806d0a26e2088f84136f95ca7e9401dd6846a61cda34d39445ef87684
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: cd05dd82f3b6b66b0ca9be70aee91fcfd1539a3894c99c60e983880a6a3c5176
|
||||
unrolled_ast: cd05dd82f3b6b66b0ca9be70aee91fcfd1539a3894c99c60e983880a6a3c5176
|
||||
ssa_ast: 707c7c8cf25cb1783c8042d08ba53c35f3c5e25b80c17f973fc3b748b91ee439
|
||||
flattened_ast: 2e4d9fe6330c108c69ae7ae2b426e6d76d036f754ce5c04033454bce78cbd2d1
|
||||
inlined_ast: 2e4d9fe6330c108c69ae7ae2b426e6d76d036f754ce5c04033454bce78cbd2d1
|
||||
dce_ast: 5694b6e0912a2d230769d8c3ea982b0744ad18d538e18e548c415fb0da9b431a
|
||||
- - initial_ast: fe4013daac58433b0e7ee77729e6dfd254b0cc25cf645e8bda38df6bff2ea6f5
|
||||
unrolled_ast: fe4013daac58433b0e7ee77729e6dfd254b0cc25cf645e8bda38df6bff2ea6f5
|
||||
ssa_ast: bdcfed2adad22237f441e2953520f53708ad3bc79c06f90f7320656b60fa50d0
|
||||
flattened_ast: 051b5cc446838992509fe969562d26e8a2e40f8d3c65e70c19221216192421e1
|
||||
inlined_ast: 051b5cc446838992509fe969562d26e8a2e40f8d3c65e70c19221216192421e1
|
||||
dce_ast: b0fe7a0eca195cf829402febb958d7c5d2e3813bdf9a8e2f9a9deb677143a6ad
|
||||
bytecode: 3bd31100c828423ff38d092cfbe9c0df772aba3b6fc24931ae33b1f50efcecb0
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 78a2df5f4cb551a93fb04cbe84fae22f1a404b38f4fa606639904f1ba45446ef
|
||||
unrolled_ast: 78a2df5f4cb551a93fb04cbe84fae22f1a404b38f4fa606639904f1ba45446ef
|
||||
ssa_ast: a9d66d2d618c2f102a0b50a736503498418c0b88afcf7c7b05936ddfacdf8872
|
||||
flattened_ast: 3d1bc760b33cf23fb977288c77ca6b06409eeabfb1ad09578d78df3969bd15a3
|
||||
inlined_ast: 3d1bc760b33cf23fb977288c77ca6b06409eeabfb1ad09578d78df3969bd15a3
|
||||
dce_ast: 4addccb9802526a9fa5948b5d6dc7801ffd52b5d34f3657d5497f2a1d8d65924
|
||||
- - initial_ast: a802229d4b6de00a7204febafff07ba1a48deacb1b247696049ea13c6b5dae46
|
||||
unrolled_ast: a802229d4b6de00a7204febafff07ba1a48deacb1b247696049ea13c6b5dae46
|
||||
ssa_ast: c84708fc6fdd2f2ac7d3d89e049b21f8798182ba7efeee69359b96c8a5715c5b
|
||||
flattened_ast: f1ac12568348ec1ae78bd965301eeacff1dbdee97b371129cebd681376d29e10
|
||||
inlined_ast: f1ac12568348ec1ae78bd965301eeacff1dbdee97b371129cebd681376d29e10
|
||||
dce_ast: feaa1c6e309a6639bebc60824b78a212d4d9f260414655260a0e7b01671236ec
|
||||
bytecode: 6a94d8f23c147c3cddc2c5a44a6f07734cbe79bc899b2b830aac61b6e6975057
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: db23254b38f2edafa88e8444beedf9c0e6d5b58e200b0c49e783b0c2e80895b8
|
||||
unrolled_ast: db23254b38f2edafa88e8444beedf9c0e6d5b58e200b0c49e783b0c2e80895b8
|
||||
ssa_ast: bd7a7134d27cae528ab6e66f0a33a746a0b52942ee9a24087f7cbf4713de63f9
|
||||
flattened_ast: 91b3cbbf48c15063c87758308f018144309bead61edc18cfb3846642fb40d4c6
|
||||
inlined_ast: 91b3cbbf48c15063c87758308f018144309bead61edc18cfb3846642fb40d4c6
|
||||
dce_ast: 8e4787b63356db1b948a37757c456d7f0008dfdb0299c1561f678a9fb833ff0b
|
||||
- - initial_ast: 9be98b23ebf981caddf95cfbef47cd250afd873c1cd1bc72e1b18fbdf42fa174
|
||||
unrolled_ast: 9be98b23ebf981caddf95cfbef47cd250afd873c1cd1bc72e1b18fbdf42fa174
|
||||
ssa_ast: 2d8c9387be8a685dca90ea4f161866c6298683bba5ef667e195bb51c69b07271
|
||||
flattened_ast: 5bc73f0e0d07e95442ff9de4c1b6324d3c0febd12e5803d7d48e3f56105f39b2
|
||||
inlined_ast: 5bc73f0e0d07e95442ff9de4c1b6324d3c0febd12e5803d7d48e3f56105f39b2
|
||||
dce_ast: c14a09c6258133c39cc0fd21c13bb64d18df171c562e2d447f5e28db349d333d
|
||||
bytecode: 5ff56b03daf136dc97334d9f0c73f26eb6e342e30b116000e7eb7cac8e2ebff5
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 4909c65c7d9ba9483ae5a54d47cb5b45c1bffb0624ef5cb87c4520d4afa2ca52
|
||||
unrolled_ast: 4909c65c7d9ba9483ae5a54d47cb5b45c1bffb0624ef5cb87c4520d4afa2ca52
|
||||
ssa_ast: 2c123587922e8a5b37abc83c6c795ab6de46b25467810f89cad4db702602e093
|
||||
flattened_ast: c01013df58690fd45025a38f2002b519cc06e4dafd15f6b960077acc67d38e82
|
||||
inlined_ast: c01013df58690fd45025a38f2002b519cc06e4dafd15f6b960077acc67d38e82
|
||||
dce_ast: 9fa94fa1597f0efd27d1fcac96efff1a8da824b937166bbc41c5536d8d7807dc
|
||||
- - initial_ast: 58b7e3117c943bd4fa0d78359d1319e5f089b525eac3749dc958515ffb368dfd
|
||||
unrolled_ast: 58b7e3117c943bd4fa0d78359d1319e5f089b525eac3749dc958515ffb368dfd
|
||||
ssa_ast: 5af8b7ed094924143b1ba05f246a417177c6bb9c61d34bc8feda5c418d365fe1
|
||||
flattened_ast: c3d87c76cc3699f14e0c1bc165367eaed92f5044ea942be4193dfbce12b0f0c5
|
||||
inlined_ast: c3d87c76cc3699f14e0c1bc165367eaed92f5044ea942be4193dfbce12b0f0c5
|
||||
dce_ast: 404e6ae5f1a61cb001a11aea3ead5082d5acd582139f56e41424a4457b14a759
|
||||
bytecode: 5552b43274ec113ad0520de7a6a457cd4ac6db08d490446eca21f148a5bbca16
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 8cc08a55a4766806701ada82b6e6fe267fcc55dd7ffa7bdcd0df847f45a55a88
|
||||
unrolled_ast: 8cc08a55a4766806701ada82b6e6fe267fcc55dd7ffa7bdcd0df847f45a55a88
|
||||
ssa_ast: a6430134eda01acb48063ce754e8f1f8eceb0831ccfc7be9c2cb57a3a6b590d1
|
||||
flattened_ast: 5007eb8364cf861e5ef11d3a782f1b97c46a35b0fe00145aac2f25de9e68505a
|
||||
inlined_ast: 5007eb8364cf861e5ef11d3a782f1b97c46a35b0fe00145aac2f25de9e68505a
|
||||
dce_ast: fbf9b644d9db05227b49190948363354a346d96c20ab9e1d5596a6490659368e
|
||||
- - initial_ast: 6bc571e09c54ab29d06a5e96ba368d7c82db558e523108a87536e672b9c184ce
|
||||
unrolled_ast: 6bc571e09c54ab29d06a5e96ba368d7c82db558e523108a87536e672b9c184ce
|
||||
ssa_ast: 7f13a8ac4e9279024b1e3da939017bef71d196ca6243b8184e4e0ff5b6ccbb00
|
||||
flattened_ast: 98b8cf065b004843080e319557ed2ff594e0783624fd5373a1c3046cb25f95da
|
||||
inlined_ast: 98b8cf065b004843080e319557ed2ff594e0783624fd5373a1c3046cb25f95da
|
||||
dce_ast: df16f37c011385cde2aeddc10ed74b041936d28475f0cb5d696550a3a970aa54
|
||||
bytecode: 325b391ad96a02efc136a7653c4a5229454ecfc76c857c6fe7d0606fd78b5336
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 7a36e76f0e626ba363421a3b51b23292bfc37b0a4419289b97f845442b6f5b0c
|
||||
unrolled_ast: 7a36e76f0e626ba363421a3b51b23292bfc37b0a4419289b97f845442b6f5b0c
|
||||
ssa_ast: c4d434b533862126fcd137af19f5ab1380b1237f2469ef812883007e66206106
|
||||
flattened_ast: 97de4b492d6b4d06f0866eb46d8f011f45a4b1caf9d606f41540dcea1ed30309
|
||||
inlined_ast: 97de4b492d6b4d06f0866eb46d8f011f45a4b1caf9d606f41540dcea1ed30309
|
||||
dce_ast: 7385743f2ca202d19e724a448188a04e8e1e4713ef5825fd6210f6a61c00df8b
|
||||
- - initial_ast: a705aac527cf63578b2f69a56779492e8a3d998dd40667e600f773a045760653
|
||||
unrolled_ast: a705aac527cf63578b2f69a56779492e8a3d998dd40667e600f773a045760653
|
||||
ssa_ast: 83d5a116b9d11cebe4417cc9c31a2a91243a3f6456675b605222613f66f80440
|
||||
flattened_ast: d4d7dd5d0adfa216b3d9e62b94737be5373dbbb4dc21f2bfe50eee8b5b861da0
|
||||
inlined_ast: d4d7dd5d0adfa216b3d9e62b94737be5373dbbb4dc21f2bfe50eee8b5b861da0
|
||||
dce_ast: 8e1e99ae2c5eabb1105ef04e5659e92d5d6516f47bf7330118a5580387cbf845
|
||||
bytecode: db7cf565e83b99b3a24b93bfbb5bdcda4f947f4eb64f454046ea83edca3ccbf3
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 92ee68761f294ea4a49a025e9132c083f57fc01587e4c52db3bafc62f35b66c7
|
||||
unrolled_ast: 92ee68761f294ea4a49a025e9132c083f57fc01587e4c52db3bafc62f35b66c7
|
||||
ssa_ast: da7d82578cb1ac8f9314811d61a9bdeeabca02f301022c9753744c04626fdc18
|
||||
flattened_ast: 3b1e9009d7f3769c4badff49c74f7af158a0ea49820d215fdebd32b2b0e062b9
|
||||
inlined_ast: 3b1e9009d7f3769c4badff49c74f7af158a0ea49820d215fdebd32b2b0e062b9
|
||||
dce_ast: d224b6ef7df21ccfefe7a0b949543696745820385a4fc547b5ed5b5e74ed13c7
|
||||
- - initial_ast: 9b04c1a3199640b1bb75bf1796c51f8247101ac841efa4e78837737f1840e941
|
||||
unrolled_ast: 9b04c1a3199640b1bb75bf1796c51f8247101ac841efa4e78837737f1840e941
|
||||
ssa_ast: e087d9dbc1082aef11c7cdc29acbd8e40140c3f19ceb2188b936e820d58a5bc6
|
||||
flattened_ast: 883e141c98634bcd7056dca257c5d3fe9606ca101e95c626f17b789874f8ed1c
|
||||
inlined_ast: 883e141c98634bcd7056dca257c5d3fe9606ca101e95c626f17b789874f8ed1c
|
||||
dce_ast: 4dd926d952ebce2dd59c1f8a967afdadc0e948af85e3f31deab550d8e4ea0107
|
||||
bytecode: d594e784e95e52089afcadbc703f266ea2fd2b211728fdbea8eea5abc5e1942b
|
||||
warnings: ""
|
||||
|
@ -2,11 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 44afe466172f202382b83ea6416ccc3447ff684aaa9ee18c38dd665a639e8760
|
||||
unrolled_ast: 44afe466172f202382b83ea6416ccc3447ff684aaa9ee18c38dd665a639e8760
|
||||
ssa_ast: 9da72c4252de24be048f58668cb3c5b492f105b23c7440a959d0474574315306
|
||||
flattened_ast: 1502430fd27a08f4eef2ca43873c588899a2c18acb15576da4b35538cb29c66e
|
||||
inlined_ast: 1502430fd27a08f4eef2ca43873c588899a2c18acb15576da4b35538cb29c66e
|
||||
dce_ast: 2e508af7d9b2d85877183259c9e576d25c062f03c38d23acdc2d65d66e1ad4fd
|
||||
- - initial_ast: 7d5ed9c373b2460d26ae2e9e92c2e1e63e59af4f9daf813971486d764b7df3fa
|
||||
unrolled_ast: 7d5ed9c373b2460d26ae2e9e92c2e1e63e59af4f9daf813971486d764b7df3fa
|
||||
ssa_ast: 8d6571c282f21bdbc7c88ee0bd602ea2e29f7ce0408cb77b4dc9fd80ec7546e5
|
||||
flattened_ast: b6ae966db6102e16ca5e2c3141dd59a957e8dc52e77d906220eddf7d5d81f301
|
||||
inlined_ast: b6ae966db6102e16ca5e2c3141dd59a957e8dc52e77d906220eddf7d5d81f301
|
||||
dce_ast: 1614b47014a0db1e2fef072ecbbae97e2d24c603b8dedcbf614ce39e340aadd2
|
||||
bytecode: e9166c477441b45359a7ab4d7ee7afd309de45ee5cad9143f0261b1c3ccf8b57
|
||||
warnings: ""
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user