diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index ef63c8b0..186a6138 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -301,6 +301,7 @@ fn convert_to_python_name(name: Str) -> Str { } } +/// This method obviously does not scale, so in the future all Python APIs will be replaced by declarations in d.er, and renaming will be done in `HIRDesugarer`. fn escape_name(ident: Identifier) -> Str { let vis = ident.vis(); let mut name = convert_to_python_name(ident.name.into_token().content).to_string(); diff --git a/compiler/erg_compiler/lib/std/_erg_std_prelude.d.er b/compiler/erg_compiler/lib/std/_erg_std_prelude.d.er new file mode 100644 index 00000000..e69de29b diff --git a/compiler/erg_compiler/lib/std/_prelude.er b/compiler/erg_compiler/lib/std/_prelude.er index 0f8386ee..a64816b3 100644 --- a/compiler/erg_compiler/lib/std/_prelude.er +++ b/compiler/erg_compiler/lib/std/_prelude.er @@ -13,8 +13,8 @@ PartialOrd(R := Self) = Trait { } Ord = Subsume PartialOrd() -EqForOrd R = Patch Ord, Impl := Eq() -EqForOrd(R). +EqForOrd R = Patch Ord +EqForOrd(R)|<: Eq()|. `==`(self, other: R): Bool = self.cmp(other) == Ordering.Equal LeForOrd = Patch Ord @@ -36,9 +36,9 @@ Add(R := Self) = Trait { } Sub(R := Self) = Trait { .Output = Type - .`_-_` = (self: Self, R) -> Self.Output + .`-` = (self: Self, R) -> Self.Output } -Mul(R := Self()) = Trait { +Mul(R := Self) = Trait { .Output = Type .`*` = (self: Self, R) -> Self.Output } @@ -46,7 +46,6 @@ Div(R := Self) = Trait { .Output = Type .`/` = (self: Self, R) -> Self.Output or Panic } -Num: (R := Type) -> Type Num = Add and Sub and Mul Seq T = Trait { @@ -54,29 +53,40 @@ Seq T = Trait { .get = (self: Ref(Self), Nat) -> T } -`_+_`: |R: Type, A <: Add(R)| (A, R) -> A.AddO -`_-_`: |R: Type, S <: Add(R)| (S, R) -> S.SubO -`*`: |R, O: Type, M <: Add(R)| (M, R) -> M.MulO -`/`: |R, O: Type, D <: Add(R)| (D, R) -> D.DivO - -AddForInt = Patch Int, Impl := Add() -AddForInt.AddO = Int -AddForInt. - `_+_`: (self: Self, other: Int) -> Int = magic("Add.`_+_`") +AddForInt = Patch Int +AddForInt|<: Add(Int)|. + AddO = Int + `_+_`(self: Self, other: Int): Int = magic("Add.`_+_`") # TODO: Mul and Div -NumForInterval M, N, O, P: Int = - Patch M..N, Impl := Add(R := O..P) and Sub(R := O..P) -NumForInterval(M, N, O, P). - `_+_`: (self: Self, other: O..P) -> M+O..N+P = magic("NumForInterval.`_+_`") - `_-_`: (self: Self, other: O..P) -> M-P..N-O = magic("NumForInterval.`_-_`") +NumForInterval M, N, O, P: Int = Patch M..N +NumForInterval(M, N, O, P)|<: Add(O..P)|. + Output = M+O..N+P + __add__(self: Self, other: O..P) = magic("NumForInterval.`_+_`") +NumForInterval(M, N, O, P)|<: Sub(O..P)|. + Output = M-P..N-O + __sub__(self: Self, other: O..P) = magic("NumForInterval.`_-_`") Read = Trait { - .read = (self: Ref(Self)) -> Str + .read = (self: Ref(Self),) -> Str } Read! = Trait { - .read! = (self: Ref!(Self)) => Str + .read! = (self: Ref!(Self),) => Str } Write! = Trait { .write! = (self: Ref!(Self), Str) => () } + +discard _x = None + +discard 1 + +# if: |T, U|(Bool, T, U) -> T or U +cond|T: Type|(c: Bool, then: T, else: T): T = + if c: + do then + do else + +assert cond(False, 1, 2) == 2 +# assert cond(True, 1, 3) == "a" +# assert "a" == cond(True, 1, 3) diff --git a/compiler/erg_compiler/lib/std/prelude.er b/compiler/erg_compiler/lib/std/prelude.er deleted file mode 100644 index 5f01c9ea..00000000 --- a/compiler/erg_compiler/lib/std/prelude.er +++ /dev/null @@ -1,13 +0,0 @@ -discard _x = None - -discard 1 - -# if: |T, U|(Bool, T, U) -> T or U -cond|T: Type|(c: Bool, then: T, else: T): T = - if c: - do then - do else - -assert cond(False, 1, 2) == 2 -# assert cond(True, 1, 3) == "a" -# assert "a" == cond(True, 1, 3) diff --git a/compiler/erg_parser/lex.rs b/compiler/erg_parser/lex.rs index e487b7c1..fb989393 100644 --- a/compiler/erg_parser/lex.rs +++ b/compiler/erg_parser/lex.rs @@ -186,7 +186,8 @@ impl Lexer /*<'a>*/ { fn is_definable_operator(s: &str) -> bool { matches!( s, - "+" | "-" + "+_" | "_+_" + | "-" | "*" | "/" | "//" @@ -1127,6 +1128,18 @@ impl Iterator for Lexer /*<'a>*/ { return self.accept(Symbol, &op); } else { let token = self.emit_token(Illegal, &op); + let hint = if op.contains('+') { + Some( + switch_lang!( + "japanese" => "二項演算子の+は`_+_`、単項演算子の+は`+_`です", + "simplified_chinese" => "二元运算符+是`_+_`,一元运算符+是`+_`", + "traditional_chinese" => "二元運算符+是`_+_`,一元運算符+是`+_`", + "english" => "the binary operator + is `_+_`, the unary operator + is `+_`", + ).into(), + ) + } else { + None + }; return Some(Err(LexError::syntax_error( 0, token.loc(), @@ -1136,7 +1149,7 @@ impl Iterator for Lexer /*<'a>*/ { "traditional_chinese" => format!("`{}`不能由用戶定義", &token.content), "english" => format!("`{}` cannot be defined by user", &token.content), ), - None, + hint, ))); } } diff --git a/tests/test.rs b/tests/test.rs index 3a8031cd..4254e143 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -66,11 +66,6 @@ fn exec_move_check() -> Result<(), ()> { expect_failure("examples/move_check.er") } -#[test] -fn exec_prelude() -> Result<(), ()> { - expect_success("compiler/erg_compiler/lib/std/prelude.er") -} - #[test] fn exec_pyimport() -> Result<(), ()> { expect_end_with("examples/pyimport.er", 111)