mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Add std
This commit is contained in:
parent
0ac63d8362
commit
b997c685dd
9 changed files with 113 additions and 25 deletions
|
@ -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 = [
|
||||
|
|
|
@ -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.
|
||||
|
|
33
compiler/erg_compiler/build.rs
Normal file
33
compiler/erg_compiler/build.rs
Normal 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(())
|
||||
}
|
|
@ -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")),
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
8
compiler/erg_compiler/std/prelude.py
Normal file
8
compiler/erg_compiler/std/prelude.py
Normal 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
|
|
@ -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]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue