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",
]
[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]
# when "debug" feature is turned on, that of the following crates will also be turned on.
debug = [

View file

@ -1,13 +1,14 @@
[package]
name = "erg_compiler"
version = "0.5.8"
description = "Centimetre: the Erg compiler"
authors = ["erg-lang team <moderation.erglang@gmail.com>"]
license = "MIT OR Apache-2.0"
edition = "2021"
repository = "https://github.com/erg-lang/erg/tree/main/src/compiler/erg_compiler"
documentation = "https://docs.rs/erg_compiler"
homepage = "https://erg-lang.github.io/"
build = "build.rs"
version.workspace = true
authors.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
documentation.workspace = true
homepage.workspace = true
[features]
# 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_arg(0);
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")]);
let subclasses_len = 1;
self.write_instr(Opcode::CALL_FUNCTION_KW);
@ -917,7 +917,7 @@ impl CodeGenerator {
self.emit_empty_func(
Some(sig.ident().inspect()),
def.sig.into_ident(),
Some(Identifier::private(Str::ever("#abstractmethod"))),
Some(Identifier::private("#abstractmethod")),
);
}
self.emit_load_const(ValueObj::None);
@ -1150,6 +1150,9 @@ impl CodeGenerator {
self.emit_load_name_instr(Identifier::public("range"));
}
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());
@ -1170,9 +1173,11 @@ impl CodeGenerator {
| TokenKind::NotEq
| TokenKind::Gre
| TokenKind::GreEq => COMPARE_OP,
TokenKind::LeftOpen | TokenKind::RightOpen | TokenKind::Closed | TokenKind::Open => {
CALL_FUNCTION
} // ERG_BINARY_RANGE,
TokenKind::LeftOpen
| TokenKind::RightOpen
| TokenKind::Closed
| TokenKind::Open
| TokenKind::InOp => CALL_FUNCTION, // ERG_BINARY_RANGE,
_ => {
CompileError::feature_error(
self.cfg.input.clone(),
@ -1191,14 +1196,22 @@ impl CodeGenerator {
TokenKind::NotEq => 3,
TokenKind::Gre => 4,
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,
};
self.write_instr(instr);
self.write_arg(arg);
self.stack_dec();
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();
}
_ => {}
@ -1597,7 +1610,7 @@ impl CodeGenerator {
log!(info "entered {} ({rec})", fn_name!());
let attrs_len = rec.attrs.len();
// making record type
let ident = Identifier::private(Str::ever("#NamedTuple"));
let ident = Identifier::private("#NamedTuple");
self.emit_load_name_instr(ident);
// record name, let it be anonymous
self.emit_load_const("Record");
@ -1615,10 +1628,10 @@ impl CodeGenerator {
self.write_arg(2);
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object
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);
// making record instance
let ident = Identifier::private(Str::ever("#rec"));
let ident = Identifier::private("#rec");
self.emit_load_name_instr(ident);
for field in rec.attrs.into_iter() {
self.emit_frameless_block(field.body.block, vec![]);
@ -2007,15 +2020,40 @@ impl CodeGenerator {
fn load_prelude(&mut self) {
self.load_record_type();
self.load_prelude_py();
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) {
self.emit_global_import_items(
Identifier::public("collections"),
vec![(
Identifier::public("namedtuple"),
Some(Identifier::private(Str::ever("#NamedTuple"))),
Some(Identifier::private("#NamedTuple")),
)],
);
}
@ -2026,11 +2064,11 @@ impl CodeGenerator {
vec![
(
Identifier::public("ABCMeta"),
Some(Identifier::private(Str::ever("#ABCMeta"))),
Some(Identifier::private("#ABCMeta")),
),
(
Identifier::public("abstractmethod"),
Some(Identifier::private(Str::ever("#abstractmethod"))),
Some(Identifier::private("#abstractmethod")),
),
],
);
@ -2041,7 +2079,7 @@ impl CodeGenerator {
Identifier::public("types"),
vec![(
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 {
Self::bare(None, VarName::from_str(name))
pub fn private(name: &'static str) -> Self {
Self::bare(None, VarName::from_static(name))
}
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]
fn exec_assert_cast() -> Result<(), ()> {
// runtime `in` is not implemented
expect_end_with("examples/assert_cast.er", 1)
expect_success("examples/assert_cast.er")
}
#[test]