Skip to content

Commit

Permalink
Merge pull request #175 from erg-lang/fix-repl
Browse files Browse the repository at this point in the history
Fix repl
  • Loading branch information
mtshiba authored Sep 22, 2022
2 parents b56236a + a5a0324 commit ecc12bb
Show file tree
Hide file tree
Showing 19 changed files with 255 additions and 269 deletions.
9 changes: 0 additions & 9 deletions compiler/erg_common/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,15 +440,6 @@ pub trait Runnable: Sized {
continue;
}

// if (expect_block(line) && !in_block)
// || (is_in_the_expected_block(line, &lines, &mut in_block) && in_block)
// {
// lines += "\n";
// output.write_all(instance.ps2().as_bytes()).unwrap();
// output.flush().unwrap();
// continue;
// }

match instance.eval(mem::take(&mut lines)) {
Ok(out) => {
output.write_all((out + "\n").as_bytes()).unwrap();
Expand Down
112 changes: 112 additions & 0 deletions compiler/erg_compiler/build_hir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use erg_common::config::ErgConfig;
use erg_common::error::MultiErrorDisplay;
use erg_common::traits::{Runnable, Stream};
use erg_common::Str;

use erg_parser::ast::AST;
use erg_parser::build_ast::ASTBuilder;

use crate::context::Context;
use crate::effectcheck::SideEffectChecker;
use crate::error::{CompileError, CompileErrors, TyCheckErrors};
use crate::hir::HIR;
use crate::lower::ASTLowerer;
use crate::mod_cache::SharedModuleCache;
use crate::ownercheck::OwnershipChecker;
use crate::reorder::Reorderer;

/// Summarize lowering, side-effect checking, and ownership checking
#[derive(Debug)]
pub struct HIRBuilder {
lowerer: ASTLowerer,
ownership_checker: OwnershipChecker,
}

impl Runnable for HIRBuilder {
type Err = CompileError;
type Errs = CompileErrors;
const NAME: &'static str = "Erg HIR builder";

fn new(cfg: ErgConfig) -> Self {
HIRBuilder::new_with_cache(cfg, Str::ever("<module>"), SharedModuleCache::new())
}

#[inline]
fn cfg(&self) -> &ErgConfig {
self.lowerer.cfg()
}

#[inline]
fn finish(&mut self) {}

fn clear(&mut self) {}

fn exec(&mut self) -> Result<(), Self::Errs> {
let mut builder = ASTBuilder::new(self.cfg().copy());
let ast = builder.build(self.input().read())?;
let hir = self.check(ast, "exec")?;
println!("{hir}");
Ok(())
}

fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
let mut builder = ASTBuilder::new(self.cfg().copy());
let ast = builder.build(src)?;
let hir = self.check(ast, "eval")?;
Ok(hir.to_string())
}
}

impl HIRBuilder {
pub fn new_with_cache<S: Into<Str>>(
cfg: ErgConfig,
mod_name: S,
mod_cache: SharedModuleCache,
) -> Self {
Self {
lowerer: ASTLowerer::new_with_cache(cfg, mod_name, mod_cache),
ownership_checker: OwnershipChecker::new(),
}
}

fn convert(&self, errs: TyCheckErrors) -> CompileErrors {
errs.into_iter()
.map(|e| CompileError::new(e.core, self.input().clone(), e.caused_by))
.collect::<Vec<_>>()
.into()
}

pub fn check(&mut self, ast: AST, mode: &str) -> Result<HIR, CompileErrors> {
let (hir, warns) = self
.lowerer
.lower(ast, mode)
.map_err(|errs| self.convert(errs))?;
if self.cfg().verbose >= 2 {
let warns = self.convert(warns);
warns.fmt_all_stderr();
}
let effect_checker = SideEffectChecker::new();
let hir = effect_checker
.check(hir)
.map_err(|errs| self.convert(errs))?;
let hir = self
.ownership_checker
.check(hir)
.map_err(|errs| self.convert(errs))?;
Ok(hir)
}

pub fn build(&mut self, src: String, mode: &str) -> Result<HIR, CompileErrors> {
let mut ast_builder = ASTBuilder::new(self.cfg().copy());
let ast = ast_builder.build(src)?;
let ast = Reorderer::new()
.reorder(ast)
.map_err(|errs| self.convert(errs))?;
let hir = self.check(ast, mode)?;
Ok(hir)
}

pub fn pop_ctx(&mut self) -> Context {
self.lowerer.ctx.pop()
}
}
48 changes: 0 additions & 48 deletions compiler/erg_compiler/builder.rs

This file was deleted.

85 changes: 0 additions & 85 deletions compiler/erg_compiler/check.rs

This file was deleted.

26 changes: 13 additions & 13 deletions compiler/erg_compiler/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
//! コンパイラーを定義する
use std::path::Path;

use erg_common::config::{ErgConfig, Input};
use erg_common::config::ErgConfig;
use erg_common::log;
use erg_common::traits::{Runnable, Stream};
use erg_parser::ast::VarName;
use erg_type::codeobj::CodeObj;

use crate::builder::HIRBuilder;
use crate::build_hir::HIRBuilder;
use crate::codegen::CodeGenerator;
use crate::error::{CompileError, CompileErrors};
use crate::link::Linker;
Expand Down Expand Up @@ -92,6 +91,7 @@ impl AccessKind {
#[derive(Debug)]
pub struct Compiler {
pub cfg: ErgConfig,
builder: HIRBuilder,
mod_cache: SharedModuleCache,
code_generator: CodeGenerator,
}
Expand All @@ -104,6 +104,7 @@ impl Runnable for Compiler {
fn new(cfg: ErgConfig) -> Self {
let mod_cache = SharedModuleCache::new();
Self {
builder: HIRBuilder::new_with_cache(cfg.copy(), "<module>", mod_cache.clone()),
code_generator: CodeGenerator::new(cfg.copy()),
mod_cache,
cfg,
Expand All @@ -124,33 +125,32 @@ impl Runnable for Compiler {

fn exec(&mut self) -> Result<(), Self::Errs> {
let path = self.input().filename().replace(".er", ".pyc");
self.compile_and_dump_as_pyc(path, "exec")
self.compile_and_dump_as_pyc(path, self.input().read(), "exec")
}

fn eval(&mut self, src: String) -> Result<String, CompileErrors> {
self.cfg.input = Input::Str(src);
let codeobj = self.compile("eval")?;
let codeobj = self.compile(src, "eval")?;
Ok(codeobj.code_info())
}
}

impl Compiler {
pub fn compile_and_dump_as_pyc<P: AsRef<Path>>(
&mut self,
path: P,
pyc_path: P,
src: String,
mode: &str,
) -> Result<(), CompileErrors> {
let code = self.compile(mode)?;
code.dump_as_pyc(path, self.cfg.python_ver)
let code = self.compile(src, mode)?;
code.dump_as_pyc(pyc_path, self.cfg.python_ver)
.expect("failed to dump a .pyc file (maybe permission denied)");
Ok(())
}

pub fn compile(&mut self, mode: &str) -> Result<CodeObj, CompileErrors> {
pub fn compile(&mut self, src: String, mode: &str) -> Result<CodeObj, CompileErrors> {
log!(info "the compiling process has started.");
let mut hir_builder = HIRBuilder::new(self.cfg.copy(), "<module>", self.mod_cache.clone());
hir_builder.build_and_cache(VarName::from_static("<module>"), mode)?;
let hir = Linker::link(self.mod_cache.clone());
let hir = self.builder.build(src, mode)?;
let hir = Linker::link(self.cfg.copy(), hir, self.mod_cache.clone());
let codeobj = self.code_generator.emit(hir);
log!(info "code object:\n{}", codeobj.code_info());
log!(
Expand Down
41 changes: 22 additions & 19 deletions compiler/erg_compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,25 @@ impl Context {
Ok(())
}

pub(crate) fn pop(&mut self) -> Result<Context, TyCheckErrors> {
pub fn pop(&mut self) -> Context {
if let Some(parent) = self.outer.as_mut() {
let parent = mem::take(parent);
let ctx = mem::take(self);
*self = *parent;
log!(info "{}: current namespace: {}", fn_name!(), self.name);
ctx
} else {
// toplevel
mem::take(self)
}
}

pub(crate) fn check_decls_and_pop(&mut self) -> Result<Context, TyCheckErrors> {
self.check_decls()?;
Ok(self.pop())
}

pub(crate) fn check_decls(&mut self) -> Result<(), TyCheckErrors> {
let mut uninited_errs = TyCheckErrors::empty();
for (name, vi) in self.decls.iter() {
uninited_errs.push(TyCheckError::uninitialized_error(
Expand All @@ -612,25 +630,10 @@ impl Context {
&vi.t,
));
}
if let Some(parent) = self.outer.as_mut() {
let parent = mem::take(parent);
let ctx = mem::take(self);
*self = *parent;
log!(info "{}: current namespace: {}", fn_name!(), self.name);
if !uninited_errs.is_empty() {
Err(uninited_errs)
} else {
Ok(ctx)
}
if !uninited_errs.is_empty() {
Err(uninited_errs)
} else {
// toplevel
let ctx = mem::take(self);
log!(info "{}: current namespace: {}", fn_name!(), self.name);
if !uninited_errs.is_empty() {
Err(uninited_errs)
} else {
Ok(ctx)
}
Ok(())
}
}
}
Loading

0 comments on commit ecc12bb

Please sign in to comment.