Skip to content

Commit

Permalink
Push most local changes
Browse files Browse the repository at this point in the history
* Refactor parsers
* Refactor error handling in parsers
* New frontend crate, unified interface to all frontends
* New printer for IR
* Use log crate for logging
* Add tests for issue in graph simplification pass
  • Loading branch information
hansihe committed Mar 9, 2020
1 parent bb38750 commit 71f907e
Show file tree
Hide file tree
Showing 83 changed files with 3,241 additions and 1,560 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]

members = [
"libeir_frontend",
"libeir_diagnostics",
"libeir_intern",
"libeir_syntax_erl",
Expand All @@ -16,4 +17,6 @@ members = [
"util/libeir_util_number",
"util/libeir_util_parse",
"util/libeir_util_parse_listing",
"util/libeir_util_dot_graph",
"util/scoped_cell",
]
2 changes: 0 additions & 2 deletions internal_lib/src/eir_internal_utils.erl

This file was deleted.

21 changes: 0 additions & 21 deletions internal_lib/src/erlang.erl

This file was deleted.

19 changes: 19 additions & 0 deletions libeir_frontend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "libeir_frontend"
version = "0.1.0"
authors = ["Hans Elias B. Josephsen <[email protected]>"]
edition = "2018"
license = "MIT OR Apache-2.0"

[dependencies]
libeir_ir = { path = "../libeir_ir" }
libeir_syntax_erl = { path = "../libeir_syntax_erl" }
libeir_util_parse = { path = "../util/libeir_util_parse" }
libeir_diagnostics = { path = "../libeir_diagnostics" }
libeir_util_parse_listing = { path = "../util/libeir_util_parse_listing" }

[features]
default = ["frontend_erlang", "frontend_abstr_erlang", "frontend_eir"]
frontend_erlang = []
frontend_abstr_erlang = []
frontend_eir = []
8 changes: 8 additions & 0 deletions libeir_frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# libeir_frontend

Wrapper crate for all the different frontends in this project.

Currently includes:
* eir frontend
* erlang frontend
* abstract erlang frontend
92 changes: 92 additions & 0 deletions libeir_frontend/src/abstr_erlang.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use std::path::Path;
use std::borrow::Cow;

use libeir_util_parse_listing::{parser::ParseError, ast::Root};
use libeir_util_parse::{Parse, ArcCodemap, Source, FileMapSource, ToDiagnostic, error_tee};
use libeir_ir::Module;
use libeir_diagnostics::{Diagnostic, FileName};
use libeir_syntax_erl::{lower_module, LowerError, lower_abstr};

use super::{Frontend, FrontendErrorReceiver};

pub enum Error {
Parse(ParseError),
Lower(LowerError),
}
impl ToDiagnostic for Error {
fn to_diagnostic(&self) -> Diagnostic {
match self {
Error::Parse(err) => err.to_diagnostic(),
Error::Lower(err) => err.to_diagnostic(),
}
}
}
impl From<ParseError> for Error {
fn from(err: ParseError) -> Error {
Error::Parse(err)
}
}
impl From<LowerError> for Error {
fn from(err: LowerError) -> Error {
Error::Lower(err)
}
}

pub struct AbstrErlangFrontend {}

impl AbstrErlangFrontend {
pub fn new() -> Self {
AbstrErlangFrontend {}
}
}

impl Frontend for AbstrErlangFrontend {
type Error = Error;

fn parse_source<'a>(
&self,
errors: &'a mut FrontendErrorReceiver<'a, Self::Error>,
codemap: ArcCodemap,
source: FileMapSource,
) -> Result<Module, ()> {
error_tee(errors, |mut errors| {
let root: Root = Root::parse(&(), &codemap, &mut errors.make_into_adapter(), source)?;
let ast = lower_abstr(&root);
let eir = lower_module(&mut errors.make_into_adapter(), &codemap, &ast)?;
Ok(eir)
})
}

fn parse_string<'a>(
&self,
errors: &'a mut FrontendErrorReceiver<'a, Self::Error>,
codemap: ArcCodemap,
source: &str,
) -> Result<Module, ()> {
let filemap = {
codemap.write().unwrap().add_filemap(
FileName::Virtual(Cow::Borrowed("nofile")),
source.to_owned(),
)
};
self.parse_source(errors, codemap, FileMapSource::new(filemap))
}

fn parse_file<'a>(
&self,
errors: &'a mut FrontendErrorReceiver<'a, Self::Error>,
codemap: ArcCodemap,
source: &Path,
) -> Result<Module, ()> {
match FileMapSource::from_path(codemap.clone(), source) {
Err(err) => {
errors.error(<Root as Parse<Root>>::file_map_error(err).into());
Err(())
},
Ok(source) => self.parse_source(errors, codemap, source),
}
}

}

impl_dyn_frontend!(AbstrErlangFrontend);
95 changes: 95 additions & 0 deletions libeir_frontend/src/eir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use std::path::Path;
use std::borrow::Cow;

use libeir_diagnostics::{Diagnostic, FileName};
use libeir_util_parse::{Parse, ArcCodemap, Source, FileMapSource, ToDiagnostic, error_tee};
use libeir_ir::{
Module,
text::{
parser::ParserError,
ast::{LowerError, Module as ModuleAst},
},
};

use super::{Frontend, FrontendErrorReceiver};

pub enum Error {
Parser(ParserError),
Lower(LowerError),
}
impl ToDiagnostic for Error {
fn to_diagnostic(&self) -> Diagnostic {
match self {
Error::Parser(err) => err.to_diagnostic(),
Error::Lower(err) => err.to_diagnostic(),
}
}
}
impl From<ParserError> for Error {
fn from(err: ParserError) -> Self {
Error::Parser(err)
}
}
impl From<LowerError> for Error {
fn from(err: LowerError) -> Self {
Error::Lower(err)
}
}

pub struct EirFrontend {}

impl EirFrontend {
pub fn new() -> Self {
EirFrontend {}
}
}

impl Frontend for EirFrontend {
type Error = Error;

fn parse_source<'a>(
&self,
errors: &'a mut FrontendErrorReceiver<'a, Self::Error>,
codemap: ArcCodemap,
source: FileMapSource,
) -> Result<Module, ()> {
error_tee(errors, |mut errors| {
let ast = ModuleAst::parse(&(), &codemap, &mut errors.make_into_adapter(), source)?;
let eir = ast.lower(&mut errors.make_into_adapter())?;
Ok(eir)
})
}

fn parse_string<'a>(
&self,
errors: &'a mut FrontendErrorReceiver<'a, Self::Error>,
codemap: ArcCodemap,
source: &str,
) -> Result<Module, ()> {
let filemap = {
codemap.write().unwrap().add_filemap(
FileName::Virtual(Cow::Borrowed("nofile")),
source.to_owned(),
)
};
self.parse_source(errors, codemap, FileMapSource::new(filemap))
}

fn parse_file<'a>(
&self,
errors: &'a mut FrontendErrorReceiver<'a, Self::Error>,
codemap: ArcCodemap,
source: &Path,
) -> Result<Module, ()> {
match FileMapSource::from_path(codemap.clone(), source) {
Err(err) => {
errors.error(<ModuleAst as Parse<ModuleAst>>::file_map_error(err).into());
Err(())
},
Ok(source) => self.parse_source(errors, codemap, source),
}
}

}

impl_dyn_frontend!(EirFrontend);
97 changes: 97 additions & 0 deletions libeir_frontend/src/erlang.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use std::path::Path;
use std::borrow::Cow;

use libeir_syntax_erl::{
lower_module, ParseConfig, ParserError, LowerError,
ast::Module as ModuleAst,
};
use libeir_diagnostics::{Diagnostic, FileName};
use libeir_util_parse::{Parse, ArcCodemap, Source, FileMapSource, ToDiagnostic, error_tee};
use libeir_ir::Module;

use super::{Frontend, FrontendErrorReceiver};

pub enum Error {
Parser(ParserError),
Lower(LowerError),
}
impl ToDiagnostic for Error {
fn to_diagnostic(&self) -> Diagnostic {
match self {
Error::Parser(err) => err.to_diagnostic(),
Error::Lower(err) => err.to_diagnostic(),
}
}
}
impl Into<Error> for ParserError {
fn into(self) -> Error {
Error::Parser(self)
}
}
impl Into<Error> for LowerError {
fn into(self) -> Error {
Error::Lower(self)
}
}

pub struct ErlangFrontend {
config: ParseConfig,
}

impl ErlangFrontend {
pub fn new(config: ParseConfig) -> Self {
ErlangFrontend {
config,
}
}
}

impl Frontend for ErlangFrontend {
type Error = Error;

fn parse_source<'a>(
&self,
errors: &'a mut FrontendErrorReceiver<'a, Self::Error>,
codemap: ArcCodemap,
source: FileMapSource,
) -> Result<Module, ()> {
error_tee(errors, |mut errors| {
let ast = ModuleAst::parse(&self.config, &codemap, &mut errors.make_into_adapter(), source)?;
let eir = lower_module(&mut errors.make_into_adapter(), &codemap, &ast)?;
Ok(eir)
})
}

fn parse_string<'a>(
&self,
errors: &'a mut FrontendErrorReceiver<'a, Self::Error>,
codemap: ArcCodemap,
source: &str,
) -> Result<Module, ()> {
let filemap = {
codemap.write().unwrap().add_filemap(
FileName::Virtual(Cow::Borrowed("nofile")),
source.to_owned(),
)
};
self.parse_source(errors, codemap, FileMapSource::new(filemap))
}

fn parse_file<'a>(
&self,
errors: &'a mut FrontendErrorReceiver<'a, Self::Error>,
codemap: ArcCodemap,
source: &Path,
) -> Result<Module, ()> {
match FileMapSource::from_path(codemap.clone(), source) {
Err(err) => {
errors.error(<ModuleAst as Parse<ModuleAst>>::file_map_error(err).into());
Err(())
},
Ok(source) => self.parse_source(errors, codemap, source),
}
}

}

impl_dyn_frontend!(ErlangFrontend);
Loading

0 comments on commit 71f907e

Please sign in to comment.