Merge pull request #2536 from AleoHQ/design/unique-node-ids

[Design] Parsing produces unique node IDs.
This commit is contained in:
d0cd 2023-08-18 18:58:27 -04:00 committed by GitHub
commit 0cccdda67e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
677 changed files with 7532 additions and 6954 deletions

View File

@ -52,9 +52,9 @@ pub struct Identifier {
simple_node_impl!(Identifier); simple_node_impl!(Identifier);
impl Identifier { impl Identifier {
/// Constructs a new identifier with `name` and a default span. /// Constructs a new identifier with `name` and `id` and a default span.
pub fn new(name: Symbol) -> Self { pub fn new(name: Symbol, id: NodeID) -> Self {
Self { name, span: Span::default(), id: NodeID::default() } Self { name, span: Span::default(), id }
} }
/// Check if the Identifier name matches the other name. /// 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(); let mut key: BTreeMap<String, String> = BTreeMap::new();
key.insert("name".to_string(), self.name.to_string()); key.insert("name".to_string(), self.name.to_string());
key.insert("span".to_string(), to_json_string(&self.span)?); 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. // Convert the serialized object into a string for use as a key.
serializer.serialize_str(&to_json_string(&key)?) serializer.serialize_str(&to_json_string(&key)?)

View File

@ -24,6 +24,10 @@ pub mod positive_number;
pub use positive_number::*; pub use positive_number::*;
pub mod node; pub mod node;
pub mod node_builder;
pub use node_builder::*;
pub mod static_string; pub mod static_string;
pub use static_string::*; pub use static_string::*;

View File

@ -19,7 +19,6 @@ use leo_span::Span;
/// A node ID. /// A node ID.
// Development Note: // Development Note:
// A `NodeID` must implement: `Copy`, `Default`, among others. // 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; pub type NodeID = usize;
/// A node in the AST. /// A node in the AST.

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

View File

@ -42,14 +42,21 @@ pub struct Finalize {
impl Finalize { impl Finalize {
/// Create a new finalize block. /// 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() { let output_type = match output.len() {
0 => Type::Unit, 0 => Type::Unit,
1 => output[0].type_(), 1 => output[0].type_(),
_ => Type::Tuple(Tuple(output.iter().map(|output| output.type_()).collect())), _ => 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 }
} }
} }

View File

@ -89,6 +89,7 @@ impl Function {
block: Block, block: Block,
finalize: Option<Finalize>, finalize: Option<Finalize>,
span: Span, span: Span,
id: NodeID,
) -> Self { ) -> Self {
// Determine the output type of the function // Determine the output type of the function
let get_output_type = |output: &Output| match &output { 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())), _ => Type::Tuple(Tuple(output.iter().map(|output| get_output_type(output)).collect())),
}; };
Function { Function { annotations, variant, identifier, input, output, output_type, block, finalize, span, id }
annotations,
variant,
identifier,
input,
output,
output_type,
block,
finalize,
span,
id: NodeID::default(),
}
} }
/// Returns function name. /// Returns function name.

View File

@ -73,8 +73,8 @@ pub enum Statement {
impl Statement { impl Statement {
/// Returns a dummy statement made from an empty block `{}`. /// Returns a dummy statement made from an empty block `{}`.
pub fn dummy(span: Span) -> Self { pub fn dummy(span: Span, id: NodeID) -> Self {
Self::Block(Block { statements: Vec::new(), span, id: NodeID::default() }) Self::Block(Block { statements: Vec::new(), span, id })
} }
} }

View File

@ -893,28 +893,29 @@ impl TryFrom<&Literal> for Value {
} }
} }
impl From<Value> for Literal { impl Literal {
fn from(v: Value) -> Self { #[allow(unused)]
fn from_value(v: Value, id: NodeID) -> Self {
use Value::*; use Value::*;
match v { match v {
Input(_, _) => todo!("We need to test if this is hittable"), Input(_, _) => todo!("We need to test if this is hittable"),
Address(v, span) => Literal::Address(v, span, NodeID::default()), Address(v, span) => Literal::Address(v, span, id),
Boolean(v, span) => Literal::Boolean(v, span, NodeID::default()), Boolean(v, span) => Literal::Boolean(v, span, id),
Struct(_ident, _values) => todo!("We need to test if this is hittable"), 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), Group(v) => Literal::Group(v),
I8(v, span) => Literal::Integer(IntegerType::I8, v.to_string(), 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, NodeID::default()), I16(v, span) => Literal::Integer(IntegerType::I16, v.to_string(), span, id),
I32(v, span) => Literal::Integer(IntegerType::I32, v.to_string(), span, NodeID::default()), I32(v, span) => Literal::Integer(IntegerType::I32, v.to_string(), span, id),
I64(v, span) => Literal::Integer(IntegerType::I64, v.to_string(), span, NodeID::default()), I64(v, span) => Literal::Integer(IntegerType::I64, v.to_string(), span, id),
I128(v, span) => Literal::Integer(IntegerType::I128, v.to_string(), span, NodeID::default()), I128(v, span) => Literal::Integer(IntegerType::I128, v.to_string(), span, id),
U8(v, span) => Literal::Integer(IntegerType::U8, v.to_string(), span, NodeID::default()), U8(v, span) => Literal::Integer(IntegerType::U8, v.to_string(), span, id),
U16(v, span) => Literal::Integer(IntegerType::U16, v.to_string(), span, NodeID::default()), U16(v, span) => Literal::Integer(IntegerType::U16, v.to_string(), span, id),
U32(v, span) => Literal::Integer(IntegerType::U32, v.to_string(), span, NodeID::default()), U32(v, span) => Literal::Integer(IntegerType::U32, v.to_string(), span, id),
U64(v, span) => Literal::Integer(IntegerType::U64, v.to_string(), span, NodeID::default()), U64(v, span) => Literal::Integer(IntegerType::U64, v.to_string(), span, id),
U128(v, span) => Literal::Integer(IntegerType::U128, v.to_string(), span, NodeID::default()), U128(v, span) => Literal::Integer(IntegerType::U128, v.to_string(), span, id),
Scalar(v, span) => Literal::Scalar(v, span, NodeID::default()), Scalar(v, span) => Literal::Scalar(v, span, id),
String(v, span) => Literal::String(v, span, NodeID::default()), String(v, span) => Literal::String(v, span, id),
} }
} }
} }

View File

@ -17,8 +17,8 @@
//! The compiler for Leo programs. //! The compiler for Leo programs.
//! //!
//! The [`Compiler`] type compiles Leo programs into R1CS circuits. //! The [`Compiler`] type compiles Leo programs into R1CS circuits.
use leo_ast::Program;
pub use leo_ast::{Ast, InputAst}; pub use leo_ast::{Ast, InputAst};
use leo_ast::{NodeBuilder, Program};
use leo_errors::{emitter::Handler, CompilerError, Result}; use leo_errors::{emitter::Handler, CompilerError, Result};
pub use leo_passes::SymbolTable; pub use leo_passes::SymbolTable;
use leo_passes::*; use leo_passes::*;
@ -48,6 +48,10 @@ pub struct Compiler<'a> {
pub input_ast: Option<InputAst>, pub input_ast: Option<InputAst>,
/// Options configuring compilation. /// Options configuring compilation.
compiler_options: CompilerOptions, 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> { impl<'a> Compiler<'a> {
@ -60,6 +64,8 @@ impl<'a> Compiler<'a> {
output_directory: PathBuf, output_directory: PathBuf,
compiler_options: Option<CompilerOptions>, compiler_options: Option<CompilerOptions>,
) -> Self { ) -> Self {
let node_builder = NodeBuilder::default();
let assigner = Assigner::default();
Self { Self {
handler, handler,
main_file_path, main_file_path,
@ -69,6 +75,8 @@ impl<'a> Compiler<'a> {
ast: Ast::new(Program::default()), ast: Ast::new(Program::default()),
input_ast: None, input_ast: None,
compiler_options: compiler_options.unwrap_or_default(), 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)); 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). // 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. // 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. // 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))?; .map_err(|e| CompilerError::file_read_error(&input_file_path, e))?;
// Parse and serialize it. // 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 { if self.compiler_options.output.initial_ast {
// Write the input AST snapshot post parsing. // Write the input AST snapshot post parsing.
if self.compiler_options.output.spans_enabled { if self.compiler_options.output.spans_enabled {
@ -166,7 +175,8 @@ impl<'a> Compiler<'a> {
/// Runs the loop unrolling pass. /// Runs the loop unrolling pass.
pub fn loop_unrolling_pass(&mut self, symbol_table: SymbolTable) -> Result<SymbolTable> { 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; self.ast = ast;
if self.compiler_options.output.unrolled_ast { if self.compiler_options.output.unrolled_ast {
@ -177,45 +187,50 @@ impl<'a> Compiler<'a> {
} }
/// Runs the static single assignment pass. /// Runs the static single assignment pass.
pub fn static_single_assignment_pass(&mut self, symbol_table: &SymbolTable) -> Result<Assigner> { pub fn static_single_assignment_pass(&mut self, symbol_table: &SymbolTable) -> Result<()> {
let (ast, assigner) = StaticSingleAssigner::do_pass((std::mem::take(&mut self.ast), symbol_table))?; self.ast = StaticSingleAssigner::do_pass((
self.ast = ast; std::mem::take(&mut self.ast),
&self.node_builder,
&self.assigner,
symbol_table,
))?;
if self.compiler_options.output.ssa_ast { if self.compiler_options.output.ssa_ast {
self.write_ast_to_json("ssa_ast.json")?; self.write_ast_to_json("ssa_ast.json")?;
} }
Ok(assigner) Ok(())
} }
/// Runs the flattening pass. /// Runs the flattening pass.
pub fn flattening_pass(&mut self, symbol_table: &SymbolTable, assigner: Assigner) -> Result<Assigner> { pub fn flattening_pass(&mut self, symbol_table: &SymbolTable) -> Result<()> {
let (ast, assigner) = Flattener::do_pass((std::mem::take(&mut self.ast), symbol_table, assigner))?; self.ast =
self.ast = ast; Flattener::do_pass((std::mem::take(&mut self.ast), symbol_table, &self.node_builder, &self.assigner))?;
if self.compiler_options.output.flattened_ast { if self.compiler_options.output.flattened_ast {
self.write_ast_to_json("flattened_ast.json")?; self.write_ast_to_json("flattened_ast.json")?;
} }
Ok(assigner) Ok(())
} }
/// Runs the function inlining pass. /// Runs the function inlining pass.
pub fn function_inlining_pass(&mut self, call_graph: &CallGraph, assigner: Assigner) -> Result<Assigner> { pub fn function_inlining_pass(&mut self, call_graph: &CallGraph) -> Result<()> {
let (ast, assigner) = FunctionInliner::do_pass((std::mem::take(&mut self.ast), call_graph, assigner))?; let ast =
FunctionInliner::do_pass((std::mem::take(&mut self.ast), &self.node_builder, call_graph, &self.assigner))?;
self.ast = ast; self.ast = ast;
if self.compiler_options.output.inlined_ast { if self.compiler_options.output.inlined_ast {
self.write_ast_to_json("inlined_ast.json")?; self.write_ast_to_json("inlined_ast.json")?;
} }
Ok(assigner) Ok(())
} }
/// Runs the dead code elimination pass. /// Runs the dead code elimination pass.
pub fn dead_code_elimination_pass(&mut self) -> Result<()> { pub fn dead_code_elimination_pass(&mut self) -> Result<()> {
if self.compiler_options.build.dce_enabled { 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 { if self.compiler_options.output.dce_ast {
@ -243,12 +258,11 @@ impl<'a> Compiler<'a> {
// TODO: Make this pass optional. // TODO: Make this pass optional.
let st = self.loop_unrolling_pass(st)?; let st = self.loop_unrolling_pass(st)?;
// TODO: Make this pass optional. self.static_single_assignment_pass(&st)?;
let assigner = 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()?; self.dead_code_elimination_pass()?;

View 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);
}
}

View File

@ -14,6 +14,9 @@
// You should have received a copy of the GNU General Public License // 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/>. // 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_compiler::{BuildOptions, Compiler, CompilerOptions};
use leo_errors::{ use leo_errors::{
emitter::{Buffer, Emitter, Handler}, emitter::{Buffer, Emitter, Handler},
@ -27,6 +30,7 @@ use leo_test_framework::{test::TestConfig, Test};
use snarkvm::prelude::*; use snarkvm::prelude::*;
use leo_ast::ProgramVisitor;
use snarkvm::{file::Manifest, package::Package}; use snarkvm::{file::Manifest, package::Package};
use std::{ use std::{
cell::RefCell, cell::RefCell,
@ -144,6 +148,8 @@ pub fn parse_program<'a>(
let name = cwd.map_or_else(|| FileName::Custom("compiler-test".into()), FileName::Real); let name = cwd.map_or_else(|| FileName::Custom("compiler-test".into()), FileName::Real);
compiler.parse_program_from_string(program_string, name)?; compiler.parse_program_from_string(program_string, name)?;
CheckUniqueNodeIds::new().visit_program(&compiler.ast.ast);
Ok(compiler) 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> { pub fn compile_and_process<'a>(parsed: &'a mut Compiler<'a>) -> Result<String, LeoError> {
let st = parsed.symbol_table_pass()?; let st = parsed.symbol_table_pass()?;
CheckUniqueNodeIds::new().visit_program(&parsed.ast.ast);
let (st, struct_graph, call_graph) = parsed.type_checker_pass(st)?; 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 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()?; parsed.dead_code_elimination_pass()?;

View File

@ -16,6 +16,7 @@
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
use leo_ast::NodeBuilder;
use leo_errors::{emitter::Handler, Result}; use leo_errors::{emitter::Handler, Result};
use leo_span::symbol::create_session_if_not_set_then; 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"); let input_string = s.source_map.load_file(&opt.input_path).expect("failed to open an input file");
Handler::with(|handler| { 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() input.to_json_string()
}) })
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())

View File

@ -16,7 +16,7 @@
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
use leo_ast::Ast; use leo_ast::{Ast, NodeBuilder};
use leo_errors::emitter::Handler; use leo_errors::emitter::Handler;
use leo_span::symbol::create_session_if_not_set_then; 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"); let code = s.source_map.load_file(&opt.input_path).expect("failed to open file");
Handler::with(|h| { 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)?; let json = Ast::to_json_string(&ast)?;
println!("{json}"); println!("{json}");
Ok(json) Ok(json)

View File

@ -31,20 +31,26 @@ pub(crate) use tokenizer::*;
pub mod parser; pub mod parser;
pub use 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}; use leo_errors::{emitter::Handler, Result};
#[cfg(test)] #[cfg(test)]
mod test; mod test;
/// Creates a new AST from a given file path and source code text. /// 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> { pub fn parse_ast(handler: &Handler, node_builder: &NodeBuilder, source: &str, start_pos: BytePos) -> Result<Ast> {
Ok(Ast::new(parser::parse(handler, source, start_pos)?)) Ok(Ast::new(parser::parse(handler, node_builder, source, start_pos)?))
} }
/// Parses program inputs from the input file path /// Parses program inputs from the input file path
pub fn parse_program_inputs(handler: &Handler, input_string: &str, start_pos: BytePos) -> Result<InputData> { pub fn parse_program_inputs(
let program_input: ProgramInput = parser::parse_input(handler, input_string, start_pos)?.try_into()?; 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 }) Ok(InputData { program_input })
} }

View File

@ -27,6 +27,8 @@ use std::{fmt::Display, mem};
pub(crate) struct ParserContext<'a> { pub(crate) struct ParserContext<'a> {
/// Handler used to side-channel emit errors from the parser. /// Handler used to side-channel emit errors from the parser.
pub(crate) handler: &'a Handler, pub(crate) handler: &'a Handler,
/// Counter used to generate unique node ids.
pub(crate) node_builder: &'a NodeBuilder,
/// All un-bumped tokens. /// All un-bumped tokens.
tokens: Vec<SpannedToken>, tokens: Vec<SpannedToken>,
/// The current token, i.e., if `p.tokens = ['3', *, '4']`, /// 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> { impl<'a> ParserContext<'a> {
/// Returns a new [`ParserContext`] type given a vector of tokens. /// 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. // Strip out comments.
tokens.retain(|x| !matches!(x.token, Token::CommentLine(_) | Token::CommentBlock(_))); tokens.retain(|x| !matches!(x.token, Token::CommentLine(_) | Token::CommentBlock(_)));
// For performance we reverse so that we get cheap `.pop()`s. // For performance we reverse so that we get cheap `.pop()`s.
@ -55,6 +57,7 @@ impl<'a> ParserContext<'a> {
let token = SpannedToken::dummy(); let token = SpannedToken::dummy();
let mut p = Self { let mut p = Self {
handler, handler,
node_builder,
disallow_struct_construction: false, disallow_struct_construction: false,
allow_identifier_underscores: false, allow_identifier_underscores: false,
prev_token: token.clone(), prev_token: token.clone(),
@ -131,7 +134,7 @@ impl<'a> ParserContext<'a> {
/// At the previous token, return and make an identifier with `name`. /// At the previous token, return and make an identifier with `name`.
fn mk_ident_prev(&self, name: Symbol) -> Identifier { fn mk_ident_prev(&self, name: Symbol) -> Identifier {
let span = self.prev_token.span; 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. /// Eats the next token if its an identifier and returns it.

View File

@ -15,11 +15,9 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use super::*; use super::*;
use leo_errors::{ParserError, Result}; use leo_errors::{ParserError, Result};
use leo_span::{sym, Symbol}; use leo_span::{sym, Symbol};
use snarkvm_console::{account::Address, network::Testnet3}; use snarkvm_console::{account::Address, network::Testnet3};
const INT_TYPES: &[Token] = &[ const INT_TYPES: &[Token] = &[
@ -75,20 +73,20 @@ impl ParserContext<'_> {
condition: Box::new(expr), condition: Box::new(expr),
if_true: Box::new(if_true), if_true: Box::new(if_true),
if_false: Box::new(if_false), if_false: Box::new(if_false),
id: NodeID::default(), id: self.node_builder.next_id(),
}); });
} }
Ok(expr) Ok(expr)
} }
/// Constructs a binary expression `left op right`. /// 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 { Expression::Binary(BinaryExpression {
span: left.span() + right.span(), span: left.span() + right.span(),
op, op,
left: Box::new(left), left: Box::new(left),
right: Box::new(right), right: Box::new(right),
id: NodeID::default(), id: node_builder.next_id(),
}) })
} }
@ -101,7 +99,7 @@ impl ParserContext<'_> {
) -> Result<Expression> { ) -> Result<Expression> {
let mut expr = f(self)?; let mut expr = f(self)?;
while let Some(op) = self.eat_bin_op(tokens) { 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) Ok(expr)
} }
@ -156,7 +154,7 @@ impl ParserContext<'_> {
let mut expr = self.parse_bitwise_exclusive_or_expression()?; 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]) { if let Some(op) = self.eat_bin_op(&[Token::Lt, Token::LtEq, Token::Gt, Token::GtEq]) {
let right = self.parse_bitwise_exclusive_or_expression()?; 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) Ok(expr)
} }
@ -169,7 +167,7 @@ impl ParserContext<'_> {
let mut expr = self.parse_ordering_expression()?; let mut expr = self.parse_ordering_expression()?;
if let Some(op) = self.eat_bin_op(&[Token::Eq, Token::NotEq]) { if let Some(op) = self.eat_bin_op(&[Token::Eq, Token::NotEq]) {
let right = self.parse_ordering_expression()?; 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) Ok(expr)
} }
@ -239,7 +237,12 @@ impl ParserContext<'_> {
if self.eat(&Token::As) { if self.eat(&Token::As) {
let (type_, end_span) = self.parse_primitive_type()?; let (type_, end_span) = self.parse_primitive_type()?;
let span = expr.span() + end_span; 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) Ok(expr)
@ -308,7 +311,7 @@ impl ParserContext<'_> {
span: op_span + inner.span(), span: op_span + inner.span(),
op, op,
receiver: Box::new(inner), 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)) { if let (true, Some(op)) = (args.is_empty(), UnaryOperation::from_symbol(method.name)) {
// Found an unary operator and the argument list is empty. // 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)) { } 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. // Found a binary operator and the argument list contains a single argument.
Ok(Expression::Binary(BinaryExpression { Ok(Expression::Binary(BinaryExpression {
@ -333,7 +341,7 @@ impl ParserContext<'_> {
op, op,
left: Box::new(receiver), left: Box::new(receiver),
right: Box::new(args.swap_remove(0)), right: Box::new(args.swap_remove(0)),
id: NodeID::default(), id: self.node_builder.next_id(),
})) }))
} else { } else {
// Attempt to parse the method call as a mapping operation. // Attempt to parse the method call as a mapping operation.
@ -345,7 +353,7 @@ impl ParserContext<'_> {
| (1, Some(CoreFunction::MappingContains)) => { | (1, Some(CoreFunction::MappingContains)) => {
// Found an instance of `<mapping>.get`, `<mapping>.get_or_use`, `<mapping>.set`, `<mapping>.remove`, or `<mapping>.contains`. // Found an instance of `<mapping>.get`, `<mapping>.get_or_use`, `<mapping>.set`, `<mapping>.remove`, or `<mapping>.contains`.
Ok(Expression::Access(AccessExpression::AssociatedFunction(AssociatedFunction { 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, name: method,
arguments: { arguments: {
let mut arguments = vec![receiver]; let mut arguments = vec![receiver];
@ -353,13 +361,13 @@ impl ParserContext<'_> {
arguments arguments
}, },
span, span,
id: NodeID::default(), id: self.node_builder.next_id(),
}))) })))
} }
_ => { _ => {
// Either an invalid unary/binary operator, or more arguments given. // Either an invalid unary/binary operator, or more arguments given.
self.emit_err(ParserError::invalid_method_call(receiver, method, args.len(), span)); 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_, ty: type_,
name: member_name, name: member_name,
arguments: args, arguments: args,
id: NodeID::default(), id: self.node_builder.next_id(),
}) })
} else { } else {
// Return the struct constant. // Return the struct constant.
@ -397,7 +405,7 @@ impl ParserContext<'_> {
span: module_name.span() + member_name.span(), span: module_name.span() + member_name.span(),
ty: type_, ty: type_,
name: member_name, name: member_name,
id: NodeID::default(), id: self.node_builder.next_id(),
}) })
})) }))
} }
@ -425,7 +433,7 @@ impl ParserContext<'_> {
tuple: Box::new(expr), tuple: Box::new(expr),
index, index,
span, span,
id: NodeID::default(), id: self.node_builder.next_id(),
})) }))
} else if self.eat(&Token::Leo) { } else if self.eat(&Token::Leo) {
// Eat an external function call. // Eat an external function call.
@ -441,7 +449,7 @@ impl ParserContext<'_> {
function: Box::new(Expression::Identifier(name)), function: Box::new(Expression::Identifier(name)),
external: Some(Box::new(expr)), external: Some(Box::new(expr)),
arguments, arguments,
id: NodeID::default(), id: self.node_builder.next_id(),
}); });
} else { } else {
// Parse identifier name. // Parse identifier name.
@ -456,7 +464,7 @@ impl ParserContext<'_> {
span: expr.span() + name.span(), span: expr.span() + name.span(),
inner: Box::new(expr), inner: Box::new(expr),
name, name,
id: NodeID::default(), id: self.node_builder.next_id(),
})) }))
} }
} }
@ -475,7 +483,7 @@ impl ParserContext<'_> {
function: Box::new(expr), function: Box::new(expr),
external: None, external: None,
arguments, 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. // Check if next token is a dot to see if we are calling recursive method.
@ -497,7 +505,7 @@ impl ParserContext<'_> {
match elements.len() { match elements.len() {
// If the tuple expression is empty, return a `UnitExpression`. // 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 { 1 => match trailing {
// If there is one element in the tuple but no trailing comma, e.g `(foo)`, return the element. // If there is one element in the tuple but no trailing comma, e.g `(foo)`, return the element.
false => Ok(elements.swap_remove(0)), false => Ok(elements.swap_remove(0)),
@ -506,7 +514,7 @@ impl ParserContext<'_> {
}, },
// Otherwise, return a tuple expression. // Otherwise, return a tuple expression.
// Note: This is the only place where `TupleExpression` is constructed in the parser. // 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)?; let end_span = check_ahead(dist, &Token::Group)?;
dist += 1; // Standing at `)` so advance one for '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. // Eat everything so that this isn't just peeking.
for _ in 0..dist { for _ in 0..dist {
@ -572,7 +581,10 @@ impl ParserContext<'_> {
let identifier = if self.allow_identifier_underscores && self.eat(&Token::Underscore) { let identifier = if self.allow_identifier_underscores && self.eat(&Token::Underscore) {
// Allow `_nonce` for struct records. // Allow `_nonce` for struct records.
let identifier_without_underscore = self.expect_identifier()?; 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 { } else {
self.expect_identifier()? self.expect_identifier()?
}; };
@ -586,7 +598,7 @@ impl ParserContext<'_> {
(None, identifier.span) (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 /// Returns an [`Expression`] AST node if the next tokens represent a
@ -600,7 +612,7 @@ impl ParserContext<'_> {
span: identifier.span + end, span: identifier.span + end,
name: identifier, name: identifier,
members, members,
id: NodeID::default(), id: self.node_builder.next_id(),
})) }))
} }
@ -628,7 +640,7 @@ impl ParserContext<'_> {
// Literal followed by `field`, e.g., `42field`. // Literal followed by `field`, e.g., `42field`.
Some(Token::Field) => { Some(Token::Field) => {
assert_no_whitespace("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`. // Literal followed by `group`, e.g., `42group`.
Some(Token::Group) => { Some(Token::Group) => {
@ -636,34 +648,36 @@ impl ParserContext<'_> {
Expression::Literal(Literal::Group(Box::new(GroupLiteral::Single( Expression::Literal(Literal::Group(Box::new(GroupLiteral::Single(
value, value,
full_span, full_span,
NodeID::default(), self.node_builder.next_id(),
)))) ))))
} }
// Literal followed by `scalar` e.g., `42scalar`. // Literal followed by `scalar` e.g., `42scalar`.
Some(Token::Scalar) => { Some(Token::Scalar) => {
assert_no_whitespace("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`. // Literal followed by other type suffix, e.g., `42u8`.
Some(suffix) => { Some(suffix) => {
assert_no_whitespace(&suffix.to_string())?; assert_no_whitespace(&suffix.to_string())?;
let int_ty = Self::token_to_int_type(suffix).expect("unknown int type token"); 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()), None => return Err(ParserError::implicit_values_not_allowed(value, span).into()),
} }
} }
Token::True => Expression::Literal(Literal::Boolean(true, span, NodeID::default())), Token::True => Expression::Literal(Literal::Boolean(true, span, self.node_builder.next_id())),
Token::False => Expression::Literal(Literal::Boolean(false, span, NodeID::default())), Token::False => Expression::Literal(Literal::Boolean(false, span, self.node_builder.next_id())),
Token::AddressLit(address_string) => { Token::AddressLit(address_string) => {
if address_string.parse::<Address<Testnet3>>().is_err() { if address_string.parse::<Address<Testnet3>>().is_err() {
self.emit_err(ParserError::invalid_address_lit(&address_string, span)); 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) => { 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) { if !self.disallow_struct_construction && self.check(&Token::LeftCurly) {
// Parse struct and records inits as struct expressions. // Parse struct and records inits as struct expressions.
// Enforce struct or record type later at type checking. // Enforce struct or record type later at type checking.
@ -673,12 +687,16 @@ impl ParserContext<'_> {
} }
} }
Token::SelfLower => { 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() }), Token::Block => {
t if crate::type_::TYPE_TOKENS.contains(&t) => { Expression::Identifier(Identifier { name: sym::block, span, id: self.node_builder.next_id() })
Expression::Identifier(Identifier { name: t.keyword_to_symbol().unwrap(), span, id: NodeID::default() })
} }
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 => { token => {
return Err(ParserError::unexpected_str(token, "expression", span).into()); return Err(ParserError::unexpected_str(token, "expression", span).into());
} }

View File

@ -109,7 +109,7 @@ impl ParserContext<'_> {
let prg_sf = with_session_globals(|s| s.source_map.new_source(&program_string, name)); 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). // 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))) Ok((import_name.name, (program_ast.into_repr(), start + end)))
} }
@ -223,7 +223,7 @@ impl ParserContext<'_> {
let (identifier, type_, span) = self.parse_typed_ident()?; 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 { ... }`. /// Parses a struct or record definition, e.g., `struct Foo { ... }` or `record Foo { ... }`.
@ -240,7 +240,7 @@ impl ParserContext<'_> {
members, members,
is_record, is_record,
span: start + end, span: start + end,
id: NodeID::default(), id: self.node_builder.next_id(),
})) }))
} }
@ -253,7 +253,13 @@ impl ParserContext<'_> {
self.expect(&Token::BigArrow)?; self.expect(&Token::BigArrow)?;
let (value_type, _) = self.parse_type()?; let (value_type, _) = self.parse_type()?;
let end = self.expect(&Token::Semicolon)?; 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. // TODO: Return a span associated with the mode.
@ -309,7 +315,7 @@ impl ParserContext<'_> {
program_name: external, program_name: external,
record, record,
span, span,
id: NodeID::default(), id: self.node_builder.next_id(),
})) }))
} else { } else {
let type_ = self.parse_type()?.0; let type_ = self.parse_type()?.0;
@ -319,7 +325,7 @@ impl ParserContext<'_> {
mode, mode,
type_, type_,
span: name.span, 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? // TODO: Could this span be made more accurate?
let mode = self.parse_mode()?; let mode = self.parse_mode()?;
let (type_, span) = self.parse_type()?; 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. /// 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; span = span + self.prev_token.span;
Ok(Output::External(External { Ok(Output::External(External {
identifier: Identifier::new(Symbol::intern("dummy")), identifier: Identifier::new(Symbol::intern("dummy"), self.node_builder.next_id()),
program_name: external, program_name: external,
record, record,
span, span,
id: NodeID::default(), id: self.node_builder.next_id(),
})) }))
} else { } else {
Ok(Output::Internal(self.parse_function_output()?)) Ok(Output::Internal(self.parse_function_output()?))
@ -373,7 +379,7 @@ impl ParserContext<'_> {
let start = self.expect(&Token::At)?; let start = self.expect(&Token::At)?;
let identifier = match self.token.token { let identifier = match self.token.token {
Token::Program => { 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()?, _ => self.expect_identifier()?,
}; };
@ -383,7 +389,7 @@ impl ParserContext<'_> {
// Check that there is no whitespace in between the `@` symbol and identifier. // 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 { match identifier.span.hi.0 - start.lo.0 > 1 + identifier.name.to_string().len() as u32 {
true => Err(ParserError::space_in_annotation(span).into()), 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 block = self.parse_block()?;
let span = start + block.span; 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; 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(),
),
))
} }
} }

View File

@ -39,15 +39,20 @@ mod statement;
pub(super) mod type_; pub(super) mod type_;
/// Creates a new program from a given file path and source code text. /// 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> { pub fn parse(handler: &Handler, node_builder: &NodeBuilder, source: &str, start_pos: BytePos) -> Result<Program> {
let mut tokens = ParserContext::new(handler, crate::tokenize(source, start_pos)?); let mut tokens = ParserContext::new(handler, node_builder, crate::tokenize(source, start_pos)?);
tokens.parse_program() tokens.parse_program()
} }
/// Parses an input file at the given file `path` and `source` code text. /// 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> { pub fn parse_input(
let mut tokens = ParserContext::new(handler, crate::tokenize(source, start_pos)?); 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() tokens.parse_input_file()
} }

View File

@ -82,7 +82,7 @@ impl ParserContext<'_> {
self.expect(&Token::Semicolon)?; self.expect(&Token::Semicolon)?;
// Return the assertion statement. // 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. /// 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. // Construct the span for the statement.
let span = place.span() + value.span(); 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. // Simplify complex assignments into simple assignments.
// For example, `x += 1` becomes `x = x + 1`, while simple assignments like `x = y` remain unchanged. // For example, `x += 1` becomes `x = x + 1`, while simple assignments like `x = y` remain unchanged.
let value = match operation { let value = match operation {
None => value, None => value,
Some(op) => Expression::Binary(BinaryExpression { Some(op) => Expression::Binary(BinaryExpression {
left: Box::new(place.clone()), left: Box::new(left),
right: Box::new(value), right: Box::new(value),
op, op,
span, 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 { } else {
// Check for `increment` and `decrement` statements. If found, emit a deprecation warning. // Check for `increment` and `decrement` statements. If found, emit a deprecation warning.
if let Expression::Call(call_expression) = &place { if let Expression::Call(call_expression) = &place {
@ -156,7 +160,7 @@ impl ParserContext<'_> {
Ok(Statement::Expression(ExpressionStatement { Ok(Statement::Expression(ExpressionStatement {
span: place.span() + end, span: place.span() + end,
expression: place, 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 { self.parse_list(Delimiter::Brace, None, |p| p.parse_statement().map(Some)).map(|(statements, _, span)| Block {
statements, statements,
span, span,
id: NodeID::default(), id: self.node_builder.next_id(),
}) })
} }
@ -177,7 +181,7 @@ impl ParserContext<'_> {
let expression = match self.token.token { let expression = match self.token.token {
// If the next token is a semicolon, implicitly return a unit expression, `()`. // If the next token is a semicolon, implicitly return a unit expression, `()`.
Token::Semicolon | Token::Then => { 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. // Otherwise, attempt to parse an expression.
_ => self.parse_expression()?, _ => self.parse_expression()?,
@ -200,7 +204,7 @@ impl ParserContext<'_> {
}; };
let end = self.expect(&Token::Semicolon)?; let end = self.expect(&Token::Semicolon)?;
let span = start + end; 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. /// Returns a [`ConditionalStatement`] AST node if the next tokens represent a conditional statement.
@ -225,7 +229,7 @@ impl ParserContext<'_> {
condition: expr, condition: expr,
then: body, then: body,
otherwise: next, otherwise: next,
id: NodeID::default(), id: self.node_builder.next_id(),
}) })
} }
@ -256,7 +260,7 @@ impl ParserContext<'_> {
stop_value: Default::default(), stop_value: Default::default(),
inclusive: false, inclusive: false,
block, block,
id: NodeID::default(), id: self.node_builder.next_id(),
}) })
} }
@ -300,14 +304,14 @@ impl ParserContext<'_> {
Default::default(), Default::default(),
ConsoleFunction::Assert(Expression::Err(ErrExpression { ConsoleFunction::Assert(Expression::Err(ErrExpression {
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
})), })),
) )
} }
}; };
self.expect(&Token::Semicolon)?; 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. /// Returns a [`DefinitionStatement`] AST node if the next tokens represent a definition statement.
@ -335,7 +339,7 @@ impl ParserContext<'_> {
place, place,
type_, type_,
value, value,
id: NodeID::default(), id: self.node_builder.next_id(),
}) })
} }
} }

View File

@ -16,7 +16,7 @@
use crate::{tokenizer, ParserContext, SpannedToken}; use crate::{tokenizer, ParserContext, SpannedToken};
use leo_ast::Statement; use leo_ast::{NodeBuilder, NodeID, Statement};
use leo_errors::{emitter::Handler, LeoError}; use leo_errors::{emitter::Handler, LeoError};
use leo_span::{ use leo_span::{
source_map::FileName, source_map::FileName,
@ -67,7 +67,8 @@ fn with_handler<T>(
logic: impl FnOnce(&mut ParserContext<'_>) -> Result<T, LeoError>, logic: impl FnOnce(&mut ParserContext<'_>) -> Result<T, LeoError>,
) -> Result<T, String> { ) -> Result<T, String> {
let (handler, buf) = Handler::new_with_buf(); 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 let parsed = handler
.extend_if_error(logic(&mut tokens)) .extend_if_error(logic(&mut tokens))
.map_err(|_| buf.extract_errs().to_string() + &buf.extract_warnings().to_string())?; .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| { create_session_if_not_set_then(|s| {
let tokenizer = tokenize(test, s)?; let tokenizer = tokenize(test, s)?;
if all_are_comments(&tokenizer) { 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) with_handler(tokenizer, |p| p.parse_statement()).map(yaml_or_fail)
}) })

View File

@ -16,41 +16,53 @@
use leo_ast::{AssignStatement, Expression, Identifier, NodeID, Statement}; use leo_ast::{AssignStatement, Expression, Identifier, NodeID, Statement};
use leo_span::Symbol; use leo_span::Symbol;
use std::fmt::Display;
use std::{cell::RefCell, fmt::Display};
/// A struct used to create assignment statements. /// A struct used to create assignment statements.
#[derive(Default)] #[derive(Debug, Default, Clone)]
pub struct Assigner { pub struct Assigner {
/// A strictly increasing counter, used to ensure that new variable names are unique. /// The inner counter.
pub(crate) counter: usize, /// `RefCell` is used here to avoid `&mut` all over the compiler.
inner: RefCell<AssignerInner>,
} }
impl Assigner { impl Assigner {
/// Return a new unique `Symbol` from a `&str`. /// 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; self.counter += 1;
Symbol::intern(&format!("{}{}{}", arg, separator, self.counter - 1)) Symbol::intern(&format!("{}{}{}", arg, separator, self.counter - 1))
} }
/// Constructs the assignment statement `place = expr;`. /// Constructs the assignment statement `place = expr;`.
/// This function should be the only place where `AssignStatement`s are constructed. /// 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 { Statement::Assign(Box::new(AssignStatement {
place: Expression::Identifier(identifier), place: Expression::Identifier(identifier),
value, value,
span: Default::default(), 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))
}
} }

View File

@ -14,21 +14,23 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use leo_ast::NodeBuilder;
use leo_span::Symbol; use leo_span::Symbol;
use indexmap::IndexSet; use indexmap::IndexSet;
#[derive(Default)] pub struct DeadCodeEliminator<'a> {
pub struct DeadCodeEliminator { /// A counter to generate unique node IDs.
pub(crate) node_builder: &'a NodeBuilder,
/// The set of used variables in the current function body. /// The set of used variables in the current function body.
pub(crate) used_variables: IndexSet<Symbol>, pub(crate) used_variables: IndexSet<Symbol>,
/// Whether or not the variables are necessary. /// Whether or not the variables are necessary.
pub(crate) is_necessary: bool, pub(crate) is_necessary: bool,
} }
impl DeadCodeEliminator { impl<'a> DeadCodeEliminator<'a> {
/// Initializes a new `DeadCodeEliminator`. /// Initializes a new `DeadCodeEliminator`.
pub fn new() -> Self { pub fn new(node_builder: &'a NodeBuilder) -> Self {
Self { used_variables: Default::default(), is_necessary: false } Self { node_builder, used_variables: Default::default(), is_necessary: false }
} }
} }

View File

@ -23,7 +23,6 @@ use leo_ast::{
ExpressionReconstructor, ExpressionReconstructor,
Identifier, Identifier,
MemberAccess, MemberAccess,
NodeID,
StructExpression, StructExpression,
StructVariableInitializer, StructVariableInitializer,
TupleAccess, TupleAccess,
@ -31,7 +30,7 @@ use leo_ast::{
}; };
use leo_span::sym; use leo_span::sym;
impl ExpressionReconstructor for DeadCodeEliminator { impl ExpressionReconstructor for DeadCodeEliminator<'_> {
type AdditionalOutput = (); type AdditionalOutput = ();
/// Reconstructs the components of an access expression. /// Reconstructs the components of an access expression.
@ -58,7 +57,7 @@ impl ExpressionReconstructor for DeadCodeEliminator {
.map(|arg| self.reconstruct_expression(arg).0) .map(|arg| self.reconstruct_expression(arg).0)
.collect(), .collect(),
span: function.span, span: function.span,
id: NodeID::default(), id: function.id,
}); });
// Unset `self.is_necessary`. // Unset `self.is_necessary`.
self.is_necessary = false; self.is_necessary = false;
@ -68,13 +67,13 @@ impl ExpressionReconstructor for DeadCodeEliminator {
inner: Box::new(self.reconstruct_expression(*member.inner).0), inner: Box::new(self.reconstruct_expression(*member.inner).0),
name: member.name, name: member.name,
span: member.span, span: member.span,
id: NodeID::default(), id: member.id,
}), }),
AccessExpression::Tuple(tuple) => AccessExpression::Tuple(TupleAccess { AccessExpression::Tuple(tuple) => AccessExpression::Tuple(TupleAccess {
tuple: Box::new(self.reconstruct_expression(*tuple.tuple).0), tuple: Box::new(self.reconstruct_expression(*tuple.tuple).0),
index: tuple.index, index: tuple.index,
span: tuple.span, span: tuple.span,
id: NodeID::default(), id: tuple.id,
}), }),
AccessExpression::AssociatedConstant(constant) => AccessExpression::AssociatedConstant(constant), 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."), None => unreachable!("Static single assignment ensures that the expression always exists."),
}, },
span: member.span, span: member.span,
id: NodeID::default(), id: member.id,
}) })
.collect(), .collect(),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
}), }),
Default::default(), Default::default(),
) )

View File

@ -16,9 +16,9 @@
use crate::DeadCodeEliminator; 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 { fn reconstruct_function(&mut self, input: Function) -> Function {
// Reset the state of the dead code eliminator. // Reset the state of the dead code eliminator.
self.used_variables.clear(); self.used_variables.clear();
@ -43,7 +43,7 @@ impl ProgramReconstructor for DeadCodeEliminator {
output_type: finalize.output_type, output_type: finalize.output_type,
block, block,
span: finalize.span, span: finalize.span,
id: NodeID::default(), id: finalize.id,
} }
}); });
@ -57,7 +57,7 @@ impl ProgramReconstructor for DeadCodeEliminator {
block, block,
finalize, finalize,
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
} }
} }
} }

View File

@ -29,13 +29,12 @@ use leo_ast::{
ExpressionReconstructor, ExpressionReconstructor,
ExpressionStatement, ExpressionStatement,
IterationStatement, IterationStatement,
NodeID,
ReturnStatement, ReturnStatement,
Statement, Statement,
StatementReconstructor, StatementReconstructor,
}; };
impl StatementReconstructor for DeadCodeEliminator { impl StatementReconstructor for DeadCodeEliminator<'_> {
fn reconstruct_assert(&mut self, input: AssertStatement) -> (Statement, Self::AdditionalOutput) { fn reconstruct_assert(&mut self, input: AssertStatement) -> (Statement, Self::AdditionalOutput) {
// Set the `is_necessary` flag. // Set the `is_necessary` flag.
self.is_necessary = true; self.is_necessary = true;
@ -52,7 +51,7 @@ impl StatementReconstructor for DeadCodeEliminator {
} }
}, },
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
}); });
// Unset the `is_necessary` flag. // Unset the `is_necessary` flag.
@ -92,7 +91,7 @@ impl StatementReconstructor for DeadCodeEliminator {
place: input.place, place: input.place,
value: self.reconstruct_expression(input.value).0, value: self.reconstruct_expression(input.value).0,
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
// Unset the `is_necessary` flag. // Unset the `is_necessary` flag.
@ -101,7 +100,7 @@ impl StatementReconstructor for DeadCodeEliminator {
(statement, Default::default()) (statement, Default::default())
} }
// Otherwise, we can eliminate it. // 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`. // Reverse the direction of `statements`.
statements.reverse(); 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. /// Flattening removes conditional statements from the program.
@ -145,7 +144,7 @@ impl StatementReconstructor for DeadCodeEliminator {
let statement = Statement::Expression(ExpressionStatement { let statement = Statement::Expression(ExpressionStatement {
expression: self.reconstruct_call(expression).0, expression: self.reconstruct_call(expression).0,
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
}); });
// Unset the `is_necessary` flag. // Unset the `is_necessary` flag.
@ -161,14 +160,14 @@ impl StatementReconstructor for DeadCodeEliminator {
.reconstruct_access(AccessExpression::AssociatedFunction(associated_function)) .reconstruct_access(AccessExpression::AssociatedFunction(associated_function))
.0, .0,
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
}), }),
Default::default(), Default::default(),
) )
} }
// Any other expression is dead code, since they do not have side effects. // 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. // 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() arguments.into_iter().map(|argument| self.reconstruct_expression(argument).0).collect()
}), }),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
}); });
// Unset the `is_necessary` flag. // Unset the `is_necessary` flag.

View File

@ -60,15 +60,15 @@ pub use dead_code_eliminator::*;
use crate::Pass; use crate::Pass;
use leo_ast::{Ast, ProgramReconstructor}; use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
use leo_errors::Result; use leo_errors::Result;
impl Pass for DeadCodeEliminator { impl<'a> Pass for DeadCodeEliminator<'a> {
type Input = Ast; type Input = (Ast, &'a NodeBuilder);
type Output = Result<Ast>; type Output = Result<Ast>;
fn do_pass(ast: Self::Input) -> Self::Output { fn do_pass((ast, node_builder): Self::Input) -> Self::Output {
let mut reconstructor = DeadCodeEliminator::new(); let mut reconstructor = DeadCodeEliminator::new(node_builder);
let program = reconstructor.reconstruct_program(ast.into_repr()); let program = reconstructor.reconstruct_program(ast.into_repr());
Ok(Ast::new(program)) Ok(Ast::new(program))

View File

@ -24,7 +24,6 @@ use leo_ast::{
ExpressionReconstructor, ExpressionReconstructor,
Member, Member,
MemberAccess, MemberAccess,
NodeID,
Statement, Statement,
StructExpression, StructExpression,
StructVariableInitializer, StructVariableInitializer,
@ -52,14 +51,14 @@ impl ExpressionReconstructor for Flattener<'_> {
.map(|arg| self.reconstruct_expression(arg).0) .map(|arg| self.reconstruct_expression(arg).0)
.collect(), .collect(),
span: function.span, span: function.span,
id: NodeID::default(), id: function.id,
})) }))
} }
AccessExpression::Member(member) => Expression::Access(AccessExpression::Member(MemberAccess { AccessExpression::Member(member) => Expression::Access(AccessExpression::Member(MemberAccess {
inner: Box::new(self.reconstruct_expression(*member.inner).0), inner: Box::new(self.reconstruct_expression(*member.inner).0),
name: member.name, name: member.name,
span: member.span, span: member.span,
id: NodeID::default(), id: member.id,
})), })),
AccessExpression::Tuple(tuple) => { AccessExpression::Tuple(tuple) => {
// Reconstruct the tuple expression. // Reconstruct the tuple expression.
@ -99,14 +98,11 @@ impl ExpressionReconstructor for Flattener<'_> {
identifier: member.identifier, identifier: member.identifier,
expression: Some(expr), expression: Some(expr),
span: member.span, span: member.span,
id: NodeID::default(), id: member.id,
}); });
} }
( (Expression::Struct(StructExpression { name: input.name, members, span: input.span, id: input.id }), statements)
Expression::Struct(StructExpression { name: input.name, members, span: input.span, id: NodeID::default() }),
statements,
)
} }
/// Reconstructs ternary expressions over tuples and structs, accumulating any statements that are generated. /// 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_true: Box::new(if_true),
if_false: Box::new(if_false), if_false: Box::new(if_false),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
}); });
// Accumulate any statements generated. // Accumulate any statements generated.
@ -165,7 +161,7 @@ impl ExpressionReconstructor for Flattener<'_> {
}) })
.collect(), .collect(),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}); });
(tuple, statements) (tuple, statements)
} }
@ -200,16 +196,16 @@ impl ExpressionReconstructor for Flattener<'_> {
inner: Box::new(Expression::Access(AccessExpression::Member(first.clone()))), inner: Box::new(Expression::Access(AccessExpression::Member(first.clone()))),
name: *identifier, name: *identifier,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}))), }))),
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess { if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
inner: Box::new(Expression::Access(AccessExpression::Member(second.clone()))), inner: Box::new(Expression::Access(AccessExpression::Member(second.clone()))),
name: *identifier, name: *identifier,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}))), }))),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}); });
// Accumulate any statements generated. // Accumulate any statements generated.
@ -223,7 +219,7 @@ impl ExpressionReconstructor for Flattener<'_> {
identifier: *identifier, identifier: *identifier,
expression: Some(Expression::Identifier(result)), expression: Some(Expression::Identifier(result)),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
} }
}) })
.collect(); .collect();
@ -232,7 +228,7 @@ impl ExpressionReconstructor for Flattener<'_> {
name: first_member_struct.identifier, name: first_member_struct.identifier,
members, members,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}); });
// Accumulate any statements generated. // Accumulate any statements generated.
@ -265,7 +261,7 @@ impl ExpressionReconstructor for Flattener<'_> {
if_true: Box::new(if_true), if_true: Box::new(if_true),
if_false: Box::new(if_false), if_false: Box::new(if_false),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
// Accumulate the new assignment statement. // Accumulate the new assignment statement.
@ -296,16 +292,16 @@ impl ExpressionReconstructor for Flattener<'_> {
inner: Box::new(Expression::Identifier(first)), inner: Box::new(Expression::Identifier(first)),
name: *identifier, name: *identifier,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}))), }))),
if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess { if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess {
inner: Box::new(Expression::Identifier(second)), inner: Box::new(Expression::Identifier(second)),
name: *identifier, name: *identifier,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}))), }))),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}); });
// Accumulate any statements generated. // Accumulate any statements generated.
@ -319,7 +315,7 @@ impl ExpressionReconstructor for Flattener<'_> {
identifier: *identifier, identifier: *identifier,
expression: Some(Expression::Identifier(result)), expression: Some(Expression::Identifier(result)),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
} }
}) })
.collect(); .collect();
@ -328,7 +324,7 @@ impl ExpressionReconstructor for Flattener<'_> {
name: first_struct.identifier, name: first_struct.identifier,
members, members,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}); });
// Accumulate any statements generated. // Accumulate any statements generated.
@ -358,7 +354,7 @@ impl ExpressionReconstructor for Flattener<'_> {
if_true: Box::new(Expression::Tuple(first_tuple.clone())), if_true: Box::new(Expression::Tuple(first_tuple.clone())),
if_false: Box::new(Expression::Tuple(second_tuple.clone())), if_false: Box::new(Expression::Tuple(second_tuple.clone())),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
}) })
} }
// Otherwise, create a new intermediate assignment for the ternary expression are return the assigned variable. // 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_true: Box::new(if_true),
if_false: Box::new(if_false), if_false: Box::new(if_false),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
// Accumulate the new assignment statement. // Accumulate the new assignment statement.

View File

@ -16,7 +16,7 @@
use crate::Flattener; use crate::Flattener;
use leo_ast::{Finalize, Function, NodeID, ProgramReconstructor, StatementReconstructor, Type}; use leo_ast::{Finalize, Function, ProgramReconstructor, StatementReconstructor, Type};
impl ProgramReconstructor for Flattener<'_> { impl ProgramReconstructor for Flattener<'_> {
/// Flattens a function's body and finalize block, if it exists. /// Flattens a function's body and finalize block, if it exists.
@ -47,7 +47,7 @@ impl ProgramReconstructor for Flattener<'_> {
output_type: finalize.output_type, output_type: finalize.output_type,
block, block,
span: finalize.span, span: finalize.span,
id: NodeID::default(), id: finalize.id,
} }
}); });
@ -78,7 +78,7 @@ impl ProgramReconstructor for Flattener<'_> {
block, block,
finalize, finalize,
span: function.span, span: function.span,
id: NodeID::default(), id: function.id,
} }
} }
} }

View File

@ -35,7 +35,6 @@ use leo_ast::{
Identifier, Identifier,
IterationStatement, IterationStatement,
Node, Node,
NodeID,
ReturnStatement, ReturnStatement,
Statement, Statement,
StatementReconstructor, StatementReconstructor,
@ -70,7 +69,7 @@ impl StatementReconstructor for Flattener<'_> {
// Flatten the arguments of the assert statement. // Flatten the arguments of the assert statement.
let assert = AssertStatement { let assert = AssertStatement {
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
variant: match input.variant { variant: match input.variant {
AssertVariant::Assert(expression) => { AssertVariant::Assert(expression) => {
let (expression, additional_statements) = self.reconstruct_expression(expression); let (expression, additional_statements) = self.reconstruct_expression(expression);
@ -104,17 +103,17 @@ impl StatementReconstructor for Flattener<'_> {
Some(guard) => ( Some(guard) => (
Statement::Assert(AssertStatement { Statement::Assert(AssertStatement {
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
variant: AssertVariant::Assert(Expression::Binary(BinaryExpression { variant: AssertVariant::Assert(Expression::Binary(BinaryExpression {
op: BinaryOperation::Or, op: BinaryOperation::Or,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
// Take the logical negation of the guard. // Take the logical negation of the guard.
left: Box::new(Expression::Unary(UnaryExpression { left: Box::new(Expression::Unary(UnaryExpression {
op: UnaryOperation::Not, op: UnaryOperation::Not,
receiver: Box::new(guard), receiver: Box::new(guard),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
})), })),
right: Box::new(match assert.variant { right: Box::new(match assert.variant {
// If the assert statement is an `assert`, use the expression as is. // If the assert statement is an `assert`, use the expression as is.
@ -125,7 +124,7 @@ impl StatementReconstructor for Flattener<'_> {
op: BinaryOperation::Eq, op: BinaryOperation::Eq,
right: Box::new(right), right: Box::new(right),
span: Default::default(), 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. // If the assert statement is an `assert_ne`, construct a new inequality expression.
AssertVariant::AssertNeq(left, right) => Expression::Binary(BinaryExpression { AssertVariant::AssertNeq(left, right) => Expression::Binary(BinaryExpression {
@ -133,7 +132,7 @@ impl StatementReconstructor for Flattener<'_> {
op: BinaryOperation::Neq, op: BinaryOperation::Neq,
right: Box::new(right), right: Box::new(right),
span: Default::default(), 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)) => { (Expression::Identifier(identifier), Expression::Tuple(tuple)) => {
self.tuples.insert(identifier.name, tuple); self.tuples.insert(identifier.name, tuple);
// Note that tuple assignments are removed from the AST. // 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`. // 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)) (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. // 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()); self.tuples.insert(lhs_identifier.name, self.tuples.get(&rhs_identifier.name).unwrap().clone());
// Note that tuple assignments are removed from the AST. // 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`. // 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)) => { (Expression::Identifier(lhs_identifier), Expression::Call(call)) => {
@ -187,6 +186,7 @@ impl StatementReconstructor for Flattener<'_> {
.map(|(i, type_)| { .map(|(i, type_)| {
let identifier = Identifier::new( let identifier = Identifier::new(
self.assigner.unique_symbol(lhs_identifier.name, format!("$index${i}$")), 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`. // If the output type is a struct, add it to `self.structs`.
@ -198,7 +198,7 @@ impl StatementReconstructor for Flattener<'_> {
}) })
.collect(), .collect(),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}; };
// Add the `tuple_expression` to `self.tuples`. // Add the `tuple_expression` to `self.tuples`.
self.tuples.insert(lhs_identifier.name, tuple_expression.clone()); self.tuples.insert(lhs_identifier.name, tuple_expression.clone());
@ -208,7 +208,7 @@ impl StatementReconstructor for Flattener<'_> {
place: Expression::Tuple(tuple_expression), place: Expression::Tuple(tuple_expression),
value: Expression::Call(call), value: Expression::Call(call),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
})), })),
statements, statements,
) )
@ -224,7 +224,7 @@ impl StatementReconstructor for Flattener<'_> {
place: Expression::Identifier(lhs_identifier), place: Expression::Identifier(lhs_identifier),
value: Expression::Call(call), value: Expression::Call(call),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
})), })),
statements, statements,
) )
@ -274,14 +274,14 @@ impl StatementReconstructor for Flattener<'_> {
place: Expression::Identifier(lhs_identifier), place: Expression::Identifier(lhs_identifier),
value, value,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
})), })),
statements, statements,
) )
} }
(Expression::Identifier(identifier), expression) => { (Expression::Identifier(identifier), expression) => {
self.update_structs(&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. // If the lhs is a tuple and the rhs is a function call, then return the reconstructed statement.
(Expression::Tuple(tuple), Expression::Call(call)) => { (Expression::Tuple(tuple), Expression::Call(call)) => {
@ -315,7 +315,7 @@ impl StatementReconstructor for Flattener<'_> {
place: Expression::Tuple(tuple), place: Expression::Tuple(tuple),
value: Expression::Call(call), value: Expression::Call(call),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
})), })),
statements, statements,
) )
@ -333,11 +333,11 @@ impl StatementReconstructor for Flattener<'_> {
place: lhs, place: lhs,
value: rhs, value: rhs,
span: Default::default(), 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. // 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)) (Expression::Tuple(lhs_tuple), Expression::Identifier(identifier))
@ -358,10 +358,10 @@ impl StatementReconstructor for Flattener<'_> {
place: lhs, place: lhs,
value: rhs, value: rhs,
span: Default::default(), 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: // 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) // - A function call that produces a tuple. (handled above)
@ -388,7 +388,7 @@ impl StatementReconstructor for Flattener<'_> {
statements.push(reconstructed_statement); 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. /// Flatten a conditional statement into a list of statements.
@ -411,7 +411,7 @@ impl StatementReconstructor for Flattener<'_> {
op: UnaryOperation::Not, op: UnaryOperation::Not,
receiver: Box::new(conditional.condition.clone()), receiver: Box::new(conditional.condition.clone()),
span: conditional.condition.span(), span: conditional.condition.span(),
id: NodeID::default(), id: conditional.condition.id(),
})); }));
// Reconstruct the otherwise-block and accumulate it constituent statements. // Reconstruct the otherwise-block and accumulate it constituent statements.
@ -424,7 +424,7 @@ impl StatementReconstructor for Flattener<'_> {
self.condition_stack.pop(); 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) { fn reconstruct_console(&mut self, _: ConsoleStatement) -> (Statement, Self::AdditionalOutput) {
@ -458,13 +458,13 @@ impl StatementReconstructor for Flattener<'_> {
span: input.span, span: input.span,
expression: Expression::Tuple(tuple), expression: Expression::Tuple(tuple),
finalize_arguments: input.finalize_arguments, finalize_arguments: input.finalize_arguments,
id: NodeID::default(), id: input.id,
})); }));
} }
// Otherwise, add the expression directly. // Otherwise, add the expression directly.
_ => self.returns.push((guard, input)), _ => self.returns.push((guard, input)),
}; };
(Statement::dummy(Default::default()), Default::default()) (Statement::dummy(Default::default(), self.node_builder.next_id()), Default::default())
} }
} }

View File

@ -25,7 +25,7 @@ use leo_ast::{
ExpressionReconstructor, ExpressionReconstructor,
Identifier, Identifier,
Member, Member,
NodeID, NodeBuilder,
ReturnStatement, ReturnStatement,
Statement, Statement,
TernaryExpression, TernaryExpression,
@ -39,8 +39,10 @@ use indexmap::IndexMap;
pub struct Flattener<'a> { pub struct Flattener<'a> {
/// The symbol table associated with the program. /// The symbol table associated with the program.
pub(crate) symbol_table: &'a SymbolTable, 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. /// A struct used to construct (unique) assignment statements.
pub(crate) assigner: Assigner, pub(crate) assigner: &'a Assigner,
/// The set of variables that are structs. /// The set of variables that are structs.
pub(crate) structs: IndexMap<Symbol, Symbol>, pub(crate) structs: IndexMap<Symbol, Symbol>,
/// A stack of condition `Expression`s visited up to the current point in the AST. /// 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> { 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 { Self {
symbol_table, symbol_table,
node_builder,
assigner, assigner,
structs: IndexMap::new(), structs: IndexMap::new(),
condition_stack: Vec::new(), condition_stack: Vec::new(),
@ -83,7 +86,7 @@ impl<'a> Flattener<'a> {
left: Box::new(acc), left: Box::new(acc),
right: Box::new(condition), right: Box::new(condition),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}) })
})) }))
} }
@ -114,14 +117,14 @@ impl<'a> Flattener<'a> {
let place = Identifier { let place = Identifier {
name: self.assigner.unique_symbol(prefix, "$"), name: self.assigner.unique_symbol(prefix, "$"),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}; };
let (value, stmts) = self.reconstruct_ternary(TernaryExpression { let (value, stmts) = self.reconstruct_ternary(TernaryExpression {
condition: Box::new(guard), condition: Box::new(guard),
if_true: Box::new(if_true), if_true: Box::new(if_true),
if_false: Box::new(if_false), if_false: Box::new(if_false),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}); });
statements.extend(stmts); statements.extend(stmts);
@ -186,7 +189,13 @@ impl<'a> Flattener<'a> {
/// A wrapper around `assigner.unique_simple_assign_statement` that updates `self.structs`. /// 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) { 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 { match &statement {
Statement::Assign(assign) => { Statement::Assign(assign) => {
self.update_structs(&place, &assign.value); 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`. /// A wrapper around `assigner.simple_assign_statement` that updates `self.structs`.
pub(crate) fn simple_assign_statement(&mut self, lhs: Identifier, rhs: Expression) -> Statement { pub(crate) fn simple_assign_statement(&mut self, lhs: Identifier, rhs: Expression) -> Statement {
self.update_structs(&lhs, &rhs); 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. /// 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, expression,
finalize_arguments, finalize_arguments,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
})); }));
} }
} }

View File

@ -61,17 +61,17 @@ pub use flattener::*;
use crate::{Assigner, Pass, SymbolTable}; use crate::{Assigner, Pass, SymbolTable};
use leo_ast::{Ast, ProgramReconstructor}; use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
use leo_errors::Result; use leo_errors::Result;
impl<'a> Pass for Flattener<'a> { impl<'a> Pass for Flattener<'a> {
type Input = (Ast, &'a SymbolTable, Assigner); type Input = (Ast, &'a SymbolTable, &'a NodeBuilder, &'a Assigner);
type Output = Result<(Ast, Assigner)>; type Output = Result<Ast>;
fn do_pass((ast, st, assigner): Self::Input) -> Self::Output { fn do_pass((ast, st, node_builder, assigner): Self::Input) -> Self::Output {
let mut reconstructor = Flattener::new(st, assigner); let mut reconstructor = Flattener::new(st, node_builder, assigner);
let program = reconstructor.reconstruct_program(ast.into_repr()); let program = reconstructor.reconstruct_program(ast.into_repr());
Ok((Ast::new(program), reconstructor.assigner)) Ok(Ast::new(program))
} }
} }

View File

@ -24,7 +24,6 @@ use leo_ast::{
ExpressionReconstructor, ExpressionReconstructor,
Identifier, Identifier,
IterationStatement, IterationStatement,
NodeID,
ProgramReconstructor, ProgramReconstructor,
Statement, Statement,
StatementReconstructor, StatementReconstructor,
@ -36,15 +35,15 @@ use leo_span::Symbol;
// TODO: Generalize the functionality of this reconstructor to be used in other passes. // 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. /// An `AssignmentRenamer` renames the left-hand side of all assignment statements in an AST node.
/// The new names are propagated to all following identifiers. /// The new names are propagated to all following identifiers.
pub struct AssignmentRenamer { pub struct AssignmentRenamer<'a> {
pub assigner: Assigner, pub assigner: &'a Assigner,
pub rename_table: RenameTable, pub rename_table: RenameTable,
pub is_lhs: bool, pub is_lhs: bool,
} }
impl AssignmentRenamer { impl<'a> AssignmentRenamer<'a> {
/// Initialize a new `AssignmentRenamer`. /// 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 } 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 = (); 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. /// 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), 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. /// Rename the variable initializers in the struct expression.
@ -100,18 +99,18 @@ impl ExpressionReconstructor for AssignmentRenamer {
), ),
}, },
span: member.span, span: member.span,
id: NodeID::default(), id: member.id,
}) })
.collect(), .collect(),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
}), }),
Default::default(), Default::default(),
) )
} }
} }
impl StatementReconstructor for AssignmentRenamer { impl StatementReconstructor for AssignmentRenamer<'_> {
/// Rename the left-hand side of the assignment statement. /// Rename the left-hand side of the assignment statement.
fn reconstruct_assign(&mut self, input: AssignStatement) -> (Statement, Self::AdditionalOutput) { fn reconstruct_assign(&mut self, input: AssignStatement) -> (Statement, Self::AdditionalOutput) {
// First rename the right-hand-side of the assignment. // First rename the right-hand-side of the assignment.
@ -124,7 +123,7 @@ impl StatementReconstructor for AssignmentRenamer {
self.is_lhs = false; 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(), Default::default(),
) )
} }
@ -150,4 +149,4 @@ impl StatementReconstructor for AssignmentRenamer {
} }
} }
impl ProgramReconstructor for AssignmentRenamer {} impl ProgramReconstructor for AssignmentRenamer<'_> {}

View File

@ -16,24 +16,27 @@
use crate::{Assigner, AssignmentRenamer, CallGraph}; use crate::{Assigner, AssignmentRenamer, CallGraph};
use leo_ast::Function; use leo_ast::{Function, NodeBuilder};
use leo_span::Symbol; use leo_span::Symbol;
use indexmap::IndexMap; use indexmap::IndexMap;
pub struct FunctionInliner<'a> { pub struct FunctionInliner<'a> {
/// A counter used to create unique NodeIDs.
pub(crate) node_builder: &'a NodeBuilder,
/// The call graph for the program. /// The call graph for the program.
pub(crate) call_graph: &'a CallGraph, pub(crate) call_graph: &'a CallGraph,
/// A wrapper around an Assigner used to create unique variable assignments. /// 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. /// A map of reconstructed functions in the current program scope.
pub(crate) reconstructed_functions: IndexMap<Symbol, Function>, pub(crate) reconstructed_functions: IndexMap<Symbol, Function>,
} }
impl<'a> FunctionInliner<'a> { impl<'a> FunctionInliner<'a> {
/// Initializes a new `FunctionInliner`. /// 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 { Self {
node_builder,
call_graph, call_graph,
assignment_renamer: AssignmentRenamer::new(assigner), assignment_renamer: AssignmentRenamer::new(assigner),
reconstructed_functions: Default::default(), reconstructed_functions: Default::default(),

View File

@ -21,7 +21,6 @@ use leo_ast::{
Expression, Expression,
ExpressionReconstructor, ExpressionReconstructor,
Identifier, Identifier,
NodeID,
ReturnStatement, ReturnStatement,
Statement, Statement,
StatementReconstructor, StatementReconstructor,
@ -90,7 +89,7 @@ impl ExpressionReconstructor for FunctionInliner<'_> {
_ => unreachable!("This branch checks that the last statement is a return statement."), _ => 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) (result, inlined_statements)

View File

@ -26,7 +26,6 @@ use leo_ast::{
ExpressionReconstructor, ExpressionReconstructor,
ExpressionStatement, ExpressionStatement,
IterationStatement, IterationStatement,
NodeID,
Statement, Statement,
StatementReconstructor, StatementReconstructor,
}; };
@ -44,14 +43,14 @@ impl StatementReconstructor for FunctionInliner<'_> {
place: lhs, place: lhs,
value: rhs, value: rhs,
span: Default::default(), 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) => ( (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, statements,
), ),
} }
@ -67,7 +66,7 @@ impl StatementReconstructor for FunctionInliner<'_> {
statements.push(reconstructed_statement); 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. /// 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. // If the resulting expression is a unit expression, return a dummy statement.
let statement = match expression { let statement = match expression {
Expression::Unit(_) => Statement::dummy(Default::default()), Expression::Unit(_) => Statement::dummy(Default::default(), self.node_builder.next_id()),
_ => Statement::Expression(ExpressionStatement { expression, span: input.span, id: NodeID::default() }), _ => Statement::Expression(ExpressionStatement { expression, span: input.span, id: input.id }),
}; };
(statement, additional_statements) (statement, additional_statements)

View File

@ -66,17 +66,17 @@ pub use function_inliner::*;
use crate::{Assigner, CallGraph, Pass}; use crate::{Assigner, CallGraph, Pass};
use leo_ast::{Ast, ProgramReconstructor}; use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
use leo_errors::Result; use leo_errors::Result;
impl<'a> Pass for FunctionInliner<'a> { impl<'a> Pass for FunctionInliner<'a> {
type Input = (Ast, &'a CallGraph, Assigner); type Input = (Ast, &'a NodeBuilder, &'a CallGraph, &'a Assigner);
type Output = Result<(Ast, Assigner)>; type Output = Result<Ast>;
fn do_pass((ast, call_graph, assigner): Self::Input) -> Self::Output { fn do_pass((ast, node_builder, call_graph, assigner): Self::Input) -> Self::Output {
let mut reconstructor = FunctionInliner::new(call_graph, assigner); let mut reconstructor = FunctionInliner::new(node_builder, call_graph, assigner);
let program = reconstructor.reconstruct_program(ast.into_repr()); let program = reconstructor.reconstruct_program(ast.into_repr());
Ok((Ast::new(program), reconstructor.assignment_renamer.assigner)) Ok(Ast::new(program))
} }
} }

View File

@ -31,15 +31,15 @@ pub use unroll_statement::*;
use crate::{Pass, SymbolTable}; use crate::{Pass, SymbolTable};
use leo_ast::{Ast, ProgramReconstructor}; use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
use leo_errors::{emitter::Handler, Result}; use leo_errors::{emitter::Handler, Result};
impl<'a> Pass for Unroller<'a> { 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)>; type Output = Result<(Ast, SymbolTable)>;
fn do_pass((ast, handler, st): Self::Input) -> Self::Output { fn do_pass((ast, handler, node_builder, st): Self::Input) -> Self::Output {
let mut reconstructor = Self::new(st, handler); let mut reconstructor = Self::new(st, handler, node_builder);
let program = reconstructor.reconstruct_program(ast.into_repr()); let program = reconstructor.reconstruct_program(ast.into_repr());
handler.last_err().map_err(|e| *e)?; handler.last_err().map_err(|e| *e)?;

View File

@ -47,7 +47,7 @@ impl ProgramReconstructor for Unroller<'_> {
output_type: finalize.output_type, output_type: finalize.output_type,
block, block,
span: finalize.span, span: finalize.span,
id: NodeID::default(), id: finalize.id,
} }
}); });
@ -62,7 +62,7 @@ impl ProgramReconstructor for Unroller<'_> {
block, block,
finalize, finalize,
span: function.span, span: function.span,
id: NodeID::default(), id: function.id,
}; };
// Exit the function's scope. // Exit the function's scope.

View File

@ -30,7 +30,7 @@ impl StatementReconstructor for Unroller<'_> {
let block = Block { let block = Block {
statements: input.statements.into_iter().map(|s| self.reconstruct_statement(s).0).collect(), statements: input.statements.into_iter().map(|s| self.reconstruct_statement(s).0).collect(),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
}; };
// Exit the block scope. // Exit the block scope.

View File

@ -22,7 +22,7 @@ use leo_ast::{
IntegerType, IntegerType,
IterationStatement, IterationStatement,
Literal, Literal,
NodeID, NodeBuilder,
Statement, Statement,
StatementReconstructor, StatementReconstructor,
Type, Type,
@ -41,13 +41,15 @@ pub struct Unroller<'a> {
pub(crate) scope_index: usize, pub(crate) scope_index: usize,
/// An error handler used for any errors found during unrolling. /// An error handler used for any errors found during unrolling.
pub(crate) handler: &'a Handler, 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? /// Are we in the midst of unrolling a loop?
pub(crate) is_unrolling: bool, pub(crate) is_unrolling: bool,
} }
impl<'a> Unroller<'a> { impl<'a> Unroller<'a> {
pub(crate) fn new(symbol_table: SymbolTable, handler: &'a Handler) -> Self { 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, is_unrolling: false } Self { symbol_table: RefCell::new(symbol_table), scope_index: 0, handler, node_builder, is_unrolling: false }
} }
/// Returns the index of the current scope. /// Returns the index of the current scope.
@ -86,7 +88,7 @@ impl<'a> Unroller<'a> {
Ok(val_as_u128) => Ok(val_as_u128), Ok(val_as_u128) => Ok(val_as_u128),
Err(err) => { Err(err) => {
self.handler.emit_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() 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. // Exit the scope of the loop body.
@ -148,36 +150,66 @@ impl<'a> Unroller<'a> {
// Reconstruct `iteration_count` as a `Literal`. // Reconstruct `iteration_count` as a `Literal`.
let value = match input.type_ { let value = match input.type_ {
Type::Integer(IntegerType::I8) => { Type::Integer(IntegerType::I8) => Literal::Integer(
Literal::Integer(IntegerType::I8, iteration_count.to_string(), Default::default(), NodeID::default()) IntegerType::I8,
} iteration_count.to_string(),
Type::Integer(IntegerType::I16) => { Default::default(),
Literal::Integer(IntegerType::I16, iteration_count.to_string(), Default::default(), NodeID::default()) self.node_builder.next_id(),
} ),
Type::Integer(IntegerType::I32) => { Type::Integer(IntegerType::I16) => Literal::Integer(
Literal::Integer(IntegerType::I32, iteration_count.to_string(), Default::default(), NodeID::default()) IntegerType::I16,
} iteration_count.to_string(),
Type::Integer(IntegerType::I64) => { Default::default(),
Literal::Integer(IntegerType::I64, iteration_count.to_string(), Default::default(), NodeID::default()) self.node_builder.next_id(),
} ),
Type::Integer(IntegerType::I128) => { Type::Integer(IntegerType::I32) => Literal::Integer(
Literal::Integer(IntegerType::I128, iteration_count.to_string(), Default::default(), NodeID::default()) IntegerType::I32,
} iteration_count.to_string(),
Type::Integer(IntegerType::U8) => { Default::default(),
Literal::Integer(IntegerType::U8, iteration_count.to_string(), Default::default(), NodeID::default()) self.node_builder.next_id(),
} ),
Type::Integer(IntegerType::U16) => { Type::Integer(IntegerType::I64) => Literal::Integer(
Literal::Integer(IntegerType::U16, iteration_count.to_string(), Default::default(), NodeID::default()) IntegerType::I64,
} iteration_count.to_string(),
Type::Integer(IntegerType::U32) => { Default::default(),
Literal::Integer(IntegerType::U32, iteration_count.to_string(), Default::default(), NodeID::default()) self.node_builder.next_id(),
} ),
Type::Integer(IntegerType::U64) => { Type::Integer(IntegerType::I128) => Literal::Integer(
Literal::Integer(IntegerType::U64, iteration_count.to_string(), Default::default(), NodeID::default()) IntegerType::I128,
} iteration_count.to_string(),
Type::Integer(IntegerType::U128) => { Default::default(),
Literal::Integer(IntegerType::U128, iteration_count.to_string(), Default::default(), NodeID::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!( _ => unreachable!(
"The iteration variable must be an integer type. This should be enforced by type checking." "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), value: Expression::Literal(value),
span: Default::default(), span: Default::default(),
place: Expression::Identifier(input.variable), place: Expression::Identifier(input.variable),
id: NodeID::default(), id: self.node_builder.next_id(),
}) })
.0, .0,
]; ];
@ -201,7 +233,7 @@ impl<'a> Unroller<'a> {
statements.push(self.reconstruct_statement(s).0); 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; self.is_unrolling = prior_is_unrolling;

View File

@ -61,17 +61,17 @@ pub use static_single_assigner::*;
use crate::{Assigner, Pass, SymbolTable}; use crate::{Assigner, Pass, SymbolTable};
use leo_ast::{Ast, ProgramConsumer}; use leo_ast::{Ast, NodeBuilder, ProgramConsumer};
use leo_errors::Result; use leo_errors::Result;
impl<'a> Pass for StaticSingleAssigner<'a> { impl<'a> Pass for StaticSingleAssigner<'a> {
type Input = (Ast, &'a SymbolTable); type Input = (Ast, &'a NodeBuilder, &'a Assigner, &'a SymbolTable);
type Output = Result<(Ast, Assigner)>; type Output = Result<Ast>;
fn do_pass((ast, symbol_table): Self::Input) -> Self::Output { fn do_pass((ast, node_builder, assigner, symbol_table): Self::Input) -> Self::Output {
let mut consumer = StaticSingleAssigner::new(symbol_table); let mut consumer = StaticSingleAssigner::new(node_builder, symbol_table, assigner);
let program = consumer.consume_program(ast.into_repr()); let program = consumer.consume_program(ast.into_repr());
Ok((Ast::new(program), consumer.assigner)) Ok(Ast::new(program))
} }
} }

View File

@ -27,7 +27,6 @@ use leo_ast::{
Identifier, Identifier,
Literal, Literal,
MemberAccess, MemberAccess,
NodeID,
Statement, Statement,
Struct, Struct,
StructExpression, StructExpression,
@ -65,7 +64,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
}) })
.collect(), .collect(),
span: function.span, span: function.span,
id: NodeID::default(), id: function.id,
}), }),
statements, statements,
) )
@ -85,7 +84,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
inner: Box::new(expr), inner: Box::new(expr),
name: member.name, name: member.name,
span: member.span, span: member.span,
id: NodeID::default(), id: member.id,
}), }),
statements, statements,
) )
@ -97,14 +96,14 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
tuple: Box::new(expr), tuple: Box::new(expr),
index: tuple.index, index: tuple.index,
span: tuple.span, span: tuple.span,
id: NodeID::default(), id: tuple.id,
}), }),
statements, statements,
) )
} }
expr => (expr, Vec::new()), 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); statements.push(statement);
(Expression::Identifier(place), statements) (Expression::Identifier(place), statements)
@ -120,12 +119,12 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
statements.append(&mut right_statements); statements.append(&mut right_statements);
// Construct and accumulate a unique assignment statement storing the result of the binary expression. // 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), left: Box::new(left_expression),
right: Box::new(right_expression), right: Box::new(right_expression),
op: input.op, op: input.op,
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
statements.push(statement); statements.push(statement);
@ -148,14 +147,14 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
.collect(); .collect();
// Construct and accumulate a new assignment statement for the call expression. // 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. // Note that we do not rename the function name.
function: input.function, function: input.function,
// Consume the arguments. // Consume the arguments.
arguments, arguments,
external: input.external, external: input.external,
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
statements.push(statement); statements.push(statement);
@ -168,11 +167,11 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
let (expression, mut statements) = self.consume_expression(*input.expression); let (expression, mut statements) = self.consume_expression(*input.expression);
// Construct and accumulate a unique assignment statement storing the result of the cast 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), expression: Box::new(expression),
type_: input.type_, type_: input.type_,
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
statements.push(statement); statements.push(statement);
@ -204,7 +203,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
identifier: arg.identifier, identifier: arg.identifier,
expression: Some(expression), expression: Some(expression),
span: arg.span, span: arg.span,
id: NodeID::default(), id: arg.id,
} }
}) })
.collect(); .collect();
@ -241,11 +240,11 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
} }
// Construct and accumulate a new assignment statement for the struct expression. // 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, name: input.name,
span: input.span, span: input.span,
members: reordered_members, members: reordered_members,
id: NodeID::default(), id: input.id,
})); }));
statements.push(statement); statements.push(statement);
@ -268,7 +267,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
false => *self.rename_table.lookup(identifier.name).unwrap_or(&identifier.name), 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. /// Consumes and returns the literal without making any modifications.
@ -290,12 +289,12 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
statements.append(&mut if_false_statements); statements.append(&mut if_false_statements);
// Construct and accumulate a unique assignment statement storing the result of the ternary expression. // 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), condition: Box::new(cond_expr),
if_true: Box::new(if_true_expr), if_true: Box::new(if_true_expr),
if_false: Box::new(if_false_expr), if_false: Box::new(if_false_expr),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
statements.push(statement); statements.push(statement);
@ -318,10 +317,10 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
.collect(); .collect();
// Construct and accumulate a new assignment statement for the tuple expression. // 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, elements,
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
statements.push(statement); statements.push(statement);
@ -334,11 +333,11 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
let (receiver, mut statements) = self.consume_expression(*input.receiver); let (receiver, mut statements) = self.consume_expression(*input.receiver);
// Construct and accumulate a new assignment statement for the unary expression. // 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, op: input.op,
receiver: Box::new(receiver), receiver: Box::new(receiver),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
statements.push(statement); statements.push(statement);

View File

@ -22,7 +22,6 @@ use leo_ast::{
Function, Function,
FunctionConsumer, FunctionConsumer,
Member, Member,
NodeID,
Program, Program,
ProgramConsumer, ProgramConsumer,
ProgramScope, ProgramScope,
@ -75,7 +74,7 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
} }
let block = 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. // Remove the `RenameTable` for the function.
self.pop(); self.pop();
@ -92,8 +91,8 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
let block = Block { let block = Block {
span: finalize.block.span, span: finalize.block.span,
id: finalize.block.id,
statements: self.consume_block(finalize.block), statements: self.consume_block(finalize.block),
id: NodeID::default(),
}; };
// Remove the `RenameTable` for the finalize block. // Remove the `RenameTable` for the finalize block.
@ -106,7 +105,7 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
output_type: finalize.output_type, output_type: finalize.output_type,
block, block,
span: finalize.span, span: finalize.span,
id: NodeID::default(), id: finalize.id,
} }
}); });
@ -120,7 +119,7 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
block, block,
finalize, finalize,
span: function.span, span: function.span,
id: NodeID::default(), id: function.id,
} }
} }
} }

View File

@ -32,7 +32,6 @@ use leo_ast::{
ExpressionStatement, ExpressionStatement,
Identifier, Identifier,
IterationStatement, IterationStatement,
NodeID,
ReturnStatement, ReturnStatement,
Statement, Statement,
StatementConsumer, StatementConsumer,
@ -76,7 +75,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
}; };
// Add the assert statement to the list of produced statements. // 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 statements
} }
@ -95,7 +94,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
}; };
self.is_lhs = false; 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 statements
} }
@ -122,8 +121,8 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
// Consume the then-block. // Consume the then-block.
let then = Block { let then = Block {
span: conditional.then.span, span: conditional.then.span,
id: conditional.then.id,
statements: self.consume_block(conditional.then), statements: self.consume_block(conditional.then),
id: NodeID::default(),
}; };
// Remove the `RenameTable` for the then-block. // 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 { let otherwise = conditional.otherwise.map(|otherwise| Box::new(Statement::Block(match *otherwise {
Statement::Block(block) => Block { Statement::Block(block) => Block {
span: block.span, span: block.span,
id: block.id,
statements: self.consume_block(block), statements: self.consume_block(block),
id: NodeID::default(),
}, },
Statement::Conditional(conditional) => Block { Statement::Conditional(conditional) => Block {
span: conditional.span, span: conditional.span,
id: conditional.id,
statements: self.consume_conditional(conditional), 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."), _ => 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. // Add reconstructed conditional statement to the list of produced statements.
statements.push(Statement::Conditional(ConditionalStatement { statements.push(Statement::Conditional(ConditionalStatement {
span: conditional.span, span: conditional.span,
id: conditional.id,
condition: condition.clone(), condition: condition.clone(),
then, then,
otherwise, otherwise,
id: NodeID::default(),
})); }));
// Compute the write set for the variables written in the then-block or otherwise-block. // 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 { Box::new(Expression::Identifier(Identifier {
name, name,
span: Default::default(), 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_true: create_phi_argument(&if_table, **symbol),
if_false: create_phi_argument(&else_table, **symbol), if_false: create_phi_argument(&else_table, **symbol),
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}); });
statements.extend(stmts); statements.extend(stmts);
// Create a new `AssignStatement` for the phi function. // Create a new `AssignStatement` for the phi function.
let assignment = self.assigner.simple_assign_statement( 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, value,
self.node_builder.next_id(),
); );
// Update the `RenameTable` with the new name of the variable. // Update the `RenameTable` with the new name of the variable.
@ -228,7 +228,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
Expression::Identifier(identifier) => identifier, Expression::Identifier(identifier) => identifier,
_ => unreachable!("`self.consume_identifier` will always return an `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) => { Expression::Tuple(tuple) => {
let elements = tuple.elements.into_iter().map(|element| { let elements = tuple.elements.into_iter().map(|element| {
@ -247,11 +247,11 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
place: Expression::Tuple(TupleExpression { place: Expression::Tuple(TupleExpression {
elements, elements,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}), }),
value, value,
span: Default::default(), span: Default::default(),
id: NodeID::default(), id: self.node_builder.next_id(),
}))); })));
} }
_ => unreachable!( _ => unreachable!(
@ -291,10 +291,10 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
arguments, arguments,
external: call.external, external: call.external,
span: call.span, span: call.span,
id: NodeID::default(), id: call.id,
}), }),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
} }
Expression::Access(AccessExpression::AssociatedFunction(associated_function)) => { Expression::Access(AccessExpression::AssociatedFunction(associated_function)) => {
@ -308,10 +308,10 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
name: associated_function.name, name: associated_function.name,
arguments, arguments,
span: associated_function.span, span: associated_function.span,
id: NodeID::default(), id: associated_function.id,
})), })),
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})) }))
} }
@ -350,7 +350,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
expression, expression,
finalize_arguments: finalize_args, finalize_arguments: finalize_args,
span: input.span, span: input.span,
id: NodeID::default(), id: input.id,
})); }));
statements statements

View File

@ -16,7 +16,11 @@
use crate::{Assigner, RenameTable, SymbolTable}; use crate::{Assigner, RenameTable, SymbolTable};
use leo_ast::{Expression, Identifier, NodeBuilder, Statement};
pub struct StaticSingleAssigner<'a> { pub struct StaticSingleAssigner<'a> {
/// A counter used to generate unique node IDs.
pub(crate) node_builder: &'a NodeBuilder,
/// The `SymbolTable` of the program. /// The `SymbolTable` of the program.
pub(crate) symbol_table: &'a SymbolTable, pub(crate) symbol_table: &'a SymbolTable,
/// The `RenameTable` for the current basic block in the AST /// 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. /// 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, pub(crate) is_lhs: bool,
/// A struct used to construct (unique) assignment statements. /// A struct used to construct (unique) assignment statements.
pub(crate) assigner: Assigner, pub(crate) assigner: &'a Assigner,
} }
impl<'a> StaticSingleAssigner<'a> { impl<'a> StaticSingleAssigner<'a> {
/// Initializes a new `StaticSingleAssigner` with an empty `RenameTable`. /// Initializes a new `StaticSingleAssigner` with an empty `RenameTable`.
pub(crate) fn new(symbol_table: &'a SymbolTable) -> Self { pub(crate) fn new(node_builder: &'a NodeBuilder, symbol_table: &'a SymbolTable, assigner: &'a Assigner) -> Self {
Self { symbol_table, rename_table: RenameTable::new(None), is_lhs: false, assigner: Assigner::default() } 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. /// 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(); let parent = self.rename_table.parent.clone().unwrap_or_default();
core::mem::replace(&mut self.rename_table, *parent) 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)
}
} }

View File

@ -16,7 +16,7 @@
use super::*; use super::*;
use leo_ast::Struct; use leo_ast::{NodeBuilder, Struct};
use leo_compiler::{Compiler, CompilerOptions, InputAst, OutputOptions}; use leo_compiler::{Compiler, CompilerOptions, InputAst, OutputOptions};
use leo_package::{ use leo_package::{
build::BuildDirectory, build::BuildDirectory,
@ -103,6 +103,9 @@ impl Command for Build {
// Initialize error handler // Initialize error handler
let handler = Handler::default(); let handler = Handler::default();
// Initialize a node counter.
let node_builder = NodeBuilder::default();
// Fetch paths to all .leo files in the source directory. // Fetch paths to all .leo files in the source directory.
let source_files = SourceDirectory::files(&package_path)?; 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))?; .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. // 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")) .map_err(|_e| println!("Warning: Failed to parse input file"))
.ok() .ok()
} else { } else {

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: aedbecdddf47324809cfe36a7329e30e0b02cb1a8e079ea3c6a1fed485eb6a23 - - initial_ast: ca70df10bc83440d704ee7f48d1fcd9add55c26ffc98a0f84f631ad65a83ec93
unrolled_ast: aedbecdddf47324809cfe36a7329e30e0b02cb1a8e079ea3c6a1fed485eb6a23 unrolled_ast: ca70df10bc83440d704ee7f48d1fcd9add55c26ffc98a0f84f631ad65a83ec93
ssa_ast: 6495fd7481d1b9490b37eb367af3f47f367d5571bed98476ba465441ffb6af52 ssa_ast: 66c5290f551b96ac177708948dd1080ddd4d00b1e3a73e33c28197e0ebdf7792
flattened_ast: d768a50e70e99bbbebbf391db1363d50ea42a2a64997319fe442c862eb477a12 flattened_ast: 2f37e06e70a4256eaff95d292b04aa0c72e34c84dfd7075e7997cf05ae4826a1
inlined_ast: d768a50e70e99bbbebbf391db1363d50ea42a2a64997319fe442c862eb477a12 inlined_ast: 2f37e06e70a4256eaff95d292b04aa0c72e34c84dfd7075e7997cf05ae4826a1
dce_ast: 195cdd11eab6742a8726b398d7fe1ad5b2ed170a9ef63b8da24e5c9bfed7e066 dce_ast: 4eda0426e943afc272c16e4fb45f9cdd8d5ea97d39cb495361a71549dfbec66e
bytecode: e434c09cee27a5dfb5a4e9e9fd26aa2ba6e7f0653fad3a4f2a7d85983ba559c9 bytecode: e434c09cee27a5dfb5a4e9e9fd26aa2ba6e7f0653fad3a4f2a7d85983ba559c9
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: e64985069c66d2678488b57ceab0026149c4ebaf1fc42ac15798fdc306f74d20 - - initial_ast: 6b548ac1d786b728c21d152061d7ae31e25fe8c3a93c38577a82f1c0c2ffd0b2
unrolled_ast: e64985069c66d2678488b57ceab0026149c4ebaf1fc42ac15798fdc306f74d20 unrolled_ast: 6b548ac1d786b728c21d152061d7ae31e25fe8c3a93c38577a82f1c0c2ffd0b2
ssa_ast: 073128b766cc8ea00519d7cdee4714796e631f2847db5f55b75d829101bd9552 ssa_ast: f3daee14d82b5ff4064f11080deef28899853dbef55479ad86e1c6fe34cec041
flattened_ast: 9b5233811932dc7004d77590063c9b7d2ff00be8bd7c7c8c81192ce5df740175 flattened_ast: 26dce66c06759444280565f35558f94c4c1550cbb589562ca7121f6651924bcc
inlined_ast: 9b5233811932dc7004d77590063c9b7d2ff00be8bd7c7c8c81192ce5df740175 inlined_ast: 26dce66c06759444280565f35558f94c4c1550cbb589562ca7121f6651924bcc
dce_ast: 9b5233811932dc7004d77590063c9b7d2ff00be8bd7c7c8c81192ce5df740175 dce_ast: 26dce66c06759444280565f35558f94c4c1550cbb589562ca7121f6651924bcc
bytecode: da1b0a83a17b801368b0a583b158d88d9d807a33000c8e89e82da123c8041aea bytecode: da1b0a83a17b801368b0a583b158d88d9d807a33000c8e89e82da123c8041aea
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 7a1afdab98a730090c3370305d8fa23a7a69f779b492288ab8bae2169b880118 - - initial_ast: 778ee6a278f90c3c9a337517771c2c3fd31cf166c0fe38ba7e1da097ec0f81f1
unrolled_ast: 7a1afdab98a730090c3370305d8fa23a7a69f779b492288ab8bae2169b880118 unrolled_ast: 778ee6a278f90c3c9a337517771c2c3fd31cf166c0fe38ba7e1da097ec0f81f1
ssa_ast: faaa8bd1f0f1f9d0c2d20cf6e8265e8db0593930bf38451509a218fdca25905a ssa_ast: 577c1fdc33f8a0182faa399d4f2a5d49f95efba574f0cf451511c3b8a447914f
flattened_ast: 94377cdcfd12afd021b97302dc880bca782aeb9ea8b908dd3f8ef19e4d231e69 flattened_ast: 90c9589974b2fe7c5e320e4ac76a1655f4b84e60ed8ec9b8c52c9f1f29e4a682
inlined_ast: 94377cdcfd12afd021b97302dc880bca782aeb9ea8b908dd3f8ef19e4d231e69 inlined_ast: 90c9589974b2fe7c5e320e4ac76a1655f4b84e60ed8ec9b8c52c9f1f29e4a682
dce_ast: 94377cdcfd12afd021b97302dc880bca782aeb9ea8b908dd3f8ef19e4d231e69 dce_ast: 90c9589974b2fe7c5e320e4ac76a1655f4b84e60ed8ec9b8c52c9f1f29e4a682
bytecode: bde2653fac0393940c5400272e53492228206e50abb36ce080b95043003ee976 bytecode: bde2653fac0393940c5400272e53492228206e50abb36ce080b95043003ee976
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 3e3635b9f0e8098731455f2d2b49026c90cea00d07461e7cbcaa5759bf823be4 - - initial_ast: 853fd69f7e97be37c0f6a19994e4e9bf9ae354ff2a41c3de90d23d8f0d777884
unrolled_ast: 3e3635b9f0e8098731455f2d2b49026c90cea00d07461e7cbcaa5759bf823be4 unrolled_ast: 853fd69f7e97be37c0f6a19994e4e9bf9ae354ff2a41c3de90d23d8f0d777884
ssa_ast: 21ca11c494c4f9c4e204f368e967727bda93ce65962c86935ce2fe6895197ebb ssa_ast: c08b13b85d836c9a2e4d0f6fb1b20ccc60a9d1aa8cc7ca81b1448ddd2feef8e0
flattened_ast: c5ebee78d83725ede5e4dce6ca0f77339b3d5dd0eb727fbf32bd6c476f569173 flattened_ast: ebfda40c22a70c7490170c019fc22eef2552122300b28947b7c1826bc889cd1e
inlined_ast: c5ebee78d83725ede5e4dce6ca0f77339b3d5dd0eb727fbf32bd6c476f569173 inlined_ast: ebfda40c22a70c7490170c019fc22eef2552122300b28947b7c1826bc889cd1e
dce_ast: c5ebee78d83725ede5e4dce6ca0f77339b3d5dd0eb727fbf32bd6c476f569173 dce_ast: ebfda40c22a70c7490170c019fc22eef2552122300b28947b7c1826bc889cd1e
bytecode: c0b90b7f7e80041dc1a314c1a87290534936018fb001c6e1291266a02393c6f2 bytecode: c0b90b7f7e80041dc1a314c1a87290534936018fb001c6e1291266a02393c6f2
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 83a584fa8274354e7caf1b9f530ee91008fb867a341045e84f1849cd8dc88e88 - - initial_ast: ab78d2239021d6f96bbea881d9937d95e08dea46f20c122899e0b36d0446c4c1
unrolled_ast: 83a584fa8274354e7caf1b9f530ee91008fb867a341045e84f1849cd8dc88e88 unrolled_ast: ab78d2239021d6f96bbea881d9937d95e08dea46f20c122899e0b36d0446c4c1
ssa_ast: 999147035ff811021e9a050ec2fabecb6ff70eacbac0ca4b6c143b9105dfd28e ssa_ast: d90f0982b624f26c17177ead06ed3d48a96627dd187a8c38b134714e33f48260
flattened_ast: 0839b38833dc1b6dfcf512a031d4c6fa17de417ee965fd33963c9ed5eb0b7b01 flattened_ast: 4bc298cb5533064ca61830980466ed1ed7c21a15d38bee043e3e0ed0348de182
inlined_ast: 0839b38833dc1b6dfcf512a031d4c6fa17de417ee965fd33963c9ed5eb0b7b01 inlined_ast: 4bc298cb5533064ca61830980466ed1ed7c21a15d38bee043e3e0ed0348de182
dce_ast: 0839b38833dc1b6dfcf512a031d4c6fa17de417ee965fd33963c9ed5eb0b7b01 dce_ast: 4bc298cb5533064ca61830980466ed1ed7c21a15d38bee043e3e0ed0348de182
bytecode: 134904b86b96581876c2ca0c6ead651dda0dc9f2fb6dc583400133410b7deede bytecode: 134904b86b96581876c2ca0c6ead651dda0dc9f2fb6dc583400133410b7deede
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 28c909dfc3df83359c4f2f4b989329201c16e944b5c1206c0b770753cf07b60a - - initial_ast: f39f9a60bf3468977bc507347f90029d098e16e97cb8f976add9a40cd986e285
unrolled_ast: 28c909dfc3df83359c4f2f4b989329201c16e944b5c1206c0b770753cf07b60a unrolled_ast: f39f9a60bf3468977bc507347f90029d098e16e97cb8f976add9a40cd986e285
ssa_ast: 9a9c933d5a770b15fda13380e32bdcb72353582dc4e60db47c46ed5a95bead6f ssa_ast: fc284c302558f32f72f8ed8186ac5114ea54a94d888de15907ad83207a02324b
flattened_ast: f7a6fe164fe7eea96468302395fa5f7a78ebed2b7bab56bbee925f773c5d290d flattened_ast: 30952aa8bf4898cf653ebb094c31cee491a570a5084776082e7174bd66893293
inlined_ast: f7a6fe164fe7eea96468302395fa5f7a78ebed2b7bab56bbee925f773c5d290d inlined_ast: 30952aa8bf4898cf653ebb094c31cee491a570a5084776082e7174bd66893293
dce_ast: f7a6fe164fe7eea96468302395fa5f7a78ebed2b7bab56bbee925f773c5d290d dce_ast: 30952aa8bf4898cf653ebb094c31cee491a570a5084776082e7174bd66893293
bytecode: 56a9fa48a00d1b38b6f60a93ef2168b2c0ce9c23ba3cb7bffa40debfc1b16180 bytecode: 56a9fa48a00d1b38b6f60a93ef2168b2c0ce9c23ba3cb7bffa40debfc1b16180
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: c78718de7e86670216551ca3e1a7ff79eac984bbd7d3916efc0471fc47dac07e - - initial_ast: 30edf3aaef89e9461c7fdf5a4e789edd00d7cc1b44be3387d4e0e59a70dc2e43
unrolled_ast: c78718de7e86670216551ca3e1a7ff79eac984bbd7d3916efc0471fc47dac07e unrolled_ast: 30edf3aaef89e9461c7fdf5a4e789edd00d7cc1b44be3387d4e0e59a70dc2e43
ssa_ast: e5a52db1daeec16966a78bb2f7ef2449af7a7e1ff6eab67a63f24030b0d8077b ssa_ast: 72b1100d61b4477e324e30ad1eced22689eb3d63a2fd672c55498ff9465429b9
flattened_ast: f7632dc71f1fcdb0c810dc41804d7a774f6470d667667ea4ebafaef764c37c62 flattened_ast: 2569b27d888761edf53ca6312a8844318e61f8a3ebeeefbd6571098cf8bee52c
inlined_ast: f7632dc71f1fcdb0c810dc41804d7a774f6470d667667ea4ebafaef764c37c62 inlined_ast: 2569b27d888761edf53ca6312a8844318e61f8a3ebeeefbd6571098cf8bee52c
dce_ast: f7632dc71f1fcdb0c810dc41804d7a774f6470d667667ea4ebafaef764c37c62 dce_ast: 2569b27d888761edf53ca6312a8844318e61f8a3ebeeefbd6571098cf8bee52c
bytecode: 2332d5b7ed9910dc65c885e1aeedbbde00e02d95a55caa300a9cb72456707034 bytecode: 2332d5b7ed9910dc65c885e1aeedbbde00e02d95a55caa300a9cb72456707034
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 9e871518f362d925d3a49dc805f25270f20d8b471e75dca55bd08ddd95dba0a7 - - initial_ast: 7c30d305deb563c4446176cc16a27c5407c78eea7275c6e528bf425d1b034647
unrolled_ast: 9e871518f362d925d3a49dc805f25270f20d8b471e75dca55bd08ddd95dba0a7 unrolled_ast: 7c30d305deb563c4446176cc16a27c5407c78eea7275c6e528bf425d1b034647
ssa_ast: 4df5ebccb2b9337d9570b8b674bf110b21f03e19eed2bd62720503675dd0ed76 ssa_ast: 378c785982c1014acc1383b29b8a09dbdfd7f393b8912626e154cedeb8a0a335
flattened_ast: 1d523dd55672a7be0a853091da70a15e24c028f0585808b60bb4d435d2e28866 flattened_ast: 152776e1ce69acad498c75211d502d36dd000025cd024771ba7b78dfa30bc824
inlined_ast: 1d523dd55672a7be0a853091da70a15e24c028f0585808b60bb4d435d2e28866 inlined_ast: 152776e1ce69acad498c75211d502d36dd000025cd024771ba7b78dfa30bc824
dce_ast: 1d523dd55672a7be0a853091da70a15e24c028f0585808b60bb4d435d2e28866 dce_ast: 152776e1ce69acad498c75211d502d36dd000025cd024771ba7b78dfa30bc824
bytecode: 990eee0b87d70df046bad969201ad8afabff10162eb70c00f837fde81fed4104 bytecode: 990eee0b87d70df046bad969201ad8afabff10162eb70c00f837fde81fed4104
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 51323fd6e2305e68d3a49b1e3beff44a25962a9d2f981952270725a10fb907eb - - initial_ast: 75366768a7b2cb5b76e0aabd11f29dcec41d1a9d20c98ba227d9c784c8e0bd64
unrolled_ast: 51323fd6e2305e68d3a49b1e3beff44a25962a9d2f981952270725a10fb907eb unrolled_ast: 75366768a7b2cb5b76e0aabd11f29dcec41d1a9d20c98ba227d9c784c8e0bd64
ssa_ast: 7480cf469ca3ed640d36d8c171a975885590bbc3cfaec0805d9d8aef6cd19518 ssa_ast: 35c7bcdf89e7d7bd2e1d1d2ada0ab6de758f91c7160a681af8174bdd19e3c4d8
flattened_ast: 2610072b45f28619332adf130aa46d92bb6d3e008c88e0d59c35407d7fe84a09 flattened_ast: 5cd80f02b55d9aea6d5a752b6a9b0b90a84deefffd9797a2da0ffe2c5405a558
inlined_ast: 2610072b45f28619332adf130aa46d92bb6d3e008c88e0d59c35407d7fe84a09 inlined_ast: 5cd80f02b55d9aea6d5a752b6a9b0b90a84deefffd9797a2da0ffe2c5405a558
dce_ast: a5cc2bdb045e2f9e981c12c2411f397b4af69a2aa6cb3a83b14403ce3155e8d6 dce_ast: a1c587fc02d556c185a43ee3ceed0be4027bbaba0c4fdd7b8939d0bb2b7907a7
bytecode: bb260232bbd0ccede368961a31abeef5edc7e00cab3348b4b8518d4e5798a6b5 bytecode: bb260232bbd0ccede368961a31abeef5edc7e00cab3348b4b8518d4e5798a6b5
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 7cce4e768432d303e86d5d8f38ca10df9fcb641ab1bd791cfed3180594f6cea7 - - initial_ast: 771493cfb3297abd1fbfda7b2cff7254f9106addefe0a8b5f489ecec1d83baa3
unrolled_ast: 7cce4e768432d303e86d5d8f38ca10df9fcb641ab1bd791cfed3180594f6cea7 unrolled_ast: 771493cfb3297abd1fbfda7b2cff7254f9106addefe0a8b5f489ecec1d83baa3
ssa_ast: a8dcccc18c4984c95a15bc850343a4c0a6bd4de3745cee2d9dc5f204bf8d5290 ssa_ast: be444afe192366899792ef107676880d8f5a6f7bd7da49586d8762b2fc3fcd37
flattened_ast: dac527fa65b44faef014c5046d668bf8f4fb6731beedf04369367b546521d54f flattened_ast: 1197ae78c9aabdcf47b4b8c21d800c7541703fef96789584fa817ebe0b8018b3
inlined_ast: dac527fa65b44faef014c5046d668bf8f4fb6731beedf04369367b546521d54f inlined_ast: 1197ae78c9aabdcf47b4b8c21d800c7541703fef96789584fa817ebe0b8018b3
dce_ast: dac527fa65b44faef014c5046d668bf8f4fb6731beedf04369367b546521d54f dce_ast: 1197ae78c9aabdcf47b4b8c21d800c7541703fef96789584fa817ebe0b8018b3
bytecode: c3a0c03f4324a6dd6baea42e664ffad91868714739e03525dcbc968582007ceb bytecode: c3a0c03f4324a6dd6baea42e664ffad91868714739e03525dcbc968582007ceb
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: c45d509ec04f7f518387ad6a3e24a97631a50ab4d0cf122af78e03df5cb41328 - - initial_ast: 7b2d55feccfedf17c5acaf63cbe41f3313518cdabf096c968e1104f3f5b4b869
unrolled_ast: c45d509ec04f7f518387ad6a3e24a97631a50ab4d0cf122af78e03df5cb41328 unrolled_ast: 7b2d55feccfedf17c5acaf63cbe41f3313518cdabf096c968e1104f3f5b4b869
ssa_ast: 6aa7493d54a6eb2a5136980f379966cb25198c905c358b807c10bdb4e163de5d ssa_ast: af9661e5a0685e552b388ee6e48b8556d367d00721159fedf35288c442f21699
flattened_ast: 047a89ee6cdf364b877eca15cdc92954c7ba669fddd3c99fece729abcfd211e3 flattened_ast: da3100e3f67e9ddaf90f4d534ac6ed5dc9897edd6fb1c95c8d27cdaecf85a7ac
inlined_ast: 047a89ee6cdf364b877eca15cdc92954c7ba669fddd3c99fece729abcfd211e3 inlined_ast: da3100e3f67e9ddaf90f4d534ac6ed5dc9897edd6fb1c95c8d27cdaecf85a7ac
dce_ast: 047a89ee6cdf364b877eca15cdc92954c7ba669fddd3c99fece729abcfd211e3 dce_ast: da3100e3f67e9ddaf90f4d534ac6ed5dc9897edd6fb1c95c8d27cdaecf85a7ac
bytecode: 3c391009be59588562aa4a34d1b00508cd253c94d35a66741962352c76a92633 bytecode: 3c391009be59588562aa4a34d1b00508cd253c94d35a66741962352c76a92633
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: d208faafad448ad0877c98ca0e950a6de31dd1ed12332c5475f670fda163280f - - initial_ast: 541f771580c270fa3c366fdea0c4aab112241afbf502c43ec0689762363c827b
unrolled_ast: d208faafad448ad0877c98ca0e950a6de31dd1ed12332c5475f670fda163280f unrolled_ast: 541f771580c270fa3c366fdea0c4aab112241afbf502c43ec0689762363c827b
ssa_ast: a69d601b77e30b0a5564c8c97308b6a4d377a8484dfcfc476f8ceeaa48334d98 ssa_ast: aaf2c7c0e099db4a5342d19b7b6e69ab4866c985b5553c53b08ff7eed8642f64
flattened_ast: dc6accfaa25f07245d9f7c6b281e9924fc02b3c2175eb8930f9a925e0372a694 flattened_ast: 027e8353d91ef1c45a9d3d1db3e0ee1f2224d7be3a41c18c9f86a688e85e5106
inlined_ast: dc6accfaa25f07245d9f7c6b281e9924fc02b3c2175eb8930f9a925e0372a694 inlined_ast: 027e8353d91ef1c45a9d3d1db3e0ee1f2224d7be3a41c18c9f86a688e85e5106
dce_ast: dc6accfaa25f07245d9f7c6b281e9924fc02b3c2175eb8930f9a925e0372a694 dce_ast: 027e8353d91ef1c45a9d3d1db3e0ee1f2224d7be3a41c18c9f86a688e85e5106
bytecode: 3ff716b96c532801f4fa5310f4eedf8f96fe15bd7db3bf087e7b64a161153945 bytecode: 3ff716b96c532801f4fa5310f4eedf8f96fe15bd7db3bf087e7b64a161153945
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 6fd597b235a9ab6fa532413d5656c125639ebe5036284da78f9e5b6c69007b7d - - initial_ast: 3498c564c77031239e93e2a745431ae348e48e542705524de326ac67afaad63f
unrolled_ast: 6fd597b235a9ab6fa532413d5656c125639ebe5036284da78f9e5b6c69007b7d unrolled_ast: 3498c564c77031239e93e2a745431ae348e48e542705524de326ac67afaad63f
ssa_ast: 08bffe308901f0274b378f5b9011df8c245fc51d69856317430b78b5916f3943 ssa_ast: 30266684ef3db98bc60a6f6dde8cb285c9e27fe79f9581aabbd4e732c368997d
flattened_ast: e77fd9b2be65e8a05590387d093a18607cdc7130fcb42c9f48820b28285219c4 flattened_ast: 19277e39b931d9c8c0a49e3e88a64b9f4bfca44b4a72e41bca5debc07a488b14
inlined_ast: e77fd9b2be65e8a05590387d093a18607cdc7130fcb42c9f48820b28285219c4 inlined_ast: 19277e39b931d9c8c0a49e3e88a64b9f4bfca44b4a72e41bca5debc07a488b14
dce_ast: 4cdfeac49296a80c83c11ed59e1eadf21051ef9d851f58a02d42d1b61b319ed1 dce_ast: 4ac699200ffa50c5304aa6f3aa5511b11e99e9fd99aa115772c4d2035cca841d
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: bd3ad043ad61fc8636d1bd58ce0b7a47267a4984546b02a42a0fced89751be66 - - initial_ast: e7a6e1d52af61fe36010137f56a679b20d90c0a0ba7194c343784c97f987d3ca
unrolled_ast: bd3ad043ad61fc8636d1bd58ce0b7a47267a4984546b02a42a0fced89751be66 unrolled_ast: e7a6e1d52af61fe36010137f56a679b20d90c0a0ba7194c343784c97f987d3ca
ssa_ast: b64e7c6c0130cf4855985b81424843521d8694b6756c137d392e0d560045851e ssa_ast: b7a79d5fc1992450ae222f2cb1511ae3845ec80cdb5612680610a33c18088d75
flattened_ast: ab295e2feb5d6e653270f88fe341d8a2aacd26e09a1949ae87c17440a2175b97 flattened_ast: b3b30f99b0f01027ba1b16806068b888cd48b5e2f04b6760c4c2530846122dde
inlined_ast: ab295e2feb5d6e653270f88fe341d8a2aacd26e09a1949ae87c17440a2175b97 inlined_ast: b3b30f99b0f01027ba1b16806068b888cd48b5e2f04b6760c4c2530846122dde
dce_ast: 91da30c194862277ddc99fef9ee7ec374649461eea7f89c29fcb48e7fa583c59 dce_ast: d4db96add4e60f670f573c31468de00be3d5b086830efd8a5a1a5dfdfc7a011e
bytecode: 680bee256d40c3ca4226844e73ae277e6db6af6398cab44674e421359f50cb83 bytecode: 680bee256d40c3ca4226844e73ae277e6db6af6398cab44674e421359f50cb83
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: c9b0ddeb037da9e40d05ede3b7a8fb64087f2ac47fb4c1f0c0523a2e3b50cb85 - - initial_ast: 200d406bb84a2b12a023d9aa6c9fb95035aed4fb171f4ae2bb7c0aa4fcf31bca
unrolled_ast: c9b0ddeb037da9e40d05ede3b7a8fb64087f2ac47fb4c1f0c0523a2e3b50cb85 unrolled_ast: 200d406bb84a2b12a023d9aa6c9fb95035aed4fb171f4ae2bb7c0aa4fcf31bca
ssa_ast: be3af5d7c55442200353dee77047d0a30d8873eb25d0b7da0786fb15b074fd1e ssa_ast: 004d243356aafdf6cad6c8506b4fbac23a46376c1b6867f7be675aaebb3eb208
flattened_ast: 5a90052cf2d88212d54c987ba60339d4b5d9579d2316965a799662ecba6b4b8c flattened_ast: e893304f6a5a44eb53da6d25d023f705bd417429c9ff793d1a5d478284ba8f18
inlined_ast: 5a90052cf2d88212d54c987ba60339d4b5d9579d2316965a799662ecba6b4b8c inlined_ast: e893304f6a5a44eb53da6d25d023f705bd417429c9ff793d1a5d478284ba8f18
dce_ast: d8ed4af576dfa745f37cd9ca9256ab9067bf9f6e56a0dbf76523ba7b859c7ff9 dce_ast: badc11deb2180b86cd9908520df6099fde87669ae29c74afd724063919950622
bytecode: 83cd9a0a063adab9de89253b1a5be0b4bbdc04a2a73a62a03fc1dd1639a4fbbf bytecode: 83cd9a0a063adab9de89253b1a5be0b4bbdc04a2a73a62a03fc1dd1639a4fbbf
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 0abc353cf7d65b1c1b0272dea8760b66a479cd83656397498c6e804fcc57eca9 - - initial_ast: 9ef072ecf82cb5748ef56540885990a387d22ab8a80fc2e2b9a76d6993f6b7b4
unrolled_ast: 0abc353cf7d65b1c1b0272dea8760b66a479cd83656397498c6e804fcc57eca9 unrolled_ast: 9ef072ecf82cb5748ef56540885990a387d22ab8a80fc2e2b9a76d6993f6b7b4
ssa_ast: ce832fb383ceccaaa63b629cea7da2a3bb918e891499dd0027e9eeb86aeb9a8d ssa_ast: ba4c512a80279acd717aa42c2cba0277cf2af2e823eba66dd07f05867cad81ba
flattened_ast: 1522af9dca9861839b442c6e5e8a935d60c4fde932fba9ae125eee7f917405ab flattened_ast: a89f2983a293f8ac22620cad50926738f987cda60e931e11de28268049470d2a
inlined_ast: 1522af9dca9861839b442c6e5e8a935d60c4fde932fba9ae125eee7f917405ab inlined_ast: a89f2983a293f8ac22620cad50926738f987cda60e931e11de28268049470d2a
dce_ast: a221711722c11cb03087868a6670573bf17f47cf1303c75515950c3e28e86626 dce_ast: 2a43b277d040dde328b04f3740ea0866eec08c66db8d28df79648e110b835602
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 8737bb14b9811f8393e7b1214f875f6298a4cced885ff1d0b103b87c4dae42e7 - - initial_ast: 3ba9621aa1e98533320d0ad870f3db063be8c640893d894d04df8951dd2e7a59
unrolled_ast: 8737bb14b9811f8393e7b1214f875f6298a4cced885ff1d0b103b87c4dae42e7 unrolled_ast: 3ba9621aa1e98533320d0ad870f3db063be8c640893d894d04df8951dd2e7a59
ssa_ast: ffdef22bb99c2f24950b74419fe2a51b15dfd3efb7f1faed43f8d452fb21ad33 ssa_ast: d02b80b89778db49120f51e4c4458a316995070f93e4c3ba602ecd376e4fb947
flattened_ast: 207311ab56f2ec438a841db6db558c009b5a74a21a335f83b957f6dd246ca922 flattened_ast: 6d7698f119f99d3e022015f3b9872842dc6575bae0c421c307f3210044df51e2
inlined_ast: 207311ab56f2ec438a841db6db558c009b5a74a21a335f83b957f6dd246ca922 inlined_ast: 6d7698f119f99d3e022015f3b9872842dc6575bae0c421c307f3210044df51e2
dce_ast: a6fde2b969db27f40d74709909bb4eb29e5108074b39429000025549838a5273 dce_ast: 870f8e40d53922c4cebc657fac8bb2b3a86429eef48114c55dbc2b8f77fa6f0e
bytecode: 941f89f9872fc4a4cd8657d4ddc9bfe76d332e25cebfb374d29f8f9359ffb4ce bytecode: 941f89f9872fc4a4cd8657d4ddc9bfe76d332e25cebfb374d29f8f9359ffb4ce
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 6b3fa8d416042367bac792f30d3b9f8b6dc91fc985f208956152b97532e26642 - - initial_ast: 3a414491dcc55c0c7f6bc1cba6293090d19391ba67132b05cc4661fc00dac263
unrolled_ast: 6b3fa8d416042367bac792f30d3b9f8b6dc91fc985f208956152b97532e26642 unrolled_ast: 3a414491dcc55c0c7f6bc1cba6293090d19391ba67132b05cc4661fc00dac263
ssa_ast: 72eebeba1f6a40149ec31a8a52d85ee72afe9997b1c25c3bfb62b1d8e01a1c5a ssa_ast: 76238bbd3667861ac9354f0c5a3cd1848bf871726c40622f067d7d96fea1f46f
flattened_ast: a994eee165bc14fc461972a8b0b45a75a1069498fc8cf5f05c72b30eb70805f3 flattened_ast: dd2041696e3f097fe38d496f74a093f1c98323691d5410c3e083f903b3b3f056
inlined_ast: a994eee165bc14fc461972a8b0b45a75a1069498fc8cf5f05c72b30eb70805f3 inlined_ast: dd2041696e3f097fe38d496f74a093f1c98323691d5410c3e083f903b3b3f056
dce_ast: 9a55f11504482e734847221e0a80a38541c9625932aa093a488d64514b660175 dce_ast: b208128a7b45a47478ab06a2d9cda30520c1477c640df9fe8238e6ecd56d4489
bytecode: b325c77f01ed291126c9b43ecbf54280a09ad0be299ca2aa8698c77af8e4d9bb bytecode: b325c77f01ed291126c9b43ecbf54280a09ad0be299ca2aa8698c77af8e4d9bb
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: c4760546fc56254c08ab900e3e94f670cfd178e1e1b078f6a5ffc83cadbc1c5f - - initial_ast: 43de96dcfc2fcd80e20165a546c8f87129f5591cf1f3efc0fdace9bb5ab0c8fe
unrolled_ast: c4760546fc56254c08ab900e3e94f670cfd178e1e1b078f6a5ffc83cadbc1c5f unrolled_ast: 43de96dcfc2fcd80e20165a546c8f87129f5591cf1f3efc0fdace9bb5ab0c8fe
ssa_ast: 3b7100d9818103d05d90878c57bf1ec2cbeb2b60b760a35f52e0dcf74673d16a ssa_ast: de4d3d7bef838786ae20d83a316bf42af23c565493261c314cc4c79c1f2c2748
flattened_ast: 5b9b91bad19337793ac938989de8eb9dd0fb57d5803bd0489779d890a95546e7 flattened_ast: 02f90df4fa62af993c497699eb0c3a336b01fa21fec3770aeae66f068c2f9172
inlined_ast: 5b9b91bad19337793ac938989de8eb9dd0fb57d5803bd0489779d890a95546e7 inlined_ast: 02f90df4fa62af993c497699eb0c3a336b01fa21fec3770aeae66f068c2f9172
dce_ast: 103fcf3bfad3b6451e678b1cb6ccfe20aee7bda22d590358b07d88a3aba2a985 dce_ast: 2616e762228cec544ac98ce250c62297917d01bce094f8f1fc33d2e1b4518208
bytecode: 1838804cfa5f0c1f7a9bb7ba88dc0207faa0e584b0b35bb34cce7091a9178fe9 bytecode: 1838804cfa5f0c1f7a9bb7ba88dc0207faa0e584b0b35bb34cce7091a9178fe9
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 48d5be1d1b3c4fb8504ce57800d53999f4a92b4899d809e727a0aec33fca028f - - initial_ast: 6256b3aa50ff83f8f05ad31bf0505e1802368bddb66b4eed8c97b3e446d7038d
unrolled_ast: 48d5be1d1b3c4fb8504ce57800d53999f4a92b4899d809e727a0aec33fca028f unrolled_ast: 6256b3aa50ff83f8f05ad31bf0505e1802368bddb66b4eed8c97b3e446d7038d
ssa_ast: 1f4e9c7d3669da233a2b67191c3d9c7fd8d5ba41f65f9256eda21c45623af813 ssa_ast: efa1cfe0ddd338265bfd1dd2167f5c288dc92280eb527b1dc94faf2e163df6ea
flattened_ast: dcef02c444b2a8482e8212aabc7af7184311ab3126ad2ca963c43488545db5d1 flattened_ast: 29d8d32740c0fecfa9a2879eb93b527f8cc9d5841a825b53e91c2401e6bd51c1
inlined_ast: dcef02c444b2a8482e8212aabc7af7184311ab3126ad2ca963c43488545db5d1 inlined_ast: 29d8d32740c0fecfa9a2879eb93b527f8cc9d5841a825b53e91c2401e6bd51c1
dce_ast: 9c7963fba2b84ad1c501e3626370b2e8bdab7b4e977cfecc9fe025c0f7affefc dce_ast: ae22e8b0e32bd60cdfaa5e6246deea26c520a11a0248d516cd47038193a84dcc
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: a5ed14e8476fdff1f5fcb5f92e0b5fb2669a33eefdf537489fb73182ee608af4 - - initial_ast: d123591ffea71b5b2a30c85d4be12428fc927acca9aa52187e858990002c0a7d
unrolled_ast: a5ed14e8476fdff1f5fcb5f92e0b5fb2669a33eefdf537489fb73182ee608af4 unrolled_ast: d123591ffea71b5b2a30c85d4be12428fc927acca9aa52187e858990002c0a7d
ssa_ast: 079195bb127ebf4db1621c06fa8f856a4a751e7a914bddc26961541efaf8ea4c ssa_ast: e79aa027e1c2ada8b44689fa102cf02e8370a6bbf5450b8a4d8a9b21d704d719
flattened_ast: d7a1868221f871563ef4151a5ec947f2bfc2fb9ae74eb60058134a1c3a503e0f flattened_ast: 481fade59dd13622963e93a4afe532c8e3975e9821fab2b1bd5386856acda3d3
inlined_ast: d7a1868221f871563ef4151a5ec947f2bfc2fb9ae74eb60058134a1c3a503e0f inlined_ast: 481fade59dd13622963e93a4afe532c8e3975e9821fab2b1bd5386856acda3d3
dce_ast: 55410ad47534700121ddd46363864fabe433a9442f81115b4670d7ed85ef4c2d dce_ast: 57e14ce61d022acc59902f8aa38347ae969e832fdf82e9eb0dc4f523825a4935
bytecode: ff9bf81abae8332e89f00ebd53dda80528d7a582ade15b2fec53a88a7c5f0532 bytecode: ff9bf81abae8332e89f00ebd53dda80528d7a582ade15b2fec53a88a7c5f0532
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 675fb4ead401c419a7a680811649b363a58356b524f5b08ec7f5569728c99f15 - - initial_ast: 63bcc0bdfa7d14f170b363969c8371129b634ceefce3638c300a5aebdb4e6059
unrolled_ast: 675fb4ead401c419a7a680811649b363a58356b524f5b08ec7f5569728c99f15 unrolled_ast: 63bcc0bdfa7d14f170b363969c8371129b634ceefce3638c300a5aebdb4e6059
ssa_ast: af736487218bf2fe2b1ca02a0b153b942394888de0c7aff41120f73a9153691f ssa_ast: 1d201bd5994f3a34787be84a453f237a04f3d7d6ba63dcaa83fea62774d1195f
flattened_ast: af8bf4d8a2829319891ddef9c9f1f56a3e051c256a7478c6aadb478e7452f85f flattened_ast: 08aabffc8a0888a1a46f6ff4a0959aaa46be5101658ca489d2ee418b0532779c
inlined_ast: af8bf4d8a2829319891ddef9c9f1f56a3e051c256a7478c6aadb478e7452f85f inlined_ast: 08aabffc8a0888a1a46f6ff4a0959aaa46be5101658ca489d2ee418b0532779c
dce_ast: 83119fda7f384e060c443262a323a15c176b5dc27e74b3bcf30a1e48aa547d28 dce_ast: 6d33bb2e76d5f2d2420844fc75556598395b6608335f15599d24f72b0551d039
bytecode: 7cbb302c804e8dcb41c04687fe6f45aa748c5b7c0821f3825d21b424a4f89828 bytecode: 7cbb302c804e8dcb41c04687fe6f45aa748c5b7c0821f3825d21b424a4f89828
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 7dbd33614fc5d7ae3aecb3273e2f9cba1f36b100452b6fbe5e5d46a2e55180f9 - - initial_ast: 1345d2b99e36401addfe556c910e2598fc9725b623eeb3a8976b87d9688cecee
unrolled_ast: 7dbd33614fc5d7ae3aecb3273e2f9cba1f36b100452b6fbe5e5d46a2e55180f9 unrolled_ast: 1345d2b99e36401addfe556c910e2598fc9725b623eeb3a8976b87d9688cecee
ssa_ast: d0aa19d9713d3ca3fdec697f4cba37bc7146815af885aeec02294537ad37f006 ssa_ast: 583bda9b3649325ae7e3e537583690f13f91d528c4b4cb52bfe6fd7f74a7de3f
flattened_ast: c5337f7ef66cab33c31de5a2b79301c919995fcb0849b2e917223e466d7a9eef flattened_ast: 4889a973b75b4f4b584f1f298f7ebb5a34ecf3e7a312d5155db108957128bf11
inlined_ast: c5337f7ef66cab33c31de5a2b79301c919995fcb0849b2e917223e466d7a9eef inlined_ast: 4889a973b75b4f4b584f1f298f7ebb5a34ecf3e7a312d5155db108957128bf11
dce_ast: 54bf7ae36ca87deca1c38d5a40b54fce8e7c1f64f638ee0d33ca74d19cee17fb dce_ast: 674eb9bb060298f3c280e86526cc8c481cf969bc4336a7891d9c6c52f85283e7
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 9e1265b1211819172c08be5779b2b0b7e1839a7aa9a88ab6c77243a9a1711345 - - initial_ast: f99f7e4852b28e80f5f897fe39256e99b0fbfd98e2f3918134dd6a2b7334bf26
unrolled_ast: 9e1265b1211819172c08be5779b2b0b7e1839a7aa9a88ab6c77243a9a1711345 unrolled_ast: f99f7e4852b28e80f5f897fe39256e99b0fbfd98e2f3918134dd6a2b7334bf26
ssa_ast: 8ad36d53ee8e5064346547ccd87488011c18fc6f902ebcb8a13a1b3cba30ba29 ssa_ast: 0b08c41beb2ce37e2b050595a1c8e6b08cb6c96df11d66d0ff914bbf079e6e05
flattened_ast: bdc6854d758b32202f4928c85f3861398fd11d0f6ec2bd0fac0972fd8e2e6648 flattened_ast: 6aced85a3c7b2a9a2af15eb886110f1a06d7645a37ad7335f9c7b9a8e7d5e59c
inlined_ast: bdc6854d758b32202f4928c85f3861398fd11d0f6ec2bd0fac0972fd8e2e6648 inlined_ast: 6aced85a3c7b2a9a2af15eb886110f1a06d7645a37ad7335f9c7b9a8e7d5e59c
dce_ast: 800890b1573816d74bc99385d77f42087f7ab4cc0d3c9ee99f26b0259a23b22c dce_ast: 9b879f75e7b4bdc4f38848eb131e9fa23b2c5d2cb424348f865941fe6f1f8164
bytecode: d5ece61c3e7fb656863858b29941f7947b344a5ff1b4985ae467689f58938553 bytecode: d5ece61c3e7fb656863858b29941f7947b344a5ff1b4985ae467689f58938553
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: c7d38c1c176bd8b4ee26013299187d1008aaa16acfba69945ddcdf17427fc072 - - initial_ast: 02256e685ce23c6aa8b840396c992ae54d9ae9c27367a697aa790f070c39b3c0
unrolled_ast: c7d38c1c176bd8b4ee26013299187d1008aaa16acfba69945ddcdf17427fc072 unrolled_ast: 02256e685ce23c6aa8b840396c992ae54d9ae9c27367a697aa790f070c39b3c0
ssa_ast: aae6639ac1536f7fd3273f6816dde1d280cd72042aa0942d20f3d7a2e2d770ac ssa_ast: d9b7b4ee5fcb97251e7ee9499ba7f2dca5edec7eb4e8ebdf83d4a1ea647eac64
flattened_ast: d3eab777e3125479f833194c950ac92ba07e420d36d664ba3636f977e08e2ef5 flattened_ast: c26d9480e3f93a232c11e55394bd44189c1911b1b3c965a76160b40415849237
inlined_ast: d3eab777e3125479f833194c950ac92ba07e420d36d664ba3636f977e08e2ef5 inlined_ast: c26d9480e3f93a232c11e55394bd44189c1911b1b3c965a76160b40415849237
dce_ast: 0d892639f1f36263305a24bffb22c87bce630bbf0e9bc80b298946e4fa9eb046 dce_ast: 8f4789bf300fb91a27af9ecae91d8e8e08bee6b2dab692e96b2636e006523aab
bytecode: a80b560327138b8bb041f5a6cea148be39bc74dad6a47f45621d207b625a1424 bytecode: a80b560327138b8bb041f5a6cea148be39bc74dad6a47f45621d207b625a1424
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: a9be315a3445f9f02b64382f5506e9d367f3aeb8f4785df88ff8ac0fadedfc1e - - initial_ast: d39d5442a88a4991fe55cf474c159b4b017d0f11daa589649ce6e86523c8b348
unrolled_ast: a9be315a3445f9f02b64382f5506e9d367f3aeb8f4785df88ff8ac0fadedfc1e unrolled_ast: d39d5442a88a4991fe55cf474c159b4b017d0f11daa589649ce6e86523c8b348
ssa_ast: 67e4e9c88fa3c8c72856a9a59bb0e3ef9211981ee9a9eef752b1f832cac121f8 ssa_ast: 223b7cbbf1fc71b67697451c1aef7cd754256d78fc8cd1f79582e83b4a33f0e5
flattened_ast: 73844e9aa33ebc6a1a878f5d83f652eb89b467c82e8f47b2190820e2b5f52ac4 flattened_ast: 9627cd027b2cc268dfe6bb256128812e76a36b30eddd739fce0ad0cd97b99a3b
inlined_ast: 73844e9aa33ebc6a1a878f5d83f652eb89b467c82e8f47b2190820e2b5f52ac4 inlined_ast: 9627cd027b2cc268dfe6bb256128812e76a36b30eddd739fce0ad0cd97b99a3b
dce_ast: 099e7069ae0639e7bafde9cf92773621394f5f1eabf432b12adae16c80e06605 dce_ast: c4423bd97d8106ae47a222f3bfeef898de82602f1d32c71cba269dd1f024c4c8
bytecode: 319405c8fe80b59376c041f234ae2ef213e2d67b50701412411ac97294f91e69 bytecode: 319405c8fe80b59376c041f234ae2ef213e2d67b50701412411ac97294f91e69
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 864840baae360688c5aeb76a2a4af4f8928ded1b8b793a3f1e6bc2d39d3bc4c0 - - initial_ast: 287629280bb3ad4fecbaaa27c933520bc6dda9ffe8dde7bc33c3f18f38710201
unrolled_ast: 864840baae360688c5aeb76a2a4af4f8928ded1b8b793a3f1e6bc2d39d3bc4c0 unrolled_ast: 287629280bb3ad4fecbaaa27c933520bc6dda9ffe8dde7bc33c3f18f38710201
ssa_ast: 7870934dbdcf3c11a8e974011343342bb8671474ef2b48c58ae84836b3c66f79 ssa_ast: 3136ccb3d0d91f0646259b8eeb7745afe69fdda24d3074e7b6a538d7987dc4bc
flattened_ast: 3c37a03f673a024359a7d233df9aa5ee0c16bcf4bf295953981005c51e4f9059 flattened_ast: 5ed98885264a17775d880d90197480ba1643b7717349239008be263602c771f5
inlined_ast: 3c37a03f673a024359a7d233df9aa5ee0c16bcf4bf295953981005c51e4f9059 inlined_ast: 5ed98885264a17775d880d90197480ba1643b7717349239008be263602c771f5
dce_ast: 9c7963fba2b84ad1c501e3626370b2e8bdab7b4e977cfecc9fe025c0f7affefc dce_ast: ae22e8b0e32bd60cdfaa5e6246deea26c520a11a0248d516cd47038193a84dcc
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 04653e3a6b37c90bb7c9dda51beb7cca18d2752671972ed2c22781453eee1576 - - initial_ast: 52e5677596cfeef742a9117e7aa7a64bcde3ae7e41380dd187b2dab1dcc98641
unrolled_ast: 04653e3a6b37c90bb7c9dda51beb7cca18d2752671972ed2c22781453eee1576 unrolled_ast: 52e5677596cfeef742a9117e7aa7a64bcde3ae7e41380dd187b2dab1dcc98641
ssa_ast: 6232d641a2106324612f574da221c5054bdb86f435d3c56d2b765cda6ffda6fd ssa_ast: 8b693f92aab3cfff4a83af4fe5b26fd8be6ed0a0eb47056571e993c06af69d95
flattened_ast: 7e1f1830c9a660702409eee8b509584dc724644d8f11888b5d9767fed3e10fb8 flattened_ast: f5f224c3f859eacc1cab290c76c5a252fcc9471c6519b06ea839df915c372bed
inlined_ast: 7e1f1830c9a660702409eee8b509584dc724644d8f11888b5d9767fed3e10fb8 inlined_ast: f5f224c3f859eacc1cab290c76c5a252fcc9471c6519b06ea839df915c372bed
dce_ast: fe5dc920e6aa68917caf37138b4d00a11a1f9d97ffb4314591855fdf76369950 dce_ast: 9d9f1fd4e6c00f33262e85963f3130276d1d0558c6525232864362ae39c2c710
bytecode: 543bce9b35ef6f58454b6f690b9fae8dcf84f639acc37546ef137d8f8e60605c bytecode: 543bce9b35ef6f58454b6f690b9fae8dcf84f639acc37546ef137d8f8e60605c
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 1ed3c248a1f803e2f43ab6dd1a22847cacee6d2dfa90849281bfde139abb7815 - - initial_ast: 67b57ec0541b7afc4a18246df9a0ca364daf41f99150b4f7f4eafe0fcebb8fb0
unrolled_ast: 1ed3c248a1f803e2f43ab6dd1a22847cacee6d2dfa90849281bfde139abb7815 unrolled_ast: 67b57ec0541b7afc4a18246df9a0ca364daf41f99150b4f7f4eafe0fcebb8fb0
ssa_ast: ef985f04dede16998deb8e67568702ea747c92e5f815d815a87622f7b501d809 ssa_ast: f0aeb009b835cd6aae86321682425cb18acf298cdd8fbf7016dfe153bc2ff793
flattened_ast: 18a771b32fe0ce395b4d0e041d9338bbfb5d822a4df3a80ae17d1ad89c545bb0 flattened_ast: c77ab4600a65575b90bf8678c98df0163d12e71811f2de2ab1d58af744d77080
inlined_ast: 18a771b32fe0ce395b4d0e041d9338bbfb5d822a4df3a80ae17d1ad89c545bb0 inlined_ast: c77ab4600a65575b90bf8678c98df0163d12e71811f2de2ab1d58af744d77080
dce_ast: e928d015f1a718a52c57eb61db26aa288c88fbd3711e7c2a310d6b1520f0d8f0 dce_ast: aae1ec2716070fc44bd4c9fdf8eecec7697dacca733e9d856976591d5b2c7e85
bytecode: 5bf36355b36caa6fcd510f195c79195a7991b45e037c7d6ffe9479f3c2bb89f6 bytecode: 5bf36355b36caa6fcd510f195c79195a7991b45e037c7d6ffe9479f3c2bb89f6
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 985487e286f41d77b95e043abaa99a700294acbdea52b026eabc1b403132d46e - - initial_ast: eee18453add65b46525525d8015118390f91663d8587d29ac84e3fa9363901d5
unrolled_ast: 985487e286f41d77b95e043abaa99a700294acbdea52b026eabc1b403132d46e unrolled_ast: eee18453add65b46525525d8015118390f91663d8587d29ac84e3fa9363901d5
ssa_ast: d5b506bf41288f39643f9c5caee3b2412ea7ea5eeec3521699cd0444c382e3b1 ssa_ast: 7d374cb4d3b4fa72bbbd7e20affecc695135175216616d09342f2ded4f67d509
flattened_ast: cccc6852933e40eaf259a903fdd11c2e74c28f8732be6d97c3e3890445c4b393 flattened_ast: a92fdd0dc104b691342d7e500db97f4fbbdde10bc484f1dacfe89154aaba7532
inlined_ast: cccc6852933e40eaf259a903fdd11c2e74c28f8732be6d97c3e3890445c4b393 inlined_ast: a92fdd0dc104b691342d7e500db97f4fbbdde10bc484f1dacfe89154aaba7532
dce_ast: 54bf7ae36ca87deca1c38d5a40b54fce8e7c1f64f638ee0d33ca74d19cee17fb dce_ast: 674eb9bb060298f3c280e86526cc8c481cf969bc4336a7891d9c6c52f85283e7
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: c184c3b9dea65d1c9972c6359cb266109146d9d5aeabcb5147d6a551d02edb01 - - initial_ast: 1d6929dba9b3e998b112af31bf99aaa8b4b28fcc507837545d61a6dd20f3a699
unrolled_ast: c184c3b9dea65d1c9972c6359cb266109146d9d5aeabcb5147d6a551d02edb01 unrolled_ast: 1d6929dba9b3e998b112af31bf99aaa8b4b28fcc507837545d61a6dd20f3a699
ssa_ast: 43e04c499f6a7be8b2f5cb861a86d610a124c22627b88c7c314cf581ce3b8247 ssa_ast: 2744497abf673f6212c9186b0f12309f628297d7207673db3866c1c343102c13
flattened_ast: bbb986a4b40aa8f7240096e02a5e0402d6c7f5bc1dc0722e85a2e118dbd0106f flattened_ast: bfefceec84c521d3cb070af34af675d029be7924d4634ae27e24819c8cd84d9e
inlined_ast: bbb986a4b40aa8f7240096e02a5e0402d6c7f5bc1dc0722e85a2e118dbd0106f inlined_ast: bfefceec84c521d3cb070af34af675d029be7924d4634ae27e24819c8cd84d9e
dce_ast: ba1f517261bb11624505c6c2fd49e3f04d942ef2b30d86e3c45334dbd1bbb577 dce_ast: 5deb4f73c7178da95cb181694632fcf4e9eaf3d659e121c106812f830839fbf2
bytecode: df6d5bbf5b971b9fbf39786a5bb74b9a26b0ddd9e9bfa501cfc4da9f260de048 bytecode: df6d5bbf5b971b9fbf39786a5bb74b9a26b0ddd9e9bfa501cfc4da9f260de048
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 328daa90b038066e97d5ba5393d4a943414bc500b5237357b9c9e58fc178e51a - - initial_ast: 7109d0444a1664ead2cb0e7f1bfe818ec8aba07e5c6711193026d06ee74d7258
unrolled_ast: 328daa90b038066e97d5ba5393d4a943414bc500b5237357b9c9e58fc178e51a unrolled_ast: 7109d0444a1664ead2cb0e7f1bfe818ec8aba07e5c6711193026d06ee74d7258
ssa_ast: 06dbcc5d9abeab1a4e1b417b3b632e14cdd85af3d6c82aebb16d74b2244780cb ssa_ast: 1e4ccf228090231a7d91df4145171f7a5c30bcd1d586d0837ec85d8e1f48b947
flattened_ast: cd05234ce579ddc5b36834020949acd415ce59f56a035f0109c8dd886938df20 flattened_ast: d6a3d02952c7d7d893242d9a65452ddc476c4b2394128b276107e3f1db3a1401
inlined_ast: cd05234ce579ddc5b36834020949acd415ce59f56a035f0109c8dd886938df20 inlined_ast: d6a3d02952c7d7d893242d9a65452ddc476c4b2394128b276107e3f1db3a1401
dce_ast: 495e6f6dde9ca039e6e55afeb94752bc044b74bf432b9193a7d01926d82e7bbb dce_ast: 097e9ccccb137cc4dabf7663760b6307e77e0f46fa425fc6d5ef0ba401ce2886
bytecode: 8e8ad00d8937c7ea19e29fd6e1162957946d6b2c1e90e0ab9b1a4f49a6685a02 bytecode: 8e8ad00d8937c7ea19e29fd6e1162957946d6b2c1e90e0ab9b1a4f49a6685a02
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 52f0ede29adf2ca4701003a3cd70dc4bbe21848bc68e57ce3ac6d5978731ac96 - - initial_ast: 91dc57e0bc7b29c3ec5eb072a66530fecdbbd065f34a435bf7c21248262c8258
unrolled_ast: 52f0ede29adf2ca4701003a3cd70dc4bbe21848bc68e57ce3ac6d5978731ac96 unrolled_ast: 91dc57e0bc7b29c3ec5eb072a66530fecdbbd065f34a435bf7c21248262c8258
ssa_ast: e9397d32377b970aa46bca1fd809ba0f0845486c39ce945b151932f716b88d9c ssa_ast: af68e87160db0c11482eb4234ec60ebeb1e8cca4750bf0f735a24a4c9e01239a
flattened_ast: 7eb3b7c843218b6b65feac487e6dd1e6319f0076985179c28f871b875b761169 flattened_ast: 1cfc41ec5fd8a4734ec207c947954e42acc8336488514a28f7a21767ae8d9f11
inlined_ast: 7eb3b7c843218b6b65feac487e6dd1e6319f0076985179c28f871b875b761169 inlined_ast: 1cfc41ec5fd8a4734ec207c947954e42acc8336488514a28f7a21767ae8d9f11
dce_ast: 7fbd1ac636ee91825d1346ff6003c33d2f1eb570952cecca69c68fd12540bc4e dce_ast: 19bfe4836913c51d8d4d72b08365f4f380d5509ab0a1335f857d0f879604371c
bytecode: 4dceb1d3b4f77019d81c7e4d97a5866c6a50147cd8cbc417bb4b6629dc2cbf70 bytecode: 4dceb1d3b4f77019d81c7e4d97a5866c6a50147cd8cbc417bb4b6629dc2cbf70
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 2619c8fef0b3503b1ae005f38fed58440f146962b20be560332bf395123eee74 - - initial_ast: 2d03bdd0a7af6b16b102171d026c64b4b79dfad1c918f6372cadfac7a0efdf48
unrolled_ast: 2619c8fef0b3503b1ae005f38fed58440f146962b20be560332bf395123eee74 unrolled_ast: 2d03bdd0a7af6b16b102171d026c64b4b79dfad1c918f6372cadfac7a0efdf48
ssa_ast: 6f7d5a0482b834872e14fb2a3ae867a6f377cfa21f3e71a17ff99ac698ad107d ssa_ast: cdbf3f51343cafafa3f5016071f94613a97ad3994b4c8dc425d11385fc61e0c9
flattened_ast: 13919263c46a63382f0fb34d8c1dbbf67d1a8485b80d2ace5bd8ae50f7a85252 flattened_ast: f9a75ef76e52b50165df620dd76ab1b575737aaa9de3ec55900855f0b88d35c8
inlined_ast: 13919263c46a63382f0fb34d8c1dbbf67d1a8485b80d2ace5bd8ae50f7a85252 inlined_ast: f9a75ef76e52b50165df620dd76ab1b575737aaa9de3ec55900855f0b88d35c8
dce_ast: 9c7963fba2b84ad1c501e3626370b2e8bdab7b4e977cfecc9fe025c0f7affefc dce_ast: ae22e8b0e32bd60cdfaa5e6246deea26c520a11a0248d516cd47038193a84dcc
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: fc696ada4c5b732d15b8f9b0ad5e7549f00cfc1da5ba57b885b66e0e6818a22a - - initial_ast: 2616d69193cd18db8e0af91be4314f4f4a4ac411ad6c0bb861881e8f56c5b1b1
unrolled_ast: fc696ada4c5b732d15b8f9b0ad5e7549f00cfc1da5ba57b885b66e0e6818a22a unrolled_ast: 2616d69193cd18db8e0af91be4314f4f4a4ac411ad6c0bb861881e8f56c5b1b1
ssa_ast: 18af862c907ef728a5d39f8965676dd43211350fe3a771a5f0faad51df67c3d3 ssa_ast: 496dd06de809c3626d968ea3fdd7c3aa83369d7a9258c565b5582f1ac90aef56
flattened_ast: fe08b7afbe25f75b31aae4a27ede152f12a7e50a6c327bdf362b13a1870984dc flattened_ast: 388802f2d2c5cd0d3debfe5e17f697e2b3b5bedcea14f2d6430fd2e8b7b380ed
inlined_ast: fe08b7afbe25f75b31aae4a27ede152f12a7e50a6c327bdf362b13a1870984dc inlined_ast: 388802f2d2c5cd0d3debfe5e17f697e2b3b5bedcea14f2d6430fd2e8b7b380ed
dce_ast: 1d3b448b8e1259dbeaae915175bc810a165219797bc67c7a12765996a523430a dce_ast: bb2b46bd36a6e76d34c3b00b4311c9e4afd2443a00c4140ad27554e9819cb16d
bytecode: e1317e9396275ce8f73b494a3595e27bdbc563874acea6fed57c0b52da1354b3 bytecode: e1317e9396275ce8f73b494a3595e27bdbc563874acea6fed57c0b52da1354b3
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 35fcb3d27fefc2e41379cef05ef329b81eac0166ddd11d78f527bc4109af41e1 - - initial_ast: ea07694a29ef275c288260ee45faf738963fbf22dbaf2afea90ac3112c25e816
unrolled_ast: 35fcb3d27fefc2e41379cef05ef329b81eac0166ddd11d78f527bc4109af41e1 unrolled_ast: ea07694a29ef275c288260ee45faf738963fbf22dbaf2afea90ac3112c25e816
ssa_ast: e86fd5bca66aa0f8199faee9ac4dd1fbaf127b900c76aedc258a79af47415bad ssa_ast: ae34127a7baf411ff8717275384763a3b3d70e29cede5c4e60a37d29ee4c0cf4
flattened_ast: 9f6a9ead21fe574985f41178303b2e49bf1697826134881eb37614e5eca94320 flattened_ast: 021b8e9d37ad1d3e2d60a5a8cc8acb88b3ad6fa9a32c30883ac5b8d4bd6e2f51
inlined_ast: 9f6a9ead21fe574985f41178303b2e49bf1697826134881eb37614e5eca94320 inlined_ast: 021b8e9d37ad1d3e2d60a5a8cc8acb88b3ad6fa9a32c30883ac5b8d4bd6e2f51
dce_ast: 9aa80eb712cd45a13d144358cfac8f5e8fb6f641732436b58b4c348d77ca25d5 dce_ast: 621c04e49940033e81bd595d8f92d1009b797ac68c9f425a3c78f835c19af863
bytecode: aee0a49b3add5225dd3e0e2343805040b94c16916e51b3405924378f62eb9f36 bytecode: aee0a49b3add5225dd3e0e2343805040b94c16916e51b3405924378f62eb9f36
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: c7b13b58b7ba847bc7592e6afa8f7b3a140c32cf3ec1f651165eaf1b99ec95a3 - - initial_ast: 765ba1aea9966566c3a979614731b96000194f38bfb4f65ab64bff44645b1ed7
unrolled_ast: c7b13b58b7ba847bc7592e6afa8f7b3a140c32cf3ec1f651165eaf1b99ec95a3 unrolled_ast: 765ba1aea9966566c3a979614731b96000194f38bfb4f65ab64bff44645b1ed7
ssa_ast: 3b4bcb28b9eac4e0e3e200013c61ce5fb7b5a8baca18d6c5c53535b6c586f81b ssa_ast: 6ee96a9485b5116b6866b9ba1355b68e8ba557beba3404ac41d2f058cc1d2692
flattened_ast: c239452165d456f374a3dc2789b07413191b90cd6b3c1f6d0a6f370440a2cdc9 flattened_ast: 7b174ac8f24146ae7516e443447988a62ad034ed29d3baa2dc0122d237f3ae75
inlined_ast: c239452165d456f374a3dc2789b07413191b90cd6b3c1f6d0a6f370440a2cdc9 inlined_ast: 7b174ac8f24146ae7516e443447988a62ad034ed29d3baa2dc0122d237f3ae75
dce_ast: 54bf7ae36ca87deca1c38d5a40b54fce8e7c1f64f638ee0d33ca74d19cee17fb dce_ast: 674eb9bb060298f3c280e86526cc8c481cf969bc4336a7891d9c6c52f85283e7
bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b bytecode: 03845ec2f54d49f71640659603ead8f68ad067a15fda438e5e13524777d1559b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: ede8e82829d45a29612d4478e4b573000d051b7c9a570a84088d83634b95e09b - - initial_ast: 34321cdfdf6022714f37f053521ec53f6fcb6ebb60b137dceb4987454ed10cce
unrolled_ast: ede8e82829d45a29612d4478e4b573000d051b7c9a570a84088d83634b95e09b unrolled_ast: 34321cdfdf6022714f37f053521ec53f6fcb6ebb60b137dceb4987454ed10cce
ssa_ast: 591cfefc44642c6b7d90cb032e8c50f106032d114d33c938de045389d81bca7e ssa_ast: 13417366f95a28a70d03f4c29e1fbabfbf4d76f78774f9208082d5787b0b144e
flattened_ast: a2192bfaf96f1e137c135cc0cfa6ffdf05d61869e9932aa8704804479d091b4c flattened_ast: 256c210818a74af6b696120cd16cb82aa29cec01f200006d88924825c194710b
inlined_ast: a2192bfaf96f1e137c135cc0cfa6ffdf05d61869e9932aa8704804479d091b4c inlined_ast: 256c210818a74af6b696120cd16cb82aa29cec01f200006d88924825c194710b
dce_ast: e1947d20d04cf487a713d633edd1cdf7ce783b15d09a3f8127f77592c300d61c dce_ast: 4cf3fc9aee1f9777f05c580011cd0990c1b1280c014f0c8721e92d336db2f0d7
bytecode: 38325ddbe5ab9363326dda92ef395e1c99e78e243d95ea4364499ccabadfd299 bytecode: 38325ddbe5ab9363326dda92ef395e1c99e78e243d95ea4364499ccabadfd299
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: d05138b425c3a1200484d4491ef3bf4d9b62e32f9c318ad0d2f55b331b955d67 - - initial_ast: b9b0e4422dd9613f2a2c75b7ed45f3f06d33129293cc888d9498f78d3926fb7c
unrolled_ast: d05138b425c3a1200484d4491ef3bf4d9b62e32f9c318ad0d2f55b331b955d67 unrolled_ast: b9b0e4422dd9613f2a2c75b7ed45f3f06d33129293cc888d9498f78d3926fb7c
ssa_ast: 0b0839366e8e3bce98d91cd768911a1c9198fe8c762b9e218e4efd3abe21afa0 ssa_ast: df5b237191728107e4ea6ef81307887a69827f268433edb6b850501528cf1279
flattened_ast: 02e32355b211e0c39bf8e9e1578de3ad37a48422518d7e20f70ecd67921df9be flattened_ast: 8ee14095f85ece807e1611d837b7beac682621eeafe72a961048ec23659ff709
inlined_ast: 02e32355b211e0c39bf8e9e1578de3ad37a48422518d7e20f70ecd67921df9be inlined_ast: 8ee14095f85ece807e1611d837b7beac682621eeafe72a961048ec23659ff709
dce_ast: d45be3fc835dad37fa8ec0b63d1931048d22f4587bcc0e6e6a18b0154cd93270 dce_ast: 872f2d0e342a1017ad2656eeb637661c880b17cad5013b4f21f08790f14a7f16
bytecode: 95e421126839d599569f1a130c5852f7da8d6e40de90885f401530d8bcc18c14 bytecode: 95e421126839d599569f1a130c5852f7da8d6e40de90885f401530d8bcc18c14
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: a9be315a3445f9f02b64382f5506e9d367f3aeb8f4785df88ff8ac0fadedfc1e - - initial_ast: d39d5442a88a4991fe55cf474c159b4b017d0f11daa589649ce6e86523c8b348
unrolled_ast: a9be315a3445f9f02b64382f5506e9d367f3aeb8f4785df88ff8ac0fadedfc1e unrolled_ast: d39d5442a88a4991fe55cf474c159b4b017d0f11daa589649ce6e86523c8b348
ssa_ast: 67e4e9c88fa3c8c72856a9a59bb0e3ef9211981ee9a9eef752b1f832cac121f8 ssa_ast: 223b7cbbf1fc71b67697451c1aef7cd754256d78fc8cd1f79582e83b4a33f0e5
flattened_ast: 73844e9aa33ebc6a1a878f5d83f652eb89b467c82e8f47b2190820e2b5f52ac4 flattened_ast: 9627cd027b2cc268dfe6bb256128812e76a36b30eddd739fce0ad0cd97b99a3b
inlined_ast: 73844e9aa33ebc6a1a878f5d83f652eb89b467c82e8f47b2190820e2b5f52ac4 inlined_ast: 9627cd027b2cc268dfe6bb256128812e76a36b30eddd739fce0ad0cd97b99a3b
dce_ast: 099e7069ae0639e7bafde9cf92773621394f5f1eabf432b12adae16c80e06605 dce_ast: c4423bd97d8106ae47a222f3bfeef898de82602f1d32c71cba269dd1f024c4c8
bytecode: 319405c8fe80b59376c041f234ae2ef213e2d67b50701412411ac97294f91e69 bytecode: 319405c8fe80b59376c041f234ae2ef213e2d67b50701412411ac97294f91e69
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: c91bd148e83d97ea9c5cad3a5663fdd82a83c3381151475090802525a7080746 - - initial_ast: 5efcfb40cfb5a64bad1c44a310bb3f51ab61b709e38ac91606d17d883e72b4b6
unrolled_ast: c91bd148e83d97ea9c5cad3a5663fdd82a83c3381151475090802525a7080746 unrolled_ast: 5efcfb40cfb5a64bad1c44a310bb3f51ab61b709e38ac91606d17d883e72b4b6
ssa_ast: 0a38c051202114aca4e5ae9a517beee7ac736361fa5b537eeb477d085b833964 ssa_ast: 9c26e8a37c872a03ba1cba5b9731bb41a336f478db8bc034b0f5a43e6a95ba63
flattened_ast: 7b95230042361cc751275babf46870a3e929f88bc327a9df3a2bf46f25522b4c flattened_ast: 49a348be0ec3ca2fd146a38dd1230ea1d7df75326192135b591aaf5cada8b93d
inlined_ast: 7b95230042361cc751275babf46870a3e929f88bc327a9df3a2bf46f25522b4c inlined_ast: 49a348be0ec3ca2fd146a38dd1230ea1d7df75326192135b591aaf5cada8b93d
dce_ast: 25a44252c57774a9a8bac44f672307eab4918c371a39566813dce234e38ccb8c dce_ast: 420f9dcd4362e135f7b86bc51faa0a13c9ac2d3bf02804c1c42df7fcca84d1ec
bytecode: bd218715549602fce75a8d64df3317bee7386870f24b3d844b01c02d1960240b bytecode: bd218715549602fce75a8d64df3317bee7386870f24b3d844b01c02d1960240b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: cd8360af7bce053a74c7add09ade31db66ed8b5900fcc33e4e0d4591c470e989 - - initial_ast: ae83c4c1c05e2741d112d9b37e3336450fcb65f65f550a561b96fcdb09d98a20
unrolled_ast: cd8360af7bce053a74c7add09ade31db66ed8b5900fcc33e4e0d4591c470e989 unrolled_ast: ae83c4c1c05e2741d112d9b37e3336450fcb65f65f550a561b96fcdb09d98a20
ssa_ast: d5b17cc240ab6f888faa6d6706de4c7d2c4402a7b6a5115b707258527205e3a6 ssa_ast: 80097e52476437805c6ce471a481f15cc829a569cf52859e25abd2f2e5b6f78d
flattened_ast: 875b99ba07c5662ee3a25d0bb18507ca8c7d5211ee40dad9368098eba5178ebf flattened_ast: e0e5fef742a4c0df6a24323863bb46ad8f4d513da37bea680253713ac87f059b
inlined_ast: 875b99ba07c5662ee3a25d0bb18507ca8c7d5211ee40dad9368098eba5178ebf inlined_ast: e0e5fef742a4c0df6a24323863bb46ad8f4d513da37bea680253713ac87f059b
dce_ast: 8895f89492c0ca019e4372fb4f7cab7a0dc254c058dcb7b527483b597687fab7 dce_ast: 169c97e859427f154a255263c8f36c0d48b381be2b4c4017a7e82f0019f43ce1
bytecode: 4b3d6980860116dfb43804924f4d2cedfb7db2d9fb783fd06b3127327e31a298 bytecode: 4b3d6980860116dfb43804924f4d2cedfb7db2d9fb783fd06b3127327e31a298
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 0a2966eef4db383661c3b4c70257eaae893bb046930cccd59f2c771d8501cb5c - - initial_ast: 54ac2e3f840659fd7b5eeb98ec7827dcfb0ee4203e8658e38664f3b659962d28
unrolled_ast: 0a2966eef4db383661c3b4c70257eaae893bb046930cccd59f2c771d8501cb5c unrolled_ast: 54ac2e3f840659fd7b5eeb98ec7827dcfb0ee4203e8658e38664f3b659962d28
ssa_ast: 3a514a3264fbd19707996f304bc43aee4d7ad24ca260c91d9751d2f14508f3c8 ssa_ast: be36a341befadaa69f857dab65976c6593638bc1f724785d6947adbd5c22ab35
flattened_ast: 66970fd4850f730a952e41ac8849536ccfc3dde5e2b3fcb571f074adb5fcf04b flattened_ast: 803a4d476a2312c115b4700073f78da88986fccfcdb4f15e5bfc9ff75e8d50b7
inlined_ast: 66970fd4850f730a952e41ac8849536ccfc3dde5e2b3fcb571f074adb5fcf04b inlined_ast: 803a4d476a2312c115b4700073f78da88986fccfcdb4f15e5bfc9ff75e8d50b7
dce_ast: 2f6696c21e443368f325ba36838dc7c03ab021e0da05abbe20d4cf639d93b126 dce_ast: b9df995586996ad6e156600744e95e2e6c2fe138d14e4e6d6fdf9454083e8815
bytecode: cf7a9eea97a35c026eeac1f4659903bec549092b56e6194f666fed520fc02b7a bytecode: cf7a9eea97a35c026eeac1f4659903bec549092b56e6194f666fed520fc02b7a
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 7ed91381838f579d46d070d84489f6c909c8ffdd2b184dab9e78f78795bd97b3 - - initial_ast: c3cde43bd5ce6bd109a485a1bf172d483f9dcac4595057fa360e07543ee690b6
unrolled_ast: 7ed91381838f579d46d070d84489f6c909c8ffdd2b184dab9e78f78795bd97b3 unrolled_ast: c3cde43bd5ce6bd109a485a1bf172d483f9dcac4595057fa360e07543ee690b6
ssa_ast: 29ddcef122568413c740e761dcbdfa184feb521eb7fd7ee44c166fd55309d562 ssa_ast: 7f864ba4330a2545c21bbdbe0268fbb73371e47d1fbdaf7fff1d05e87a8236cc
flattened_ast: b6cfdf163495696b9579f35fe07925b4d3330c311aef4cb857618bbe8dce9791 flattened_ast: d9914036faa2860c628ed5f50494f06b06d7a80f283f11a1e7c1545969c24741
inlined_ast: b6cfdf163495696b9579f35fe07925b4d3330c311aef4cb857618bbe8dce9791 inlined_ast: d9914036faa2860c628ed5f50494f06b06d7a80f283f11a1e7c1545969c24741
dce_ast: 510d6f51ce40b821e99729f0def26529a4c6f16f01e929ca747f23d48fd6e254 dce_ast: 2a9f1176a540d39660da33d14faa266e3795274285ccb68540b59ebfcf448320
bytecode: d3d4c9152f574443e543ea5f0f1f0148116006c76aaaa2e014f268d7ab9d05df bytecode: d3d4c9152f574443e543ea5f0f1f0148116006c76aaaa2e014f268d7ab9d05df
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: e4528d944261a3586e66e83a22a5e4372c7a45c0a3ea689927007aa37681d6d9 - - initial_ast: 5dd5cefd1086637c19b2aabcd0dbb3bb45b6c15e8ab8f81d462145f39228b3de
unrolled_ast: e4528d944261a3586e66e83a22a5e4372c7a45c0a3ea689927007aa37681d6d9 unrolled_ast: 5dd5cefd1086637c19b2aabcd0dbb3bb45b6c15e8ab8f81d462145f39228b3de
ssa_ast: 8a901b31ecf54ceef87eda818276ca5fc2de348c1e84e4cf386c4e3f7b989059 ssa_ast: 3e104420807e18487278b84b750ca52a086cb2f74a54df1c74d7302b76a57549
flattened_ast: d11751292a1314a84cf32c7333bc8bc412c5cc35e480d68a4a1a421110afdc0b flattened_ast: a4b78b37258e0ead4c42527345c5854b39491406a6e33eddf76c789993272f6d
inlined_ast: d11751292a1314a84cf32c7333bc8bc412c5cc35e480d68a4a1a421110afdc0b inlined_ast: a4b78b37258e0ead4c42527345c5854b39491406a6e33eddf76c789993272f6d
dce_ast: 592fabdaf4bc757afe4855bc4156f5191e76bdaa156057990234564304cbad70 dce_ast: f1e385ab26cde7676981f5b8b9996e5cd6264dbed5053d4d79dd6930febae2fa
bytecode: 23b5c88c1d028f0b038f1005427c79779230306d235088802d5668e93117c120 bytecode: 23b5c88c1d028f0b038f1005427c79779230306d235088802d5668e93117c120
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 3c01ed969e2830bbef88c1f734850dfaf83bb7429d807b446eb9b2b9c6857e64 - - initial_ast: 7b625bf89cb9265228bc7b13ed0f3b732e246d4f054461eda8fae457a272a5b8
unrolled_ast: 3c01ed969e2830bbef88c1f734850dfaf83bb7429d807b446eb9b2b9c6857e64 unrolled_ast: 7b625bf89cb9265228bc7b13ed0f3b732e246d4f054461eda8fae457a272a5b8
ssa_ast: 90a0ab34741185c64f0b2f051649100c1170b1f44728dc1ba27050ebf9efdd9c ssa_ast: 553e9d2bb4a265c89d6fc102270d7db5b128ce9e000f50dc5f77f165cb7e5743
flattened_ast: 02b4f16917bd5e473d38677f9d0bc9e2c280b5951c362bc32213088d26f248d2 flattened_ast: ad88dd2788bf38f99242519aad875ca84cdecafff7f4e6847cb8523ee7dd2e41
inlined_ast: 02b4f16917bd5e473d38677f9d0bc9e2c280b5951c362bc32213088d26f248d2 inlined_ast: ad88dd2788bf38f99242519aad875ca84cdecafff7f4e6847cb8523ee7dd2e41
dce_ast: eb0931dbc9d952b1d43e219c3e912e2ebcce4248ee2278d4ef06b1583058cf3d dce_ast: 22badc4cb8f786aedb95733789faa02b6062a61d96db4fc206e32c6e07f182a1
bytecode: b195e16806d0a26e2088f84136f95ca7e9401dd6846a61cda34d39445ef87684 bytecode: b195e16806d0a26e2088f84136f95ca7e9401dd6846a61cda34d39445ef87684
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: cd05dd82f3b6b66b0ca9be70aee91fcfd1539a3894c99c60e983880a6a3c5176 - - initial_ast: fe4013daac58433b0e7ee77729e6dfd254b0cc25cf645e8bda38df6bff2ea6f5
unrolled_ast: cd05dd82f3b6b66b0ca9be70aee91fcfd1539a3894c99c60e983880a6a3c5176 unrolled_ast: fe4013daac58433b0e7ee77729e6dfd254b0cc25cf645e8bda38df6bff2ea6f5
ssa_ast: 707c7c8cf25cb1783c8042d08ba53c35f3c5e25b80c17f973fc3b748b91ee439 ssa_ast: bdcfed2adad22237f441e2953520f53708ad3bc79c06f90f7320656b60fa50d0
flattened_ast: 2e4d9fe6330c108c69ae7ae2b426e6d76d036f754ce5c04033454bce78cbd2d1 flattened_ast: 051b5cc446838992509fe969562d26e8a2e40f8d3c65e70c19221216192421e1
inlined_ast: 2e4d9fe6330c108c69ae7ae2b426e6d76d036f754ce5c04033454bce78cbd2d1 inlined_ast: 051b5cc446838992509fe969562d26e8a2e40f8d3c65e70c19221216192421e1
dce_ast: 5694b6e0912a2d230769d8c3ea982b0744ad18d538e18e548c415fb0da9b431a dce_ast: b0fe7a0eca195cf829402febb958d7c5d2e3813bdf9a8e2f9a9deb677143a6ad
bytecode: 3bd31100c828423ff38d092cfbe9c0df772aba3b6fc24931ae33b1f50efcecb0 bytecode: 3bd31100c828423ff38d092cfbe9c0df772aba3b6fc24931ae33b1f50efcecb0
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 78a2df5f4cb551a93fb04cbe84fae22f1a404b38f4fa606639904f1ba45446ef - - initial_ast: a802229d4b6de00a7204febafff07ba1a48deacb1b247696049ea13c6b5dae46
unrolled_ast: 78a2df5f4cb551a93fb04cbe84fae22f1a404b38f4fa606639904f1ba45446ef unrolled_ast: a802229d4b6de00a7204febafff07ba1a48deacb1b247696049ea13c6b5dae46
ssa_ast: a9d66d2d618c2f102a0b50a736503498418c0b88afcf7c7b05936ddfacdf8872 ssa_ast: c84708fc6fdd2f2ac7d3d89e049b21f8798182ba7efeee69359b96c8a5715c5b
flattened_ast: 3d1bc760b33cf23fb977288c77ca6b06409eeabfb1ad09578d78df3969bd15a3 flattened_ast: f1ac12568348ec1ae78bd965301eeacff1dbdee97b371129cebd681376d29e10
inlined_ast: 3d1bc760b33cf23fb977288c77ca6b06409eeabfb1ad09578d78df3969bd15a3 inlined_ast: f1ac12568348ec1ae78bd965301eeacff1dbdee97b371129cebd681376d29e10
dce_ast: 4addccb9802526a9fa5948b5d6dc7801ffd52b5d34f3657d5497f2a1d8d65924 dce_ast: feaa1c6e309a6639bebc60824b78a212d4d9f260414655260a0e7b01671236ec
bytecode: 6a94d8f23c147c3cddc2c5a44a6f07734cbe79bc899b2b830aac61b6e6975057 bytecode: 6a94d8f23c147c3cddc2c5a44a6f07734cbe79bc899b2b830aac61b6e6975057
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: db23254b38f2edafa88e8444beedf9c0e6d5b58e200b0c49e783b0c2e80895b8 - - initial_ast: 9be98b23ebf981caddf95cfbef47cd250afd873c1cd1bc72e1b18fbdf42fa174
unrolled_ast: db23254b38f2edafa88e8444beedf9c0e6d5b58e200b0c49e783b0c2e80895b8 unrolled_ast: 9be98b23ebf981caddf95cfbef47cd250afd873c1cd1bc72e1b18fbdf42fa174
ssa_ast: bd7a7134d27cae528ab6e66f0a33a746a0b52942ee9a24087f7cbf4713de63f9 ssa_ast: 2d8c9387be8a685dca90ea4f161866c6298683bba5ef667e195bb51c69b07271
flattened_ast: 91b3cbbf48c15063c87758308f018144309bead61edc18cfb3846642fb40d4c6 flattened_ast: 5bc73f0e0d07e95442ff9de4c1b6324d3c0febd12e5803d7d48e3f56105f39b2
inlined_ast: 91b3cbbf48c15063c87758308f018144309bead61edc18cfb3846642fb40d4c6 inlined_ast: 5bc73f0e0d07e95442ff9de4c1b6324d3c0febd12e5803d7d48e3f56105f39b2
dce_ast: 8e4787b63356db1b948a37757c456d7f0008dfdb0299c1561f678a9fb833ff0b dce_ast: c14a09c6258133c39cc0fd21c13bb64d18df171c562e2d447f5e28db349d333d
bytecode: 5ff56b03daf136dc97334d9f0c73f26eb6e342e30b116000e7eb7cac8e2ebff5 bytecode: 5ff56b03daf136dc97334d9f0c73f26eb6e342e30b116000e7eb7cac8e2ebff5
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 4909c65c7d9ba9483ae5a54d47cb5b45c1bffb0624ef5cb87c4520d4afa2ca52 - - initial_ast: 58b7e3117c943bd4fa0d78359d1319e5f089b525eac3749dc958515ffb368dfd
unrolled_ast: 4909c65c7d9ba9483ae5a54d47cb5b45c1bffb0624ef5cb87c4520d4afa2ca52 unrolled_ast: 58b7e3117c943bd4fa0d78359d1319e5f089b525eac3749dc958515ffb368dfd
ssa_ast: 2c123587922e8a5b37abc83c6c795ab6de46b25467810f89cad4db702602e093 ssa_ast: 5af8b7ed094924143b1ba05f246a417177c6bb9c61d34bc8feda5c418d365fe1
flattened_ast: c01013df58690fd45025a38f2002b519cc06e4dafd15f6b960077acc67d38e82 flattened_ast: c3d87c76cc3699f14e0c1bc165367eaed92f5044ea942be4193dfbce12b0f0c5
inlined_ast: c01013df58690fd45025a38f2002b519cc06e4dafd15f6b960077acc67d38e82 inlined_ast: c3d87c76cc3699f14e0c1bc165367eaed92f5044ea942be4193dfbce12b0f0c5
dce_ast: 9fa94fa1597f0efd27d1fcac96efff1a8da824b937166bbc41c5536d8d7807dc dce_ast: 404e6ae5f1a61cb001a11aea3ead5082d5acd582139f56e41424a4457b14a759
bytecode: 5552b43274ec113ad0520de7a6a457cd4ac6db08d490446eca21f148a5bbca16 bytecode: 5552b43274ec113ad0520de7a6a457cd4ac6db08d490446eca21f148a5bbca16
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 8cc08a55a4766806701ada82b6e6fe267fcc55dd7ffa7bdcd0df847f45a55a88 - - initial_ast: 6bc571e09c54ab29d06a5e96ba368d7c82db558e523108a87536e672b9c184ce
unrolled_ast: 8cc08a55a4766806701ada82b6e6fe267fcc55dd7ffa7bdcd0df847f45a55a88 unrolled_ast: 6bc571e09c54ab29d06a5e96ba368d7c82db558e523108a87536e672b9c184ce
ssa_ast: a6430134eda01acb48063ce754e8f1f8eceb0831ccfc7be9c2cb57a3a6b590d1 ssa_ast: 7f13a8ac4e9279024b1e3da939017bef71d196ca6243b8184e4e0ff5b6ccbb00
flattened_ast: 5007eb8364cf861e5ef11d3a782f1b97c46a35b0fe00145aac2f25de9e68505a flattened_ast: 98b8cf065b004843080e319557ed2ff594e0783624fd5373a1c3046cb25f95da
inlined_ast: 5007eb8364cf861e5ef11d3a782f1b97c46a35b0fe00145aac2f25de9e68505a inlined_ast: 98b8cf065b004843080e319557ed2ff594e0783624fd5373a1c3046cb25f95da
dce_ast: fbf9b644d9db05227b49190948363354a346d96c20ab9e1d5596a6490659368e dce_ast: df16f37c011385cde2aeddc10ed74b041936d28475f0cb5d696550a3a970aa54
bytecode: 325b391ad96a02efc136a7653c4a5229454ecfc76c857c6fe7d0606fd78b5336 bytecode: 325b391ad96a02efc136a7653c4a5229454ecfc76c857c6fe7d0606fd78b5336
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 7a36e76f0e626ba363421a3b51b23292bfc37b0a4419289b97f845442b6f5b0c - - initial_ast: a705aac527cf63578b2f69a56779492e8a3d998dd40667e600f773a045760653
unrolled_ast: 7a36e76f0e626ba363421a3b51b23292bfc37b0a4419289b97f845442b6f5b0c unrolled_ast: a705aac527cf63578b2f69a56779492e8a3d998dd40667e600f773a045760653
ssa_ast: c4d434b533862126fcd137af19f5ab1380b1237f2469ef812883007e66206106 ssa_ast: 83d5a116b9d11cebe4417cc9c31a2a91243a3f6456675b605222613f66f80440
flattened_ast: 97de4b492d6b4d06f0866eb46d8f011f45a4b1caf9d606f41540dcea1ed30309 flattened_ast: d4d7dd5d0adfa216b3d9e62b94737be5373dbbb4dc21f2bfe50eee8b5b861da0
inlined_ast: 97de4b492d6b4d06f0866eb46d8f011f45a4b1caf9d606f41540dcea1ed30309 inlined_ast: d4d7dd5d0adfa216b3d9e62b94737be5373dbbb4dc21f2bfe50eee8b5b861da0
dce_ast: 7385743f2ca202d19e724a448188a04e8e1e4713ef5825fd6210f6a61c00df8b dce_ast: 8e1e99ae2c5eabb1105ef04e5659e92d5d6516f47bf7330118a5580387cbf845
bytecode: db7cf565e83b99b3a24b93bfbb5bdcda4f947f4eb64f454046ea83edca3ccbf3 bytecode: db7cf565e83b99b3a24b93bfbb5bdcda4f947f4eb64f454046ea83edca3ccbf3
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 92ee68761f294ea4a49a025e9132c083f57fc01587e4c52db3bafc62f35b66c7 - - initial_ast: 9b04c1a3199640b1bb75bf1796c51f8247101ac841efa4e78837737f1840e941
unrolled_ast: 92ee68761f294ea4a49a025e9132c083f57fc01587e4c52db3bafc62f35b66c7 unrolled_ast: 9b04c1a3199640b1bb75bf1796c51f8247101ac841efa4e78837737f1840e941
ssa_ast: da7d82578cb1ac8f9314811d61a9bdeeabca02f301022c9753744c04626fdc18 ssa_ast: e087d9dbc1082aef11c7cdc29acbd8e40140c3f19ceb2188b936e820d58a5bc6
flattened_ast: 3b1e9009d7f3769c4badff49c74f7af158a0ea49820d215fdebd32b2b0e062b9 flattened_ast: 883e141c98634bcd7056dca257c5d3fe9606ca101e95c626f17b789874f8ed1c
inlined_ast: 3b1e9009d7f3769c4badff49c74f7af158a0ea49820d215fdebd32b2b0e062b9 inlined_ast: 883e141c98634bcd7056dca257c5d3fe9606ca101e95c626f17b789874f8ed1c
dce_ast: d224b6ef7df21ccfefe7a0b949543696745820385a4fc547b5ed5b5e74ed13c7 dce_ast: 4dd926d952ebce2dd59c1f8a967afdadc0e948af85e3f31deab550d8e4ea0107
bytecode: d594e784e95e52089afcadbc703f266ea2fd2b211728fdbea8eea5abc5e1942b bytecode: d594e784e95e52089afcadbc703f266ea2fd2b211728fdbea8eea5abc5e1942b
warnings: "" warnings: ""

View File

@ -2,11 +2,11 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- - initial_ast: 44afe466172f202382b83ea6416ccc3447ff684aaa9ee18c38dd665a639e8760 - - initial_ast: 7d5ed9c373b2460d26ae2e9e92c2e1e63e59af4f9daf813971486d764b7df3fa
unrolled_ast: 44afe466172f202382b83ea6416ccc3447ff684aaa9ee18c38dd665a639e8760 unrolled_ast: 7d5ed9c373b2460d26ae2e9e92c2e1e63e59af4f9daf813971486d764b7df3fa
ssa_ast: 9da72c4252de24be048f58668cb3c5b492f105b23c7440a959d0474574315306 ssa_ast: 8d6571c282f21bdbc7c88ee0bd602ea2e29f7ce0408cb77b4dc9fd80ec7546e5
flattened_ast: 1502430fd27a08f4eef2ca43873c588899a2c18acb15576da4b35538cb29c66e flattened_ast: b6ae966db6102e16ca5e2c3141dd59a957e8dc52e77d906220eddf7d5d81f301
inlined_ast: 1502430fd27a08f4eef2ca43873c588899a2c18acb15576da4b35538cb29c66e inlined_ast: b6ae966db6102e16ca5e2c3141dd59a957e8dc52e77d906220eddf7d5d81f301
dce_ast: 2e508af7d9b2d85877183259c9e576d25c062f03c38d23acdc2d65d66e1ad4fd dce_ast: 1614b47014a0db1e2fef072ecbbae97e2d24c603b8dedcbf614ce39e340aadd2
bytecode: e9166c477441b45359a7ab4d7ee7afd309de45ee5cad9143f0261b1c3ccf8b57 bytecode: e9166c477441b45359a7ab4d7ee7afd309de45ee5cad9143f0261b1c3ccf8b57
warnings: "" warnings: ""

Some files were not shown because too many files have changed in this diff Show More