This commit is contained in:
Shunsuke Shibayama 2022-10-09 17:56:17 +09:00
parent 0ac63d8362
commit b997c685dd
9 changed files with 113 additions and 25 deletions

View file

@ -18,6 +18,15 @@ members = [
"compiler/erg_type", "compiler/erg_type",
] ]
[workspace.package]
version = "0.5.8"
authors = ["erg-lang team <moderation.erglang@gmail.com>"]
license = "MIT OR Apache-2.0"
edition = "2021"
repository = "https://github.com/erg-lang/erg"
documentation = "https://docs.rs/erg"
homepage = "https://erg-lang.org/"
[features] [features]
# when "debug" feature is turned on, that of the following crates will also be turned on. # when "debug" feature is turned on, that of the following crates will also be turned on.
debug = [ debug = [

View file

@ -1,13 +1,14 @@
[package] [package]
name = "erg_compiler" name = "erg_compiler"
version = "0.5.8"
description = "Centimetre: the Erg compiler" description = "Centimetre: the Erg compiler"
authors = ["erg-lang team <moderation.erglang@gmail.com>"] build = "build.rs"
license = "MIT OR Apache-2.0" version.workspace = true
edition = "2021" authors.workspace = true
repository = "https://github.com/erg-lang/erg/tree/main/src/compiler/erg_compiler" license.workspace = true
documentation = "https://docs.rs/erg_compiler" edition.workspace = true
homepage = "https://erg-lang.github.io/" repository.workspace = true
documentation.workspace = true
homepage.workspace = true
[features] [features]
# when "debug" feature is turned on, that of parser will also be turned on. # when "debug" feature is turned on, that of parser will also be turned on.

View file

@ -0,0 +1,33 @@
#![allow(deprecated)]
use std::env;
use std::fs;
use std::path;
fn main() -> std::io::Result<()> {
// Create a ".erg" directory
let erg_path = env::home_dir()
.expect("failed to get the location of the home dir")
.to_str()
.expect("invalid encoding of the home dir name")
.to_string()
+ "/.erg";
if !path::Path::new(&erg_path).exists() {
fs::create_dir(&erg_path)?;
fs::create_dir(format!("{erg_path}/std"))?;
}
println!("cargo:rustc-env=ERG_PATH={erg_path}");
println!("cargo:rustc-env=ERG_STD_PATH={erg_path}/std");
// create a std library in ".erg"
for res in fs::read_dir("std")? {
let entry = res?;
let path = entry.path();
let filename = path
.file_name()
.expect("this is not a file")
.to_str()
.unwrap();
fs::copy(&path, format!("{erg_path}/std/{filename}"))?;
}
Ok(())
}

View file

@ -867,7 +867,7 @@ impl CodeGenerator {
self.write_instr(MAKE_FUNCTION); self.write_instr(MAKE_FUNCTION);
self.write_arg(0); self.write_arg(0);
self.emit_load_const(def.sig.ident().inspect().clone()); self.emit_load_const(def.sig.ident().inspect().clone());
self.emit_load_name_instr(Identifier::private(Str::ever("#ABCMeta"))); self.emit_load_name_instr(Identifier::private("#ABCMeta"));
self.emit_load_const(vec![ValueObj::from("metaclass")]); self.emit_load_const(vec![ValueObj::from("metaclass")]);
let subclasses_len = 1; let subclasses_len = 1;
self.write_instr(Opcode::CALL_FUNCTION_KW); self.write_instr(Opcode::CALL_FUNCTION_KW);
@ -917,7 +917,7 @@ impl CodeGenerator {
self.emit_empty_func( self.emit_empty_func(
Some(sig.ident().inspect()), Some(sig.ident().inspect()),
def.sig.into_ident(), def.sig.into_ident(),
Some(Identifier::private(Str::ever("#abstractmethod"))), Some(Identifier::private("#abstractmethod")),
); );
} }
self.emit_load_const(ValueObj::None); self.emit_load_const(ValueObj::None);
@ -1150,6 +1150,9 @@ impl CodeGenerator {
self.emit_load_name_instr(Identifier::public("range")); self.emit_load_name_instr(Identifier::public("range"));
} }
TokenKind::LeftOpen | TokenKind::Closed | TokenKind::Open => todo!(), TokenKind::LeftOpen | TokenKind::Closed | TokenKind::Open => todo!(),
TokenKind::InOp => {
self.emit_load_name_instr(Identifier::private("#in_operator"));
}
_ => {} _ => {}
} }
let type_pair = TypePair::new(bin.lhs_t(), bin.rhs_t()); let type_pair = TypePair::new(bin.lhs_t(), bin.rhs_t());
@ -1170,9 +1173,11 @@ impl CodeGenerator {
| TokenKind::NotEq | TokenKind::NotEq
| TokenKind::Gre | TokenKind::Gre
| TokenKind::GreEq => COMPARE_OP, | TokenKind::GreEq => COMPARE_OP,
TokenKind::LeftOpen | TokenKind::RightOpen | TokenKind::Closed | TokenKind::Open => { TokenKind::LeftOpen
CALL_FUNCTION | TokenKind::RightOpen
} // ERG_BINARY_RANGE, | TokenKind::Closed
| TokenKind::Open
| TokenKind::InOp => CALL_FUNCTION, // ERG_BINARY_RANGE,
_ => { _ => {
CompileError::feature_error( CompileError::feature_error(
self.cfg.input.clone(), self.cfg.input.clone(),
@ -1191,14 +1196,22 @@ impl CodeGenerator {
TokenKind::NotEq => 3, TokenKind::NotEq => 3,
TokenKind::Gre => 4, TokenKind::Gre => 4,
TokenKind::GreEq => 5, TokenKind::GreEq => 5,
TokenKind::LeftOpen | TokenKind::RightOpen | TokenKind::Closed | TokenKind::Open => 2, TokenKind::LeftOpen
| TokenKind::RightOpen
| TokenKind::Closed
| TokenKind::Open
| TokenKind::InOp => 2,
_ => type_pair as u8, _ => type_pair as u8,
}; };
self.write_instr(instr); self.write_instr(instr);
self.write_arg(arg); self.write_arg(arg);
self.stack_dec(); self.stack_dec();
match &bin.op.kind { match &bin.op.kind {
TokenKind::LeftOpen | TokenKind::RightOpen | TokenKind::Open | TokenKind::Closed => { TokenKind::LeftOpen
| TokenKind::RightOpen
| TokenKind::Open
| TokenKind::Closed
| TokenKind::InOp => {
self.stack_dec(); self.stack_dec();
} }
_ => {} _ => {}
@ -1597,7 +1610,7 @@ impl CodeGenerator {
log!(info "entered {} ({rec})", fn_name!()); log!(info "entered {} ({rec})", fn_name!());
let attrs_len = rec.attrs.len(); let attrs_len = rec.attrs.len();
// making record type // making record type
let ident = Identifier::private(Str::ever("#NamedTuple")); let ident = Identifier::private("#NamedTuple");
self.emit_load_name_instr(ident); self.emit_load_name_instr(ident);
// record name, let it be anonymous // record name, let it be anonymous
self.emit_load_const("Record"); self.emit_load_const("Record");
@ -1615,10 +1628,10 @@ impl CodeGenerator {
self.write_arg(2); self.write_arg(2);
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object // (1 (subroutine) + argc + kwsc) input objects -> 1 return object
self.stack_dec_n((1 + 2 + 0) - 1); self.stack_dec_n((1 + 2 + 0) - 1);
let ident = Identifier::private(Str::ever("#rec")); let ident = Identifier::private("#rec");
self.emit_store_instr(ident, Name); self.emit_store_instr(ident, Name);
// making record instance // making record instance
let ident = Identifier::private(Str::ever("#rec")); let ident = Identifier::private("#rec");
self.emit_load_name_instr(ident); self.emit_load_name_instr(ident);
for field in rec.attrs.into_iter() { for field in rec.attrs.into_iter() {
self.emit_frameless_block(field.body.block, vec![]); self.emit_frameless_block(field.body.block, vec![]);
@ -2007,15 +2020,40 @@ impl CodeGenerator {
fn load_prelude(&mut self) { fn load_prelude(&mut self) {
self.load_record_type(); self.load_record_type();
self.load_prelude_py();
self.record_type_loaded = true; self.record_type_loaded = true;
} }
fn load_prelude_py(&mut self) {
self.emit_global_import_items(
Identifier::public("sys"),
vec![(
Identifier::public("path"),
Some(Identifier::private("#path")),
)],
);
self.emit_load_name_instr(Identifier::private("#path"));
self.emit_load_method_instr("Array!", None, Identifier::public("push!"));
self.emit_load_const(env!("ERG_STD_PATH"));
self.write_instr(CALL_METHOD);
self.write_arg(1u8);
self.stack_dec();
self.emit_pop_top();
self.emit_global_import_items(
Identifier::public("prelude"),
vec![(
Identifier::public("in_operator"),
Some(Identifier::private("#in_operator")),
)],
);
}
fn load_record_type(&mut self) { fn load_record_type(&mut self) {
self.emit_global_import_items( self.emit_global_import_items(
Identifier::public("collections"), Identifier::public("collections"),
vec![( vec![(
Identifier::public("namedtuple"), Identifier::public("namedtuple"),
Some(Identifier::private(Str::ever("#NamedTuple"))), Some(Identifier::private("#NamedTuple")),
)], )],
); );
} }
@ -2026,11 +2064,11 @@ impl CodeGenerator {
vec![ vec![
( (
Identifier::public("ABCMeta"), Identifier::public("ABCMeta"),
Some(Identifier::private(Str::ever("#ABCMeta"))), Some(Identifier::private("#ABCMeta")),
), ),
( (
Identifier::public("abstractmethod"), Identifier::public("abstractmethod"),
Some(Identifier::private(Str::ever("#abstractmethod"))), Some(Identifier::private("#abstractmethod")),
), ),
], ],
); );
@ -2041,7 +2079,7 @@ impl CodeGenerator {
Identifier::public("types"), Identifier::public("types"),
vec![( vec![(
Identifier::public("ModuleType"), Identifier::public("ModuleType"),
Some(Identifier::private(Str::ever("#ModuleType"))), Some(Identifier::private("#ModuleType")),
)], )],
); );
} }

View file

@ -365,8 +365,8 @@ impl Identifier {
) )
} }
pub fn private(name: Str) -> Self { pub fn private(name: &'static str) -> Self {
Self::bare(None, VarName::from_str(name)) Self::bare(None, VarName::from_static(name))
} }
pub fn private_with_line(name: Str, line: usize) -> Self { pub fn private_with_line(name: Str, line: usize) -> Self {

View file

@ -0,0 +1,8 @@
def in_operator(x, y):
if type(y) == type:
if isinstance(x, y):
return True
# TODO: trait check
return False
else:
return x in y

View file

@ -13,8 +13,7 @@ fn exec_addition() -> Result<(), ()> {
#[test] #[test]
fn exec_assert_cast() -> Result<(), ()> { fn exec_assert_cast() -> Result<(), ()> {
// runtime `in` is not implemented expect_success("examples/assert_cast.er")
expect_end_with("examples/assert_cast.er", 1)
} }
#[test] #[test]