Support Python 3.9 as tier-2

This commit is contained in:
Shunsuke Shibayama 2022-12-28 20:38:04 +09:00
parent bf48ed0cb2
commit 54dbd1ec22
10 changed files with 26 additions and 187 deletions

View file

@ -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

View file

@ -159,7 +159,7 @@
## Requirements ## Requirements
[Python3](https://www.python.org/)インタープリタがインストールされている必要があります。すでにインストールされているならセットアップは不要です。 [Python3 (3.7~3.11)](https://www.python.org/)インタープリタがインストールされている必要があります。すでにインストールされているならセットアップは不要です。
## インストール ## インストール

View file

@ -159,7 +159,7 @@
## 要求 ## 要求
[Python3](https://www.python.org/) 解释器是必需的。如果计算机上已安装它,则无需进行任何设置 [Python3 (3.7~3.11)](https://www.python.org/) 解释器是必需的。如果计算机上已安装它,则无需进行任何设置
## 安装 ## 安装

View file

@ -159,7 +159,7 @@
## 要求 ## 要求
[Python3 (3.10.x)](https://www.python.org/) 解釋器是必需的。如果計算機上已安裝它,則無需進行任何設置 [Python3 (3.7~3.11)](https://www.python.org/) 解釋器是必需的。如果計算機上已安裝它,則無需進行任何設置
## 安裝 ## 安裝

View file

@ -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(),

View file

@ -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__()

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)));