mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
1 parent
07e339a7fb
commit
55061c7b6a
24 files changed
+147
-173
No files matched your search
Generated
+1
@@ -1753,6 +1753,7 @@ dependencies = [
|
||||
"rustpython-ast",
|
||||
"rustpython-compiler-core",
|
||||
"rustpython-parser",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Vendored
+2
-6
@@ -760,8 +760,6 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
|
||||
self.assertEqual(ast.dump(a), ast.dump(b))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_parse_in_error(self):
|
||||
try:
|
||||
1/0
|
||||
@@ -1101,8 +1099,6 @@ Module(
|
||||
malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
|
||||
self.assertRaises(ValueError, ast.literal_eval, malformed)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_literal_eval_trailing_ws(self):
|
||||
self.assertEqual(ast.literal_eval(" -1"), -1)
|
||||
self.assertEqual(ast.literal_eval("\t\t-1"), -1)
|
||||
@@ -1121,8 +1117,6 @@ Module(
|
||||
with self.assertRaisesRegex(ValueError, msg):
|
||||
ast.literal_eval(node)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_literal_eval_syntax_errors(self):
|
||||
with self.assertRaisesRegex(SyntaxError, "unexpected indent"):
|
||||
ast.literal_eval(r'''
|
||||
@@ -1767,6 +1761,8 @@ class ASTValidatorTests(unittest.TestCase):
|
||||
ast.MatchMapping([], [], rest="_"),
|
||||
]
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_match_validation_pattern(self):
|
||||
name_x = ast.Name('x', ast.Load())
|
||||
for pattern in self._MATCH_PATTERNS:
|
||||
|
||||
@@ -17,6 +17,7 @@ itertools = "0.10.3"
|
||||
log = "0.4.16"
|
||||
num-complex = { version = "0.4.0", features = ["serde"] }
|
||||
num-traits = "0.2.14"
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
rustpython-parser = { path = "../parser" }
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::{error::Error, fmt};
|
||||
use std::fmt;
|
||||
|
||||
pub type CodegenError = rustpython_compiler_core::BaseError<CodegenErrorType>;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum CodegenErrorType {
|
||||
/// Invalid assignment, cannot store value in target.
|
||||
@@ -79,5 +79,3 @@ impl fmt::Display for CodegenErrorType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for CodegenErrorType {}
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::Location;
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct BaseError<T> {
|
||||
@@ -87,3 +86,24 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> CompileError<T> {
|
||||
pub fn from<U>(error: BaseError<U>, source: &str) -> Self
|
||||
where
|
||||
T: From<U>,
|
||||
{
|
||||
let statement = get_statement(source, error.location);
|
||||
CompileError {
|
||||
body: error.into(),
|
||||
statement,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_statement(source: &str, loc: Location) -> Option<String> {
|
||||
if loc.column() == 0 || loc.row() == 0 {
|
||||
return None;
|
||||
}
|
||||
let line = source.split('\n').nth(loc.row() - 1)?.to_owned();
|
||||
Some(line + "\n")
|
||||
}
|
||||
@@ -117,8 +117,7 @@ impl From<FStringError> for LalrpopError<Location, Tok, LexicalError> {
|
||||
}
|
||||
|
||||
/// Represents an error during parsing
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ParseError(rustpython_compiler_core::BaseError<ParseErrorType>);
|
||||
pub type ParseError = rustpython_compiler_core::BaseError<ParseErrorType>;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ParseErrorType {
|
||||
@@ -134,66 +133,44 @@ pub enum ParseErrorType {
|
||||
Lexical(LexicalErrorType),
|
||||
}
|
||||
|
||||
impl From<ParseError> for rustpython_compiler_core::BaseError<ParseErrorType> {
|
||||
fn from(err: ParseError) -> Self {
|
||||
err.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParseError> for ParseErrorType {
|
||||
fn from(err: ParseError) -> Self {
|
||||
err.0.error
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert `lalrpop_util::ParseError` to our internal type
|
||||
impl ParseError {
|
||||
fn new(error: ParseErrorType, location: Location, source_path: String) -> Self {
|
||||
Self(rustpython_compiler_core::BaseError {
|
||||
error,
|
||||
pub(crate) fn parse_error_from_lalrpop(
|
||||
err: LalrpopError<Location, Tok, LexicalError>,
|
||||
source_path: &str,
|
||||
) -> ParseError {
|
||||
let source_path = source_path.to_owned();
|
||||
match err {
|
||||
// TODO: Are there cases where this isn't an EOF?
|
||||
LalrpopError::InvalidToken { location } => ParseError {
|
||||
error: ParseErrorType::Eof,
|
||||
location,
|
||||
source_path,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn from_lalrpop(
|
||||
err: LalrpopError<Location, Tok, LexicalError>,
|
||||
source_path: &str,
|
||||
) -> Self {
|
||||
let source_path = source_path.to_owned();
|
||||
match err {
|
||||
// TODO: Are there cases where this isn't an EOF?
|
||||
LalrpopError::InvalidToken { location } => {
|
||||
ParseError::new(ParseErrorType::Eof, location, source_path)
|
||||
}
|
||||
LalrpopError::ExtraToken { token } => {
|
||||
ParseError::new(ParseErrorType::ExtraToken(token.1), token.0, source_path)
|
||||
}
|
||||
LalrpopError::User { error } => ParseError::new(
|
||||
ParseErrorType::Lexical(error.error),
|
||||
error.location,
|
||||
},
|
||||
LalrpopError::ExtraToken { token } => ParseError {
|
||||
error: ParseErrorType::ExtraToken(token.1),
|
||||
location: token.0,
|
||||
source_path,
|
||||
},
|
||||
LalrpopError::User { error } => ParseError {
|
||||
error: ParseErrorType::Lexical(error.error),
|
||||
location: error.location,
|
||||
source_path,
|
||||
},
|
||||
LalrpopError::UnrecognizedToken { token, expected } => {
|
||||
// Hacky, but it's how CPython does it. See PyParser_AddToken,
|
||||
// in particular "Only one possible expected token" comment.
|
||||
let expected = (expected.len() == 1).then(|| expected[0].clone());
|
||||
ParseError {
|
||||
error: ParseErrorType::UnrecognizedToken(token.1, expected),
|
||||
location: token.0,
|
||||
source_path,
|
||||
),
|
||||
LalrpopError::UnrecognizedToken { token, expected } => {
|
||||
// Hacky, but it's how CPython does it. See PyParser_AddToken,
|
||||
// in particular "Only one possible expected token" comment.
|
||||
let expected = (expected.len() == 1).then(|| expected[0].clone());
|
||||
ParseError::new(
|
||||
ParseErrorType::UnrecognizedToken(token.1, expected),
|
||||
token.0,
|
||||
source_path,
|
||||
)
|
||||
}
|
||||
LalrpopError::UnrecognizedEOF { location, .. } => {
|
||||
ParseError::new(ParseErrorType::Eof, location, source_path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ParseError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
LalrpopError::UnrecognizedEOF { location, .. } => ParseError {
|
||||
error: ParseErrorType::Eof,
|
||||
location,
|
||||
source_path,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,16 +214,3 @@ impl ParseErrorType {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for ParseError {
|
||||
type Target = rustpython_compiler_core::BaseError<ParseErrorType>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for ParseError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -186,7 +186,7 @@ impl<'a> FStringParser<'a> {
|
||||
vec![self.expr(ExprKind::FormattedValue {
|
||||
value: Box::new(
|
||||
parse_fstring_expr(&expression)
|
||||
.map_err(|e| InvalidExpression(Box::new(e.into())))?,
|
||||
.map_err(|e| InvalidExpression(Box::new(e.error)))?,
|
||||
),
|
||||
conversion: conversion as _,
|
||||
format_spec: spec,
|
||||
@@ -204,7 +204,7 @@ impl<'a> FStringParser<'a> {
|
||||
self.expr(ExprKind::FormattedValue {
|
||||
value: Box::new(
|
||||
parse_fstring_expr(&expression)
|
||||
.map_err(|e| InvalidExpression(Box::new(e.into())))?,
|
||||
.map_err(|e| InvalidExpression(Box::new(e.error)))?,
|
||||
),
|
||||
conversion: (if conversion == ConversionFlag::None && spec.is_none()
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ pub fn parse(source: &str, mode: Mode, source_path: &str) -> Result<ast::Mod, Pa
|
||||
|
||||
python::TopParser::new()
|
||||
.parse(tokenizer)
|
||||
.map_err(|e| ParseError::from_lalrpop(e, source_path))
|
||||
.map_err(|e| crate::error::parse_error_from_lalrpop(e, source_path))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
+5
-28
@@ -1,7 +1,7 @@
|
||||
use rustpython_codegen::{compile, symboltable};
|
||||
use rustpython_compiler_core::CodeObject;
|
||||
use rustpython_parser::{
|
||||
ast::{fold::Fold, ConstantOptimizer, Location},
|
||||
ast::{fold::Fold, ConstantOptimizer},
|
||||
error::ParseErrorType,
|
||||
parser,
|
||||
};
|
||||
@@ -12,31 +12,16 @@ pub use rustpython_compiler_core::{BaseError as CompileErrorBody, Mode};
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum CompileErrorType {
|
||||
#[error(transparent)]
|
||||
Compile(#[from] rustpython_codegen::error::CodegenErrorType),
|
||||
Codegen(#[from] rustpython_codegen::error::CodegenErrorType),
|
||||
#[error(transparent)]
|
||||
Parse(#[from] rustpython_parser::error::ParseErrorType),
|
||||
}
|
||||
|
||||
pub type CompileError = rustpython_compiler_core::CompileError<CompileErrorType>;
|
||||
|
||||
fn error_from_codegen(
|
||||
error: rustpython_codegen::error::CodegenError,
|
||||
source: &str,
|
||||
) -> CompileError {
|
||||
let statement = get_statement(source, error.location);
|
||||
CompileError {
|
||||
body: error.into(),
|
||||
statement,
|
||||
}
|
||||
}
|
||||
|
||||
fn error_from_parse(error: rustpython_parser::error::ParseError, source: &str) -> CompileError {
|
||||
let error: CompileErrorBody<ParseErrorType> = error.into();
|
||||
let statement = get_statement(source, error.location);
|
||||
CompileError {
|
||||
body: error.into(),
|
||||
statement,
|
||||
}
|
||||
CompileError::from(error, source)
|
||||
}
|
||||
|
||||
/// Compile a given sourcecode into a bytecode object.
|
||||
@@ -60,7 +45,7 @@ pub fn compile(
|
||||
.fold_mod(ast)
|
||||
.unwrap_or_else(|e| match e {});
|
||||
}
|
||||
compile::compile_top(&ast, source_path, mode, opts).map_err(|e| error_from_codegen(e, source))
|
||||
compile::compile_top(&ast, source_path, mode, opts).map_err(|e| CompileError::from(e, source))
|
||||
}
|
||||
|
||||
pub fn compile_symtable(
|
||||
@@ -79,13 +64,5 @@ pub fn compile_symtable(
|
||||
symboltable::SymbolTable::scan_expr(&expr)
|
||||
}
|
||||
};
|
||||
res.map_err(|e| error_from_codegen(e.into_codegen_error(source_path.to_owned()), source))
|
||||
}
|
||||
|
||||
fn get_statement(source: &str, loc: Location) -> Option<String> {
|
||||
if loc.column() == 0 || loc.row() == 0 {
|
||||
return None;
|
||||
}
|
||||
let line = source.split('\n').nth(loc.row() - 1)?.to_owned();
|
||||
Some(line + "\n")
|
||||
res.map_err(|e| CompileError::from(e.into_codegen_error(source_path.to_owned()), source))
|
||||
}
|
||||
+5
-6
@@ -13,8 +13,7 @@ extern crate env_logger;
|
||||
extern crate log;
|
||||
|
||||
use clap::{App, Arg};
|
||||
|
||||
use rustpython_compiler as compile;
|
||||
use rustpython_compiler as compiler;
|
||||
use std::error::Error;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
@@ -62,7 +61,7 @@ fn main() {
|
||||
let optimize = matches.occurrences_of("optimize") as u8;
|
||||
let scripts = matches.values_of_os("scripts").unwrap();
|
||||
|
||||
let opts = compile::CompileOpts {
|
||||
let opts = compiler::CompileOpts {
|
||||
optimize,
|
||||
..Default::default()
|
||||
};
|
||||
@@ -81,12 +80,12 @@ fn main() {
|
||||
|
||||
fn display_script(
|
||||
path: &Path,
|
||||
mode: compile::Mode,
|
||||
opts: compile::CompileOpts,
|
||||
mode: compiler::Mode,
|
||||
opts: compiler::CompileOpts,
|
||||
expand_codeobjects: bool,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let source = fs::read_to_string(path)?;
|
||||
let code = compile::compile(&source, mode, path.to_string_lossy().into_owned(), opts)?;
|
||||
let code = compiler::compile(&source, mode, path.to_string_lossy().into_owned(), opts)?;
|
||||
println!("{}:", path.display());
|
||||
if expand_codeobjects {
|
||||
println!("{}", code.display_expand_codeobjects());
|
||||
|
||||
@@ -7,7 +7,7 @@ fn main() -> vm::PyResult<()> {
|
||||
let code_obj = vm
|
||||
.compile(
|
||||
r#"print("Hello World!")"#,
|
||||
vm::compile::Mode::Exec,
|
||||
vm::compiler::Mode::Exec,
|
||||
"<embedded>".to_owned(),
|
||||
)
|
||||
.map_err(|err| vm.new_syntax_error(&err))?;
|
||||
|
||||
@@ -62,9 +62,9 @@ def fib(n):
|
||||
.expect("Failed to read line of input");
|
||||
|
||||
// this line also automatically prints the output
|
||||
// (note that this is only the case when compile::Mode::Single is passed to vm.compile)
|
||||
// (note that this is only the case when compiler::Mode::Single is passed to vm.compile)
|
||||
match vm
|
||||
.compile(&input, vm::compile::Mode::Single, "<embedded>".to_owned())
|
||||
.compile(&input, vm::compiler::Mode::Single, "<embedded>".to_owned())
|
||||
.map_err(|err| vm.new_syntax_error(&err))
|
||||
.and_then(|code_obj| vm.run_code_obj(code_obj, scope.clone()))
|
||||
{
|
||||
|
||||
+2
-2
@@ -17,9 +17,9 @@ flame-it = ["flame", "flamer"]
|
||||
freeze-stdlib = ["rustpython-pylib/freeze-stdlib"]
|
||||
jit = ["rustpython-jit"]
|
||||
threading = ["rustpython-common/threading"]
|
||||
compiler = ["parser", "codegen"]
|
||||
compiler = ["parser", "codegen", "rustpython-compiler"]
|
||||
ast = ["rustpython-ast"]
|
||||
codegen = ["rustpython-compiler", "rustpython-codegen", "ast"]
|
||||
codegen = ["rustpython-codegen", "ast"]
|
||||
parser = ["rustpython-parser", "ast"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
+22
-5
@@ -1,3 +1,5 @@
|
||||
use crate::{builtins::PyBaseExceptionRef, convert::ToPyException, VirtualMachine};
|
||||
|
||||
#[cfg(feature = "rustpython-codegen")]
|
||||
pub use rustpython_codegen::CompileOpts;
|
||||
#[cfg(feature = "rustpython-compiler")]
|
||||
@@ -8,9 +10,24 @@ pub use rustpython_compiler_core::Mode;
|
||||
mod error {
|
||||
#[cfg(all(feature = "rustpython-parser", feature = "rustpython-codegen"))]
|
||||
panic!("Use --features=compiler to enable both parser and codegen");
|
||||
#[cfg(feature = "rustpython-parser")]
|
||||
pub type CompileError = rustpython_compiler_core::CompileError<rustpython_parser::ParseError>;
|
||||
#[cfg(feature = "rustpython-codegen")]
|
||||
pub type CompileError =
|
||||
rustpython_compiler_core::CompileError<rustpython_codegen::CodegenError>;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum CompileErrorType {
|
||||
#[cfg(feature = "rustpython-codegen")]
|
||||
#[error(transparent)]
|
||||
Codegen(#[from] rustpython_codegen::error::CodegenErrorType),
|
||||
#[cfg(feature = "rustpython-parser")]
|
||||
#[error(transparent)]
|
||||
Parse(#[from] rustpython_parser::error::ParseErrorType),
|
||||
}
|
||||
|
||||
pub type CompileError = rustpython_compiler_core::CompileError<CompileErrorType>;
|
||||
}
|
||||
#[cfg(not(feature = "rustpython-compiler"))]
|
||||
pub use error::{CompileError, CompileErrorType};
|
||||
|
||||
impl ToPyException for CompileError {
|
||||
fn to_pyexception(&self, vm: &VirtualMachine) -> PyBaseExceptionRef {
|
||||
vm.new_syntax_error(self)
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -46,6 +46,7 @@ mod bytesinner;
|
||||
pub mod cformat;
|
||||
pub mod class;
|
||||
mod codecs;
|
||||
pub mod compiler;
|
||||
pub mod convert;
|
||||
mod coroutine;
|
||||
mod dictdatatype;
|
||||
@@ -87,8 +88,6 @@ pub use self::vm::{Context, Interpreter, Settings, VirtualMachine};
|
||||
pub use rustpython_common as common;
|
||||
pub use rustpython_compiler_core as bytecode;
|
||||
|
||||
pub mod compiler;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod __exports {
|
||||
pub use paste;
|
||||
|
||||
+10
-6
@@ -8,6 +8,8 @@ mod gen;
|
||||
use crate::{
|
||||
builtins::{self, PyStrRef, PyType},
|
||||
class::{PyClassImpl, StaticType},
|
||||
compiler::CompileError,
|
||||
convert::ToPyException,
|
||||
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, TryFromObject,
|
||||
VirtualMachine,
|
||||
};
|
||||
@@ -263,10 +265,13 @@ impl Node for ast::ConversionFlag {
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustpython-parser")]
|
||||
pub(crate) fn parse(vm: &VirtualMachine, source: &str, mode: parser::Mode) -> PyResult {
|
||||
// TODO: use vm.new_syntax_error()
|
||||
let top = parser::parse(source, mode, "<unknown>")
|
||||
.map_err(|err| vm.new_value_error(format!("{}", err)))?;
|
||||
pub(crate) fn parse(
|
||||
vm: &VirtualMachine,
|
||||
source: &str,
|
||||
mode: parser::Mode,
|
||||
) -> Result<PyObjectRef, CompileError> {
|
||||
let top =
|
||||
parser::parse(source, mode, "<unknown>").map_err(|err| CompileError::from(err, source))?;
|
||||
Ok(top.ast_to_object(vm))
|
||||
}
|
||||
|
||||
@@ -280,8 +285,7 @@ pub(crate) fn compile(
|
||||
let opts = vm.compile_opts();
|
||||
let ast = Node::ast_from_object(vm, object)?;
|
||||
let code = codegen::compile::compile_top(&ast, filename.to_owned(), mode, opts)
|
||||
// TODO: use vm.new_syntax_error()
|
||||
.map_err(|err| vm.new_value_error(err.to_string()))?;
|
||||
.map_err(|err| CompileError::from(err, "<unknown>").to_pyexception(vm))?; // FIXME source
|
||||
Ok(vm.ctx.new_code(code).into())
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ use crate::{class::PyClassImpl, PyObjectRef, VirtualMachine};
|
||||
/// Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices.
|
||||
#[pymodule]
|
||||
mod builtins {
|
||||
#[cfg(feature = "rustpython-compiler")]
|
||||
use crate::{
|
||||
builtins::{
|
||||
asyncgenerator::PyAsyncGen,
|
||||
@@ -20,12 +19,11 @@ mod builtins {
|
||||
PyByteArray, PyBytes, PyDictRef, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType,
|
||||
},
|
||||
common::{hash::PyHash, str::to_ascii},
|
||||
compiler,
|
||||
convert::ToPyException,
|
||||
format::call_object_format,
|
||||
function::Either,
|
||||
function::{
|
||||
ArgBytesLike, ArgCallable, ArgIntoBool, ArgIterable, ArgMapping, ArgStrOrBytesLike,
|
||||
FuncArgs, KwArgs, OptionalArg, OptionalOption, PosArgs, PyArithmeticValue,
|
||||
Either, FuncArgs, KwArgs, OptionalArg, OptionalOption, PosArgs, PyArithmeticValue,
|
||||
},
|
||||
protocol::{PyIter, PyIterReturn},
|
||||
py_io,
|
||||
@@ -39,9 +37,6 @@ mod builtins {
|
||||
#[cfg(not(feature = "rustpython-compiler"))]
|
||||
const CODEGEN_NOT_SUPPORTED: &str =
|
||||
"can't compile() to bytecode when the `codegen` feature of rustpython is disabled";
|
||||
#[cfg(not(feature = "rustpython-parser"))]
|
||||
const PARSER_NOT_SUPPORTED: &str =
|
||||
"can't compile() source code when the `parser` feature of rustpython is disabled";
|
||||
|
||||
#[pyfunction]
|
||||
fn abs(x: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -144,7 +139,7 @@ mod builtins {
|
||||
#[cfg(feature = "rustpython-codegen")]
|
||||
{
|
||||
let mode = mode_str
|
||||
.parse::<compiler::Mode>()
|
||||
.parse::<crate::compiler::Mode>()
|
||||
.map_err(|err| vm.new_value_error(err.to_string()))?;
|
||||
return ast::compile(vm, args.source, args.filename.as_str(), mode);
|
||||
}
|
||||
@@ -152,6 +147,8 @@ mod builtins {
|
||||
|
||||
#[cfg(not(feature = "rustpython-parser"))]
|
||||
{
|
||||
const PARSER_NOT_SUPPORTED: &str =
|
||||
"can't compile() source code when the `parser` feature of rustpython is disabled";
|
||||
Err(vm.new_type_error(PARSER_NOT_SUPPORTED.to_owned()))
|
||||
}
|
||||
#[cfg(feature = "rustpython-parser")]
|
||||
@@ -178,18 +175,18 @@ mod builtins {
|
||||
#[cfg(feature = "rustpython-compiler")]
|
||||
{
|
||||
let mode = mode_str
|
||||
.parse::<compiler::Mode>()
|
||||
.parse::<crate::compiler::Mode>()
|
||||
.map_err(|err| vm.new_value_error(err.to_string()))?;
|
||||
let code = vm
|
||||
.compile(source, mode, args.filename.as_str().to_owned())
|
||||
.map_err(|err| vm.new_syntax_error(&err))?;
|
||||
.map_err(|err| err.to_pyexception(vm))?;
|
||||
Ok(code.into())
|
||||
}
|
||||
} else {
|
||||
let mode = mode_str
|
||||
.parse::<parser::Mode>()
|
||||
.map_err(|err| vm.new_value_error(err.to_string()))?;
|
||||
ast::parse(vm, source, mode)
|
||||
ast::parse(vm, source, mode).map_err(|e| e.to_pyexception(vm))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,14 +7,6 @@ use crate::{
|
||||
};
|
||||
|
||||
impl VirtualMachine {
|
||||
/// Returns a basic CompileOpts instance with options accurate to the vm. Used
|
||||
/// as the CompileOpts for `vm.compile()`.
|
||||
pub fn compile_opts(&self) -> CompileOpts {
|
||||
CompileOpts {
|
||||
optimize: self.state.settings.optimize,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile(
|
||||
&self,
|
||||
source: &str,
|
||||
|
||||
@@ -11,7 +11,7 @@ use std::sync::atomic::Ordering;
|
||||
/// Runs a simple embedded hello world program.
|
||||
/// ```
|
||||
/// use rustpython_vm::Interpreter;
|
||||
/// use rustpython_vm::compile::Mode;
|
||||
/// use rustpython_vm::compiler::Mode;
|
||||
/// Interpreter::without_stdlib(Default::default()).enter(|vm| {
|
||||
/// let scope = vm.new_scope_with_builtins();
|
||||
/// let code_obj = vm.compile(r#"print("Hello World!")"#,
|
||||
|
||||
+10
-1
@@ -384,6 +384,15 @@ impl VirtualMachine {
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a basic CompileOpts instance with options accurate to the vm. Used
|
||||
/// as the CompileOpts for `vm.compile()`.
|
||||
#[cfg(feature = "rustpython-codegen")]
|
||||
pub fn compile_opts(&self) -> crate::compiler::CompileOpts {
|
||||
crate::compiler::CompileOpts {
|
||||
optimize: self.state.settings.optimize,
|
||||
}
|
||||
}
|
||||
|
||||
// To be called right before raising the recursion depth.
|
||||
fn check_recursive_call(&self, _where: &str) -> PyResult<()> {
|
||||
if self.recursion_depth.get() >= self.recursion_limit.get() {
|
||||
@@ -794,7 +803,7 @@ fn test_nested_frozen() {
|
||||
let code_obj = vm
|
||||
.compile(
|
||||
"from dir_module.dir_module_inner import value2",
|
||||
vm::compile::Mode::Exec,
|
||||
vm::compiler::Mode::Exec,
|
||||
"<embedded>".to_owned(),
|
||||
)
|
||||
.map_err(|err| vm.new_syntax_error(&err))
|
||||
|
||||
+8
-6
@@ -1,5 +1,3 @@
|
||||
#[cfg(feature = "rustpython-compiler")]
|
||||
use crate::compiler::{CompileError, CompileErrorType};
|
||||
use crate::{
|
||||
builtins::{
|
||||
pystr::IntoPyStrRef,
|
||||
@@ -209,13 +207,17 @@ impl VirtualMachine {
|
||||
self.new_exception_msg(overflow_error, msg)
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustpython-compiler")]
|
||||
pub fn new_syntax_error(&self, error: &CompileError) -> PyBaseExceptionRef {
|
||||
#[cfg(any(feature = "rustpython-parser", feature = "rustpython-codegen"))]
|
||||
pub fn new_syntax_error(&self, error: &crate::compiler::CompileError) -> PyBaseExceptionRef {
|
||||
let syntax_error_type = match &error.error {
|
||||
CompileErrorType::Parse(p) if p.is_indentation_error() => {
|
||||
#[cfg(feature = "rustpython-parser")]
|
||||
crate::compiler::CompileErrorType::Parse(p) if p.is_indentation_error() => {
|
||||
self.ctx.exceptions.indentation_error
|
||||
}
|
||||
CompileErrorType::Parse(p) if p.is_tab_error() => self.ctx.exceptions.tab_error,
|
||||
#[cfg(feature = "rustpython-parser")]
|
||||
crate::compiler::CompileErrorType::Parse(p) if p.is_tab_error() => {
|
||||
self.ctx.exceptions.tab_error
|
||||
}
|
||||
_ => self.ctx.exceptions.syntax_error,
|
||||
}
|
||||
.to_owned();
|
||||
|
||||
@@ -4,7 +4,7 @@ use js_sys::{Array, ArrayBuffer, Object, Promise, Reflect, SyntaxError, Uint8Arr
|
||||
use rustpython_parser::error::ParseErrorType;
|
||||
use rustpython_vm::{
|
||||
builtins::PyBaseExceptionRef,
|
||||
compile::{CompileError, CompileErrorType},
|
||||
compiler::{CompileError, CompileErrorType},
|
||||
exceptions,
|
||||
function::{ArgBytesLike, FuncArgs},
|
||||
py_serde, AsObject, PyObjectRef, PyPayload, PyResult, TryFromBorrowedObject, VirtualMachine,
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ pub fn _setup_console_error() {
|
||||
pub mod eval {
|
||||
use crate::vm_class::VMStore;
|
||||
use js_sys::{Object, Reflect, TypeError};
|
||||
use rustpython_vm::compile::Mode;
|
||||
use rustpython_vm::compiler::Mode;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
const PY_EVAL_VM_ID: &str = "__py_eval_vm";
|
||||
|
||||
@@ -5,10 +5,8 @@ use crate::{
|
||||
};
|
||||
use js_sys::{Object, TypeError};
|
||||
use rustpython_vm::{
|
||||
builtins::PyWeak,
|
||||
compile::{self, Mode},
|
||||
scope::Scope,
|
||||
Interpreter, PyObjectRef, PyPayload, PyRef, PyResult, Settings, VirtualMachine,
|
||||
builtins::PyWeak, compiler::Mode, scope::Scope, Interpreter, PyObjectRef, PyPayload, PyRef,
|
||||
PyResult, Settings, VirtualMachine,
|
||||
};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
@@ -324,7 +322,7 @@ impl WASMVirtualMachine {
|
||||
pub(crate) fn run(
|
||||
&self,
|
||||
source: &str,
|
||||
mode: compile::Mode,
|
||||
mode: Mode,
|
||||
source_path: Option<String>,
|
||||
) -> Result<JsValue, JsValue> {
|
||||
self.with_vm(|vm, StoredVirtualMachine { ref scope, .. }| {
|
||||
@@ -337,11 +335,11 @@ impl WASMVirtualMachine {
|
||||
}
|
||||
|
||||
pub fn exec(&self, source: &str, source_path: Option<String>) -> Result<JsValue, JsValue> {
|
||||
self.run(source, compile::Mode::Exec, source_path)
|
||||
self.run(source, Mode::Exec, source_path)
|
||||
}
|
||||
|
||||
pub fn eval(&self, source: &str, source_path: Option<String>) -> Result<JsValue, JsValue> {
|
||||
self.run(source, compile::Mode::Eval, source_path)
|
||||
self.run(source, Mode::Eval, source_path)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = execSingle)]
|
||||
@@ -350,6 +348,6 @@ impl WASMVirtualMachine {
|
||||
source: &str,
|
||||
source_path: Option<String>,
|
||||
) -> Result<JsValue, JsValue> {
|
||||
self.run(source, compile::Mode::Single, source_path)
|
||||
self.run(source, Mode::Single, source_path)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user