mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 04:44:44 +00:00
Merge branch 'main' of https://github.com/GreasySlug/erg into split-err-msg
This commit is contained in:
commit
ff24c62de1
31 changed files with 878 additions and 412 deletions
|
@ -9,6 +9,10 @@
|
||||||
<p align='center'>
|
<p align='center'>
|
||||||
<a href="https://github.com/erg-lang/erg/releases"><img alt="Build status" src="https://img.shields.io/github/v/release/erg-lang/erg.svg"></a>
|
<a href="https://github.com/erg-lang/erg/releases"><img alt="Build status" src="https://img.shields.io/github/v/release/erg-lang/erg.svg"></a>
|
||||||
<a href="https://github.com/erg-lang/erg/actions/workflows/rust.yml"><img alt="Build status" src="https://github.com/erg-lang/erg/actions/workflows/rust.yml/badge.svg"></a>
|
<a href="https://github.com/erg-lang/erg/actions/workflows/rust.yml"><img alt="Build status" src="https://github.com/erg-lang/erg/actions/workflows/rust.yml/badge.svg"></a>
|
||||||
|
<br>
|
||||||
|
<a href="https://erg-lang.org/erg-playground" data-size="large">
|
||||||
|
<img src="https://img.shields.io/static/v1?style=for-the-badge&label=&message=playground&color=green">
|
||||||
|
</a>
|
||||||
<br>
|
<br>
|
||||||
<a href='./README_JA.md'>日本語</a> | <a href='./README_zh-CN.md'>简体中文</a> | <a href='./README_zh-TW.md'>繁體中文</a>
|
<a href='./README_JA.md'>日本語</a> | <a href='./README_zh-CN.md'>简体中文</a> | <a href='./README_zh-TW.md'>繁體中文</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
<a href="https://github.com/erg-lang/erg/releases"><img alt="Build status" src="https://img.shields.io/github/v/release/erg-lang/erg.svg"></a>
|
<a href="https://github.com/erg-lang/erg/releases"><img alt="Build status" src="https://img.shields.io/github/v/release/erg-lang/erg.svg"></a>
|
||||||
<a href="https://github.com/erg-lang/erg/actions/workflows/rust.yml"><img alt="Build status" src="https://github.com/erg-lang/erg/actions/workflows/rust.yml/badge.svg"></a>
|
<a href="https://github.com/erg-lang/erg/actions/workflows/rust.yml"><img alt="Build status" src="https://github.com/erg-lang/erg/actions/workflows/rust.yml/badge.svg"></a>
|
||||||
<br>
|
<br>
|
||||||
|
<a href="https://erg-lang.org/erg-playground" data-size="large">
|
||||||
|
<img src="https://img.shields.io/static/v1?style=for-the-badge&label=&message=playground&color=green">
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
<a href="https://github.com/erg-lang/erg/releases"><img alt="Build status" src="https://img.shields.io/github/v/release/erg-lang/erg.svg"></a>
|
<a href="https://github.com/erg-lang/erg/releases"><img alt="Build status" src="https://img.shields.io/github/v/release/erg-lang/erg.svg"></a>
|
||||||
<a href="https://github.com/erg-lang/erg/actions/workflows/rust.yml"><img alt="Build status" src="https://github.com/erg-lang/erg/actions/workflows/rust.yml/badge.svg"></a>
|
<a href="https://github.com/erg-lang/erg/actions/workflows/rust.yml"><img alt="Build status" src="https://github.com/erg-lang/erg/actions/workflows/rust.yml/badge.svg"></a>
|
||||||
<br>
|
<br>
|
||||||
|
<a href="https://erg-lang.org/erg-playground" data-size="large">
|
||||||
|
<img src="https://img.shields.io/static/v1?style=for-the-badge&label=&message=playground&color=green">
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
<a href="https://github.com/erg-lang/erg/releases"><img alt="Build status" src="https://img.shields.io/github/v/release/erg-lang/erg.svg"></a>
|
<a href="https://github.com/erg-lang/erg/releases"><img alt="Build status" src="https://img.shields.io/github/v/release/erg-lang/erg.svg"></a>
|
||||||
<a href="https://github.com/erg-lang/erg/actions/workflows/rust.yml"><img alt="Build status" src="https://github.com/erg-lang/erg/actions/workflows/rust.yml/badge.svg"></a>
|
<a href="https://github.com/erg-lang/erg/actions/workflows/rust.yml"><img alt="Build status" src="https://github.com/erg-lang/erg/actions/workflows/rust.yml/badge.svg"></a>
|
||||||
<br>
|
<br>
|
||||||
|
<a href="https://erg-lang.org/erg-playground" data-size="large">
|
||||||
|
<img src="https://img.shields.io/static/v1?style=for-the-badge&label=&message=playground&color=green">
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,181 +0,0 @@
|
||||||
use std::borrow::Borrow;
|
|
||||||
use std::fmt;
|
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::ops::{Add, Deref};
|
|
||||||
|
|
||||||
use crate::style::{StyledString, StyledStrings};
|
|
||||||
use crate::Str;
|
|
||||||
|
|
||||||
pub type ArcStr = std::sync::Arc<str>;
|
|
||||||
|
|
||||||
/// Used to hold an immutable string.
|
|
||||||
///
|
|
||||||
/// It can construct as a const (by AtomicStr::ever).
|
|
||||||
#[derive(Debug, Clone, Eq)]
|
|
||||||
pub enum AtomicStr {
|
|
||||||
Arc(ArcStr),
|
|
||||||
Static(&'static str),
|
|
||||||
}
|
|
||||||
|
|
||||||
// unsafe impl Sync for AtomicStr {}
|
|
||||||
|
|
||||||
impl PartialEq for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &AtomicStr) -> bool {
|
|
||||||
self[..] == other[..]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Add<&str> for AtomicStr {
|
|
||||||
type Output = AtomicStr;
|
|
||||||
#[inline]
|
|
||||||
fn add(self, other: &str) -> AtomicStr {
|
|
||||||
AtomicStr::from(&format!("{self}{other}"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hash for AtomicStr {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
match self {
|
|
||||||
AtomicStr::Arc(s) => s[..].hash(state),
|
|
||||||
AtomicStr::Static(s) => (*s).hash(state),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for AtomicStr {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
AtomicStr::Arc(s) => write!(f, "{s}"),
|
|
||||||
AtomicStr::Static(s) => write!(f, "{s}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// &'static str -> &strになってしまわないように
|
|
||||||
// あえて`impl<S: Into<Str>> From<S> for AtomicStr { ... }`はしない
|
|
||||||
impl From<&'static str> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: &'static str) -> Self {
|
|
||||||
AtomicStr::ever(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&String> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: &String) -> Self {
|
|
||||||
AtomicStr::Arc((s[..]).into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: String) -> Self {
|
|
||||||
AtomicStr::Arc((s[..]).into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&ArcStr> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: &ArcStr) -> Self {
|
|
||||||
AtomicStr::Arc(s.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ArcStr> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: ArcStr) -> Self {
|
|
||||||
AtomicStr::Arc(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&AtomicStr> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: &AtomicStr) -> Self {
|
|
||||||
match s {
|
|
||||||
AtomicStr::Arc(s) => AtomicStr::Arc(s.clone()),
|
|
||||||
AtomicStr::Static(s) => AtomicStr::Static(s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Str> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: Str) -> Self {
|
|
||||||
match s {
|
|
||||||
Str::Rc(s) => AtomicStr::Arc((&s[..]).into()),
|
|
||||||
Str::Static(s) => AtomicStr::Static(s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Str> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: &Str) -> Self {
|
|
||||||
match s {
|
|
||||||
Str::Rc(s) => AtomicStr::Arc((&s[..]).into()),
|
|
||||||
Str::Static(s) => AtomicStr::Static(s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<StyledString> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: StyledString) -> Self {
|
|
||||||
AtomicStr::Arc(s.to_string().into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<StyledStrings> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn from(s: StyledStrings) -> Self {
|
|
||||||
AtomicStr::Arc(s.to_string().into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for AtomicStr {
|
|
||||||
type Target = str;
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self.borrow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Borrow<str> for AtomicStr {
|
|
||||||
#[inline]
|
|
||||||
fn borrow(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
AtomicStr::Arc(s) => s.borrow(),
|
|
||||||
AtomicStr::Static(s) => s,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<str> for AtomicStr {
|
|
||||||
fn as_ref(&self) -> &str {
|
|
||||||
self.borrow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AtomicStr {
|
|
||||||
pub const fn ever(s: &'static str) -> Self {
|
|
||||||
AtomicStr::Static(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn arc(s: &str) -> Self {
|
|
||||||
AtomicStr::Arc(s.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_rc(self) -> ArcStr {
|
|
||||||
match self {
|
|
||||||
AtomicStr::Arc(s) => s,
|
|
||||||
AtomicStr::Static(s) => ArcStr::from(s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_uppercase(&self) -> bool {
|
|
||||||
self.chars()
|
|
||||||
.next()
|
|
||||||
.map(|c| c.is_uppercase())
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{stderr, BufWriter, Write as _};
|
use std::io::{stderr, BufWriter, Write as _};
|
||||||
|
|
||||||
use crate::astr::AtomicStr;
|
|
||||||
use crate::config::Input;
|
use crate::config::Input;
|
||||||
use crate::style::Attribute;
|
use crate::style::Attribute;
|
||||||
use crate::style::Characters;
|
use crate::style::Characters;
|
||||||
|
@ -25,95 +24,95 @@ use crate::{impl_display_from_debug, switch_lang};
|
||||||
pub enum ErrorKind {
|
pub enum ErrorKind {
|
||||||
/* compile errors */
|
/* compile errors */
|
||||||
AssignError = 0,
|
AssignError = 0,
|
||||||
AttributeError,
|
AttributeError = 1,
|
||||||
BytecodeError,
|
BytecodeError = 2,
|
||||||
CompilerSystemError,
|
CompilerSystemError = 3,
|
||||||
EnvironmentError,
|
EnvironmentError = 4,
|
||||||
FeatureError,
|
FeatureError = 5,
|
||||||
ImportError,
|
ImportError = 6,
|
||||||
IndentationError,
|
IndentationError = 7,
|
||||||
NameError,
|
NameError = 8,
|
||||||
NotImplementedError,
|
NotImplementedError = 9,
|
||||||
PatternError,
|
PatternError = 10,
|
||||||
SyntaxError,
|
SyntaxError = 11,
|
||||||
TabError,
|
TabError = 12,
|
||||||
TypeError,
|
TypeError = 13,
|
||||||
UnboundLocalError,
|
UnboundLocalError = 14,
|
||||||
PurityError,
|
PurityError = 15,
|
||||||
HasEffect,
|
HasEffect = 16,
|
||||||
MoveError,
|
MoveError = 17,
|
||||||
NotConstExpr,
|
NotConstExpr = 18,
|
||||||
InheritanceError,
|
InheritanceError = 19,
|
||||||
VisibilityError,
|
VisibilityError = 20,
|
||||||
MethodError,
|
MethodError = 21,
|
||||||
DummyError,
|
DummyError = 22,
|
||||||
/* compile warnings */
|
/* compile warnings */
|
||||||
AttributeWarning = 60,
|
AttributeWarning = 60,
|
||||||
CastWarning,
|
CastWarning = 61,
|
||||||
DeprecationWarning,
|
DeprecationWarning = 62,
|
||||||
FutureWarning,
|
FutureWarning = 63,
|
||||||
ImportWarning,
|
ImportWarning = 64,
|
||||||
PendingDeprecationWarning,
|
PendingDeprecationWarning = 65,
|
||||||
SyntaxWarning,
|
SyntaxWarning = 66,
|
||||||
TypeWarning,
|
TypeWarning = 67,
|
||||||
NameWarning,
|
NameWarning = 68,
|
||||||
UnusedWarning,
|
UnusedWarning = 69,
|
||||||
Warning,
|
Warning = 70,
|
||||||
/* runtime errors */
|
/* runtime errors */
|
||||||
ArithmeticError = 100,
|
ArithmeticError = 100,
|
||||||
AssertionError,
|
AssertionError = 101,
|
||||||
BlockingIOError,
|
BlockingIOError = 102,
|
||||||
BrokenPipeError,
|
BrokenPipeError = 103,
|
||||||
BufferError,
|
BufferError = 104,
|
||||||
ChildProcessError,
|
ChildProcessError = 105,
|
||||||
ConnectionAbortedError,
|
ConnectionAbortedError = 106,
|
||||||
ConnectionError,
|
ConnectionError = 107,
|
||||||
ConnectionRefusedError,
|
ConnectionRefusedError = 108,
|
||||||
ConnectionResetError,
|
ConnectionResetError = 109,
|
||||||
EOFError,
|
EOFError = 110,
|
||||||
FileExistsError,
|
FileExistsError = 111,
|
||||||
FileNotFoundError,
|
FileNotFoundError = 112,
|
||||||
IndexError,
|
IndexError = 113,
|
||||||
InterruptedError,
|
InterruptedError = 114,
|
||||||
IoError,
|
IoError = 115,
|
||||||
IsADirectoryError,
|
IsADirectoryError = 116,
|
||||||
KeyError,
|
KeyError = 117,
|
||||||
LookupError,
|
LookupError = 118,
|
||||||
MemoryError,
|
MemoryError = 119,
|
||||||
ModuleNotFoundError,
|
ModuleNotFoundError = 120,
|
||||||
NotADirectoryError,
|
NotADirectoryError = 121,
|
||||||
OSError,
|
OSError = 122,
|
||||||
OverflowError,
|
OverflowError = 123,
|
||||||
PermissionError,
|
PermissionError = 124,
|
||||||
ProcessLookupError,
|
ProcessLookupError = 125,
|
||||||
RecursionError,
|
RecursionError = 126,
|
||||||
ReferenceError,
|
ReferenceError = 127,
|
||||||
RuntimeAttributeError,
|
RuntimeAttributeError = 128,
|
||||||
RuntimeError,
|
RuntimeError = 129,
|
||||||
RuntimeTypeError,
|
RuntimeTypeError = 130,
|
||||||
RuntimeUnicodeError,
|
RuntimeUnicodeError = 131,
|
||||||
TimeoutError,
|
TimeoutError = 132,
|
||||||
UnicodeError,
|
UnicodeError = 133,
|
||||||
UserError,
|
UserError = 134,
|
||||||
ValueError,
|
ValueError = 135,
|
||||||
VMSystemError,
|
VMSystemError = 136,
|
||||||
WindowsError,
|
WindowsError = 137,
|
||||||
ZeroDivisionError,
|
ZeroDivisionError = 138,
|
||||||
/* runtime warnings */
|
/* runtime warnings */
|
||||||
BytesWarning = 180,
|
BytesWarning = 180,
|
||||||
ResourceWarning,
|
ResourceWarning = 181,
|
||||||
RuntimeWarning,
|
RuntimeWarning = 182,
|
||||||
UnicodeWarning,
|
UnicodeWarning = 183,
|
||||||
UserWarning,
|
UserWarning = 184,
|
||||||
/* exceptions */
|
/* exceptions */
|
||||||
BaseException = 200,
|
BaseException = 200,
|
||||||
Exception,
|
Exception = 201,
|
||||||
GeneratorExit,
|
GeneratorExit = 202,
|
||||||
KeyboardInterrupt,
|
KeyboardInterrupt = 203,
|
||||||
StopAsyncIteration,
|
StopAsyncIteration = 204,
|
||||||
StopIteration,
|
StopIteration = 205,
|
||||||
SystemExit,
|
SystemExit = 206,
|
||||||
UserException,
|
UserException = 207,
|
||||||
}
|
}
|
||||||
|
|
||||||
use ErrorKind::*;
|
use ErrorKind::*;
|
||||||
|
@ -327,8 +326,8 @@ fn format_context<E: ErrorDisplay + ?Sized>(
|
||||||
chars: &Characters,
|
chars: &Characters,
|
||||||
// kinds of error for specify the color
|
// kinds of error for specify the color
|
||||||
mark: char,
|
mark: char,
|
||||||
sub_msg: &[AtomicStr],
|
sub_msg: &[String],
|
||||||
hint: Option<&AtomicStr>,
|
hint: Option<&String>,
|
||||||
) -> String {
|
) -> String {
|
||||||
let mark = mark.to_string();
|
let mark = mark.to_string();
|
||||||
let codes = if e.input().is_repl() {
|
let codes = if e.input().is_repl() {
|
||||||
|
@ -388,12 +387,12 @@ fn format_context<E: ErrorDisplay + ?Sized>(
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct SubMessage {
|
pub struct SubMessage {
|
||||||
pub loc: Location,
|
pub loc: Location,
|
||||||
msg: Vec<AtomicStr>,
|
msg: Vec<String>,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SubMessage {
|
impl SubMessage {
|
||||||
pub fn ambiguous_new(loc: Location, msg: Vec<AtomicStr>, hint: Option<AtomicStr>) -> Self {
|
pub fn ambiguous_new(loc: Location, msg: Vec<String>, hint: Option<String>) -> Self {
|
||||||
Self { loc, msg, hint }
|
Self { loc, msg, hint }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,11 +404,11 @@ impl SubMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_hint<S: Into<AtomicStr>>(&mut self, hint: S) {
|
pub fn set_hint<S: Into<String>>(&mut self, hint: S) {
|
||||||
self.hint = Some(hint.into());
|
self.hint = Some(hint.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_hint(self) -> Option<AtomicStr> {
|
pub fn get_hint(self) -> Option<String> {
|
||||||
self.hint
|
self.hint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +499,7 @@ impl SubMessage {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct ErrorCore {
|
pub struct ErrorCore {
|
||||||
pub sub_messages: Vec<SubMessage>,
|
pub sub_messages: Vec<SubMessage>,
|
||||||
pub main_message: AtomicStr,
|
pub main_message: String,
|
||||||
pub errno: usize,
|
pub errno: usize,
|
||||||
pub kind: ErrorKind,
|
pub kind: ErrorKind,
|
||||||
pub loc: Location,
|
pub loc: Location,
|
||||||
|
@ -508,7 +507,7 @@ pub struct ErrorCore {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorCore {
|
impl ErrorCore {
|
||||||
pub fn new<S: Into<AtomicStr>>(
|
pub fn new<S: Into<String>>(
|
||||||
sub_messages: Vec<SubMessage>,
|
sub_messages: Vec<SubMessage>,
|
||||||
main_message: S,
|
main_message: S,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! provides utilities for parser, compiler, and vm crate.
|
//! provides utilities for parser, compiler, and vm crate.
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
pub mod astr;
|
|
||||||
pub mod cache;
|
pub mod cache;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod datetime;
|
pub mod datetime;
|
||||||
|
|
|
@ -357,6 +357,174 @@ pub const BUILTIN_PYTHON_MODS: [&str; 170] = [
|
||||||
"zlib",
|
"zlib",
|
||||||
"zoneinfo",
|
"zoneinfo",
|
||||||
];
|
];
|
||||||
|
#[cfg(not(any(windows, unix)))]
|
||||||
|
pub const BUILTIN_PYTHON_MODS: [&str; 165] = [
|
||||||
|
"abc",
|
||||||
|
"argparse",
|
||||||
|
"array",
|
||||||
|
"ast",
|
||||||
|
"asyncio",
|
||||||
|
"atexit",
|
||||||
|
"base64",
|
||||||
|
"bdb",
|
||||||
|
"binascii",
|
||||||
|
"binhex",
|
||||||
|
"bisect",
|
||||||
|
"builtins",
|
||||||
|
"bz2",
|
||||||
|
"calendar",
|
||||||
|
"cmath",
|
||||||
|
"code",
|
||||||
|
"codecs",
|
||||||
|
"codeop",
|
||||||
|
"collections",
|
||||||
|
"colorsys",
|
||||||
|
"compileall",
|
||||||
|
"concurrent",
|
||||||
|
"configparser",
|
||||||
|
"contextlib",
|
||||||
|
"contextvars",
|
||||||
|
"copy",
|
||||||
|
"copyreg",
|
||||||
|
"cProfile",
|
||||||
|
"csv",
|
||||||
|
"ctypes",
|
||||||
|
"dataclasses",
|
||||||
|
"datetime",
|
||||||
|
"dbm",
|
||||||
|
"decimal",
|
||||||
|
"difflib",
|
||||||
|
"dis",
|
||||||
|
"distutils",
|
||||||
|
"doctest",
|
||||||
|
"email",
|
||||||
|
"encodings",
|
||||||
|
"ensurepip",
|
||||||
|
"enum",
|
||||||
|
"errno",
|
||||||
|
"faulthandler",
|
||||||
|
"filecmp",
|
||||||
|
"fileinput",
|
||||||
|
"fnmatch",
|
||||||
|
"fractions",
|
||||||
|
"ftplib",
|
||||||
|
"functools",
|
||||||
|
"gc",
|
||||||
|
"getopt",
|
||||||
|
"getpass",
|
||||||
|
"gettext",
|
||||||
|
"glob",
|
||||||
|
"graphlib",
|
||||||
|
"gzip",
|
||||||
|
"hashlib",
|
||||||
|
"heapq",
|
||||||
|
"hmac",
|
||||||
|
"html",
|
||||||
|
"http",
|
||||||
|
"imaplib",
|
||||||
|
"importlib",
|
||||||
|
"inspect",
|
||||||
|
"io",
|
||||||
|
"ipaddress",
|
||||||
|
"itertools",
|
||||||
|
"json",
|
||||||
|
"keyword",
|
||||||
|
"lib2to3",
|
||||||
|
"linecache",
|
||||||
|
"locale",
|
||||||
|
"logging",
|
||||||
|
"lzma",
|
||||||
|
"mailbox",
|
||||||
|
"marshal",
|
||||||
|
"math",
|
||||||
|
"mimetypes",
|
||||||
|
"mmap",
|
||||||
|
"modulefinder",
|
||||||
|
"multiprocessing",
|
||||||
|
"netrc",
|
||||||
|
"numbers",
|
||||||
|
"operator",
|
||||||
|
"os",
|
||||||
|
"pathlib",
|
||||||
|
"pdb",
|
||||||
|
"pickle",
|
||||||
|
"pickletools",
|
||||||
|
"pkgutil",
|
||||||
|
"platform",
|
||||||
|
"plistlib",
|
||||||
|
"poplib",
|
||||||
|
"pprint",
|
||||||
|
"profile",
|
||||||
|
"pstats",
|
||||||
|
"py_compile",
|
||||||
|
"pyclbr",
|
||||||
|
"pydoc",
|
||||||
|
"queue",
|
||||||
|
"quopri",
|
||||||
|
"random",
|
||||||
|
"re",
|
||||||
|
"reprlib",
|
||||||
|
"rlcompleter",
|
||||||
|
"runpy",
|
||||||
|
"sched",
|
||||||
|
"secrets",
|
||||||
|
"select",
|
||||||
|
"selectors",
|
||||||
|
"shelve",
|
||||||
|
"shlex",
|
||||||
|
"shutil",
|
||||||
|
"signal",
|
||||||
|
"site",
|
||||||
|
"smtplib",
|
||||||
|
"socket",
|
||||||
|
"socketserver",
|
||||||
|
"sqlite3",
|
||||||
|
"ssl",
|
||||||
|
"stat",
|
||||||
|
"statistics",
|
||||||
|
"string",
|
||||||
|
"stringprep",
|
||||||
|
"struct",
|
||||||
|
"subprocess",
|
||||||
|
"symtable",
|
||||||
|
"sys",
|
||||||
|
"sysconfig",
|
||||||
|
"tabnanny",
|
||||||
|
"tarfile",
|
||||||
|
"tempfile",
|
||||||
|
"test",
|
||||||
|
"textwrap",
|
||||||
|
"threading",
|
||||||
|
"time",
|
||||||
|
"timeit",
|
||||||
|
"tkinter",
|
||||||
|
"token",
|
||||||
|
"tokenize",
|
||||||
|
"trace",
|
||||||
|
"traceback",
|
||||||
|
"tracemalloc",
|
||||||
|
"turtle",
|
||||||
|
"turtledemo",
|
||||||
|
"types",
|
||||||
|
"typing",
|
||||||
|
"unicodedata",
|
||||||
|
"unittest",
|
||||||
|
"urllib",
|
||||||
|
"uuid",
|
||||||
|
"venv",
|
||||||
|
"warnings",
|
||||||
|
"wave",
|
||||||
|
"weakref",
|
||||||
|
"webbrowser",
|
||||||
|
"wsgiref",
|
||||||
|
"xml",
|
||||||
|
"xmlrpc",
|
||||||
|
"zipapp",
|
||||||
|
"zipfile",
|
||||||
|
"zipimport",
|
||||||
|
"zlib",
|
||||||
|
"zoneinfo",
|
||||||
|
];
|
||||||
|
|
||||||
pub fn which_python() -> String {
|
pub fn which_python() -> String {
|
||||||
let (cmd, python) = if cfg!(windows) {
|
let (cmd, python) = if cfg!(windows) {
|
||||||
|
@ -416,6 +584,12 @@ pub struct PythonVersion {
|
||||||
pub micro: Option<u8>,
|
pub micro: Option<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for PythonVersion {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(3, Some(11), Some(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PythonVersion {
|
impl PythonVersion {
|
||||||
pub const fn new(major: u8, minor: Option<u8>, micro: Option<u8>) -> Self {
|
pub const fn new(major: u8, minor: Option<u8>, micro: Option<u8>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -47,6 +47,20 @@ impl fmt::Display for Str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&Str> for String {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: &Str) -> Self {
|
||||||
|
s.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Str> for String {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: Str) -> Self {
|
||||||
|
s.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// &'static str -> &strになってしまわないように
|
// &'static str -> &strになってしまわないように
|
||||||
// あえて`impl<S: Into<Str>> From<S> for Str { ... }`はしない
|
// あえて`impl<S: Into<Str>> From<S> for Str { ... }`はしない
|
||||||
impl From<&'static str> for Str {
|
impl From<&'static str> for Str {
|
||||||
|
|
|
@ -464,6 +464,12 @@ impl std::fmt::Display for StyledStrings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<StyledStrings> for String {
|
||||||
|
fn from(s: StyledStrings) -> Self {
|
||||||
|
s.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -350,7 +350,7 @@ fn is_in_the_expected_block(src: &str, lines: &str, in_block: &mut bool) -> bool
|
||||||
|
|
||||||
/// This trait implements REPL (Read-Eval-Print-Loop) automatically
|
/// This trait implements REPL (Read-Eval-Print-Loop) automatically
|
||||||
/// The `exec` method is called for file input, etc.
|
/// The `exec` method is called for file input, etc.
|
||||||
pub trait Runnable: Sized {
|
pub trait Runnable: Sized + Default {
|
||||||
type Err: ErrorDisplay;
|
type Err: ErrorDisplay;
|
||||||
type Errs: MultiErrorDisplay<Self::Err>;
|
type Errs: MultiErrorDisplay<Self::Err>;
|
||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl<S: AsRawFd> IsTty for S {
|
||||||
|
|
||||||
/// returns true if this is a tty
|
/// returns true if this is a tty
|
||||||
#[cfg(any(target_arch = "wasm32", target_env = "sgx"))]
|
#[cfg(any(target_arch = "wasm32", target_env = "sgx"))]
|
||||||
impl<S: AsRawFd> IsTty for S {
|
impl IsTty for std::io::Stdin {
|
||||||
fn is_tty(&self) -> bool {
|
fn is_tty(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::mod_cache::SharedModuleCache;
|
||||||
use crate::ownercheck::OwnershipChecker;
|
use crate::ownercheck::OwnershipChecker;
|
||||||
|
|
||||||
/// Summarize lowering, side-effect checking, and ownership checking
|
/// Summarize lowering, side-effect checking, and ownership checking
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct HIRBuilder {
|
pub struct HIRBuilder {
|
||||||
lowerer: ASTLowerer,
|
lowerer: ASTLowerer,
|
||||||
ownership_checker: OwnershipChecker,
|
ownership_checker: OwnershipChecker,
|
||||||
|
|
|
@ -7,7 +7,6 @@ use std::process;
|
||||||
use crate::ty::codeobj::MakeFunctionFlags;
|
use crate::ty::codeobj::MakeFunctionFlags;
|
||||||
use crate::ty::codeobj::{CodeObj, CodeObjFlags};
|
use crate::ty::codeobj::{CodeObj, CodeObjFlags};
|
||||||
use crate::ty::value::GenTypeObj;
|
use crate::ty::value::GenTypeObj;
|
||||||
use erg_common::astr::AtomicStr;
|
|
||||||
use erg_common::cache::CacheSet;
|
use erg_common::cache::CacheSet;
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::env::erg_std_path;
|
use erg_common::env::erg_std_path;
|
||||||
|
@ -131,7 +130,7 @@ pub struct PyCodeGenStack(Vec<PyCodeGenUnit>);
|
||||||
|
|
||||||
impl_stream_for_wrapper!(PyCodeGenStack, PyCodeGenUnit);
|
impl_stream_for_wrapper!(PyCodeGenStack, PyCodeGenUnit);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct PyCodeGenerator {
|
pub struct PyCodeGenerator {
|
||||||
cfg: ErgConfig,
|
cfg: ErgConfig,
|
||||||
pub(crate) py_version: PythonVersion,
|
pub(crate) py_version: PythonVersion,
|
||||||
|
@ -1265,7 +1264,7 @@ impl PyCodeGenerator {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
unary.op.loc(),
|
unary.op.loc(),
|
||||||
&unary.op.inspect().clone(),
|
&unary.op.inspect().clone(),
|
||||||
AtomicStr::from(unary.op.content),
|
String::from(unary.op.content),
|
||||||
)
|
)
|
||||||
.write_to_stderr();
|
.write_to_stderr();
|
||||||
NOT_IMPLEMENTED
|
NOT_IMPLEMENTED
|
||||||
|
@ -1348,7 +1347,7 @@ impl PyCodeGenerator {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
binop.loc(),
|
binop.loc(),
|
||||||
&binop.inspect().clone(),
|
&binop.inspect().clone(),
|
||||||
AtomicStr::from(binop.content),
|
String::from(binop.content),
|
||||||
)
|
)
|
||||||
.write_to_stderr();
|
.write_to_stderr();
|
||||||
Opcode310::NOT_IMPLEMENTED
|
Opcode310::NOT_IMPLEMENTED
|
||||||
|
@ -1416,7 +1415,7 @@ impl PyCodeGenerator {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
binop.loc(),
|
binop.loc(),
|
||||||
&binop.inspect().clone(),
|
&binop.inspect().clone(),
|
||||||
AtomicStr::from(binop.content),
|
String::from(binop.content),
|
||||||
)
|
)
|
||||||
.write_to_stderr();
|
.write_to_stderr();
|
||||||
Opcode311::NOT_IMPLEMENTED
|
Opcode311::NOT_IMPLEMENTED
|
||||||
|
|
|
@ -91,7 +91,7 @@ impl AccessKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a `CodeObj` from an String or other File inputs.
|
/// Generates a `CodeObj` from an String or other File inputs.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Compiler {
|
pub struct Compiler {
|
||||||
pub cfg: ErgConfig,
|
pub cfg: ErgConfig,
|
||||||
builder: HIRBuilder,
|
builder: HIRBuilder,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use erg_common::astr::AtomicStr;
|
|
||||||
use erg_common::enum_unwrap;
|
use erg_common::enum_unwrap;
|
||||||
|
|
||||||
use crate::ty::typaram::TyParam;
|
use crate::ty::typaram::TyParam;
|
||||||
|
@ -26,11 +25,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_type_mismatch_hint(
|
pub(crate) fn get_type_mismatch_hint(&self, expected: &Type, found: &Type) -> Option<String> {
|
||||||
&self,
|
|
||||||
expected: &Type,
|
|
||||||
found: &Type,
|
|
||||||
) -> Option<AtomicStr> {
|
|
||||||
let expected = if let Type::FreeVar(fv) = expected {
|
let expected = if let Type::FreeVar(fv) = expected {
|
||||||
if fv.is_linked() {
|
if fv.is_linked() {
|
||||||
fv.crack().clone()
|
fv.crack().clone()
|
||||||
|
@ -42,12 +37,12 @@ impl Context {
|
||||||
expected.clone()
|
expected.clone()
|
||||||
};
|
};
|
||||||
match (&expected.qual_name()[..], &found.qual_name()[..]) {
|
match (&expected.qual_name()[..], &found.qual_name()[..]) {
|
||||||
("Eq", "Float") => Some(AtomicStr::ever("Float has no equivalence relation defined. you should use `l - r <= Float.EPSILON` instead of `l == r`.")),
|
("Eq", "Float") => Some(String::from("Float has no equivalence relation defined. you should use `l - r <= Float.EPSILON` instead of `l == r`.")),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_no_candidate_hint(&self, proj: &Type) -> Option<AtomicStr> {
|
pub(crate) fn get_no_candidate_hint(&self, proj: &Type) -> Option<String> {
|
||||||
match proj {
|
match proj {
|
||||||
Type::Proj { lhs, rhs: _ } => {
|
Type::Proj { lhs, rhs: _ } => {
|
||||||
if let Type::FreeVar(fv) = lhs.as_ref() {
|
if let Type::FreeVar(fv) = lhs.as_ref() {
|
||||||
|
@ -69,9 +64,7 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
(sup, sub)
|
(sup, sub)
|
||||||
};
|
};
|
||||||
Some(AtomicStr::from(format!(
|
Some(format!("cannot {verb} {l} {preposition} {r}"))
|
||||||
"cannot {verb} {l} {preposition} {r}"
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::context::Context;
|
||||||
use crate::ty::constructors::{and, mono};
|
use crate::ty::constructors::{and, mono};
|
||||||
use crate::ty::value::{EvalValueResult, GenTypeObj, TypeObj, ValueObj};
|
use crate::ty::value::{EvalValueResult, GenTypeObj, TypeObj, ValueObj};
|
||||||
use crate::ty::ValueArgs;
|
use crate::ty::ValueArgs;
|
||||||
use erg_common::astr::AtomicStr;
|
|
||||||
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
|
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
|
||||||
use erg_common::style::{Color, StyledStr, StyledString, THEME};
|
use erg_common::style::{Color, StyledStr, StyledString, THEME};
|
||||||
|
|
||||||
|
@ -24,7 +23,7 @@ pub fn class_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueOb
|
||||||
let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
|
let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!("{REQ_ERR} is not passed")),
|
format!("{REQ_ERR} is not passed"),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::TypeError,
|
ErrorKind::TypeError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -34,9 +33,9 @@ pub fn class_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueOb
|
||||||
let require = StyledString::new(&format!("{}", require), Some(ERR), None);
|
let require = StyledString::new(&format!("{}", require), Some(ERR), None);
|
||||||
return Err(ErrorCore::new(
|
return Err(ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!(
|
format!(
|
||||||
"non-type object {require} is passed to {REQ_WARN}",
|
"non-type object {require} is passed to {REQ_WARN}",
|
||||||
)),
|
),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::TypeError,
|
ErrorKind::TypeError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -54,7 +53,7 @@ pub fn inherit_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<Value
|
||||||
let sup = StyledStr::new("Super", Some(ERR), None);
|
let sup = StyledStr::new("Super", Some(ERR), None);
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!("{sup} is not passed")),
|
format!("{sup} is not passed"),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::KeyError,
|
ErrorKind::KeyError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -64,9 +63,9 @@ pub fn inherit_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<Value
|
||||||
let sup_ty = StyledString::new(&format!("{}", sup), Some(ERR), None);
|
let sup_ty = StyledString::new(&format!("{}", sup), Some(ERR), None);
|
||||||
return Err(ErrorCore::new(
|
return Err(ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!(
|
format!(
|
||||||
"non-class object {sup_ty} is passed to {SUP_WARN}",
|
"non-class object {sup_ty} is passed to {SUP_WARN}",
|
||||||
)),
|
),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::TypeError,
|
ErrorKind::TypeError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -88,7 +87,7 @@ pub fn inheritable_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<
|
||||||
let class = args.remove_left_or_key("Class").ok_or_else(|| {
|
let class = args.remove_left_or_key("Class").ok_or_else(|| {
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!("{CLASS_ERR} is not passed")),
|
format!("{CLASS_ERR} is not passed"),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::KeyError,
|
ErrorKind::KeyError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -120,7 +119,7 @@ pub fn trait_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueOb
|
||||||
let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
|
let require = args.remove_left_or_key("Requirement").ok_or_else(|| {
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!("{REQ_ERR} is not passed")),
|
format!("{REQ_ERR} is not passed"),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::KeyError,
|
ErrorKind::KeyError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -130,9 +129,9 @@ pub fn trait_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueOb
|
||||||
let require = StyledString::new(&format!("{}", require), Some(ERR), None);
|
let require = StyledString::new(&format!("{}", require), Some(ERR), None);
|
||||||
return Err(ErrorCore::new(
|
return Err(ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!(
|
format!(
|
||||||
"non-type object {require} is passed to {REQ_WARN}",
|
"non-type object {require} is passed to {REQ_WARN}",
|
||||||
)),
|
),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::TypeError,
|
ErrorKind::TypeError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -149,7 +148,7 @@ pub fn subsume_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<Value
|
||||||
let sup = args.remove_left_or_key("Super").ok_or_else(|| {
|
let sup = args.remove_left_or_key("Super").ok_or_else(|| {
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!("{SUP_ERR} is not passed")),
|
format!("{SUP_ERR} is not passed"),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::KeyError,
|
ErrorKind::KeyError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -159,9 +158,9 @@ pub fn subsume_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<Value
|
||||||
let sup = StyledString::new(&format!("{}", sup), Some(ERR), None);
|
let sup = StyledString::new(&format!("{}", sup), Some(ERR), None);
|
||||||
return Err(ErrorCore::new(
|
return Err(ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!(
|
format!(
|
||||||
"non-trait object {sup} is passed to {SUP_WARN}",
|
"non-trait object {sup} is passed to {SUP_WARN}",
|
||||||
)),
|
),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::TypeError,
|
ErrorKind::TypeError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -187,12 +186,12 @@ pub fn __array_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorCore::new(
|
Err(ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!(
|
format!(
|
||||||
"[{}] has {} elements, but accessed {}th element",
|
"[{}] has {} elements, but accessed {}th element",
|
||||||
erg_common::fmt_vec(&slf),
|
erg_common::fmt_vec(&slf),
|
||||||
slf.len(),
|
slf.len(),
|
||||||
index
|
index
|
||||||
)),
|
),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::IndexError,
|
ErrorKind::IndexError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -226,7 +225,7 @@ pub fn __dict_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<V
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorCore::new(
|
Err(ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!("{slf} has no key {index}",)),
|
format!("{slf} has no key {index}"),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::IndexError,
|
ErrorKind::IndexError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
@ -251,7 +250,7 @@ pub fn __range_getitem__(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorCore::new(
|
Err(ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
AtomicStr::from(format!("Index out of range: {}", index)),
|
format!("Index out of range: {}", index),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
ErrorKind::IndexError,
|
ErrorKind::IndexError,
|
||||||
Location::Unknown,
|
Location::Unknown,
|
||||||
|
|
|
@ -921,6 +921,12 @@ impl Context {
|
||||||
Immutable,
|
Immutable,
|
||||||
Public,
|
Public,
|
||||||
);
|
);
|
||||||
|
str_.register_builtin_impl(
|
||||||
|
"format",
|
||||||
|
fn_met(Str, vec![], Some(kw("args", Obj)), vec![], Str),
|
||||||
|
Immutable,
|
||||||
|
Public,
|
||||||
|
);
|
||||||
let mut str_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
let mut str_eq = Self::builtin_methods(Some(mono("Eq")), 2);
|
||||||
str_eq.register_builtin_impl("__eq__", fn1_met(Str, Str, Bool), Const, Public);
|
str_eq.register_builtin_impl("__eq__", fn1_met(Str, Str, Bool), Const, Public);
|
||||||
str_.register_trait(Str, str_eq);
|
str_.register_trait(Str, str_eq);
|
||||||
|
|
|
@ -18,7 +18,6 @@ use std::mem;
|
||||||
use std::option::Option; // conflicting to Type::Option
|
use std::option::Option; // conflicting to Type::Option
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use erg_common::astr::AtomicStr;
|
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::ErgConfig;
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
|
@ -792,8 +791,8 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn caused_by(&self) -> AtomicStr {
|
pub fn caused_by(&self) -> String {
|
||||||
AtomicStr::arc(&self.name[..])
|
String::from(&self.name[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_outer(&self) -> Option<&Context> {
|
pub(crate) fn get_outer(&self) -> Option<&Context> {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
use std::fmt;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use erg_common::astr::AtomicStr;
|
|
||||||
use erg_common::config::Input;
|
use erg_common::config::Input;
|
||||||
use erg_common::error::{
|
use erg_common::error::{
|
||||||
ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay, SubMessage,
|
ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay, SubMessage,
|
||||||
};
|
};
|
||||||
use erg_common::set::Set;
|
use erg_common::set::Set;
|
||||||
use erg_common::style::{Attribute, Color, StyledStr, StyledString, StyledStrings, THEME};
|
use erg_common::style::{Attribute, Color, StyledStr, StyledString, StyledStrings, Theme, THEME};
|
||||||
use erg_common::traits::{Locational, Stream};
|
use erg_common::traits::{Locational, Stream};
|
||||||
use erg_common::vis::Visibility;
|
use erg_common::vis::Visibility;
|
||||||
use erg_common::{
|
use erg_common::{
|
||||||
|
@ -113,7 +113,8 @@ pub fn readable_name(name: &str) -> &str {
|
||||||
pub struct CompileError {
|
pub struct CompileError {
|
||||||
pub core: Box<ErrorCore>, // ErrorCore is large, so box it
|
pub core: Box<ErrorCore>, // ErrorCore is large, so box it
|
||||||
pub input: Input,
|
pub input: Input,
|
||||||
pub caused_by: AtomicStr,
|
pub caused_by: String,
|
||||||
|
pub theme: Theme,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_display_and_error!(CompileError);
|
impl_display_and_error!(CompileError);
|
||||||
|
@ -123,7 +124,8 @@ impl From<ParserRunnerError> for CompileError {
|
||||||
Self {
|
Self {
|
||||||
core: Box::new(err.core),
|
core: Box::new(err.core),
|
||||||
input: err.input,
|
input: err.input,
|
||||||
caused_by: "".into(),
|
caused_by: "".to_owned(),
|
||||||
|
theme: THEME,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,11 +153,12 @@ const URL: StyledStr = StyledStr::new(
|
||||||
);
|
);
|
||||||
|
|
||||||
impl CompileError {
|
impl CompileError {
|
||||||
pub fn new(core: ErrorCore, input: Input, caused_by: AtomicStr) -> Self {
|
pub fn new(core: ErrorCore, input: Input, caused_by: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
core: Box::new(core),
|
core: Box::new(core),
|
||||||
input,
|
input,
|
||||||
caused_by,
|
caused_by,
|
||||||
|
theme: THEME,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +220,7 @@ impl CompileError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn feature_error(input: Input, loc: Location, name: &str, caused_by: AtomicStr) -> Self {
|
pub fn feature_error(input: Input, loc: Location, name: &str, caused_by: String) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(loc)],
|
vec![SubMessage::only_loc(loc)],
|
||||||
|
@ -300,7 +303,7 @@ impl TyCheckError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = readable_name(name);
|
let name = readable_name(name);
|
||||||
|
@ -327,7 +330,7 @@ impl TyCheckError {
|
||||||
errno: usize,
|
errno: usize,
|
||||||
callee: &C,
|
callee: &C,
|
||||||
param_ts: impl Iterator<Item = &'a Type>,
|
param_ts: impl Iterator<Item = &'a Type>,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let param_ts = fmt_iter(param_ts);
|
let param_ts = fmt_iter(param_ts);
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -357,13 +360,13 @@ impl TyCheckError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
nth_param: Option<usize>,
|
nth_param: Option<usize>,
|
||||||
expect: &Type,
|
expect: &Type,
|
||||||
found: &Type,
|
found: &Type,
|
||||||
candidates: Option<Set<Type>>,
|
candidates: Option<Set<Type>>,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let ord = match nth_param {
|
let ord = match nth_param {
|
||||||
Some(pos) => switch_lang!(
|
Some(pos) => switch_lang!(
|
||||||
|
@ -422,7 +425,7 @@ impl TyCheckError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
expect: &Type,
|
expect: &Type,
|
||||||
found: &Type,
|
found: &Type,
|
||||||
|
@ -471,7 +474,7 @@ impl TyCheckError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
t: &Type,
|
t: &Type,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -497,7 +500,7 @@ impl TyCheckError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
expect: usize,
|
expect: usize,
|
||||||
found: usize,
|
found: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -541,7 +544,7 @@ impl TyCheckError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
expr_t: &Type,
|
expr_t: &Type,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -566,7 +569,7 @@ impl TyCheckError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
expr: &str,
|
expr: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -601,7 +604,7 @@ impl TyCheckError {
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
callee_name: &str,
|
callee_name: &str,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
params_len: usize,
|
params_len: usize,
|
||||||
pos_args_len: usize,
|
pos_args_len: usize,
|
||||||
kw_args_len: usize,
|
kw_args_len: usize,
|
||||||
|
@ -667,7 +670,7 @@ passed keyword args: {kw_args_len}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
callee_name: &str,
|
callee_name: &str,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
missing_len: usize,
|
missing_len: usize,
|
||||||
missing_params: Vec<Str>,
|
missing_params: Vec<Str>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -697,7 +700,7 @@ passed keyword args: {kw_args_len}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
callee_name: &str,
|
callee_name: &str,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
arg_name: &str,
|
arg_name: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = readable_name(callee_name);
|
let name = readable_name(callee_name);
|
||||||
|
@ -725,7 +728,7 @@ passed keyword args: {kw_args_len}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
callee_name: &str,
|
callee_name: &str,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
param_name: &str,
|
param_name: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = readable_name(callee_name);
|
let name = readable_name(callee_name);
|
||||||
|
@ -754,7 +757,7 @@ passed keyword args: {kw_args_len}"
|
||||||
lhs_t: &Type,
|
lhs_t: &Type,
|
||||||
rhs_t: &Type,
|
rhs_t: &Type,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut lhs_typ = StyledStrings::default();
|
let mut lhs_typ = StyledStrings::default();
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
|
@ -800,7 +803,7 @@ passed keyword args: {kw_args_len}"
|
||||||
lhs_t: &Type,
|
lhs_t: &Type,
|
||||||
rhs_t: &Type,
|
rhs_t: &Type,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let lhs_t = StyledString::new(&format!("{}", lhs_t), Some(WARN), Some(Attribute::Bold));
|
let lhs_t = StyledString::new(&format!("{}", lhs_t), Some(WARN), Some(Attribute::Bold));
|
||||||
let rhs_t = StyledString::new(&format!("{}", rhs_t), Some(WARN), Some(Attribute::Bold));
|
let rhs_t = StyledString::new(&format!("{}", rhs_t), Some(WARN), Some(Attribute::Bold));
|
||||||
|
@ -828,7 +831,7 @@ passed keyword args: {kw_args_len}"
|
||||||
sub_t: &Type,
|
sub_t: &Type,
|
||||||
sup_t: &Type,
|
sup_t: &Type,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut sub_type = StyledStrings::default();
|
let mut sub_type = StyledStrings::default();
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
|
@ -875,7 +878,7 @@ passed keyword args: {kw_args_len}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
lhs: &Predicate,
|
lhs: &Predicate,
|
||||||
rhs: &Predicate,
|
rhs: &Predicate,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut lhs_uni = StyledStrings::default();
|
let mut lhs_uni = StyledStrings::default();
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
|
@ -920,8 +923,8 @@ passed keyword args: {kw_args_len}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
proj: &Type,
|
proj: &Type,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -947,8 +950,8 @@ passed keyword args: {kw_args_len}"
|
||||||
class: &Type,
|
class: &Type,
|
||||||
trait_: &Type,
|
trait_: &Type,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -972,9 +975,9 @@ passed keyword args: {kw_args_len}"
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -1008,12 +1011,12 @@ passed keyword args: {kw_args_len}"
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
member_name: &str,
|
member_name: &str,
|
||||||
trait_type: &Type,
|
trait_type: &Type,
|
||||||
expect: &Type,
|
expect: &Type,
|
||||||
found: &Type,
|
found: &Type,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut expct = StyledStrings::default();
|
let mut expct = StyledStrings::default();
|
||||||
expct.push_str_with_color_and_attribute(&format!("{}", trait_type), WARN, Attribute::Bold);
|
expct.push_str_with_color_and_attribute(&format!("{}", trait_type), WARN, Attribute::Bold);
|
||||||
|
@ -1059,11 +1062,11 @@ passed keyword args: {kw_args_len}"
|
||||||
pub fn trait_member_not_defined_error(
|
pub fn trait_member_not_defined_error(
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
member_name: &str,
|
member_name: &str,
|
||||||
trait_type: &Type,
|
trait_type: &Type,
|
||||||
class_type: &Type,
|
class_type: &Type,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let member_name = StyledString::new(member_name, Some(WARN), Some(Attribute::Bold));
|
let member_name = StyledString::new(member_name, Some(WARN), Some(Attribute::Bold));
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -1088,11 +1091,11 @@ passed keyword args: {kw_args_len}"
|
||||||
pub fn not_in_trait_error(
|
pub fn not_in_trait_error(
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
member_name: &str,
|
member_name: &str,
|
||||||
trait_type: &Type,
|
trait_type: &Type,
|
||||||
class_type: &Type,
|
class_type: &Type,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let member_name = StyledString::new(member_name, Some(WARN), Some(Attribute::Bold));
|
let member_name = StyledString::new(member_name, Some(WARN), Some(Attribute::Bold));
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -1118,7 +1121,7 @@ passed keyword args: {kw_args_len}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
name: &str,
|
name: &str,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -1144,7 +1147,7 @@ passed keyword args: {kw_args_len}"
|
||||||
errno: usize,
|
errno: usize,
|
||||||
expr: &(impl Locational + Display),
|
expr: &(impl Locational + Display),
|
||||||
candidates: &[Type],
|
candidates: &[Type],
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let hint = Some(
|
let hint = Some(
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
|
@ -1197,7 +1200,7 @@ pub type EvalResult<T> = TyCheckResult<T>;
|
||||||
pub type SingleEvalResult<T> = SingleTyCheckResult<T>;
|
pub type SingleEvalResult<T> = SingleTyCheckResult<T>;
|
||||||
|
|
||||||
impl EvalError {
|
impl EvalError {
|
||||||
pub fn not_const_expr(input: Input, errno: usize, loc: Location, caused_by: AtomicStr) -> Self {
|
pub fn not_const_expr(input: Input, errno: usize, loc: Location, caused_by: String) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(loc)],
|
vec![SubMessage::only_loc(loc)],
|
||||||
|
@ -1216,12 +1219,7 @@ impl EvalError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalid_literal(
|
pub fn invalid_literal(input: Input, errno: usize, loc: Location, caused_by: String) -> Self {
|
||||||
input: Input,
|
|
||||||
errno: usize,
|
|
||||||
loc: Location,
|
|
||||||
caused_by: AtomicStr,
|
|
||||||
) -> Self {
|
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(loc)],
|
vec![SubMessage::only_loc(loc)],
|
||||||
|
@ -1245,7 +1243,7 @@ pub type EffectError = TyCheckError;
|
||||||
pub type EffectErrors = TyCheckErrors;
|
pub type EffectErrors = TyCheckErrors;
|
||||||
|
|
||||||
impl EffectError {
|
impl EffectError {
|
||||||
pub fn has_effect<S: Into<AtomicStr>>(
|
pub fn has_effect<S: Into<String>>(
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
|
@ -1269,7 +1267,7 @@ impl EffectError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn proc_assign_error<S: Into<AtomicStr>>(
|
pub fn proc_assign_error<S: Into<String>>(
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
sig: &Signature,
|
sig: &Signature,
|
||||||
|
@ -1307,7 +1305,7 @@ pub type OwnershipError = TyCheckError;
|
||||||
pub type OwnershipErrors = TyCheckErrors;
|
pub type OwnershipErrors = TyCheckErrors;
|
||||||
|
|
||||||
impl OwnershipError {
|
impl OwnershipError {
|
||||||
pub fn move_error<S: Into<AtomicStr>>(
|
pub fn move_error<S: Into<String>>(
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
@ -1355,13 +1353,13 @@ pub type LowerResult<T> = TyCheckResult<T>;
|
||||||
pub type SingleLowerResult<T> = SingleTyCheckResult<T>;
|
pub type SingleLowerResult<T> = SingleTyCheckResult<T>;
|
||||||
|
|
||||||
impl LowerError {
|
impl LowerError {
|
||||||
pub fn syntax_error<S: Into<AtomicStr>>(
|
pub fn syntax_error<S: Into<String>>(
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
desc: S,
|
desc: S,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -1380,7 +1378,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = readable_name(name);
|
let name = readable_name(name);
|
||||||
|
@ -1406,7 +1404,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = readable_name(name);
|
let name = readable_name(name);
|
||||||
|
@ -1432,7 +1430,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
spec_t: &Type,
|
spec_t: &Type,
|
||||||
found_t: &Type,
|
found_t: &Type,
|
||||||
|
@ -1462,7 +1460,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
similar_name: Option<&str>,
|
similar_name: Option<&str>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -1475,7 +1473,6 @@ impl LowerError {
|
||||||
"traditional_chinese" => format!("存在相同名稱變量: {n}"),
|
"traditional_chinese" => format!("存在相同名稱變量: {n}"),
|
||||||
"english" => format!("exists a similar name variable: {n}"),
|
"english" => format!("exists a similar name variable: {n}"),
|
||||||
)
|
)
|
||||||
.into()
|
|
||||||
});
|
});
|
||||||
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -1500,7 +1497,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
typ: &Type,
|
typ: &Type,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let typ = StyledString::new(&typ.to_string(), Some(ERR), Some(Attribute::Bold));
|
let typ = StyledString::new(&typ.to_string(), Some(ERR), Some(Attribute::Bold));
|
||||||
|
@ -1533,7 +1530,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
obj_t: &Type,
|
obj_t: &Type,
|
||||||
name: &str,
|
name: &str,
|
||||||
similar_name: Option<&str>,
|
similar_name: Option<&str>,
|
||||||
|
@ -1545,7 +1542,6 @@ impl LowerError {
|
||||||
"traditional_chinese" => format!("具有相同名稱的屬性: {n}"),
|
"traditional_chinese" => format!("具有相同名稱的屬性: {n}"),
|
||||||
"english" => format!("has a similar name attribute: {n}"),
|
"english" => format!("has a similar name attribute: {n}"),
|
||||||
)
|
)
|
||||||
.into()
|
|
||||||
});
|
});
|
||||||
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -1571,7 +1567,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
obj_name: &str,
|
obj_name: &str,
|
||||||
obj_t: &Type,
|
obj_t: &Type,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
@ -1585,7 +1581,6 @@ impl LowerError {
|
||||||
"traditional_chinese" => format!("具有相同名稱的屬性: {n}"),
|
"traditional_chinese" => format!("具有相同名稱的屬性: {n}"),
|
||||||
"english" => format!("has a similar name attribute: {n}"),
|
"english" => format!("has a similar name attribute: {n}"),
|
||||||
)
|
)
|
||||||
.into()
|
|
||||||
});
|
});
|
||||||
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
let found = StyledString::new(name, Some(ERR), Some(Attribute::Bold));
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -1610,7 +1605,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = StyledString::new(readable_name(name), Some(WARN), Some(Attribute::Bold));
|
let name = StyledString::new(readable_name(name), Some(WARN), Some(Attribute::Bold));
|
||||||
|
@ -1637,7 +1632,7 @@ impl LowerError {
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
name: &str,
|
name: &str,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = StyledString::new(readable_name(name), Some(WARN), Some(Attribute::Bold));
|
let name = StyledString::new(readable_name(name), Some(WARN), Some(Attribute::Bold));
|
||||||
Self::new(
|
Self::new(
|
||||||
|
@ -1658,7 +1653,7 @@ impl LowerError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn del_error(input: Input, errno: usize, ident: &Identifier, caused_by: AtomicStr) -> Self {
|
pub fn del_error(input: Input, errno: usize, ident: &Identifier, caused_by: String) -> Self {
|
||||||
let name = StyledString::new(
|
let name = StyledString::new(
|
||||||
readable_name(ident.inspect()),
|
readable_name(ident.inspect()),
|
||||||
Some(WARN),
|
Some(WARN),
|
||||||
|
@ -1686,7 +1681,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -1725,7 +1720,7 @@ impl LowerError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn override_error<S: Into<AtomicStr>>(
|
pub fn override_error<S: Into<String>>(
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
@ -1789,7 +1784,7 @@ impl LowerError {
|
||||||
errno: usize,
|
errno: usize,
|
||||||
class: String,
|
class: String,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -1814,8 +1809,8 @@ impl LowerError {
|
||||||
errno: usize,
|
errno: usize,
|
||||||
desc: String,
|
desc: String,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -1835,7 +1830,7 @@ impl LowerError {
|
||||||
errno: usize,
|
errno: usize,
|
||||||
mod_name: &str,
|
mod_name: &str,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let desc = switch_lang!(
|
let desc = switch_lang!(
|
||||||
"japanese" => format!("{mod_name}モジュールはお使いの環境をサポートしていません"),
|
"japanese" => format!("{mod_name}モジュールはお使いの環境をサポートしていません"),
|
||||||
|
@ -1851,7 +1846,7 @@ impl LowerError {
|
||||||
errno: usize,
|
errno: usize,
|
||||||
desc: String,
|
desc: String,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
similar_erg_mod: Option<Str>,
|
similar_erg_mod: Option<Str>,
|
||||||
similar_py_mod: Option<Str>,
|
similar_py_mod: Option<Str>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -1948,7 +1943,6 @@ impl LowerError {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let hint = hint.map(AtomicStr::from);
|
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::ambiguous_new(
|
vec![SubMessage::ambiguous_new(
|
||||||
|
@ -1970,7 +1964,7 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
|
@ -1990,7 +1984,7 @@ impl LowerError {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declare_error(input: Input, errno: usize, loc: Location, caused_by: AtomicStr) -> Self {
|
pub fn declare_error(input: Input, errno: usize, loc: Location, caused_by: String) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(loc)],
|
vec![SubMessage::only_loc(loc)],
|
||||||
|
@ -2014,10 +2008,10 @@ impl LowerError {
|
||||||
input: Input,
|
input: Input,
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
caused_by: AtomicStr,
|
caused_by: String,
|
||||||
name: &str,
|
name: &str,
|
||||||
cast_to: &Type,
|
cast_to: &Type,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = StyledString::new(name, Some(WARN), Some(Attribute::Bold));
|
let name = StyledString::new(name, Some(WARN), Some(Attribute::Bold));
|
||||||
let found = StyledString::new(&format!("{}", cast_to), Some(WARN), Some(Attribute::Bold));
|
let found = StyledString::new(&format!("{}", cast_to), Some(WARN), Some(Attribute::Bold));
|
||||||
|
@ -2065,6 +2059,12 @@ impl From<CompileError> for CompileErrors {
|
||||||
|
|
||||||
impl MultiErrorDisplay<CompileError> for CompileErrors {}
|
impl MultiErrorDisplay<CompileError> for CompileErrors {}
|
||||||
|
|
||||||
|
impl fmt::Display for CompileErrors {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.fmt_all(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl CompileErrors {
|
impl CompileErrors {
|
||||||
pub fn flush(&mut self) -> Self {
|
pub fn flush(&mut self) -> Self {
|
||||||
Self(self.0.drain(..).collect())
|
Self(self.0.drain(..).collect())
|
||||||
|
|
|
@ -21,5 +21,6 @@ pub mod mod_cache;
|
||||||
pub mod optimize;
|
pub mod optimize;
|
||||||
pub mod ownercheck;
|
pub mod ownercheck;
|
||||||
pub mod reorder;
|
pub mod reorder;
|
||||||
|
pub mod transpile;
|
||||||
pub mod ty;
|
pub mod ty;
|
||||||
pub mod varinfo;
|
pub mod varinfo;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
//!
|
//!
|
||||||
//! ASTLowerer(ASTからHIRへの変換器)を実装
|
//! ASTLowerer(ASTからHIRへの変換器)を実装
|
||||||
|
|
||||||
use erg_common::astr::AtomicStr;
|
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::ErgConfig;
|
||||||
use erg_common::dict;
|
use erg_common::dict;
|
||||||
use erg_common::error::{Location, MultiErrorDisplay};
|
use erg_common::error::{Location, MultiErrorDisplay};
|
||||||
|
@ -161,7 +160,7 @@ impl ASTLowerer {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
expr.loc(),
|
expr.loc(),
|
||||||
AtomicStr::arc(&self.ctx.name[..]),
|
String::from(&self.ctx.name[..]),
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => format!("式の評価結果(: {})が使われていません", expr.ref_t()),
|
"japanese" => format!("式の評価結果(: {})が使われていません", expr.ref_t()),
|
||||||
"simplified_chinese" => format!("表达式评估结果(: {})未使用", expr.ref_t()),
|
"simplified_chinese" => format!("表达式评估结果(: {})未使用", expr.ref_t()),
|
||||||
|
@ -226,7 +225,7 @@ impl ASTLowerer {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
elem.loc(),
|
elem.loc(),
|
||||||
AtomicStr::arc(&self.ctx.name[..]),
|
String::from(&self.ctx.name[..]),
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => "配列の要素は全て同じ型である必要があります",
|
"japanese" => "配列の要素は全て同じ型である必要があります",
|
||||||
"simplified_chinese" => "数组元素必须全部是相同类型",
|
"simplified_chinese" => "数组元素必须全部是相同类型",
|
||||||
|
@ -372,7 +371,7 @@ impl ASTLowerer {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
elem.loc(),
|
elem.loc(),
|
||||||
AtomicStr::arc(&self.ctx.name[..]),
|
String::from(&self.ctx.name[..]),
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => "集合の要素は全て同じ型である必要があります",
|
"japanese" => "集合の要素は全て同じ型である必要があります",
|
||||||
"simplified_chinese" => "集合元素必须全部是相同类型",
|
"simplified_chinese" => "集合元素必须全部是相同类型",
|
||||||
|
@ -404,7 +403,7 @@ impl ASTLowerer {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
normal_set.loc(),
|
normal_set.loc(),
|
||||||
AtomicStr::arc(&self.ctx.name[..]),
|
String::arc(&self.ctx.name[..]),
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => "要素が重複しています",
|
"japanese" => "要素が重複しています",
|
||||||
"simplified_chinese" => "元素重复",
|
"simplified_chinese" => "元素重复",
|
||||||
|
@ -498,7 +497,7 @@ impl ASTLowerer {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
loc,
|
loc,
|
||||||
AtomicStr::arc(&self.ctx.name[..]),
|
String::from(&self.ctx.name[..]),
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => "Dictの値は全て同じ型である必要があります",
|
"japanese" => "Dictの値は全て同じ型である必要があります",
|
||||||
"simplified_chinese" => "Dict的值必须是同一类型",
|
"simplified_chinese" => "Dict的值必须是同一类型",
|
||||||
|
@ -543,7 +542,7 @@ impl ASTLowerer {
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
normal_set.loc(),
|
normal_set.loc(),
|
||||||
AtomicStr::arc(&self.ctx.name[..]),
|
String::arc(&self.ctx.name[..]),
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => "要素が重複しています",
|
"japanese" => "要素が重複しています",
|
||||||
"simplified_chinese" => "元素重复",
|
"simplified_chinese" => "元素重复",
|
||||||
|
|
|
@ -10,6 +10,7 @@ use erg_common::traits::Runnable;
|
||||||
|
|
||||||
use erg_compiler::build_hir::HIRBuilder;
|
use erg_compiler::build_hir::HIRBuilder;
|
||||||
use erg_compiler::lower::ASTLowerer;
|
use erg_compiler::lower::ASTLowerer;
|
||||||
|
use erg_compiler::transpile::Transpiler;
|
||||||
use erg_compiler::ty::deserialize::Deserializer;
|
use erg_compiler::ty::deserialize::Deserializer;
|
||||||
use erg_compiler::Compiler;
|
use erg_compiler::Compiler;
|
||||||
|
|
||||||
|
@ -31,6 +32,9 @@ fn run() {
|
||||||
"check" => {
|
"check" => {
|
||||||
HIRBuilder::run(cfg);
|
HIRBuilder::run(cfg);
|
||||||
}
|
}
|
||||||
|
"transpile" => {
|
||||||
|
Transpiler::run(cfg);
|
||||||
|
}
|
||||||
"compile" | "exec" => {
|
"compile" | "exec" => {
|
||||||
Compiler::run(cfg);
|
Compiler::run(cfg);
|
||||||
}
|
}
|
||||||
|
|
429
compiler/erg_compiler/transpile.rs
Normal file
429
compiler/erg_compiler/transpile.rs
Normal file
|
@ -0,0 +1,429 @@
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
use erg_common::config::ErgConfig;
|
||||||
|
use erg_common::log;
|
||||||
|
use erg_common::traits::{Runnable, Stream};
|
||||||
|
use erg_common::Str;
|
||||||
|
|
||||||
|
use erg_parser::ast::ParamPattern;
|
||||||
|
|
||||||
|
use crate::build_hir::HIRBuilder;
|
||||||
|
use crate::desugar_hir::HIRDesugarer;
|
||||||
|
use crate::error::{CompileError, CompileErrors};
|
||||||
|
use crate::hir::{
|
||||||
|
Accessor, Array, Block, Call, ClassDef, Def, Dict, Expr, Identifier, Lambda, Params, Set,
|
||||||
|
Signature, Tuple, HIR,
|
||||||
|
};
|
||||||
|
use crate::link::Linker;
|
||||||
|
use crate::mod_cache::SharedModuleCache;
|
||||||
|
use crate::ty::Type;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct PyScript {
|
||||||
|
pub filename: Str,
|
||||||
|
pub code: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a `PyScript` from an String or other File inputs.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Transpiler {
|
||||||
|
pub cfg: ErgConfig,
|
||||||
|
builder: HIRBuilder,
|
||||||
|
mod_cache: SharedModuleCache,
|
||||||
|
script_generator: ScriptGenerator,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Runnable for Transpiler {
|
||||||
|
type Err = CompileError;
|
||||||
|
type Errs = CompileErrors;
|
||||||
|
const NAME: &'static str = "Erg transpiler";
|
||||||
|
|
||||||
|
fn new(cfg: ErgConfig) -> Self {
|
||||||
|
let mod_cache = SharedModuleCache::new();
|
||||||
|
let py_mod_cache = SharedModuleCache::new();
|
||||||
|
Self {
|
||||||
|
builder: HIRBuilder::new_with_cache(
|
||||||
|
cfg.copy(),
|
||||||
|
"<module>",
|
||||||
|
mod_cache.clone(),
|
||||||
|
py_mod_cache,
|
||||||
|
),
|
||||||
|
script_generator: ScriptGenerator::new(),
|
||||||
|
mod_cache,
|
||||||
|
cfg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn cfg(&self) -> &ErgConfig {
|
||||||
|
&self.cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn finish(&mut self) {}
|
||||||
|
|
||||||
|
fn clear(&mut self) {
|
||||||
|
// self.builder.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec(&mut self) -> Result<i32, Self::Errs> {
|
||||||
|
let path = self.input().filename().replace(".er", ".py");
|
||||||
|
let script = self.transpile(self.input().read(), "exec")?;
|
||||||
|
let mut f = File::create(&path).unwrap();
|
||||||
|
f.write_all(script.code.as_bytes()).unwrap();
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eval(&mut self, src: String) -> Result<String, CompileErrors> {
|
||||||
|
let script = self.transpile(src, "eval")?;
|
||||||
|
Ok(script.code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Transpiler {
|
||||||
|
pub fn transpile(&mut self, src: String, mode: &str) -> Result<PyScript, CompileErrors> {
|
||||||
|
log!(info "the transpiling process has started.");
|
||||||
|
let hir = self.build_link_desugar(src, mode)?;
|
||||||
|
let script = self.script_generator.transpile(hir);
|
||||||
|
log!(info "code:\n{}", script.code);
|
||||||
|
log!(info "the transpiling process has completed");
|
||||||
|
Ok(script)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_link_desugar(&mut self, src: String, mode: &str) -> Result<HIR, CompileErrors> {
|
||||||
|
let artifact = self
|
||||||
|
.builder
|
||||||
|
.build(src, mode)
|
||||||
|
.map_err(|artifact| artifact.errors)?;
|
||||||
|
let linker = Linker::new(&self.cfg, &self.mod_cache);
|
||||||
|
let hir = linker.link(artifact.hir);
|
||||||
|
Ok(HIRDesugarer::desugar(hir))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ScriptGenerator {
|
||||||
|
level: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScriptGenerator {
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self { level: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transpile(&mut self, hir: HIR) -> PyScript {
|
||||||
|
let mut code = self.load_prelude();
|
||||||
|
for chunk in hir.module.into_iter() {
|
||||||
|
code += &self.transpile_expr(chunk);
|
||||||
|
code.push('\n');
|
||||||
|
}
|
||||||
|
PyScript {
|
||||||
|
filename: hir.name,
|
||||||
|
code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_prelude(&mut self) -> String {
|
||||||
|
"from collections import namedtuple as NamedTuple__\n".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpile_expr(&mut self, expr: Expr) -> String {
|
||||||
|
match expr {
|
||||||
|
Expr::Lit(lit) => lit.token.content.to_string(),
|
||||||
|
Expr::Call(call) => self.transpile_call(call),
|
||||||
|
Expr::BinOp(bin) => {
|
||||||
|
let mut code = "(".to_string();
|
||||||
|
code += &self.transpile_expr(*bin.lhs);
|
||||||
|
code += &bin.op.content;
|
||||||
|
code += &self.transpile_expr(*bin.rhs);
|
||||||
|
code += ")";
|
||||||
|
code
|
||||||
|
}
|
||||||
|
Expr::UnaryOp(unary) => {
|
||||||
|
let mut code = "(".to_string();
|
||||||
|
code += &unary.op.content;
|
||||||
|
code += &self.transpile_expr(*unary.expr);
|
||||||
|
code += ")";
|
||||||
|
code
|
||||||
|
}
|
||||||
|
Expr::Array(array) => match array {
|
||||||
|
Array::Normal(arr) => {
|
||||||
|
let mut code = "[".to_string();
|
||||||
|
for elem in arr.elems.pos_args {
|
||||||
|
code += &format!("{},", self.transpile_expr(elem.expr));
|
||||||
|
}
|
||||||
|
code += "]";
|
||||||
|
code
|
||||||
|
}
|
||||||
|
other => todo!("transpiling {other}"),
|
||||||
|
},
|
||||||
|
Expr::Set(set) => match set {
|
||||||
|
Set::Normal(st) => {
|
||||||
|
let mut code = "{".to_string();
|
||||||
|
for elem in st.elems.pos_args {
|
||||||
|
code += &format!("{},", self.transpile_expr(elem.expr));
|
||||||
|
}
|
||||||
|
code += "}";
|
||||||
|
code
|
||||||
|
}
|
||||||
|
other => todo!("transpiling {other}"),
|
||||||
|
},
|
||||||
|
Expr::Record(rec) => {
|
||||||
|
let mut attrs = "[".to_string();
|
||||||
|
let mut values = "(".to_string();
|
||||||
|
for mut attr in rec.attrs.into_iter() {
|
||||||
|
attrs += &format!("'{}',", Self::transpile_ident(attr.sig.into_ident()));
|
||||||
|
if attr.body.block.len() > 1 {
|
||||||
|
todo!("transpile instant blocks")
|
||||||
|
}
|
||||||
|
values += &format!("{},", self.transpile_expr(attr.body.block.remove(0)));
|
||||||
|
}
|
||||||
|
attrs += "]";
|
||||||
|
values += ")";
|
||||||
|
format!("NamedTuple__('Record', {attrs}){values}")
|
||||||
|
}
|
||||||
|
Expr::Tuple(tuple) => match tuple {
|
||||||
|
Tuple::Normal(tup) => {
|
||||||
|
let mut code = "(".to_string();
|
||||||
|
for elem in tup.elems.pos_args {
|
||||||
|
code += &format!("{},", self.transpile_expr(elem.expr));
|
||||||
|
}
|
||||||
|
code += ")";
|
||||||
|
code
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Expr::Dict(dict) => match dict {
|
||||||
|
Dict::Normal(dic) => {
|
||||||
|
let mut code = "{".to_string();
|
||||||
|
for kv in dic.kvs {
|
||||||
|
code += &format!(
|
||||||
|
"({}): ({}),",
|
||||||
|
self.transpile_expr(kv.key),
|
||||||
|
self.transpile_expr(kv.value)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
code += "}";
|
||||||
|
code
|
||||||
|
}
|
||||||
|
other => todo!("transpiling {other}"),
|
||||||
|
},
|
||||||
|
Expr::Accessor(acc) => match acc {
|
||||||
|
Accessor::Ident(ident) => Self::transpile_ident(ident),
|
||||||
|
Accessor::Attr(attr) => {
|
||||||
|
format!(
|
||||||
|
"({}).{}",
|
||||||
|
self.transpile_expr(*attr.obj),
|
||||||
|
Self::transpile_ident(attr.ident)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Expr::Def(def) => self.transpile_def(def),
|
||||||
|
Expr::Lambda(lambda) => self.transpile_lambda(lambda),
|
||||||
|
Expr::ClassDef(classdef) => self.transpile_classdef(classdef),
|
||||||
|
Expr::AttrDef(mut adef) => {
|
||||||
|
let mut code = format!("{} = ", self.transpile_expr(Expr::Accessor(adef.attr)));
|
||||||
|
if adef.block.len() > 1 {
|
||||||
|
todo!("transpile instant blocks")
|
||||||
|
}
|
||||||
|
let expr = adef.block.remove(0);
|
||||||
|
code += &self.transpile_expr(expr);
|
||||||
|
code
|
||||||
|
}
|
||||||
|
// TODO:
|
||||||
|
Expr::Compound(comp) => {
|
||||||
|
let mut code = "".to_string();
|
||||||
|
for expr in comp.into_iter() {
|
||||||
|
code += &self.transpile_expr(expr);
|
||||||
|
code += &format!("\n{}", " ".repeat(self.level));
|
||||||
|
}
|
||||||
|
code
|
||||||
|
}
|
||||||
|
other => todo!("transpile {other}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpile_call(&mut self, mut call: Call) -> String {
|
||||||
|
match call.obj.local_name() {
|
||||||
|
Some("assert") => {
|
||||||
|
let mut code = format!("assert {}", self.transpile_expr(call.args.remove(0)));
|
||||||
|
if let Some(msg) = call.args.try_remove(0) {
|
||||||
|
code += &format!(", {}", self.transpile_expr(msg));
|
||||||
|
}
|
||||||
|
code
|
||||||
|
}
|
||||||
|
Some("if" | "if!") => {
|
||||||
|
let cond = self.transpile_expr(call.args.remove(0));
|
||||||
|
let Expr::Lambda(mut block) = call.args.remove(0) else { todo!() };
|
||||||
|
let then = self.transpile_expr(block.body.remove(0));
|
||||||
|
if let Some(Expr::Lambda(mut block)) = call.args.try_remove(0) {
|
||||||
|
let els = self.transpile_expr(block.body.remove(0));
|
||||||
|
format!("{then} if {cond} else {els}")
|
||||||
|
} else {
|
||||||
|
format!("{then} if {cond} else None")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some("for" | "for!") => {
|
||||||
|
let mut code = "for ".to_string();
|
||||||
|
let iter = call.args.remove(0);
|
||||||
|
let Expr::Lambda(block) = call.args.remove(0) else { todo!() };
|
||||||
|
let sig = block.params.non_defaults.get(0).unwrap();
|
||||||
|
let ParamPattern::VarName(param) = &sig.pat else { todo!() };
|
||||||
|
code += &format!("{}__ ", ¶m.token().content);
|
||||||
|
code += &format!("in {}:\n", self.transpile_expr(iter));
|
||||||
|
code += &self.transpile_block(block.body, false);
|
||||||
|
code
|
||||||
|
}
|
||||||
|
Some("while" | "while!") => {
|
||||||
|
let mut code = "while ".to_string();
|
||||||
|
let cond = call.args.remove(0);
|
||||||
|
let Expr::Lambda(block) = call.args.remove(0) else { todo!() };
|
||||||
|
code += &format!("{}:\n", self.transpile_expr(cond));
|
||||||
|
code += &self.transpile_block(block.body, false);
|
||||||
|
code
|
||||||
|
}
|
||||||
|
// TODO:
|
||||||
|
Some("match" | "match!") => {
|
||||||
|
let mut code = "match ".to_string();
|
||||||
|
let cond = call.args.remove(0);
|
||||||
|
code += &format!("{}:\n", self.transpile_expr(cond));
|
||||||
|
while let Some(Expr::Lambda(arm)) = call.args.try_remove(0) {
|
||||||
|
self.level += 1;
|
||||||
|
code += &" ".repeat(self.level);
|
||||||
|
let target = arm.params.non_defaults.get(0).unwrap();
|
||||||
|
let ParamPattern::VarName(param) = &target.pat else { todo!() };
|
||||||
|
code += &format!("case {}__:\n", ¶m.token().content);
|
||||||
|
code += &self.transpile_block(arm.body, false);
|
||||||
|
self.level -= 1;
|
||||||
|
}
|
||||||
|
code
|
||||||
|
}
|
||||||
|
_ => self.transpile_simple_call(call),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpile_simple_call(&mut self, mut call: Call) -> String {
|
||||||
|
let mut code = format!("({})", self.transpile_expr(*call.obj));
|
||||||
|
if let Some(attr) = call.attr_name {
|
||||||
|
code += &format!(".{}", Self::transpile_ident(attr));
|
||||||
|
}
|
||||||
|
code.push('(');
|
||||||
|
while let Some(arg) = call.args.try_remove_pos(0) {
|
||||||
|
code += &self.transpile_expr(arg.expr);
|
||||||
|
code.push(',');
|
||||||
|
}
|
||||||
|
while let Some(arg) = call.args.try_remove_kw(0) {
|
||||||
|
code += &format!("{}={},", arg.keyword, self.transpile_expr(arg.expr));
|
||||||
|
}
|
||||||
|
code.push(')');
|
||||||
|
code
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpile_ident(ident: Identifier) -> String {
|
||||||
|
if let Some(py_name) = ident.vi.py_name {
|
||||||
|
py_name.to_string()
|
||||||
|
} else if ident.dot.is_some() {
|
||||||
|
ident.name.into_token().content.to_string()
|
||||||
|
} else {
|
||||||
|
let name = ident.name.into_token().content;
|
||||||
|
let name = name.replace('!', "__erg_proc__");
|
||||||
|
let name = name.replace('$', "erg_shared__");
|
||||||
|
format!("{name}__")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpile_params(&mut self, params: Params) -> String {
|
||||||
|
let mut code = String::new();
|
||||||
|
for non_default in params.non_defaults {
|
||||||
|
let ParamPattern::VarName(param) = non_default.pat else { todo!() };
|
||||||
|
code += &format!("{}__,", param.into_token().content);
|
||||||
|
}
|
||||||
|
for default in params.defaults {
|
||||||
|
let ParamPattern::VarName(param) = default.sig.pat else { todo!() };
|
||||||
|
code += &format!(
|
||||||
|
"{}__ = {},",
|
||||||
|
param.into_token().content,
|
||||||
|
self.transpile_expr(default.default_val)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
code
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpile_block(&mut self, block: Block, return_last: bool) -> String {
|
||||||
|
self.level += 1;
|
||||||
|
let mut code = String::new();
|
||||||
|
let last = block.len() - 1;
|
||||||
|
for (i, chunk) in block.into_iter().enumerate() {
|
||||||
|
code += &" ".repeat(self.level);
|
||||||
|
if i == last && return_last {
|
||||||
|
code += "return ";
|
||||||
|
}
|
||||||
|
code += &self.transpile_expr(chunk);
|
||||||
|
code.push('\n');
|
||||||
|
}
|
||||||
|
self.level -= 1;
|
||||||
|
code
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpile_lambda(&mut self, lambda: Lambda) -> String {
|
||||||
|
let mut code = format!("(lambda {}:", self.transpile_params(lambda.params));
|
||||||
|
if lambda.body.len() > 1 {
|
||||||
|
todo!("multi line lambda");
|
||||||
|
}
|
||||||
|
code += &self.transpile_block(lambda.body, false);
|
||||||
|
code.pop(); // \n
|
||||||
|
code.push(')');
|
||||||
|
code
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpile_def(&mut self, mut def: Def) -> String {
|
||||||
|
match def.sig {
|
||||||
|
Signature::Var(var) => {
|
||||||
|
let mut code = format!("{} = ", Self::transpile_ident(var.ident));
|
||||||
|
if def.body.block.len() > 1 {
|
||||||
|
todo!("transpile instant blocks")
|
||||||
|
}
|
||||||
|
let expr = def.body.block.remove(0);
|
||||||
|
code += &self.transpile_expr(expr);
|
||||||
|
code
|
||||||
|
}
|
||||||
|
Signature::Subr(subr) => {
|
||||||
|
let mut code = format!(
|
||||||
|
"def {}({}):\n",
|
||||||
|
Self::transpile_ident(subr.ident),
|
||||||
|
self.transpile_params(subr.params)
|
||||||
|
);
|
||||||
|
code += &self.transpile_block(def.body.block, true);
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpile_classdef(&mut self, classdef: ClassDef) -> String {
|
||||||
|
let class_name = Self::transpile_ident(classdef.sig.into_ident());
|
||||||
|
let mut code = format!("class {class_name}():\n");
|
||||||
|
let mut init_method = format!(
|
||||||
|
"{}def __init__(self, param__):\n",
|
||||||
|
" ".repeat(self.level + 1)
|
||||||
|
);
|
||||||
|
match classdef.__new__.non_default_params().unwrap()[0].typ() {
|
||||||
|
Type::Record(rec) => {
|
||||||
|
for field in rec.keys() {
|
||||||
|
init_method += &format!(
|
||||||
|
"{}self.{} = param__.{}\n",
|
||||||
|
" ".repeat(self.level + 2),
|
||||||
|
field.symbol,
|
||||||
|
field.symbol
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => todo!("{other}"),
|
||||||
|
}
|
||||||
|
code += &init_method;
|
||||||
|
if classdef.need_to_gen_new {
|
||||||
|
code += &format!("def new(x): return {class_name}.__call__(x)\n");
|
||||||
|
}
|
||||||
|
code += &self.transpile_block(classdef.methods, false);
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,6 @@
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
|
|
||||||
use erg_common::astr::AtomicStr;
|
|
||||||
use erg_common::cache::CacheSet;
|
use erg_common::cache::CacheSet;
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
|
@ -21,8 +20,8 @@ use super::{HasType, Type};
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DeserializeError {
|
pub struct DeserializeError {
|
||||||
pub errno: usize,
|
pub errno: usize,
|
||||||
pub caused_by: AtomicStr,
|
pub caused_by: String,
|
||||||
pub desc: AtomicStr,
|
pub desc: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for DeserializeError {
|
impl From<std::io::Error> for DeserializeError {
|
||||||
|
@ -50,11 +49,7 @@ impl From<DeserializeError> for ErrorCore {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeserializeError {
|
impl DeserializeError {
|
||||||
pub fn new<S: Into<AtomicStr>, T: Into<AtomicStr>>(
|
pub fn new<S: Into<String>, T: Into<String>>(errno: usize, caused_by: S, desc: T) -> Self {
|
||||||
errno: usize,
|
|
||||||
caused_by: S,
|
|
||||||
desc: T,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
errno,
|
errno,
|
||||||
caused_by: caused_by.into(),
|
caused_by: caused_by.into(),
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crate::error::{ParserRunnerError, ParserRunnerErrors};
|
||||||
use crate::parse::ParserRunner;
|
use crate::parse::ParserRunner;
|
||||||
|
|
||||||
/// Summarize parsing and desugaring
|
/// Summarize parsing and desugaring
|
||||||
|
#[derive(Debug, Default)]
|
||||||
pub struct ASTBuilder {
|
pub struct ASTBuilder {
|
||||||
runner: ParserRunner,
|
runner: ParserRunner,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
//! defines `ParseError` and others.
|
//! defines `ParseError` and others.
|
||||||
//!
|
//!
|
||||||
//! パーサーが出すエラーを定義
|
//! パーサーが出すエラーを定義
|
||||||
use erg_common::astr::AtomicStr;
|
use std::fmt;
|
||||||
|
|
||||||
use erg_common::config::Input;
|
use erg_common::config::Input;
|
||||||
use erg_common::error::{
|
use erg_common::error::{
|
||||||
ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay, SubMessage,
|
ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay, SubMessage,
|
||||||
|
@ -39,7 +40,7 @@ impl LexError {
|
||||||
Self(Box::new(core))
|
Self(Box::new(core))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_hint<S: Into<AtomicStr>>(&mut self, hint: S) {
|
pub fn set_hint<S: Into<String>>(&mut self, hint: S) {
|
||||||
if let Some(sub_msg) = self.0.sub_messages.get_mut(0) {
|
if let Some(sub_msg) = self.0.sub_messages.get_mut(0) {
|
||||||
sub_msg.set_hint(hint)
|
sub_msg.set_hint(hint)
|
||||||
}
|
}
|
||||||
|
@ -95,11 +96,11 @@ impl LexError {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax_error<S: Into<AtomicStr>>(
|
pub fn syntax_error<S: Into<String>>(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
desc: S,
|
desc: S,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(ErrorCore::new(
|
Self::new(ErrorCore::new(
|
||||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||||
|
@ -110,11 +111,11 @@ impl LexError {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax_warning<S: Into<AtomicStr>>(
|
pub fn syntax_warning<S: Into<String>>(
|
||||||
errno: usize,
|
errno: usize,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
desc: S,
|
desc: S,
|
||||||
hint: Option<AtomicStr>,
|
hint: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(ErrorCore::new(
|
Self::new(ErrorCore::new(
|
||||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||||
|
@ -139,7 +140,6 @@ impl LexError {
|
||||||
"traditional_chinese" => format!("存在相同名稱變量: {n}"),
|
"traditional_chinese" => format!("存在相同名稱變量: {n}"),
|
||||||
"english" => format!("exists a similar name variable: {n}"),
|
"english" => format!("exists a similar name variable: {n}"),
|
||||||
)
|
)
|
||||||
.into()
|
|
||||||
});
|
});
|
||||||
let name = StyledString::new(name, Some(ERR), Some(Attribute::Underline));
|
let name = StyledString::new(name, Some(ERR), Some(Attribute::Underline));
|
||||||
Self::new(ErrorCore::new(
|
Self::new(ErrorCore::new(
|
||||||
|
@ -217,6 +217,12 @@ impl_stream_for_wrapper!(ParserRunnerErrors, ParserRunnerError);
|
||||||
|
|
||||||
impl MultiErrorDisplay<ParserRunnerError> for ParserRunnerErrors {}
|
impl MultiErrorDisplay<ParserRunnerError> for ParserRunnerErrors {}
|
||||||
|
|
||||||
|
impl fmt::Display for ParserRunnerErrors {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.fmt_all(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ParserRunnerErrors {
|
impl ParserRunnerErrors {
|
||||||
pub fn convert(input: &Input, errs: ParseErrors) -> Self {
|
pub fn convert(input: &Input, errs: ParseErrors) -> Self {
|
||||||
Self(
|
Self(
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::token::{Token, TokenCategory, TokenKind, TokenStream};
|
||||||
use TokenKind::*;
|
use TokenKind::*;
|
||||||
|
|
||||||
/// Lexerは使い捨てなので、Runnerを用意
|
/// Lexerは使い捨てなので、Runnerを用意
|
||||||
|
#[derive(Debug, Default)]
|
||||||
pub struct LexerRunner {
|
pub struct LexerRunner {
|
||||||
cfg: ErgConfig,
|
cfg: ErgConfig,
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ParserRunner {
|
pub struct ParserRunner {
|
||||||
cfg: ErgConfig,
|
cfg: ErgConfig,
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,12 @@ pub struct DummyVM {
|
||||||
stream: Option<TcpStream>,
|
stream: Option<TcpStream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for DummyVM {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(ErgConfig::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Runnable for DummyVM {
|
impl Runnable for DummyVM {
|
||||||
type Err = EvalError;
|
type Err = EvalError;
|
||||||
type Errs = EvalErrors;
|
type Errs = EvalErrors;
|
||||||
|
|
|
@ -14,6 +14,7 @@ use erg_parser::ParserRunner;
|
||||||
|
|
||||||
use erg_compiler::build_hir::HIRBuilder;
|
use erg_compiler::build_hir::HIRBuilder;
|
||||||
use erg_compiler::lower::ASTLowerer;
|
use erg_compiler::lower::ASTLowerer;
|
||||||
|
use erg_compiler::transpile::Transpiler;
|
||||||
use erg_compiler::ty::deserialize::Deserializer;
|
use erg_compiler::ty::deserialize::Deserializer;
|
||||||
use erg_compiler::Compiler;
|
use erg_compiler::Compiler;
|
||||||
|
|
||||||
|
@ -37,6 +38,9 @@ fn run() {
|
||||||
"compile" => {
|
"compile" => {
|
||||||
Compiler::run(cfg);
|
Compiler::run(cfg);
|
||||||
}
|
}
|
||||||
|
"transpile" => {
|
||||||
|
Transpiler::run(cfg);
|
||||||
|
}
|
||||||
"exec" => {
|
"exec" => {
|
||||||
DummyVM::run(cfg);
|
DummyVM::run(cfg);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue