Skip to content

Commit

Permalink
CST function as a feature of the AST module
Browse files Browse the repository at this point in the history
  • Loading branch information
KyleBuilds committed Sep 29, 2024
1 parent dab2851 commit a2dfd57
Show file tree
Hide file tree
Showing 76 changed files with 286 additions and 2,592 deletions.
15 changes: 0 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ edition = "2021"
members = [
"compiler/ast",
"compiler/compiler",
"compiler/cst",
"compiler/parser",
"compiler/passes",
"compiler/span",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,17 @@
use serde::{Deserialize, Serialize};
use std::fmt;

/// The sort of bindings to introduce, either `let` or `const`.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum DeclarationType {
/// This is a `const` binding.
Const,
/// This is a `let` binding.
Let,
#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq, )]
pub enum Comment {
CommentLine(String),
CommentBlock(String)
}

impl fmt::Display for DeclarationType {
impl fmt::Display for Comment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DeclarationType::Const => write!(f, "const"),
DeclarationType::Let => write!(f, "let"),
Comment::CommentLine(content) => write!(f, "{}", content),
Comment::CommentBlock(content) => writeln!(f, "{}", content),
}
}
}
}
3 changes: 3 additions & 0 deletions compiler/ast/src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ pub use node_builder::*;

pub mod static_string;
pub use static_string::*;

pub mod comment;
pub use comment::*;
83 changes: 83 additions & 0 deletions compiler/ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ pub mod value;
pub mod stub;
pub use self::stub::*;

pub mod program_cst;
pub use self::program_cst::*;

pub use self::value::*;

pub use common::node::*;
Expand All @@ -74,6 +77,9 @@ use leo_errors::{AstError, Result};
pub struct Ast {
pub ast: Program,
}
pub struct Cst {
pub cst: CSTProgram
}

impl Ast {
/// Creates a new AST from a given program tree.
Expand Down Expand Up @@ -152,6 +158,83 @@ impl AsRef<Program> for Ast {
}
}

impl Cst {
/// Creates a new AST from a given program tree.
pub fn new(program: CSTProgram) -> Self {
Self { cst: program }
}

/// Returns a reference to the inner program AST representation.
pub fn as_repr(&self) -> &CSTProgram {
&self.cst
}

pub fn into_repr(self) -> CSTProgram {
self.cst
}

/// Serializes the ast into a JSON string.
pub fn to_json_string(&self) -> Result<String> {
Ok(serde_json::to_string_pretty(&self.cst).map_err(|e| AstError::failed_to_convert_ast_to_json_string(&e))?)
}

// Converts the ast into a JSON value.
// Note that there is no corresponding `from_json_value` function
// since we modify JSON values leaving them unable to be converted
// back into Programs.
pub fn to_json_value(&self) -> Result<serde_json::Value> {
Ok(serde_json::to_value(&self.cst).map_err(|e| AstError::failed_to_convert_ast_to_json_value(&e))?)
}

/// Serializes the ast into a JSON file.
pub fn to_json_file(&self, mut path: std::path::PathBuf, file_name: &str) -> Result<()> {
path.push(file_name);
let file = std::fs::File::create(&path).map_err(|e| AstError::failed_to_create_ast_json_file(&path, &e))?;
let writer = std::io::BufWriter::new(file);
Ok(serde_json::to_writer_pretty(writer, &self.cst)
.map_err(|e| AstError::failed_to_write_ast_to_json_file(&path, &e))?)
}

/// Serializes the ast into a JSON value and removes keys from object mappings before writing to a file.
pub fn to_json_file_without_keys(
&self,
mut path: std::path::PathBuf,
file_name: &str,
excluded_keys: &[&str],
) -> Result<()> {
path.push(file_name);
let file = std::fs::File::create(&path).map_err(|e| AstError::failed_to_create_ast_json_file(&path, &e))?;
let writer = std::io::BufWriter::new(file);

let mut value = self.to_json_value().unwrap();
for key in excluded_keys {
value = remove_key_from_json(value, key);
}
value = normalize_json_value(value);

Ok(serde_json::to_writer_pretty(writer, &value)
.map_err(|e| AstError::failed_to_write_ast_to_json_file(&path, &e))?)
}

/// Deserializes the JSON string into a ast.
pub fn from_json_string(json: &str) -> Result<Self> {
let cst: CSTProgram = serde_json::from_str(json).map_err(|e| AstError::failed_to_read_json_string_to_ast(&e))?;
Ok(Self { cst })
}

/// Deserializes the JSON string into a ast from a file.
pub fn from_json_file(path: std::path::PathBuf) -> Result<Self> {
let data = std::fs::read_to_string(&path).map_err(|e| AstError::failed_to_read_json_file(&path, &e))?;
Self::from_json_string(&data)
}
}

impl AsRef<CSTProgram> for Cst {
fn as_ref(&self) -> &CSTProgram {
&self.cst
}
}

/// Helper function to recursively filter keys from AST JSON
pub fn remove_key_from_json(value: serde_json::Value, key: &str) -> serde_json::Value {
match value {
Expand Down
81 changes: 81 additions & 0 deletions compiler/ast/src/program_cst/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// 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/>.

//! A Leo program consists of import statements and program scopes.

use super::*;

use leo_span::{span::Pos, Span, Symbol};

use crate::{ Comment, Stub };
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use std::fmt;

/// Stores the Leo program abstract syntax tree.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct CSTProgram {
/// A map from import names to import definitions.
pub imports: IndexMap<Symbol, (CSTProgram, Span, usize)>,
/// A map from program stub names to program stub scopes.
pub stubs: IndexMap<Symbol, (Stub, usize)>,
/// A map from program names to program scopes.
pub program_scopes: IndexMap<Symbol, (ProgramScope, usize)>,
/// A map from prefix names to comment.
pub comments: Vec<(Comment, usize)>
}
impl fmt::Display for CSTProgram {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let len = self.imports.len() + self.program_scopes.len() + self.comments.len() + self.stubs.len();
for index in 0..len {
for (id, import) in self.imports.iter() {
if index == import.2 {
writeln!(f, "import {id}.leo;")?;
}
}
for (_, stub) in self.stubs.iter() {
if index == stub.1 {
stub.0.fmt(f)?;
writeln!(f,)?;
}
}
for (_, program_scope) in self.program_scopes.iter() {
if index == program_scope.1 {
program_scope.0.fmt(f)?;
}
}
for comment in &self.comments {
if index == comment.1 {
comment.0.fmt(f)?;
}
}
}

Ok(())
}
}

impl Default for CSTProgram {
/// Constructs an empty program node.
fn default() -> Self {
Self {
imports: IndexMap::new(),
stubs: IndexMap::new(),
program_scopes: IndexMap::new(),
comments: vec![]
}
}
}
56 changes: 0 additions & 56 deletions compiler/cst/Cargo.toml

This file was deleted.

Loading

0 comments on commit a2dfd57

Please sign in to comment.