diff --git a/Cargo.lock b/Cargo.lock index 7e6c4dae1a..66bd5aae98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,6 +24,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +[[package]] +name = "ahash" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" + [[package]] name = "ahash" version = "0.6.2" @@ -876,6 +882,9 @@ name = "hashbrown" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +dependencies = [ + "ahash 0.4.7", +] [[package]] name = "hermit-abi" @@ -1875,7 +1884,7 @@ dependencies = [ name = "rustpython-compiler-core" version = "0.1.2" dependencies = [ - "ahash", + "ahash 0.6.2", "indexmap", "insta", "itertools", @@ -1885,6 +1894,7 @@ dependencies = [ "rustpython-ast", "rustpython-bytecode", "rustpython-parser", + "scopeguard", ] [[package]] @@ -1922,7 +1932,8 @@ dependencies = [ name = "rustpython-parser" version = "0.1.2" dependencies = [ - "ahash", + "ahash 0.6.2", + "hashbrown", "lalrpop", "lalrpop-util", "log", @@ -1948,7 +1959,7 @@ name = "rustpython-vm" version = "0.1.2" dependencies = [ "adler32", - "ahash", + "ahash 0.6.2", "atty", "base64", "bitflags", @@ -2233,13 +2244,12 @@ checksum = "ae524f056d7d770e174287294f562e95044c68e88dec909a00d2094805db9d75" [[package]] name = "socket2" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", "winapi", ] diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 2b8cc2d723..f750b0f8d9 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -5,4 +5,4 @@ authors = ["RustPython Team"] edition = "2018" [dependencies] -num-bigint = "0.3" +num-bigint = { version = "0.3", default-features = false } diff --git a/ast/src/ast.rs b/ast/src/ast.rs index 43b04ff44e..46cbe0aea7 100644 --- a/ast/src/ast.rs +++ b/ast/src/ast.rs @@ -5,6 +5,7 @@ //! location of the node. pub use crate::location::Location; +use alloc::{boxed::Box, string::String, vec::Vec}; use num_bigint::BigInt; #[allow(clippy::large_enum_variant)] diff --git a/ast/src/lib.rs b/ast/src/lib.rs index acc0e36214..d92bae3417 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -1,3 +1,7 @@ +#![no_std] + +extern crate alloc; + mod ast; mod location; diff --git a/ast/src/location.rs b/ast/src/location.rs index 324c2a33c2..3e9f4ee217 100644 --- a/ast/src/location.rs +++ b/ast/src/location.rs @@ -1,6 +1,6 @@ //! Datatypes to support source location information. -use std::fmt; +use core::fmt; /// A location somewhere in the sourcecode. #[derive(Clone, Copy, Debug, Default, PartialEq)] diff --git a/bytecode/Cargo.toml b/bytecode/Cargo.toml index b01c6eacd3..04247553dc 100644 --- a/bytecode/Cargo.toml +++ b/bytecode/Cargo.toml @@ -7,13 +7,16 @@ edition = "2018" repository = "https://github.com/RustPython/RustPython" license = "MIT" +[features] +std = ["bstr/std", "itertools/use_std", "lz4_flex/std"] +default = ["std"] [dependencies] bincode = "1.1" bitflags = "1.1" -lz4_flex = "0.7" -num-bigint = { version = "0.3", features = ["serde"] } -num-complex = { version = "0.3", features = ["serde"] } +lz4_flex = { version = "0.7", default-features = false, features = ["safe-decode", "safe-encode"] } +num-bigint = { version = "0.3", default-features = false, features = ["serde"] } +num-complex = { version = "0.3", default-features = false, features = ["serde"] } serde = { version = "1.0", features = ["derive"] } -itertools = "0.9" -bstr = "0.2" +itertools = { version = "0.9", default-features = false } +bstr = { version = "0.2", default-features = false } diff --git a/bytecode/src/lib.rs b/bytecode/src/lib.rs index 691bd507a8..3c231d17ee 100644 --- a/bytecode/src/lib.rs +++ b/bytecode/src/lib.rs @@ -3,15 +3,19 @@ #![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")] #![doc(html_root_url = "https://docs.rs/rustpython-bytecode/")] +#![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + +use alloc::collections::BTreeSet; +use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec}; use bitflags::bitflags; use bstr::ByteSlice; +use core::fmt; use itertools::Itertools; use num_bigint::BigInt; use num_complex::Complex64; use serde::{Deserialize, Serialize}; -use std::collections::BTreeSet; -use std::fmt; /// Sourcecode location. #[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)] @@ -722,6 +726,7 @@ impl fmt::Display for CodeDeserializeError { } } } +#[cfg(feature = "std")] impl std::error::Error for CodeDeserializeError {} impl CodeObject { diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 9baa8ff4d3..3c1032915d 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -7,15 +7,20 @@ repository = "https://github.com/RustPython/RustPython" license = "MIT" edition = "2018" +[features] +std = ["rustpython-bytecode/std", "itertools/use_std"] +default = ["std"] + [dependencies] indexmap = "1.0" -itertools = "0.9" -rustpython-bytecode = { path = "../bytecode", version = "0.1.1" } +itertools = { version = "0.9", default-features = false } +rustpython-bytecode = { path = "../bytecode", version = "0.1.1", default-features = false } rustpython-ast = { path = "../ast" } num-complex = { version = "0.3", features = ["serde"] } num-traits = "0.2" log = "0.4" ahash = "0.6" +scopeguard = "1.1" [dev-dependencies] rustpython-parser = { path = "../parser" } diff --git a/compiler/porcelain/Cargo.toml b/compiler/porcelain/Cargo.toml index e07c746c1a..171f64f8c1 100644 --- a/compiler/porcelain/Cargo.toml +++ b/compiler/porcelain/Cargo.toml @@ -5,6 +5,10 @@ description = "A usability wrapper around rustpython-parser and rustpython-compi authors = ["RustPython Team"] edition = "2018" +[features] +std = ["rustpython-compiler-core/std", "rustpython-bytecode/std", "rustpython-parser/std"] +default = ["std"] + [dependencies] thiserror = "1.0" rustpython-compiler-core = { path = ".." } diff --git a/compiler/src/compile.rs b/compiler/src/compile.rs index 46e0e4c1e4..14d9b832c1 100644 --- a/compiler/src/compile.rs +++ b/compiler/src/compile.rs @@ -10,12 +10,15 @@ use crate::ir::{self, CodeInfo}; pub use crate::mode::Mode; use crate::symboltable::{make_symbol_table, statements_to_symbol_table, SymbolScope, SymbolTable}; use crate::IndexSet; +use alloc::{borrow::ToOwned, boxed::Box, format, string::String, vec, vec::Vec}; use itertools::Itertools; use num_complex::Complex64; use num_traits::ToPrimitive; use rustpython_ast as ast; use rustpython_bytecode::{self as bytecode, CodeObject, ConstantData, Instruction}; +pub use crate::mode::Mode; + type CompileResult = Result; enum NameUsage { diff --git a/compiler/src/error.rs b/compiler/src/error.rs index f1fa58e5c0..c41772e4ee 100644 --- a/compiler/src/error.rs +++ b/compiler/src/error.rs @@ -1,7 +1,9 @@ use rustpython_ast::Location; +use alloc::string::String; +use core::fmt; +#[cfg(feature = "std")] use std::error::Error; -use std::fmt; #[derive(Debug)] pub struct CompileError { @@ -78,6 +80,7 @@ impl fmt::Display for CompileErrorType { } } +#[cfg(feature = "std")] impl Error for CompileErrorType {} impl fmt::Display for CompileError { @@ -86,8 +89,5 @@ impl fmt::Display for CompileError { } } -impl Error for CompileError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - None - } -} +#[cfg(feature = "std")] +impl Error for CompileError {} diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 3116547de3..f06dc6767c 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -1,6 +1,9 @@ //! Compile a Python AST or source code into bytecode consumable by RustPython. #![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")] #![doc(html_root_url = "https://docs.rs/rustpython-compiler/")] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; #[macro_use] extern crate log; diff --git a/compiler/src/mode.rs b/compiler/src/mode.rs index f926309aff..f28bfbd1f4 100644 --- a/compiler/src/mode.rs +++ b/compiler/src/mode.rs @@ -1,3 +1,5 @@ +use core::fmt; + #[derive(Clone, Copy)] pub enum Mode { Exec, @@ -5,7 +7,7 @@ pub enum Mode { Single, } -impl std::str::FromStr for Mode { +impl core::str::FromStr for Mode { type Err = ModeParseError; fn from_str(s: &str) -> Result { match s { @@ -22,8 +24,8 @@ pub struct ModeParseError { _priv: (), } -impl std::fmt::Display for ModeParseError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl fmt::Display for ModeParseError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, r#"mode should be "exec", "eval", or "single""#) } } diff --git a/compiler/src/symboltable.rs b/compiler/src/symboltable.rs index 4f22b8df5a..e09aab93bf 100644 --- a/compiler/src/symboltable.rs +++ b/compiler/src/symboltable.rs @@ -9,8 +9,9 @@ Inspirational file: https://github.com/python/cpython/blob/master/Python/symtabl use crate::error::{CompileError, CompileErrorType}; use crate::IndexMap; +use alloc::{borrow::ToOwned, format, string::String, vec, vec::Vec}; +use core::fmt; use rustpython_ast::{self as ast, Location}; -use std::fmt; pub fn make_symbol_table(program: &ast::Program) -> Result { let mut builder = SymbolTableBuilder::default(); @@ -187,8 +188,8 @@ impl SymbolTable { } } -impl std::fmt::Debug for SymbolTable { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl fmt::Debug for SymbolTable { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "SymbolTable({:?} symbols, {:?} sub scopes)", @@ -209,8 +210,9 @@ fn analyze_symbol_table(symbol_table: &mut SymbolTable) -> SymbolTableResult { type SymbolMap = IndexMap; mod stack { - use std::panic; - use std::ptr::NonNull; + use alloc::vec::Vec; + use core::ptr::NonNull; + pub struct StackStack { v: Vec>, } @@ -227,9 +229,10 @@ mod stack { F: FnOnce(&mut Self) -> R, { self.v.push(x.into()); - let res = panic::catch_unwind(panic::AssertUnwindSafe(|| f(self))); - self.v.pop(); - res.unwrap_or_else(|x| panic::resume_unwind(x)) + let mut this = scopeguard::guard(self, |this| { + this.v.pop(); + }); + f(&mut this) } pub fn iter(&self) -> impl Iterator + DoubleEndedIterator + '_ { @@ -273,7 +276,7 @@ struct SymbolTableAnalyzer { impl SymbolTableAnalyzer { fn analyze_symbol_table(&mut self, symbol_table: &mut SymbolTable) -> SymbolTableResult { - let symbols = std::mem::take(&mut symbol_table.symbols); + let symbols = core::mem::take(&mut symbol_table.symbols); let sub_tables = &mut *symbol_table.sub_tables; let mut info = (symbols, symbol_table.typ); @@ -469,7 +472,7 @@ impl SymbolTableAnalyzer { SymbolTableType::Class => { // named expressions are forbidden in comprehensions on class scope return Err(SymbolTableError { - error: "assignment expression within a comprehension cannot be used in a class body".to_string(), + error: "assignment expression within a comprehension cannot be used in a class body".to_owned(), // TODO: accurate location info, somehow location: Location::default(), }); @@ -999,7 +1002,7 @@ impl SymbolTableBuilder { // comprehension iterator definitions if let ExpressionContext::IterDefinitionExp = context { return Err(SymbolTableError { - error: "assignment expression cannot be used in a comprehension iterable expression".to_string(), + error: "assignment expression cannot be used in a comprehension iterable expression".to_owned(), // TODO: accurate location info, somehow location: Location::default(), }); @@ -1218,7 +1221,7 @@ impl SymbolTableBuilder { return Err(SymbolTableError { error: "assignment expression cannot be used in a comprehension iterable expression" - .to_string(), + .to_owned(), location, }); } diff --git a/parser/Cargo.toml b/parser/Cargo.toml index 2550555fd6..a1a6682728 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -8,17 +8,22 @@ repository = "https://github.com/RustPython/RustPython" license = "MIT" edition = "2018" +[features] +std = [] +default = ["std", "lalrpop-util/std", "num-bigint/std"] + [build-dependencies] -lalrpop = "0.19" +lalrpop = "0.19.4" [dependencies] rustpython-ast = { path = "../ast" } -lalrpop-util = "0.19.1" +lalrpop-util = { version = "0.19.4", default-features = false } log = "0.4.1" -num-bigint = "0.3" -num-traits = "0.2" +num-bigint = { version = "0.3", default-features = false } +num-traits = { version = "0.2", default-features = false } unic-emoji-char = "0.9" unic-ucd-ident = "0.9" unicode_names2 = "0.4" phf = { version = "0.8", features = ["macros"] } ahash = "0.6" +hashbrown = "0.9" diff --git a/parser/src/error.rs b/parser/src/error.rs index 3fee075ec6..616d0cce6c 100644 --- a/parser/src/error.rs +++ b/parser/src/error.rs @@ -5,8 +5,10 @@ use lalrpop_util::ParseError as LalrpopError; use crate::ast::Location; use crate::token::Tok; +use alloc::{boxed::Box, string::String}; +use core::fmt; +#[cfg(feature = "std")] use std::error::Error; -use std::fmt; /// Represents an error during lexical scanning. #[derive(Debug, PartialEq)] @@ -70,6 +72,16 @@ impl fmt::Display for LexicalErrorType { } } +#[cfg(feature = "std")] +impl Error for LexicalErrorType { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + LexicalErrorType::FStringError(e) => Some(e), + _ => None, + } + } +} + // TODO: consolidate these with ParseError #[derive(Debug, PartialEq)] pub struct FStringError { @@ -119,6 +131,16 @@ impl From for LalrpopError { } } +#[cfg(feature = "std")] +impl Error for FStringErrorType { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + FStringErrorType::InvalidExpression(e) => Some(e.as_ref()), + _ => None, + } + } +} + /// Represents an error during parsing #[derive(Debug, PartialEq)] pub struct ParseError { @@ -204,14 +226,22 @@ impl fmt::Display for ParseErrorType { } } -impl Error for ParseErrorType {} +#[cfg(feature = "std")] +impl Error for ParseErrorType { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + ParseErrorType::Lexical(e) => Some(e), + _ => None, + } + } +} impl ParseErrorType { pub fn is_indentation_error(&self) -> bool { match self { ParseErrorType::Lexical(LexicalErrorType::IndentationError) => true, ParseErrorType::UnrecognizedToken(token, expected) => { - *token == Tok::Indent || expected.clone() == Some("Indent".to_owned()) + *token == Tok::Indent || expected.as_ref().map_or(false, |s| s == "Indent") } _ => false, } @@ -225,15 +255,16 @@ impl ParseErrorType { } } -impl std::ops::Deref for ParseError { +impl core::ops::Deref for ParseError { type Target = ParseErrorType; fn deref(&self) -> &Self::Target { &self.error } } +#[cfg(feature = "std")] impl Error for ParseError { fn source(&self) -> Option<&(dyn Error + 'static)> { - None + self.error.source() } } diff --git a/parser/src/fstring.rs b/parser/src/fstring.rs index b67f9e462d..23772c3b38 100644 --- a/parser/src/fstring.rs +++ b/parser/src/fstring.rs @@ -1,6 +1,5 @@ -use std::iter; -use std::mem; -use std::str; +use alloc::{borrow::ToOwned, boxed::Box, format, string::String, vec, vec::Vec}; +use core::{iter, mem, str}; use crate::ast::{ConversionFlag, Expression, Location, StringGroup}; use crate::error::{FStringError, FStringErrorType, ParseError}; @@ -81,7 +80,7 @@ impl<'a> FStringParser<'a> { // match a python 3.8 self documenting expression // format '{' PYTHON_EXPRESSION '=' FORMAT_SPECIFIER? '}' '=' if self.chars.peek() != Some(&'=') && delims.is_empty() => { - pred_expression_text = expression.to_string(); // safe expression before = to print it + pred_expression_text = expression.to_owned(); // safe expression before = to print it } ':' if delims.is_empty() => { diff --git a/parser/src/function.rs b/parser/src/function.rs index 2ff18b44fd..bb8eb9ff51 100644 --- a/parser/src/function.rs +++ b/parser/src/function.rs @@ -1,5 +1,5 @@ -use ahash::RandomState; -use std::collections::HashSet; +use alloc::{string::String, vec, vec::Vec}; +use hashbrown::HashSet; use crate::ast; use crate::error::{LexicalError, LexicalErrorType}; @@ -46,7 +46,8 @@ pub fn parse_args(func_args: Vec) -> Result { diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs index 268be3863a..5a2e405a71 100644 --- a/parser/src/lexer.rs +++ b/parser/src/lexer.rs @@ -5,12 +5,19 @@ pub use super::token::Tok; use crate::ast::Location; use crate::error::{LexicalError, LexicalErrorType}; +use alloc::{ + borrow::ToOwned, + format, + string::{String, ToString}, + vec, + vec::Vec, +}; +use core::char; +use core::cmp::Ordering; +use core::str::FromStr; use num_bigint::BigInt; use num_traits::identities::Zero; use num_traits::Num; -use std::char; -use std::cmp::Ordering; -use std::str::FromStr; use unic_emoji_char::is_emoji_presentation; use unic_ucd_ident::{is_xid_continue, is_xid_start}; @@ -436,8 +443,8 @@ where } } match p { - 0xD800..=0xDFFF => Ok(std::char::REPLACEMENT_CHARACTER), - _ => std::char::from_u32(p).ok_or(unicode_error), + 0xD800..=0xDFFF => Ok(char::REPLACEMENT_CHARACTER), + _ => char::from_u32(p).ok_or(unicode_error), } } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 80030e61b9..0e697c18b7 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -17,6 +17,13 @@ #![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")] #![doc(html_root_url = "https://docs.rs/rustpython-parser/")] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +// hack to get around lalrpop hardcoding ::std::* paths +#[cfg(not(feature = "std"))] +extern crate self as std; #[macro_use] extern crate log; diff --git a/parser/src/mode.rs b/parser/src/mode.rs index 7614aa82f3..92cf394e83 100644 --- a/parser/src/mode.rs +++ b/parser/src/mode.rs @@ -1,10 +1,12 @@ +use core::fmt; + #[derive(Clone, Copy)] pub enum Mode { Program, Statement, } -impl std::str::FromStr for Mode { +impl core::str::FromStr for Mode { type Err = ModeParseError; fn from_str(s: &str) -> Result { match s { @@ -20,8 +22,8 @@ pub struct ModeParseError { _priv: (), } -impl std::fmt::Display for ModeParseError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl fmt::Display for ModeParseError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, r#"mode should be "exec", "eval", or "single""#) } } diff --git a/parser/src/parser.rs b/parser/src/parser.rs index a2659c4280..9d96975161 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -5,7 +5,8 @@ //! parse a whole program, a single statement, or a single //! expression. -use std::iter; +use alloc::vec::Vec; +use core::iter; use crate::ast; use crate::error::ParseError; @@ -106,6 +107,7 @@ mod tests { use super::parse_expression; use super::parse_program; use super::parse_statement; + use alloc::borrow::ToOwned; use num_bigint::BigInt; fn mk_ident(name: &str, row: usize, col: usize) -> ast::Expression { @@ -136,7 +138,7 @@ mod tests { custom: (), node: ast::ExpressionType::String { value: ast::StringGroup::Constant { - value: String::from(value), + value: value.to_owned(), }, }, } @@ -158,8 +160,8 @@ mod tests { #[test] fn test_parse_print_hello() { - let source = String::from("print('Hello world')"); - let parse_ast = parse_program(&source).unwrap(); + let source = "print('Hello world')"; + let parse_ast = parse_program(source).unwrap(); assert_eq!( parse_ast, ast::Program { @@ -184,8 +186,8 @@ mod tests { #[test] fn test_parse_print_2() { - let source = String::from("print('Hello world', 2)"); - let parse_ast = parse_program(&source).unwrap(); + let source = "print('Hello world', 2)"; + let parse_ast = parse_program(source).unwrap(); assert_eq!( parse_ast, ast::Program { @@ -210,8 +212,8 @@ mod tests { #[test] fn test_parse_kwargs() { - let source = String::from("my_func('positional', keyword=2)"); - let parse_ast = parse_program(&source).unwrap(); + let source = "my_func('positional', keyword=2)"; + let parse_ast = parse_program(source).unwrap(); assert_eq!( parse_ast, ast::Program { @@ -239,8 +241,8 @@ mod tests { #[test] fn test_parse_if_elif_else() { - let source = String::from("if 1: 10\nelif 2: 20\nelse: 30"); - let parse_ast = parse_statement(&source).unwrap(); + let source = "if 1: 10\nelif 2: 20\nelse: 30"; + let parse_ast = parse_statement(source).unwrap(); assert_eq!( parse_ast, vec![ast::Statement { @@ -265,8 +267,8 @@ mod tests { #[test] fn test_parse_lambda() { - let source = String::from("lambda x, y: x * y"); // lambda(x, y): x * y"); - let parse_ast = parse_statement(&source); + let source = "lambda x, y: x * y"; // lambda(x, y): x * y"); + let parse_ast = parse_statement(source); assert_eq!( parse_ast, Ok(vec![as_statement(ast::Expression { @@ -278,12 +280,12 @@ mod tests { args: vec![ ast::Parameter { location: ast::Location::new(1, 8), - arg: String::from("x"), + arg: "x".to_owned(), annotation: None, }, ast::Parameter { location: ast::Location::new(1, 11), - arg: String::from("y"), + arg: "y".to_owned(), annotation: None, } ], @@ -309,10 +311,10 @@ mod tests { #[test] fn test_parse_tuples() { - let source = String::from("a, b = 4, 5"); + let source = "a, b = 4, 5"; assert_eq!( - parse_statement(&source), + parse_statement(source), Ok(vec![ast::Statement { location: ast::Location::new(1, 1), custom: (), @@ -338,16 +340,19 @@ mod tests { #[test] fn test_parse_class() { - let source = String::from( - "class Foo(A, B):\n def __init__(self):\n pass\n def method_with_default(self, arg='default'):\n pass", - ); + let source = "\ +class Foo(A, B): + def __init__(self): + pass + def method_with_default(self, arg='default'): + pass"; assert_eq!( - parse_statement(&source), + parse_statement(source), Ok(vec![ast::Statement { location: ast::Location::new(1, 1), custom: (), node: ast::StatementType::ClassDef { - name: String::from("Foo"), + name: "Foo".to_owned(), bases: vec![mk_ident("A", 1, 11), mk_ident("B", 1, 14)], keywords: vec![], body: vec![ @@ -356,12 +361,12 @@ mod tests { custom: (), node: ast::StatementType::FunctionDef { is_async: false, - name: String::from("__init__"), + name: "__init__".to_owned(), args: Box::new(ast::Parameters { posonlyargs_count: 0, args: vec![ast::Parameter { location: ast::Location::new(2, 15), - arg: String::from("self"), + arg: "self".to_owned(), annotation: None, }], kwonlyargs: vec![], @@ -384,18 +389,18 @@ mod tests { custom: (), node: ast::StatementType::FunctionDef { is_async: false, - name: String::from("method_with_default"), + name: "method_with_default".to_owned(), args: Box::new(ast::Parameters { posonlyargs_count: 0, args: vec![ ast::Parameter { location: ast::Location::new(4, 26), - arg: String::from("self"), + arg: "self".to_owned(), annotation: None, }, ast::Parameter { location: ast::Location::new(4, 32), - arg: String::from("arg"), + arg: "arg".to_owned(), annotation: None, } ], @@ -423,8 +428,8 @@ mod tests { #[test] fn test_parse_dict_comprehension() { - let source = String::from("{x1: x2 for y in z}"); - let parse_ast = parse_expression(&source).unwrap(); + let source = "{x1: x2 for y in z}"; + let parse_ast = parse_expression(source).unwrap(); assert_eq!( parse_ast, ast::Expression { @@ -449,8 +454,8 @@ mod tests { #[test] fn test_parse_list_comprehension() { - let source = String::from("[x for y in z]"); - let parse_ast = parse_expression(&source).unwrap(); + let source = "[x for y in z]"; + let parse_ast = parse_expression(source).unwrap(); assert_eq!( parse_ast, ast::Expression { @@ -474,8 +479,8 @@ mod tests { #[test] fn test_parse_double_list_comprehension() { - let source = String::from("[x for y, y2 in z for a in b if a < 5 if a > 10]"); - let parse_ast = parse_expression(&source).unwrap(); + let source = "[x for y, y2 in z for a in b if a < 5 if a > 10]"; + let parse_ast = parse_expression(source).unwrap(); assert_eq!( parse_ast, ast::Expression { diff --git a/parser/src/python.lalrpop b/parser/src/python.lalrpop index 4fdfdc2f32..fc1b50cecd 100644 --- a/parser/src/python.lalrpop +++ b/parser/src/python.lalrpop @@ -3,13 +3,12 @@ // See also: file:///usr/share/doc/python/html/reference/compound_stmts.html#function-definitions // See also: https://greentreesnakes.readthedocs.io/en/latest/nodes.html#keyword -use std::iter::FromIterator; - use crate::ast; use crate::fstring::parse_located_fstring; use crate::function::{parse_args, parse_params}; use crate::error::LexicalError; use crate::lexer; +use alloc::{boxed::Box, string::{String, ToString}, vec, vec::Vec}; use num_bigint::BigInt; @@ -26,7 +25,7 @@ pub Top: ast::Top = { Program: ast::Program = { => ast::Program { - statements: Vec::from_iter(lines.into_iter().flatten()) + statements: lines.into_iter().flatten().collect(), }, }; diff --git a/parser/src/token.rs b/parser/src/token.rs index 316c34e48e..c7df437ff3 100644 --- a/parser/src/token.rs +++ b/parser/src/token.rs @@ -1,7 +1,8 @@ //! Different token definitions. //! Loosely based on token.h from CPython source: +use alloc::{string::String, vec::Vec}; +use core::fmt::{self, Write}; use num_bigint::BigInt; -use std::fmt::{self, Write}; /// Python source code can be tokenized in a sequence of these tokens. #[derive(Clone, Debug, PartialEq)] diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 2088b1f038..ca32f9bbb7 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -9,13 +9,14 @@ edition = "2018" include = ["src/**/*.rs", "Cargo.toml", "build.rs", "Lib/**/*.py"] [features] -default = ["compile-parse", "threading"] +default = ["compile-parse", "threading", "std"] vm-tracing-logging = [] flame-it = ["flame", "flamer"] freeze-stdlib = ["rustpython-pylib"] jit = ["rustpython-jit"] threading = ["rustpython-common/threading"] compile-parse = ["rustpython-parser", "rustpython-compiler"] +std = ["rustpython-compiler/std"] # enables compiler-core/std, parser/std, etc ssl = ["openssl", "openssl-sys", "openssl-probe"] diff --git a/vm/src/lib.rs b/vm/src/lib.rs index ad962df2b1..fc28b1eb5e 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -12,6 +12,7 @@ #![allow(clippy::module_inception)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")] #![doc(html_root_url = "https://docs.rs/rustpython-vm/")] +#![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "flame-it")] #[macro_use] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy