mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-01 13:11:11 +00:00
Support Python 3.9 as tier-2
This commit is contained in:
parent
bf48ed0cb2
commit
54dbd1ec22
10 changed files with 26 additions and 187 deletions
|
@ -159,7 +159,7 @@
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
A [Python3 (3.7 | 3.8 | 3.10 | 3.11)](https://www.python.org/) interpreter is required. If it is already installed on your machine, no setup is required.
|
A [Python3 (3.7~3.11)](https://www.python.org/) interpreter is required. If it is already installed on your machine, no setup is required.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
[Python3](https://www.python.org/)インタープリタがインストールされている必要があります。すでにインストールされているならセットアップは不要です。
|
[Python3 (3.7~3.11)](https://www.python.org/)インタープリタがインストールされている必要があります。すでにインストールされているならセットアップは不要です。
|
||||||
|
|
||||||
## インストール
|
## インストール
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@
|
||||||
|
|
||||||
## 要求
|
## 要求
|
||||||
|
|
||||||
[Python3](https://www.python.org/) 解释器是必需的。如果计算机上已安装它,则无需进行任何设置
|
[Python3 (3.7~3.11)](https://www.python.org/) 解释器是必需的。如果计算机上已安装它,则无需进行任何设置
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@
|
||||||
|
|
||||||
## 要求
|
## 要求
|
||||||
|
|
||||||
[Python3 (3.10.x)](https://www.python.org/) 解釋器是必需的。如果計算機上已安裝它,則無需進行任何設置
|
[Python3 (3.7~3.11)](https://www.python.org/) 解釋器是必需的。如果計算機上已安裝它,則無需進行任何設置
|
||||||
|
|
||||||
## 安裝
|
## 安裝
|
||||||
|
|
||||||
|
|
|
@ -1702,11 +1702,11 @@ impl PyCodeGenerator {
|
||||||
self.write_instr(Opcode310::JUMP_ABSOLUTE);
|
self.write_instr(Opcode310::JUMP_ABSOLUTE);
|
||||||
self.write_arg(idx_for_iter / 2);
|
self.write_arg(idx_for_iter / 2);
|
||||||
}
|
}
|
||||||
Some(8) => {
|
Some(9 | 8 | 7) => {
|
||||||
self.write_instr(Opcode308::JUMP_ABSOLUTE);
|
self.write_instr(Opcode308::JUMP_ABSOLUTE);
|
||||||
self.write_arg(idx_for_iter);
|
self.write_arg(idx_for_iter);
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!("not supported Python version"),
|
||||||
}
|
}
|
||||||
let idx_end = self.lasti();
|
let idx_end = self.lasti();
|
||||||
self.calc_edit_jump(idx_for_iter + 1, idx_end - idx_for_iter - 2);
|
self.calc_edit_jump(idx_for_iter + 1, idx_end - idx_for_iter - 2);
|
||||||
|
@ -2172,8 +2172,8 @@ impl PyCodeGenerator {
|
||||||
"with!" => match self.py_version.minor {
|
"with!" => match self.py_version.minor {
|
||||||
Some(11) => self.emit_with_instr_311(args),
|
Some(11) => self.emit_with_instr_311(args),
|
||||||
Some(10) => self.emit_with_instr_310(args),
|
Some(10) => self.emit_with_instr_310(args),
|
||||||
Some(8) => self.emit_with_instr_308(args),
|
Some(9 | 8 | 7) => self.emit_with_instr_308(args),
|
||||||
_ => todo!(),
|
_ => todo!("not supported Python version"),
|
||||||
},
|
},
|
||||||
// "pyimport" | "py" are here
|
// "pyimport" | "py" are here
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -3005,11 +3005,7 @@ impl PyCodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_in_op(&mut self) {
|
fn load_in_op(&mut self) {
|
||||||
let mod_name = if self.py_version.minor >= Some(10) {
|
let mod_name = Identifier::public("_erg_std_prelude");
|
||||||
Identifier::public("_erg_std_prelude")
|
|
||||||
} else {
|
|
||||||
Identifier::public("_erg_std_prelude_old")
|
|
||||||
};
|
|
||||||
self.emit_global_import_items(
|
self.emit_global_import_items(
|
||||||
mod_name,
|
mod_name,
|
||||||
vec![(
|
vec![(
|
||||||
|
@ -3021,11 +3017,7 @@ impl PyCodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_mutate_op(&mut self) {
|
fn load_mutate_op(&mut self) {
|
||||||
let mod_name = if self.py_version.minor >= Some(10) {
|
let mod_name = Identifier::public("_erg_std_prelude");
|
||||||
Identifier::public("_erg_std_prelude")
|
|
||||||
} else {
|
|
||||||
Identifier::public("_erg_std_prelude_old")
|
|
||||||
};
|
|
||||||
self.emit_global_import_items(
|
self.emit_global_import_items(
|
||||||
mod_name,
|
mod_name,
|
||||||
vec![(
|
vec![(
|
||||||
|
@ -3062,11 +3054,7 @@ impl PyCodeGenerator {
|
||||||
self.emit_call_instr(1, Method);
|
self.emit_call_instr(1, Method);
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
self.emit_pop_top();
|
self.emit_pop_top();
|
||||||
let erg_std_mod = if self.py_version.minor >= Some(10) {
|
let erg_std_mod = Identifier::public("_erg_std_prelude");
|
||||||
Identifier::public("_erg_std_prelude")
|
|
||||||
} else {
|
|
||||||
Identifier::public("_erg_std_prelude_old")
|
|
||||||
};
|
|
||||||
// escaping
|
// escaping
|
||||||
self.emit_global_import_items(
|
self.emit_global_import_items(
|
||||||
erg_std_mod.clone(),
|
erg_std_mod.clone(),
|
||||||
|
|
|
@ -24,7 +24,7 @@ class Nat(Int):
|
||||||
class NatMut(IntMut): # and Nat
|
class NatMut(IntMut): # and Nat
|
||||||
value: Nat
|
value: Nat
|
||||||
|
|
||||||
def __init__(self, n):
|
def __init__(self, n: Nat):
|
||||||
self.value = n
|
self.value = n
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.value.__repr__()
|
return self.value.__repr__()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from _erg_nat import Nat
|
from _erg_nat import Nat
|
||||||
from _erg_str import Str
|
from _erg_str import Str
|
||||||
|
|
||||||
from collections.abc import Iterable, Sequence, Iterator, Container
|
# from collections.abc import Iterable, Sequence, Iterator, Container
|
||||||
|
|
||||||
class Range:
|
class Range:
|
||||||
def __init__(self, start, end):
|
def __init__(self, start, end):
|
||||||
|
@ -15,6 +15,7 @@ class Range:
|
||||||
return res
|
return res
|
||||||
else:
|
else:
|
||||||
raise IndexError("Index out of range")
|
raise IndexError("Index out of range")
|
||||||
|
# TODO: for Str, etc.
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
if self.start in self:
|
if self.start in self:
|
||||||
if self.end in self:
|
if self.end in self:
|
||||||
|
@ -33,9 +34,9 @@ class Range:
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return RangeIterator(rng=self)
|
return RangeIterator(rng=self)
|
||||||
|
|
||||||
Sequence.register(Range)
|
# Sequence.register(Range)
|
||||||
Container.register(Range)
|
# Container.register(Range)
|
||||||
Iterable.register(Range)
|
# Iterable.register(Range)
|
||||||
|
|
||||||
# represents `start<..end`
|
# represents `start<..end`
|
||||||
class LeftOpenRange(Range):
|
class LeftOpenRange(Range):
|
||||||
|
@ -92,4 +93,4 @@ class RangeIterator:
|
||||||
return result
|
return result
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
Iterator.register(RangeIterator)
|
# Iterator.register(RangeIterator)
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
from typing import TypeVar, Union, _SpecialForm, _type_check
|
# from typing import TypeVar, Union, _SpecialForm, _type_check
|
||||||
|
|
||||||
class Error:
|
class Error:
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
||||||
T = TypeVar("T")
|
# T = TypeVar("T")
|
||||||
@_SpecialForm
|
# @_SpecialForm
|
||||||
def Result(self, parameters):
|
def Result(self, parameters):
|
||||||
"""Result type.
|
"""Result type.
|
||||||
|
|
||||||
Result[T] is equivalent to Union[T, Error].
|
Result[T] is equivalent to Union[T, Error].
|
||||||
"""
|
"""
|
||||||
arg = _type_check(parameters, f"{self} requires a single type.")
|
# arg = _type_check(parameters, f"{self} requires a single type.")
|
||||||
return Union[arg, Error]
|
return [arg, Error]
|
||||||
|
|
||||||
def is_ok(obj: Result[T]) -> bool:
|
def is_ok(obj) -> bool:
|
||||||
return not isinstance(obj, Error)
|
return not isinstance(obj, Error)
|
||||||
|
|
|
@ -1,152 +0,0 @@
|
||||||
class Error:
|
|
||||||
def __init__(self, message):
|
|
||||||
self.message = message
|
|
||||||
|
|
||||||
def is_ok(obj) -> bool:
|
|
||||||
return not isinstance(obj, Error)
|
|
||||||
|
|
||||||
def in_operator(x, y):
|
|
||||||
if type(y) == type:
|
|
||||||
if isinstance(x, y):
|
|
||||||
return True
|
|
||||||
elif is_ok(y.try_new(x)):
|
|
||||||
return True
|
|
||||||
# TODO: trait check
|
|
||||||
return False
|
|
||||||
elif (type(y) == list or type(y) == set) and type(y[0]) == type:
|
|
||||||
# FIXME:
|
|
||||||
type_check = in_operator(x[0], y[0])
|
|
||||||
len_check = len(x) == len(y)
|
|
||||||
return type_check and len_check
|
|
||||||
elif type(y) == dict and type(next(iter(y.keys()))) == type:
|
|
||||||
# TODO:
|
|
||||||
type_check = True # in_operator(x[next(iter(x.keys()))], next(iter(y.keys())))
|
|
||||||
len_check = len(x) >= len(y)
|
|
||||||
return type_check and len_check
|
|
||||||
else:
|
|
||||||
return x in y
|
|
||||||
|
|
||||||
class Nat(int):
|
|
||||||
def try_new(i: int): # -> Result[Nat]
|
|
||||||
if i >= 0:
|
|
||||||
return Nat(i)
|
|
||||||
else:
|
|
||||||
return Error("Nat can't be negative")
|
|
||||||
|
|
||||||
def times(self, f):
|
|
||||||
for _ in range(self):
|
|
||||||
f()
|
|
||||||
|
|
||||||
class Bool(Nat):
|
|
||||||
def try_new(b: bool): # -> Result[Nat]
|
|
||||||
if b == True or b == False:
|
|
||||||
return Bool(b)
|
|
||||||
else:
|
|
||||||
return Error("Bool can't be other than True or False")
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
if self:
|
|
||||||
return "True"
|
|
||||||
else:
|
|
||||||
return "False"
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return self.__str__()
|
|
||||||
|
|
||||||
class Str(str):
|
|
||||||
def __instancecheck__(cls, obj):
|
|
||||||
return obj == Str or obj == str
|
|
||||||
|
|
||||||
def try_new(s: str): # -> Result[Nat]
|
|
||||||
if isinstance(s, str):
|
|
||||||
return Str(s)
|
|
||||||
else:
|
|
||||||
return Error("Str can't be other than str")
|
|
||||||
|
|
||||||
class Range:
|
|
||||||
def __init__(self, start, end):
|
|
||||||
self.start = start
|
|
||||||
self.end = end
|
|
||||||
def __contains__(self, item):
|
|
||||||
pass
|
|
||||||
def __getitem__(self, item):
|
|
||||||
pass
|
|
||||||
def __len__(self):
|
|
||||||
pass
|
|
||||||
def __iter__(self):
|
|
||||||
return RangeIterator(rng=self)
|
|
||||||
|
|
||||||
# represents `start<..end`
|
|
||||||
class LeftOpenRange(Range):
|
|
||||||
def __contains__(self, item):
|
|
||||||
return self.start < item <= self.end
|
|
||||||
def __getitem__(self, item):
|
|
||||||
return NotImplemented
|
|
||||||
def __len__(self):
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
# represents `start..<end`
|
|
||||||
class RightOpenRange(Range):
|
|
||||||
def __contains__(self, item):
|
|
||||||
return self.start <= item < self.end
|
|
||||||
def __getitem__(self, item):
|
|
||||||
return NotImplemented
|
|
||||||
def __len__(self):
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
# represents `start<..<end`
|
|
||||||
class OpenRange(Range):
|
|
||||||
def __contains__(self, item):
|
|
||||||
return self.start < item < self.end
|
|
||||||
def __getitem__(self, item):
|
|
||||||
return NotImplemented
|
|
||||||
def __len__(self):
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
# represents `start..end`
|
|
||||||
class ClosedRange(Range):
|
|
||||||
def __contains__(self, item):
|
|
||||||
return self.start <= item <= self.end
|
|
||||||
def __getitem__(self, item):
|
|
||||||
return NotImplemented
|
|
||||||
def __len__(self):
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
class RangeIterator:
|
|
||||||
def __init__(self, rng):
|
|
||||||
self.rng = rng
|
|
||||||
self.needle = self.rng.start
|
|
||||||
if type(self.rng.start) == int:
|
|
||||||
if not(self.needle in self.rng):
|
|
||||||
self.needle += 1
|
|
||||||
elif type(self.rng.start) == str:
|
|
||||||
if not(self.needle in self.rng):
|
|
||||||
self.needle = chr(ord(self.needle) + 1)
|
|
||||||
else:
|
|
||||||
if not(self.needle in self.rng):
|
|
||||||
self.needle = self.needle.incremented()
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
if type(self.rng.start) == int:
|
|
||||||
if self.needle in self.rng:
|
|
||||||
result = self.needle
|
|
||||||
self.needle += 1
|
|
||||||
return result
|
|
||||||
elif type(self.rng.start) == str:
|
|
||||||
if self.needle in self.rng:
|
|
||||||
result = self.needle
|
|
||||||
self.needle = chr(ord(self.needle) + 1)
|
|
||||||
return result
|
|
||||||
else:
|
|
||||||
if self.needle in self.rng:
|
|
||||||
result = self.needle
|
|
||||||
self.needle = self.needle.incremented()
|
|
||||||
return result
|
|
||||||
raise StopIteration
|
|
||||||
|
|
||||||
class Array(list):
|
|
||||||
def push(self, value):
|
|
||||||
self.append(value)
|
|
||||||
return self
|
|
|
@ -72,6 +72,8 @@ fn _exec_vm(file_path: &'static str) -> Result<i32, CompileErrors> {
|
||||||
};
|
};
|
||||||
// cfg.target_version = Some(PythonVersion::new(3, Some(8), Some(10))); // your Python's version
|
// cfg.target_version = Some(PythonVersion::new(3, Some(8), Some(10))); // your Python's version
|
||||||
// cfg.py_magic_num = Some(3413); // in (most) 3.8.x
|
// cfg.py_magic_num = Some(3413); // in (most) 3.8.x
|
||||||
|
// cfg.target_version = Some(PythonVersion::new(3, Some(9), Some(0)));
|
||||||
|
// cfg.py_magic_num = Some(3425); // in (most) 3.9.x
|
||||||
// cfg.target_version = Some(PythonVersion::new(3, Some(10), Some(6)));
|
// cfg.target_version = Some(PythonVersion::new(3, Some(10), Some(6)));
|
||||||
// cfg.py_magic_num = Some(3439); // in (most) 3.10.x
|
// cfg.py_magic_num = Some(3439); // in (most) 3.10.x
|
||||||
cfg.target_version = Some(PythonVersion::new(3, Some(11), Some(0)));
|
cfg.target_version = Some(PythonVersion::new(3, Some(11), Some(0)));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue