mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-02 21:44:34 +00:00
Fix builtin types methods
This commit is contained in:
parent
c56ef64576
commit
8cdc735486
12 changed files with 180 additions and 7 deletions
|
@ -475,6 +475,7 @@ impl PyCodeGenerator {
|
||||||
fn emit_load_const<C: Into<ValueObj>>(&mut self, cons: C) {
|
fn emit_load_const<C: Into<ValueObj>>(&mut self, cons: C) {
|
||||||
let value: ValueObj = cons.into();
|
let value: ValueObj = cons.into();
|
||||||
let is_str = value.is_str();
|
let is_str = value.is_str();
|
||||||
|
let is_float = value.is_float();
|
||||||
let is_int = value.is_int();
|
let is_int = value.is_int();
|
||||||
let is_nat = value.is_nat();
|
let is_nat = value.is_nat();
|
||||||
let is_bool = value.is_bool();
|
let is_bool = value.is_bool();
|
||||||
|
@ -488,12 +489,15 @@ impl PyCodeGenerator {
|
||||||
} else if is_int {
|
} else if is_int {
|
||||||
self.emit_push_null();
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::public("Int"));
|
self.emit_load_name_instr(Identifier::public("Int"));
|
||||||
|
} else if is_float {
|
||||||
|
self.emit_push_null();
|
||||||
|
self.emit_load_name_instr(Identifier::public("Float"));
|
||||||
} else if is_str {
|
} else if is_str {
|
||||||
self.emit_push_null();
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::public("Str"));
|
self.emit_load_name_instr(Identifier::public("Str"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let wrapped = is_str || is_int; // is_int => is_nat and is_bool
|
let wrapped = is_str || is_float; // is_float => is_int && is_nat && is_bool
|
||||||
let idx = self
|
let idx = self
|
||||||
.mut_cur_block_codeobj()
|
.mut_cur_block_codeobj()
|
||||||
.consts
|
.consts
|
||||||
|
@ -678,7 +682,7 @@ impl PyCodeGenerator {
|
||||||
"if__" | "for__" | "while__" | "with__" | "discard__" => {
|
"if__" | "for__" | "while__" | "with__" | "discard__" => {
|
||||||
self.load_control();
|
self.load_control();
|
||||||
}
|
}
|
||||||
"int__" | "nat__" => {
|
"int__" | "nat__" | "str__" | "float__" => {
|
||||||
self.load_convertors();
|
self.load_convertors();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -278,7 +278,7 @@ impl Context {
|
||||||
);
|
);
|
||||||
self.register_builtin_py_impl(FUNC_ROUND, t_round, Immutable, vis, Some(FUNC_ROUND));
|
self.register_builtin_py_impl(FUNC_ROUND, t_round, Immutable, vis, Some(FUNC_ROUND));
|
||||||
self.register_builtin_py_impl(FUNC_SORTED, t_sorted, Immutable, vis, Some(FUNC_SORTED));
|
self.register_builtin_py_impl(FUNC_SORTED, t_sorted, Immutable, vis, Some(FUNC_SORTED));
|
||||||
self.register_builtin_py_impl(FUNC_STR, t_str, Immutable, vis, Some(FUNC_STR));
|
self.register_builtin_py_impl(FUNC_STR, t_str, Immutable, vis, Some(FUNC_STR__));
|
||||||
self.register_builtin_py_impl(FUNC_SUM, t_sum, Immutable, vis, Some(FUNC_SUM));
|
self.register_builtin_py_impl(FUNC_SUM, t_sum, Immutable, vis, Some(FUNC_SUM));
|
||||||
self.register_builtin_py_impl(FUNC_ZIP, t_zip, Immutable, vis, Some(FUNC_ZIP));
|
self.register_builtin_py_impl(FUNC_ZIP, t_zip, Immutable, vis, Some(FUNC_ZIP));
|
||||||
let name = if cfg!(feature = "py_compatible") {
|
let name = if cfg!(feature = "py_compatible") {
|
||||||
|
|
|
@ -225,6 +225,7 @@ const FUNC_INT__: &str = "int__";
|
||||||
const FUNC_FLOAT: &str = "float";
|
const FUNC_FLOAT: &str = "float";
|
||||||
const FUNC_BOOL: &str = "bool";
|
const FUNC_BOOL: &str = "bool";
|
||||||
const FUNC_STR: &str = "str";
|
const FUNC_STR: &str = "str";
|
||||||
|
const FUNC_STR__: &str = "str__";
|
||||||
const FUNC_TYPE: &str = "type";
|
const FUNC_TYPE: &str = "type";
|
||||||
const CODE_TYPE: &str = "CodeType";
|
const CODE_TYPE: &str = "CodeType";
|
||||||
const MODULE_TYPE: &str = "ModuleType";
|
const MODULE_TYPE: &str = "ModuleType";
|
||||||
|
|
|
@ -19,3 +19,9 @@ def with__(obj, body):
|
||||||
|
|
||||||
def discard__(obj):
|
def discard__(obj):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def then__(x, f):
|
||||||
|
if x == None or x == NotImplemented:
|
||||||
|
return x
|
||||||
|
else:
|
||||||
|
return f(x)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
from _erg_int import Int
|
from _erg_int import Int
|
||||||
from _erg_nat import Nat
|
from _erg_nat import Nat
|
||||||
|
from _erg_float import Float
|
||||||
|
from _erg_str import Str
|
||||||
|
|
||||||
def int__(i):
|
def int__(i):
|
||||||
try:
|
try:
|
||||||
|
@ -12,3 +14,15 @@ def nat__(i):
|
||||||
return Nat(i)
|
return Nat(i)
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def float__(f):
|
||||||
|
try:
|
||||||
|
return Float(f)
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def str__(s):
|
||||||
|
try:
|
||||||
|
return Str(s)
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
100
crates/erg_compiler/lib/std/_erg_float.py
Normal file
100
crates/erg_compiler/lib/std/_erg_float.py
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
from _erg_result import Error
|
||||||
|
from _erg_control import then__
|
||||||
|
|
||||||
|
class Float(float):
|
||||||
|
def try_new(i): # -> Result[Nat]
|
||||||
|
if isinstance(i, float):
|
||||||
|
Float(i)
|
||||||
|
else:
|
||||||
|
Error("not a float")
|
||||||
|
def mutate(self):
|
||||||
|
return FloatMut(self)
|
||||||
|
def __add__(self, other):
|
||||||
|
return then__(super().__add__(other), Float)
|
||||||
|
def __radd__(self, other):
|
||||||
|
return then__(super().__radd__(other), Float)
|
||||||
|
def __sub__(self, other):
|
||||||
|
return then__(super().__sub__(other), Float)
|
||||||
|
def __rsub__(self, other):
|
||||||
|
return then__(super().__rsub__(other), Float)
|
||||||
|
def __mul__(self, other):
|
||||||
|
return then__(super().__mul__(other), Float)
|
||||||
|
def __rmul__(self, other):
|
||||||
|
return then__(super().__rmul__(other), Float)
|
||||||
|
def __div__(self, other):
|
||||||
|
return then__(super().__div__(other), Float)
|
||||||
|
def __rdiv__(self, other):
|
||||||
|
return then__(super().__rdiv__(other), Float)
|
||||||
|
def __floordiv__(self, other):
|
||||||
|
return then__(super().__floordiv__(other), Float)
|
||||||
|
def __rfloordiv__(self, other):
|
||||||
|
return then__(super().__rfloordiv__(other), Float)
|
||||||
|
def __pow__(self, other):
|
||||||
|
return then__(super().__pow__(other), Float)
|
||||||
|
def __rpow__(self, other):
|
||||||
|
return then__(super().__rpow__(other), Float)
|
||||||
|
|
||||||
|
class FloatMut(): # inherits Float
|
||||||
|
value: Float
|
||||||
|
|
||||||
|
def __init__(self, i):
|
||||||
|
self.value = Float(i)
|
||||||
|
def __repr__(self):
|
||||||
|
return self.value.__repr__()
|
||||||
|
def __deref__(self):
|
||||||
|
return self.value
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return self.value == other
|
||||||
|
else:
|
||||||
|
return self.value == other.value
|
||||||
|
def __ne__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return self.value != other
|
||||||
|
else:
|
||||||
|
return self.value != other.value
|
||||||
|
def __le__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return self.value <= other
|
||||||
|
else:
|
||||||
|
return self.value <= other.value
|
||||||
|
def __ge__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return self.value >= other
|
||||||
|
else:
|
||||||
|
return self.value >= other.value
|
||||||
|
def __lt__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return self.value < other
|
||||||
|
else:
|
||||||
|
return self.value < other.value
|
||||||
|
def __gt__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return self.value > other
|
||||||
|
else:
|
||||||
|
return self.value > other.value
|
||||||
|
def __add__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return FloatMut(self.value + other)
|
||||||
|
else:
|
||||||
|
return FloatMut(self.value + other.value)
|
||||||
|
def __sub__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return FloatMut(self.value - other)
|
||||||
|
else:
|
||||||
|
return FloatMut(self.value - other.value)
|
||||||
|
def __mul__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return FloatMut(self.value * other)
|
||||||
|
else:
|
||||||
|
return FloatMut(self.value * other.value)
|
||||||
|
def __floordiv__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return FloatMut(self.value // other)
|
||||||
|
else:
|
||||||
|
return FloatMut(self.value // other.value)
|
||||||
|
def __pow__(self, other):
|
||||||
|
if isinstance(other, Float):
|
||||||
|
return FloatMut(self.value ** other)
|
||||||
|
else:
|
||||||
|
return FloatMut(self.value ** other.value)
|
|
@ -1,4 +1,5 @@
|
||||||
from _erg_result import Error
|
from _erg_result import Error
|
||||||
|
from _erg_control import then__
|
||||||
|
|
||||||
class Int(int):
|
class Int(int):
|
||||||
def try_new(i): # -> Result[Nat]
|
def try_new(i): # -> Result[Nat]
|
||||||
|
@ -12,6 +13,30 @@ class Int(int):
|
||||||
return Int(self - 1)
|
return Int(self - 1)
|
||||||
def mutate(self):
|
def mutate(self):
|
||||||
return IntMut(self)
|
return IntMut(self)
|
||||||
|
def __add__(self, other):
|
||||||
|
return then__(super().__add__(other), Int)
|
||||||
|
def __radd__(self, other):
|
||||||
|
return then__(super().__radd__(other), Int)
|
||||||
|
def __sub__(self, other):
|
||||||
|
return then__(super().__sub__(other), Int)
|
||||||
|
def __rsub__(self, other):
|
||||||
|
return then__(super().__rsub__(other), Int)
|
||||||
|
def __mul__(self, other):
|
||||||
|
return then__(super().__mul__(other), Int)
|
||||||
|
def __rmul__(self, other):
|
||||||
|
return then__(super().__rmul__(other), Int)
|
||||||
|
def __div__(self, other):
|
||||||
|
return then__(super().__div__(other), Int)
|
||||||
|
def __rdiv__(self, other):
|
||||||
|
return then__(super().__rdiv__(other), Int)
|
||||||
|
def __floordiv__(self, other):
|
||||||
|
return then__(super().__floordiv__(other), Int)
|
||||||
|
def __rfloordiv__(self, other):
|
||||||
|
return then__(super().__rfloordiv__(other), Int)
|
||||||
|
def __pow__(self, other):
|
||||||
|
return then__(super().__pow__(other), Int)
|
||||||
|
def __rpow__(self, other):
|
||||||
|
return then__(super().__rpow__(other), Int)
|
||||||
|
|
||||||
class IntMut(): # inherits Int
|
class IntMut(): # inherits Int
|
||||||
value: Int
|
value: Int
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from _erg_result import Error
|
from _erg_result import Error
|
||||||
from _erg_int import Int
|
from _erg_int import Int, IntMut
|
||||||
from _erg_int import IntMut
|
from _erg_control import then__
|
||||||
|
|
||||||
class Nat(Int):
|
class Nat(Int):
|
||||||
def try_new(i): # -> Result[Nat]
|
def try_new(i): # -> Result[Nat]
|
||||||
|
@ -20,6 +20,10 @@ class Nat(Int):
|
||||||
return 0
|
return 0
|
||||||
def mutate(self):
|
def mutate(self):
|
||||||
return NatMut(self)
|
return NatMut(self)
|
||||||
|
def __add__(self, other):
|
||||||
|
return then__(super().__add__(other), Nat)
|
||||||
|
def __mul__(self, other):
|
||||||
|
return then__(super().__mul__(other), Nat)
|
||||||
|
|
||||||
class NatMut(IntMut): # and Nat
|
class NatMut(IntMut): # and Nat
|
||||||
value: Nat
|
value: Nat
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from _erg_range import Range, LeftOpenRange, RightOpenRange, OpenRange, ClosedRange, RangeIterator
|
from _erg_range import Range, LeftOpenRange, RightOpenRange, OpenRange, ClosedRange, RangeIterator
|
||||||
from _erg_result import Result, Error, is_ok
|
from _erg_result import Result, Error, is_ok
|
||||||
|
from _erg_float import Float, FloatMut
|
||||||
from _erg_int import Int, IntMut
|
from _erg_int import Int, IntMut
|
||||||
from _erg_nat import Nat, NatMut
|
from _erg_nat import Nat, NatMut
|
||||||
from _erg_bool import Bool
|
from _erg_bool import Bool
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from _erg_result import Error
|
from _erg_result import Error
|
||||||
from _erg_int import Int
|
from _erg_int import Int
|
||||||
|
from _erg_control import then__
|
||||||
|
|
||||||
class Str(str):
|
class Str(str):
|
||||||
def __instancecheck__(cls, obj):
|
def __instancecheck__(cls, obj):
|
||||||
|
@ -18,6 +19,14 @@ class Str(str):
|
||||||
return StrMut(self)
|
return StrMut(self)
|
||||||
def to_int(self):
|
def to_int(self):
|
||||||
return Int(self) if self.isdigit() else None
|
return Int(self) if self.isdigit() else None
|
||||||
|
def __add__(self, other):
|
||||||
|
return then__(super().__add__(other), Str)
|
||||||
|
def __radd__(self, other):
|
||||||
|
return then__(super().__radd__(other), Str)
|
||||||
|
def __mul__(self, other):
|
||||||
|
return then__(super().__mul__(other), Str)
|
||||||
|
def __mod__(self, other):
|
||||||
|
return then__(super().__mod__(other), Str)
|
||||||
|
|
||||||
class StrMut(): # Inherits Str
|
class StrMut(): # Inherits Str
|
||||||
value: Str
|
value: Str
|
||||||
|
|
|
@ -701,14 +701,23 @@ impl ValueObj {
|
||||||
ValueObj::Type(TypeObj::Generated(gen))
|
ValueObj::Type(TypeObj::Generated(gen))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add Complex
|
||||||
pub fn is_num(&self) -> bool {
|
pub fn is_num(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Int(_) | Self::Nat(_) | Self::Float(_) | Self::Bool(_) => true,
|
Self::Float(_) | Self::Int(_) | Self::Nat(_) | Self::Bool(_) => true,
|
||||||
Self::Mut(n) => n.borrow().is_num(),
|
Self::Mut(n) => n.borrow().is_num(),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_float(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Float(_) | Self::Int(_) | Self::Nat(_) | Self::Bool(_) => true,
|
||||||
|
Self::Mut(n) => n.borrow().is_float(),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_int(&self) -> bool {
|
pub fn is_int(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Int(_) | Self::Nat(_) | Self::Bool(_) => true,
|
Self::Int(_) | Self::Nat(_) | Self::Bool(_) => true,
|
||||||
|
|
|
@ -27,7 +27,7 @@ D""""#
|
||||||
);
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
let output = eval("print 1");
|
let output = eval("print 1"); // print! is correct
|
||||||
assert_eq!(output.stdout, "");
|
assert_eq!(output.stdout, "");
|
||||||
assert!(!output.stderr.is_empty());
|
assert!(!output.stderr.is_empty());
|
||||||
assert_eq!(output.status_code, Some(1));
|
assert_eq!(output.status_code, Some(1));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue