parse imports

This commit is contained in:
collin 2020-04-17 12:51:02 -07:00
parent 1743c7a1f1
commit 1e9e49db57
7 changed files with 173 additions and 17 deletions

View File

@ -1,4 +1,9 @@
def main() -> (bool[4]):
bool[2] a = [true, true]
bool[4] x = [...a, ...a]
return x
from "./path/to/my/module" import MySymbol
def foo() -> (field):
// return myGlobal <- not allowed
return 42
def main() -> (field):
myGlobal = 42
return foo()

View File

@ -0,0 +1,70 @@
use std::fmt;
use std::path::Path;
type ImportPath<'ast> = &'ast Path;
pub(crate) type PathString<'ast> = &'ast str;
#[derive(Clone)]
pub struct Import<'ast> {
source: ImportPath<'ast>,
symbol: Option<PathString<'ast>>,
alias: Option<PathString<'ast>>,
}
impl<'ast> Import<'ast> {
pub fn new(symbol: Option<PathString<'ast>>, source: ImportPath<'ast>) -> Import<'ast> {
Import {
source,
symbol,
alias: None,
}
}
pub fn new_with_alias(
symbol: Option<PathString<'ast>>,
source: ImportPath<'ast>,
alias: PathString<'ast>,
) -> Import<'ast> {
Import {
source,
symbol,
alias: Some(alias),
}
}
pub fn alias(mut self, alias: Option<PathString<'ast>>) -> Self {
self.alias = alias;
self
}
pub fn get_alias(&self) -> &Option<PathString<'ast>> {
&self.alias
}
pub fn get_source(&self) -> &Path {
&self.source
}
}
impl<'ast> fmt::Display for Import<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.alias {
Some(ref alias) => write!(f, "import {} as {}", self.source.display(), alias),
None => write!(f, "import {}", self.source.display()),
}
}
}
impl<'ast> fmt::Debug for Import<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.alias {
Some(ref alias) => write!(
f,
"import(source: {}, alias: {})",
self.source.display(),
alias
),
None => write!(f, "import source: {})", self.source.display()),
}
}
}

View File

@ -10,6 +10,9 @@ pub use self::types::*;
pub mod constraints;
pub use self::constraints::*;
pub mod imports;
pub use self::imports::*;
pub mod types_display;
pub use self::types_display::*;

View File

@ -4,6 +4,7 @@
//! @author Collin Chin <collin@aleo.org>
//! @date 2020
use crate::aleo_program::Import;
use std::collections::HashMap;
/// A variable in a constraint system.
@ -173,7 +174,8 @@ impl Function {
/// A simple program with statement expressions, program arguments and program returns.
#[derive(Debug, Clone)]
pub struct Program {
pub struct Program<'ast> {
pub imports: Vec<Import<'ast>>,
pub structs: HashMap<Variable, Struct>,
pub functions: HashMap<FunctionName, Function>,
}

View File

@ -5,9 +5,11 @@
//! @author Collin Chin <collin@aleo.org>
//! @date 2020
use crate::aleo_program::StructMember;
use crate::{aleo_program::types, ast};
use crate::aleo_program::{types, Import, PathString};
use crate::ast;
use std::collections::HashMap;
use std::path::Path;
impl<'ast> From<ast::Field<'ast>> for types::FieldExpression {
fn from(field: ast::Field<'ast>) -> Self {
@ -558,7 +560,7 @@ impl<'ast> types::Expression {
.members
.into_iter()
.map(|member| types::StructMember::from(member))
.collect::<Vec<StructMember>>();
.collect::<Vec<types::StructMember>>();
types::Expression::Struct(variable, members)
}
@ -745,9 +747,34 @@ impl<'ast> From<ast::Function<'ast>> for types::Function {
}
}
impl<'ast> From<ast::File<'ast>> for types::Program {
impl<'ast> From<ast::Variable<'ast>> for PathString<'ast> {
fn from(import: ast::Variable<'ast>) -> Self {
import.span.as_str()
}
}
impl<'ast> From<ast::Import<'ast>> for Import<'ast> {
fn from(import: ast::Import<'ast>) -> Self {
match import {
ast::Import::Main(import) => Import::new(None, Path::new(import.source.span.as_str()))
.alias(import.alias.map(|alias| PathString::from(alias))),
ast::Import::From(import) => Import::new(
Some(PathString::from(import.symbol)),
Path::new(import.source.span.as_str()),
)
.alias(import.alias.map(|alias| PathString::from(alias))),
}
}
}
impl<'ast> From<ast::File<'ast>> for types::Program<'ast> {
fn from(file: ast::File<'ast>) -> Self {
// Compiled ast -> aleo program representation
let imports = file
.imports
.into_iter()
.map(|import| Import::from(import))
.collect::<Vec<Import>>();
let mut structs = HashMap::new();
let mut functions = HashMap::new();
@ -765,6 +792,10 @@ impl<'ast> From<ast::File<'ast>> for types::Program {
);
});
types::Program { structs, functions }
types::Program {
imports,
structs,
functions,
}
}
}

View File

@ -864,20 +864,58 @@ pub struct Function<'ast> {
pub span: Span<'ast>,
}
// Utilities
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::EOI))]
pub struct EOI;
// Imports
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::import_source))]
pub struct ImportSource<'ast> {
#[pest_ast(outer(with(span_into_string)))]
pub value: String,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::main_import))]
pub struct MainImport<'ast> {
pub source: ImportSource<'ast>,
pub alias: Option<Variable<'ast>>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::from_import))]
pub struct FromImport<'ast> {
pub source: ImportSource<'ast>,
pub symbol: Variable<'ast>,
pub alias: Option<Variable<'ast>>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::import))]
pub enum Import<'ast> {
Main(MainImport<'ast>),
From(FromImport<'ast>),
}
// File
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::file))]
pub struct File<'ast> {
pub imports: Vec<Import<'ast>>,
pub structs: Vec<Struct<'ast>>,
pub functions: Vec<Function<'ast>>,
pub eoi: EOI,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
// Utilities
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::EOI))]
pub struct EOI;

View File

@ -162,6 +162,13 @@ function_definition = {"def" ~ function_name ~ "(" ~ parameter_list ~ ")" ~ "->"
COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
WHITESPACE = _{ " " | "\t" ~ (NEWLINE)* }
/// Imports
import = { main_import | from_import }
from_import = { "from" ~ "\"" ~ import_source ~ "\"" ~ "import" ~ variable ~ ("as" ~ variable)? ~ NEWLINE*}
main_import = {"import" ~ "\"" ~ import_source ~ "\"" ~ ("as" ~ variable)? ~ NEWLINE+}
import_source = @{(!"\"" ~ ANY)*}
/// Abstract Syntax Tree File
file = { SOI ~ NEWLINE* ~ struct_definition* ~ NEWLINE* ~ function_definition* ~ NEWLINE* ~ EOI }
file = { SOI ~ NEWLINE* ~ import* ~ NEWLINE* ~ struct_definition* ~ NEWLINE* ~ function_definition* ~ NEWLINE* ~ EOI }