Lower values of char and byte literals
This commit is contained in:
parent
0218aeba7a
commit
9856144b0b
@ -983,9 +983,11 @@ fn from(ast_lit_kind: ast::LiteralKind) -> Self {
|
|||||||
let text = s.value().map(Box::from).unwrap_or_else(Default::default);
|
let text = s.value().map(Box::from).unwrap_or_else(Default::default);
|
||||||
Literal::String(text)
|
Literal::String(text)
|
||||||
}
|
}
|
||||||
LiteralKind::Byte => Literal::Uint(Default::default(), Some(BuiltinUint::U8)),
|
LiteralKind::Byte(b) => {
|
||||||
|
Literal::Uint(b.value().unwrap_or_default() as u128, Some(BuiltinUint::U8))
|
||||||
|
}
|
||||||
|
LiteralKind::Char(c) => Literal::Char(c.value().unwrap_or_default()),
|
||||||
LiteralKind::Bool(val) => Literal::Bool(val),
|
LiteralKind::Bool(val) => Literal::Bool(val),
|
||||||
LiteralKind::Char => Literal::Char(Default::default()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3507,6 +3507,94 @@ fn hover_const_eval() {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
This is a doc
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
// show char literal
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
/// This is a doc
|
||||||
|
const FOO$0: char = 'a';
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
*FOO*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
const FOO: char = 'a'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This is a doc
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
// show escaped char literal
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
/// This is a doc
|
||||||
|
const FOO$0: char = '\x61';
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
*FOO*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
const FOO: char = 'a'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This is a doc
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
// show byte literal
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
/// This is a doc
|
||||||
|
const FOO$0: u8 = b'a';
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
*FOO*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
const FOO: u8 = 97 (0x61)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This is a doc
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
// show escaped byte literal
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
/// This is a doc
|
||||||
|
const FOO$0: u8 = b'\x61';
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
*FOO*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
const FOO: u8 = 97 (0x61)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
This is a doc
|
This is a doc
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
//!
|
//!
|
||||||
//! The `cli` submodule implements some batch-processing analysis, primarily as
|
//! The `cli` submodule implements some batch-processing analysis, primarily as
|
||||||
//! a debugging aid.
|
//! a debugging aid.
|
||||||
#![recursion_limit = "512"]
|
|
||||||
|
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
|
|
||||||
|
@ -283,8 +283,8 @@ pub enum LiteralKind {
|
|||||||
ByteString(ast::ByteString),
|
ByteString(ast::ByteString),
|
||||||
IntNumber(ast::IntNumber),
|
IntNumber(ast::IntNumber),
|
||||||
FloatNumber(ast::FloatNumber),
|
FloatNumber(ast::FloatNumber),
|
||||||
Char,
|
Char(ast::Char),
|
||||||
Byte,
|
Byte(ast::Byte),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,12 +312,16 @@ pub fn kind(&self) -> LiteralKind {
|
|||||||
if let Some(t) = ast::ByteString::cast(token.clone()) {
|
if let Some(t) = ast::ByteString::cast(token.clone()) {
|
||||||
return LiteralKind::ByteString(t);
|
return LiteralKind::ByteString(t);
|
||||||
}
|
}
|
||||||
|
if let Some(t) = ast::Char::cast(token.clone()) {
|
||||||
|
return LiteralKind::Char(t);
|
||||||
|
}
|
||||||
|
if let Some(t) = ast::Byte::cast(token.clone()) {
|
||||||
|
return LiteralKind::Byte(t);
|
||||||
|
}
|
||||||
|
|
||||||
match token.kind() {
|
match token.kind() {
|
||||||
T![true] => LiteralKind::Bool(true),
|
T![true] => LiteralKind::Bool(true),
|
||||||
T![false] => LiteralKind::Bool(false),
|
T![false] => LiteralKind::Bool(false),
|
||||||
CHAR => LiteralKind::Char,
|
|
||||||
BYTE => LiteralKind::Byte,
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,48 @@ fn cast(syntax: SyntaxToken) -> Option<Self> {
|
|||||||
fn syntax(&self) -> &SyntaxToken { &self.syntax }
|
fn syntax(&self) -> &SyntaxToken { &self.syntax }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Char {
|
||||||
|
pub(crate) syntax: SyntaxToken,
|
||||||
|
}
|
||||||
|
impl std::fmt::Display for Char {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(&self.syntax, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl AstToken for Char {
|
||||||
|
fn can_cast(kind: SyntaxKind) -> bool { kind == CHAR }
|
||||||
|
fn cast(syntax: SyntaxToken) -> Option<Self> {
|
||||||
|
if Self::can_cast(syntax.kind()) {
|
||||||
|
Some(Self { syntax })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn syntax(&self) -> &SyntaxToken { &self.syntax }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Byte {
|
||||||
|
pub(crate) syntax: SyntaxToken,
|
||||||
|
}
|
||||||
|
impl std::fmt::Display for Byte {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(&self.syntax, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl AstToken for Byte {
|
||||||
|
fn can_cast(kind: SyntaxKind) -> bool { kind == BYTE }
|
||||||
|
fn cast(syntax: SyntaxToken) -> Option<Self> {
|
||||||
|
if Self::can_cast(syntax.kind()) {
|
||||||
|
Some(Self { syntax })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn syntax(&self) -> &SyntaxToken { &self.syntax }
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Ident {
|
pub struct Ident {
|
||||||
pub(crate) syntax: SyntaxToken,
|
pub(crate) syntax: SyntaxToken,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use rustc_lexer::unescape::{unescape_literal, Mode};
|
use rustc_lexer::unescape::{unescape_byte, unescape_char, unescape_literal, Mode};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, AstToken},
|
ast::{self, AstToken},
|
||||||
@ -406,3 +406,35 @@ fn test_string_escape() {
|
|||||||
check_string_value(r"C:\\Windows\\System32\\", "C:\\Windows\\System32\\");
|
check_string_value(r"C:\\Windows\\System32\\", "C:\\Windows\\System32\\");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ast::Char {
|
||||||
|
pub fn value(&self) -> Option<char> {
|
||||||
|
let mut text = self.text();
|
||||||
|
if text.starts_with('\'') {
|
||||||
|
text = &text[1..];
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if text.ends_with('\'') {
|
||||||
|
text = &text[0..text.len() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
unescape_char(text).ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ast::Byte {
|
||||||
|
pub fn value(&self) -> Option<u8> {
|
||||||
|
let mut text = self.text();
|
||||||
|
if text.starts_with("b\'") {
|
||||||
|
text = &text[2..];
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if text.ends_with('\'') {
|
||||||
|
text = &text[0..text.len() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
unescape_byte(text).ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -585,7 +585,7 @@ fn ty(&self) -> proc_macro2::Ident {
|
|||||||
|
|
||||||
fn lower(grammar: &Grammar) -> AstSrc {
|
fn lower(grammar: &Grammar) -> AstSrc {
|
||||||
let mut res = AstSrc {
|
let mut res = AstSrc {
|
||||||
tokens: "Whitespace Comment String ByteString IntNumber FloatNumber Ident"
|
tokens: "Whitespace Comment String ByteString IntNumber FloatNumber Char Byte Ident"
|
||||||
.split_ascii_whitespace()
|
.split_ascii_whitespace()
|
||||||
.map(|it| it.to_string())
|
.map(|it| it.to_string())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
|
@ -151,12 +151,12 @@ fn unquote(text: &str, prefix_len: usize, end_delimiter: char) -> Option<&str> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::LiteralKind::Char => {
|
ast::LiteralKind::Char(_) => {
|
||||||
if let Some(Err(e)) = unquote(text, 1, '\'').map(unescape_char) {
|
if let Some(Err(e)) = unquote(text, 1, '\'').map(unescape_char) {
|
||||||
push_err(1, e);
|
push_err(1, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::LiteralKind::Byte => {
|
ast::LiteralKind::Byte(_) => {
|
||||||
if let Some(Err(e)) = unquote(text, 2, '\'').map(unescape_byte) {
|
if let Some(Err(e)) = unquote(text, 2, '\'').map(unescape_byte) {
|
||||||
push_err(2, e);
|
push_err(2, e);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user