remove bigints

escape-analysis
Sebastien Bourdeauducq 2021-12-26 00:23:54 +08:00
parent ec986dfdf3
commit 80d3ab1b0f
22 changed files with 189 additions and 138 deletions

35
Cargo.lock generated
View File

@ -497,7 +497,6 @@ version = "0.1.0"
dependencies = [
"fxhash",
"lazy_static",
"num-bigint 0.4.3",
"parking_lot",
"string-interner",
]
@ -512,7 +511,6 @@ dependencies = [
"insta",
"itertools",
"nac3parser",
"num-bigint 0.3.3",
"num-traits",
"parking_lot",
"rayon",
@ -529,7 +527,6 @@ dependencies = [
"lalrpop-util",
"log",
"nac3ast",
"num-bigint 0.4.3",
"num-traits",
"phf",
"unic-emoji-char",
@ -553,38 +550,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "num-bigint"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-bigint"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"

View File

@ -10,7 +10,6 @@ constant-optimization = ["fold"]
fold = []
[dependencies]
num-bigint = "0.4.0"
lazy_static = "1.4.0"
parking_lot = "0.11.1"
string-interner = "0.13.0"

View File

@ -1,12 +1,10 @@
use num_bigint::BigInt;
#[derive(Clone, Debug, PartialEq)]
pub enum Constant {
None,
Bool(bool),
Str(String),
Bytes(Vec<u8>),
Int(BigInt),
Int(Option<i64>),
Tuple(Vec<Constant>),
Float(f64),
Complex { real: f64, imag: f64 },
@ -28,9 +26,14 @@ impl From<bool> for Constant {
Self::Bool(b)
}
}
impl From<BigInt> for Constant {
fn from(i: BigInt) -> Constant {
Self::Int(i)
impl From<i32> for Constant {
fn from(i: i32) -> Constant {
Self::Int(Some(i as i64))
}
}
impl From<i64> for Constant {
fn from(i: i64) -> Constant {
Self::Int(Some(i))
}
}
@ -136,7 +139,7 @@ mod tests {
location,
custom,
node: ExprKind::Constant {
value: BigInt::from(1).into(),
value: 1.into(),
kind: None,
},
},
@ -144,7 +147,7 @@ mod tests {
location,
custom,
node: ExprKind::Constant {
value: BigInt::from(2).into(),
value: 2.into(),
kind: None,
},
},
@ -158,7 +161,7 @@ mod tests {
location,
custom,
node: ExprKind::Constant {
value: BigInt::from(3).into(),
value: 3.into(),
kind: None,
},
},
@ -166,7 +169,7 @@ mod tests {
location,
custom,
node: ExprKind::Constant {
value: BigInt::from(4).into(),
value: 4.into(),
kind: None,
},
},
@ -174,7 +177,7 @@ mod tests {
location,
custom,
node: ExprKind::Constant {
value: BigInt::from(5).into(),
value: 5.into(),
kind: None,
},
},
@ -194,12 +197,12 @@ mod tests {
custom,
node: ExprKind::Constant {
value: Constant::Tuple(vec![
BigInt::from(1).into(),
BigInt::from(2).into(),
1.into(),
2.into(),
Constant::Tuple(vec![
BigInt::from(3).into(),
BigInt::from(4).into(),
BigInt::from(5).into(),
3.into(),
4.into(),
5.into(),
])
]),
kind: None

View File

@ -5,7 +5,6 @@ authors = ["M-Labs"]
edition = "2018"
[dependencies]
num-bigint = "0.3"
num-traits = "0.2"
itertools = "0.10.1"
crossbeam = "0.8.1"

View File

@ -123,7 +123,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
let ty = self.ctx.bool_type();
ty.const_int(if *v { 1 } else { 0 }, false).into()
}
Constant::Int(v) => {
Constant::Int(Some(val)) => {
let ty = if self.unifier.unioned(ty, self.primitives.int32) {
self.ctx.i32_type()
} else if self.unifier.unioned(ty, self.primitives.int64) {
@ -131,8 +131,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
} else {
unreachable!();
};
let val: i64 = v.try_into().unwrap();
ty.const_int(val as u64, false).into()
ty.const_int(*val as u64, false).into()
}
Constant::Float(v) => {
assert!(self.unifier.unioned(ty, self.primitives.float));

View File

@ -412,13 +412,23 @@ pub fn parse_parameter_default_value(default: &ast::Expr, resolver: &(dyn Symbol
fn handle_constant(val: &Constant, loc: &Location) -> Result<SymbolValue, String> {
match val {
Constant::Int(v) => {
if let Ok(v) = v.try_into() {
Ok(SymbolValue::I32(v))
} else {
Err(format!(
"integer value out of range at {}",
loc
))
match v {
Some(v) => {
if let Ok(v) = (*v).try_into() {
Ok(SymbolValue::I32(v))
} else {
Err(format!(
"integer value out of range at {}",
loc
))
}
},
None => {
Err(format!(
"integer value out of range at {}",
loc
))
}
}
}
Constant::Float(v) => Ok(SymbolValue::Double(*v)),
@ -439,8 +449,8 @@ pub fn parse_parameter_default_value(default: &ast::Expr, resolver: &(dyn Symbol
} => {
if args.len() == 1 {
match &args[0].node {
ast::ExprKind::Constant { value: Constant::Int(v), .. } =>
Ok(SymbolValue::I64(v.try_into().unwrap())),
ast::ExprKind::Constant { value: Constant::Int(Some(v)), .. } =>
Ok(SymbolValue::I64(*v)),
_ => Err(format!("only allow constant integer here at {}", default.location))
}
} else {

View File

@ -680,11 +680,8 @@ impl<'a> Inferencer<'a> {
if let ExprKind::Constant { value: ast::Constant::Int(val), kind } =
&args[0].node
{
let int64: Result<i64, _> = val.try_into();
let custom;
if int64.is_ok() {
custom = Some(self.primitives.int64);
} else {
let custom = Some(self.primitives.int64);
if val.is_none() {
return Err("Integer out of bound".into());
}
return Ok(Located {
@ -777,12 +774,17 @@ impl<'a> Inferencer<'a> {
match constant {
ast::Constant::Bool(_) => Ok(self.primitives.bool),
ast::Constant::Int(val) => {
let int32: Result<i32, _> = val.try_into();
// int64 would be handled separately in functions
if int32.is_ok() {
Ok(self.primitives.int32)
} else {
Err("Integer out of bound".into())
match val {
Some(val) => {
let int32: Result<i32, _> = (*val).try_into();
// int64 is handled separately in functions
if int32.is_ok() {
Ok(self.primitives.int32)
} else {
Err("Integer out of bound".into())
}
},
None => Err("Integer out of bound".into())
}
}
ast::Constant::Float(_) => Ok(self.primitives.float),
@ -907,7 +909,11 @@ impl<'a> Inferencer<'a> {
}
ast::ExprKind::Constant { value: ast::Constant::Int(val), .. } => {
// the index is a constant, so value can be a sequence.
let ind: i32 = val.try_into().map_err(|_| "Index must be int32".to_string())?;
let ind: Option<i32> = match val {
Some(val) => (*val).try_into().ok(),
None => None,
};
let ind = ind.ok_or_else(|| "Index must be int32".to_string())?;
let map = once((ind, ty)).collect();
let seq = self.unifier.add_sequence(map);
self.constrain(value.custom.unwrap(), seq, &value.location)?;

View File

@ -14,7 +14,6 @@ lalrpop = "0.19.6"
nac3ast = { path = "../nac3ast" }
lalrpop-util = "0.19.6"
log = "0.4.1"
num-bigint = "0.4.0"
num-traits = "0.2"
unic-emoji-char = "0.9"
unic-ucd-ident = "0.9"

View File

@ -5,12 +5,11 @@
pub use super::token::Tok;
use crate::ast::Location;
use crate::error::{LexicalError, LexicalErrorType};
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 std::num::IntErrorKind;
use unic_emoji_char::is_emoji_presentation;
use unic_ucd_ident::{is_xid_continue, is_xid_start};
@ -287,10 +286,18 @@ where
fn lex_number_radix(&mut self, start_pos: Location, radix: u32) -> LexResult {
let value_text = self.radix_run(radix);
let end_pos = self.get_pos();
let value = BigInt::from_str_radix(&value_text, radix).map_err(|e| LexicalError {
error: LexicalErrorType::OtherError(format!("{:?}", e)),
location: start_pos,
})?;
let value = match i64::from_str_radix(&value_text, radix) {
Ok(value) => Some(value),
Err(e) => {
match e.kind() {
IntErrorKind::PosOverflow | IntErrorKind::NegOverflow => None,
_ => return Err(LexicalError {
error: LexicalErrorType::OtherError(format!("{:?}", e)),
location: start_pos,
}),
}
}
};
Ok((start_pos, Tok::Int { value }, end_pos))
}
@ -353,8 +360,14 @@ where
Ok((start_pos, Tok::Complex { real: 0.0, imag }, end_pos))
} else {
let end_pos = self.get_pos();
let value = value_text.parse::<BigInt>().unwrap();
if start_is_zero && !value.is_zero() {
// assumption: value_text contains a valid integer.
// parse should only fail because of overflow.
let value = value_text.parse::<i64>().ok();
let nonzero = match value {
Some(value) => !value.is_zero(),
None => true
};
if start_is_zero && nonzero {
return Err(LexicalError {
error: LexicalErrorType::OtherError("Invalid Token".to_owned()),
location: self.get_pos(),
@ -1321,7 +1334,6 @@ where
#[cfg(test)]
mod tests {
use super::{make_tokenizer, NewlineHandler, Tok};
use num_bigint::BigInt;
const WINDOWS_EOL: &str = "\r\n";
const MAC_EOL: &str = "\r";
@ -1449,16 +1461,16 @@ class Foo(A, B):
tokens,
vec![
Tok::Int {
value: BigInt::from(47),
value: Some(47i64),
},
Tok::Int {
value: BigInt::from(13),
value: Some(13i64),
},
Tok::Int {
value: BigInt::from(0),
value: Some(0i64),
},
Tok::Int {
value: BigInt::from(123),
value: Some(123i64),
},
Tok::Float { value: 0.2 },
Tok::Complex {
@ -1481,7 +1493,7 @@ class Foo(A, B):
fn $name() {
let source = format!(r"99232 # {}", $eol);
let tokens = lex_source(&source);
assert_eq!(tokens, vec![Tok::Int { value: BigInt::from(99232) }, Tok::Newline]);
assert_eq!(tokens, vec![Tok::Int { value: Some(99232i64) }, Tok::Newline]);
}
)*
}
@ -1504,9 +1516,9 @@ class Foo(A, B):
assert_eq!(
tokens,
vec![
Tok::Int { value: BigInt::from(123) },
Tok::Int { value: Some(123i64) },
Tok::Newline,
Tok::Int { value: BigInt::from(456) },
Tok::Int { value: Some(456i64) },
Tok::Newline,
]
)
@ -1533,15 +1545,15 @@ class Foo(A, B):
},
Tok::Equal,
Tok::Int {
value: BigInt::from(99)
value: Some(99i64)
},
Tok::Plus,
Tok::Int {
value: BigInt::from(2)
value: Some(2i64)
},
Tok::Minus,
Tok::Int {
value: BigInt::from(0)
value: Some(0i64)
},
Tok::Newline,
]
@ -1568,7 +1580,7 @@ class Foo(A, B):
Tok::Newline,
Tok::Indent,
Tok::Return,
Tok::Int { value: BigInt::from(99) },
Tok::Int { value: Some(99i64) },
Tok::Newline,
Tok::Dedent,
]
@ -1611,7 +1623,7 @@ class Foo(A, B):
Tok::Newline,
Tok::Indent,
Tok::Return,
Tok::Int { value: BigInt::from(99) },
Tok::Int { value: Some(99i64) },
Tok::Newline,
Tok::Dedent,
Tok::Dedent,
@ -1649,7 +1661,7 @@ class Foo(A, B):
Tok::Newline,
Tok::Indent,
Tok::Return,
Tok::Int { value: BigInt::from(99) },
Tok::Int { value: Some(99i64) },
Tok::Newline,
Tok::Dedent,
Tok::Dedent,
@ -1687,9 +1699,9 @@ class Foo(A, B):
},
Tok::Equal,
Tok::Lsqb,
Tok::Int { value: BigInt::from(1) },
Tok::Int { value: Some(1i64) },
Tok::Comma,
Tok::Int { value: BigInt::from(2) },
Tok::Int { value: Some(2i64) },
Tok::Rsqb,
Tok::Newline,
]

View File

@ -31,7 +31,6 @@ pub fn parse_program(source: &str) -> Result<ast::Suite, ParseError> {
///
/// # Example
/// ```
/// extern crate num_bigint;
/// use nac3parser::{parser, ast};
/// let expr = parser::parse_expression("1 + 2").unwrap();
///

View File

@ -14,7 +14,6 @@ use crate::lexer;
use crate::config_comment_helper::*;
use lalrpop_util::ParseError;
use num_bigint::BigInt;
grammar;
@ -920,7 +919,7 @@ Factor: ast::Expr = {
match (&op, &e.node) {
(ast::Unaryop::USub, ast::ExprKind::Constant { value: Constant::Int(val), kind }) => {
ast::ExprKind::Constant {
value: Constant::Int(-val),
value: if let Some(val) = val { Constant::Int(Some(-val)) } else { Constant::Int(None) },
kind: kind.clone()
}
}
@ -1362,7 +1361,7 @@ extern {
"True" => lexer::Tok::True,
"False" => lexer::Tok::False,
"None" => lexer::Tok::None,
int => lexer::Tok::Int { value: <BigInt> },
int => lexer::Tok::Int { value: <Option<i64>> },
float => lexer::Tok::Float { value: <f64> },
complex => lexer::Tok::Complex { real: <f64>, imag: <f64> },
string => lexer::Tok::String { value: <String>, is_fstring: <bool> },

View File

@ -1,5 +1,6 @@
---
source: parser/src/fstring.rs
source: nac3parser/src/fstring.rs
assertion_line: 382
expression: parse_ast
---
@ -25,7 +26,9 @@ Located {
custom: (),
node: Constant {
value: Int(
42,
Some(
42,
),
),
kind: None,
},
@ -42,7 +45,9 @@ Located {
custom: (),
node: Constant {
value: Int(
42,
Some(
42,
),
),
kind: None,
},

View File

@ -1,5 +1,6 @@
---
source: parser/src/fstring.rs
source: nac3parser/src/fstring.rs
assertion_line: 375
expression: parse_ast
---
@ -25,7 +26,9 @@ Located {
custom: (),
node: Constant {
value: Int(
1,
Some(
1,
),
),
kind: None,
},
@ -42,7 +45,9 @@ Located {
custom: (),
node: Constant {
value: Int(
2,
Some(
2,
),
),
kind: None,
},

View File

@ -1,5 +1,6 @@
---
source: nac3parser/src/parser.rs
assertion_line: 218
expression: parse_program(&source).unwrap()
---
@ -172,7 +173,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
3,
Some(
3,
),
),
kind: None,
},
@ -219,7 +222,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
3,
Some(
3,
),
),
kind: None,
},
@ -262,7 +267,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
3,
Some(
3,
),
),
kind: None,
},
@ -337,7 +344,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
3,
Some(
3,
),
),
kind: None,
},

View File

@ -1,5 +1,6 @@
---
source: nac3parser/src/parser.rs
assertion_line: 186
expression: parse_program(&source).unwrap()
---
@ -74,7 +75,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
1,
Some(
1,
),
),
kind: None,
},
@ -177,7 +180,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
2,
Some(
2,
),
),
kind: None,
},
@ -220,7 +225,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
1,
Some(
1,
),
),
kind: None,
},
@ -234,7 +241,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
2,
Some(
2,
),
),
kind: None,
},
@ -263,7 +272,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
1,
Some(
1,
),
),
kind: None,
},
@ -284,7 +295,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
3,
Some(
3,
),
),
kind: None,
},

View File

@ -1,5 +1,6 @@
---
source: parser/src/parser.rs
source: nac3parser/src/parser.rs
assertion_line: 164
expression: parse_ast
---
@ -125,7 +126,9 @@ Located {
custom: (),
node: Constant {
value: Int(
5,
Some(
5,
),
),
kind: None,
},
@ -163,7 +166,9 @@ Located {
custom: (),
node: Constant {
value: Int(
10,
Some(
10,
),
),
kind: None,
},

View File

@ -1,5 +1,6 @@
---
source: nac3parser/src/parser.rs
assertion_line: 118
expression: parse_ast
---
@ -19,7 +20,9 @@ expression: parse_ast
custom: (),
node: Constant {
value: Int(
1,
Some(
1,
),
),
kind: None,
},
@ -40,7 +43,9 @@ expression: parse_ast
custom: (),
node: Constant {
value: Int(
10,
Some(
10,
),
),
kind: None,
},
@ -65,7 +70,9 @@ expression: parse_ast
custom: (),
node: Constant {
value: Int(
2,
Some(
2,
),
),
kind: None,
},
@ -86,7 +93,9 @@ expression: parse_ast
custom: (),
node: Constant {
value: Int(
20,
Some(
20,
),
),
kind: None,
},
@ -111,7 +120,9 @@ expression: parse_ast
custom: (),
node: Constant {
value: Int(
30,
Some(
30,
),
),
kind: None,
},

View File

@ -1,5 +1,6 @@
---
source: nac3parser/src/parser.rs
assertion_line: 111
expression: parse_ast
---
@ -63,7 +64,9 @@ expression: parse_ast
custom: (),
node: Constant {
value: Int(
2,
Some(
2,
),
),
kind: None,
},

View File

@ -1,5 +1,6 @@
---
source: nac3parser/src/parser.rs
assertion_line: 104
expression: parse_ast
---
@ -51,7 +52,9 @@ expression: parse_ast
custom: (),
node: Constant {
value: Int(
2,
Some(
2,
),
),
kind: None,
},

View File

@ -1,5 +1,6 @@
---
source: nac3parser/src/parser.rs
assertion_line: 132
expression: parse_program(&source).unwrap()
---
@ -63,7 +64,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
4,
Some(
4,
),
),
kind: None,
},
@ -76,7 +79,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
5,
Some(
5,
),
),
kind: None,
},

View File

@ -1,5 +1,6 @@
---
source: nac3parser/src/parser.rs
assertion_line: 199
expression: parse_program(&source).unwrap()
---
@ -51,7 +52,9 @@ expression: parse_program(&source).unwrap()
custom: (),
node: Constant {
value: Int(
3,
Some(
3,
),
),
kind: None,
},

View File

@ -1,6 +1,5 @@
//! Different token definitions.
//! Loosely based on token.h from CPython source:
use num_bigint::BigInt;
use std::fmt::{self, Write};
use crate::ast;
@ -8,7 +7,7 @@ use crate::ast;
#[derive(Clone, Debug, PartialEq)]
pub enum Tok {
Name { name: ast::StrRef },
Int { value: BigInt },
Int { value: Option<i64> },
Float { value: f64 },
Complex { real: f64, imag: f64 },
String { value: String, is_fstring: bool },
@ -113,7 +112,7 @@ impl fmt::Display for Tok {
use Tok::*;
match self {
Name { name } => write!(f, "'{}'", ast::get_str_from_ref(&ast::get_str_ref_lock(), *name)),
Int { value } => write!(f, "'{}'", value),
Int { value } => if let Some(value) = value { write!(f, "'{}'", value) } else { write!(f, "'#OFL#'") },
Float { value } => write!(f, "'{}'", value),
Complex { real, imag } => write!(f, "{}j{}", real, imag),
String { value, is_fstring } => {