Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
evan-schott committed Oct 3, 2023
1 parent e803375 commit aa805f2
Show file tree
Hide file tree
Showing 35 changed files with 324 additions and 206 deletions.
3 changes: 3 additions & 0 deletions compiler/ast/src/passes/consumer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub trait StatementConsumer {
Statement::Block(stmt) => self.consume_block(stmt),
Statement::Conditional(stmt) => self.consume_conditional(stmt),
Statement::Console(stmt) => self.consume_console(stmt),
Statement::Const(stmt) => self.consume_const(stmt),
Statement::Definition(stmt) => self.consume_definition(stmt),
Statement::Expression(stmt) => self.consume_expression_statement(stmt),
Statement::Iteration(stmt) => self.consume_iteration(*stmt),
Expand All @@ -95,6 +96,8 @@ pub trait StatementConsumer {

fn consume_console(&mut self, input: ConsoleStatement) -> Self::Output;

fn consume_const(&mut self, input: ConstDeclaration) -> Self::Output;

fn consume_definition(&mut self, input: DefinitionStatement) -> Self::Output;

fn consume_expression_statement(&mut self, input: ExpressionStatement) -> Self::Output;
Expand Down
18 changes: 16 additions & 2 deletions compiler/ast/src/passes/reconstructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ pub trait StatementReconstructor: ExpressionReconstructor {
}
Statement::Conditional(stmt) => self.reconstruct_conditional(stmt),
Statement::Console(stmt) => self.reconstruct_console(stmt),
Statement::Const(stmt) => self.reconstruct_const(stmt),
Statement::Definition(stmt) => self.reconstruct_definition(stmt),
Statement::Expression(stmt) => self.reconstruct_expression_statement(stmt),
Statement::Iteration(stmt) => self.reconstruct_iteration(*stmt),
Expand Down Expand Up @@ -287,6 +288,19 @@ pub trait StatementReconstructor: ExpressionReconstructor {
)
}

fn reconstruct_const(&mut self, input: ConstDeclaration) -> (Statement, Self::AdditionalOutput) {
(
Statement::Const(ConstDeclaration {
place: input.place,
type_: input.type_,
value: self.reconstruct_expression(input.value).0,
span: input.span,
id: input.id,
}),
Default::default(),
)
}

fn reconstruct_definition(&mut self, input: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
(
Statement::Definition(DefinitionStatement {
Expand Down Expand Up @@ -368,7 +382,7 @@ pub trait ProgramReconstructor: StatementReconstructor {
structs: input.structs.into_iter().map(|(i, c)| (i, self.reconstruct_struct(c))).collect(),
mappings: input.mappings.into_iter().map(|(id, mapping)| (id, self.reconstruct_mapping(mapping))).collect(),
functions: input.functions.into_iter().map(|(i, f)| (i, self.reconstruct_function(f))).collect(),
consts: input.consts.into_iter().map(|(i, c)| (i, self.reconstruct_const(c))).collect(),
consts: input.consts.into_iter().map(|(i, c)| (i, self.reconstruct_global_const(c))).collect(),
span: input.span,
}
}
Expand Down Expand Up @@ -396,7 +410,7 @@ pub trait ProgramReconstructor: StatementReconstructor {
}
}

fn reconstruct_const(&mut self, input: DefinitionStatement) -> DefinitionStatement {
fn reconstruct_global_const(&mut self, input: ConstDeclaration) -> ConstDeclaration {
input
}

Expand Down
7 changes: 5 additions & 2 deletions compiler/ast/src/passes/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
Statement::Block(stmt) => self.visit_block(stmt),
Statement::Conditional(stmt) => self.visit_conditional(stmt),
Statement::Console(stmt) => self.visit_console(stmt),
Statement::Const(stmt) => self.visit_const(stmt),
Statement::Definition(stmt) => self.visit_definition(stmt),
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
Statement::Iteration(stmt) => self.visit_iteration(stmt),
Expand Down Expand Up @@ -177,6 +178,10 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
};
}

fn visit_const(&mut self, input: &'a ConstDeclaration) {
self.visit_expression(&input.value, &Default::default());
}

fn visit_definition(&mut self, input: &'a DefinitionStatement) {
self.visit_expression(&input.value, &Default::default());
}
Expand Down Expand Up @@ -233,6 +238,4 @@ pub trait ProgramVisitor<'a>: StatementVisitor<'a> {
self.visit_block(&finalize.block);
}
}

fn visit_const(&mut self, _input: &'a DefinitionStatement) {}
}
4 changes: 2 additions & 2 deletions compiler/ast/src/program/program_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

//! A Leo program scope consists of struct, function, and mapping definitions.

use crate::{DefinitionStatement, Function, Mapping, ProgramId, Struct};
use crate::{ConstDeclaration, Function, Mapping, ProgramId, Struct};

use indexmap::IndexMap;
use leo_span::{Span, Symbol};
Expand All @@ -29,7 +29,7 @@ pub struct ProgramScope {
/// The program id of the program scope.
pub program_id: ProgramId,
/// A map from const names to const definitions.
pub consts: IndexMap<Symbol, DefinitionStatement>,
pub consts: IndexMap<Symbol, ConstDeclaration>,
/// A map from struct names to struct definitions.
pub structs: IndexMap<Symbol, Struct>,
/// A map from mapping names to mapping definitions.
Expand Down
46 changes: 46 additions & 0 deletions compiler/ast/src/statement/const_.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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::{Expression, Identifier, Node, NodeID, Type};
use leo_span::Span;

use serde::{Deserialize, Serialize};
use std::fmt;

/// A constant declaration statement.
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct ConstDeclaration {
/// The place to assign to. As opposed to `DefinitionStatement`, this can only be an identifier
pub place: Identifier,
/// The type of the binding, if specified, or inferred otherwise.
pub type_: Type,
/// An initializer value for the binding.
pub value: Expression,
/// The span excluding the semicolon.
pub span: Span,
/// The ID of the node.
pub id: NodeID,
}

impl fmt::Display for ConstDeclaration {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.place)?;
write!(f, ": {}", self.type_)?;
write!(f, " = {};", self.value)
}
}

crate::simple_node_impl!(ConstDeclaration);
10 changes: 10 additions & 0 deletions compiler/ast/src/statement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub use conditional::*;
pub mod console;
pub use console::*;

pub mod const_;
pub use const_::*;

pub mod definition;
pub use definition::*;

Expand Down Expand Up @@ -61,6 +64,8 @@ pub enum Statement {
Conditional(ConditionalStatement),
/// A console logging statement.
Console(ConsoleStatement),
/// A binding from identifier to constant value.
Const(ConstDeclaration),
/// A binding or set of bindings / variables to declare.
Definition(DefinitionStatement),
/// An expression statement
Expand All @@ -86,6 +91,7 @@ impl fmt::Display for Statement {
Statement::Block(x) => x.fmt(f),
Statement::Conditional(x) => x.fmt(f),
Statement::Console(x) => x.fmt(f),
Statement::Const(x) => x.fmt(f),
Statement::Definition(x) => x.fmt(f),
Statement::Expression(x) => x.fmt(f),
Statement::Iteration(x) => x.fmt(f),
Expand All @@ -103,6 +109,7 @@ impl Node for Statement {
Block(n) => n.span(),
Conditional(n) => n.span(),
Console(n) => n.span(),
Const(n) => n.span(),
Definition(n) => n.span(),
Expression(n) => n.span(),
Iteration(n) => n.span(),
Expand All @@ -118,6 +125,7 @@ impl Node for Statement {
Block(n) => n.set_span(span),
Conditional(n) => n.set_span(span),
Console(n) => n.set_span(span),
Const(n) => n.set_span(span),
Definition(n) => n.set_span(span),
Expression(n) => n.set_span(span),
Iteration(n) => n.set_span(span),
Expand All @@ -133,6 +141,7 @@ impl Node for Statement {
Block(n) => n.id(),
Conditional(n) => n.id(),
Console(n) => n.id(),
Const(n) => n.id(),
Definition(n) => n.id(),
Expression(n) => n.id(),
Iteration(n) => n.id(),
Expand All @@ -148,6 +157,7 @@ impl Node for Statement {
Block(n) => n.set_id(id),
Conditional(n) => n.set_id(id),
Console(n) => n.set_id(id),
Const(n) => n.set_id(id),
Definition(n) => n.set_id(id),
Expression(n) => n.set_id(id),
Iteration(n) => n.set_id(id),
Expand Down
4 changes: 2 additions & 2 deletions compiler/parser/src/parser/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ impl ParserContext<'_> {
while self.has_next() {
match &self.token.token {
Token::Const => {
let definition = self.parse_const_definition_statement()?;
consts.insert(Symbol::intern(&definition.place.to_string()), definition);
let declaration = self.parse_const_declaration_statement()?;
consts.insert(Symbol::intern(&declaration.place.to_string()), declaration);
}
Token::Struct | Token::Record => {
let (id, struct_) = self.parse_struct()?;
Expand Down
25 changes: 5 additions & 20 deletions compiler/parser/src/parser/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl ParserContext<'_> {
Token::For => Ok(Statement::Iteration(Box::new(self.parse_loop_statement()?))),
Token::Assert | Token::AssertEq | Token::AssertNeq => Ok(self.parse_assert_statement()?),
Token::Let => Ok(Statement::Definition(self.parse_definition_statement()?)),
Token::Const => Ok(Statement::Definition(self.parse_const_definition_statement()?)),
Token::Const => Ok(Statement::Const(self.parse_const_declaration_statement()?)),
Token::LeftCurly => Ok(Statement::Block(self.parse_block()?)),
Token::Console => Err(ParserError::console_statements_are_not_yet_supported(self.token.span).into()),
Token::Finalize => Err(ParserError::finalize_statements_are_deprecated(self.token.span).into()),
Expand Down Expand Up @@ -315,34 +315,19 @@ impl ParserContext<'_> {
Ok(ConsoleStatement { span: keyword + span, function, id: self.node_builder.next_id() })
}

/// Returns a [`DefinitionStatement`] AST node if the next tokens represent a const definition statement.
pub(super) fn parse_const_definition_statement(&mut self) -> Result<DefinitionStatement> {
/// Returns a [`ConstDeclaration`] AST node if the next tokens represent a const declaration statement.
pub(super) fn parse_const_declaration_statement(&mut self) -> Result<ConstDeclaration> {
self.expect(&Token::Const)?;
let decl_span = self.prev_token.span;
let decl_type = match &self.prev_token.token {
Token::Const => DeclarationType::Const,
_ => unreachable!(
"parse_const_definition_statement shouldn't produce this as have already ensured that first token was 'Const'"
),
};

// Parse variable name and type.
let place = self.parse_expression()?;
self.expect(&Token::Colon)?;
let type_ = self.parse_type()?.0;
let (place, type_, _) = self.parse_typed_ident()?;

self.expect(&Token::Assign)?;
let value = self.parse_expression()?;
self.expect(&Token::Semicolon)?;

Ok(DefinitionStatement {
span: decl_span + value.span(),
declaration_type: decl_type,
place,
type_,
value,
id: self.node_builder.next_id(),
})
Ok(ConstDeclaration { span: decl_span + value.span(), place, type_, value, id: self.node_builder.next_id() })
}

/// Returns a [`DefinitionStatement`] AST node if the next tokens represent a definition statement.
Expand Down
3 changes: 3 additions & 0 deletions compiler/passes/src/code_generation/visit_statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ impl<'a> CodeGenerator<'a> {
Statement::Block(stmt) => self.visit_block(stmt),
Statement::Conditional(stmt) => self.visit_conditional(stmt),
Statement::Console(stmt) => self.visit_console(stmt),
Statement::Const(_) => {
unreachable!("`ConstStatement`s should not be in the AST at this phase of compilation.")
}
Statement::Definition(stmt) => self.visit_definition(stmt),
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
Statement::Iteration(stmt) => self.visit_iteration(stmt),
Expand Down
10 changes: 5 additions & 5 deletions compiler/passes/src/common/constant_propagation_table/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use indexmap::IndexMap;
use std::cell::RefCell;

use leo_ast::Literal;
use leo_ast::Expression;
use leo_errors::Result;
use leo_span::Symbol;

Expand All @@ -30,7 +30,7 @@ pub struct ConstantPropagationTable {
pub(crate) parent: Option<Box<ConstantPropagationTable>>,
/// The known constants in the current scope
/// This field is populated as necessary.
pub(crate) constants: IndexMap<Symbol, Literal>,
pub(crate) constants: IndexMap<Symbol, Expression>,
/// The index of the current scope.
pub(crate) scope_index: usize,
/// The sub-scopes of this scope.
Expand All @@ -47,8 +47,8 @@ impl ConstantPropagationTable {
}

/// Inserts a constant into the constant propagation table.
pub fn insert_constant(&mut self, symbol: Symbol, literal: Literal) -> Result<()> {
self.constants.insert(symbol, literal);
pub fn insert_constant(&mut self, symbol: Symbol, expr: Expression) -> Result<()> {
self.constants.insert(symbol, expr);
Ok(())
}

Expand All @@ -66,7 +66,7 @@ impl ConstantPropagationTable {
}

/// Attempts to lookup a constant in the constant propagation table.
pub fn lookup_constant(&self, symbol: Symbol) -> Option<&Literal> {
pub fn lookup_constant(&self, symbol: Symbol) -> Option<&Expression> {
if let Some(constant) = self.constants.get(&symbol) {
Some(constant)
} else if let Some(parent) = self.parent.as_ref() {
Expand Down
4 changes: 2 additions & 2 deletions compiler/passes/src/loop_unrolling/unroll_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ impl ExpressionReconstructor for Unroller<'_> {

fn reconstruct_identifier(&mut self, input: Identifier) -> (Expression, Self::AdditionalOutput) {
// Substitute the identifier with the constant value if it is a constant.
if let Some(literal) = self.constant_propagation_table.borrow().lookup_constant(input.name) {
return (Expression::Literal(literal.clone()), Default::default());
if let Some(expr) = self.constant_propagation_table.borrow().lookup_constant(input.name) {
return (expr.clone(), Default::default());
}
(Expression::Identifier(input), Default::default())
}
Expand Down
Loading

0 comments on commit aa805f2

Please sign in to comment.