Lower values of char and byte literals

This commit is contained in:
Laurențiu Nicola 2022-05-05 08:10:07 +03:00
parent 0218aeba7a
commit 9856144b0b
8 changed files with 178 additions and 11 deletions

View file

@ -283,8 +283,8 @@ pub enum LiteralKind {
ByteString(ast::ByteString),
IntNumber(ast::IntNumber),
FloatNumber(ast::FloatNumber),
Char,
Byte,
Char(ast::Char),
Byte(ast::Byte),
Bool(bool),
}
@ -312,12 +312,16 @@ impl ast::Literal {
if let Some(t) = ast::ByteString::cast(token.clone()) {
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() {
T![true] => LiteralKind::Bool(true),
T![false] => LiteralKind::Bool(false),
CHAR => LiteralKind::Char,
BYTE => LiteralKind::Byte,
_ => unreachable!(),
}
}

View file

@ -132,6 +132,48 @@ impl AstToken for FloatNumber {
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)]
pub struct Ident {
pub(crate) syntax: SyntaxToken,

View file

@ -2,7 +2,7 @@
use std::borrow::Cow;
use rustc_lexer::unescape::{unescape_literal, Mode};
use rustc_lexer::unescape::{unescape_byte, unescape_char, unescape_literal, Mode};
use crate::{
ast::{self, AstToken},
@ -406,3 +406,35 @@ mod tests {
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()
}
}