mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
gccrs: libproc_macro: Change rust literal internals
Rust interface literal internals were taking a type and storing that type. This lead to multiple problems such as various conversion from string to int/float/other type as well as dead end on undetermined types (type checker runs at a later stage). libgrust/ChangeLog: * libproc_macro/rust/bridge.rs: Add ffistring module. * libproc_macro/rust/bridge/literal.rs: Rework type internals. * libproc_macro/rust/bridge/ffistring.rs: New file. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
This commit is contained in:
parent
842a8307ca
commit
5605333c90
@ -1,3 +1,4 @@
|
|||||||
|
pub mod ffistring;
|
||||||
pub mod group;
|
pub mod group;
|
||||||
pub mod ident;
|
pub mod ident;
|
||||||
pub mod literal;
|
pub mod literal;
|
||||||
|
48
libgrust/libproc_macro/rust/bridge/ffistring.rs
Normal file
48
libgrust/libproc_macro/rust/bridge/ffistring.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use std::convert::TryInto;
|
||||||
|
use std::ffi::c_uchar;
|
||||||
|
use std::fmt;
|
||||||
|
use std::slice::from_raw_parts;
|
||||||
|
use std::str::from_utf8;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn FFIString__new(data: *const c_uchar, len: u64) -> FFIString;
|
||||||
|
fn FFIString__drop(string: *mut FFIString);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FFIString {
|
||||||
|
data: *const c_uchar,
|
||||||
|
len: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FFIString {
|
||||||
|
pub fn new(string: &str) -> FFIString {
|
||||||
|
unsafe { FFIString__new(string.as_ptr(), string.len() as u64) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for FFIString {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
FFIString::new(&self.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for FFIString {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
FFIString__drop(self as *mut FFIString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for FFIString {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.write_str(
|
||||||
|
from_utf8(unsafe {
|
||||||
|
from_raw_parts(self.data, self.len.try_into().map_err(|_| fmt::Error)?)
|
||||||
|
})
|
||||||
|
.map_err(|_| fmt::Error)?,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,220 +1,166 @@
|
|||||||
use bridge::span::Span;
|
use bridge::{ffistring::FFIString, span::Span};
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::TryInto;
|
||||||
use std::ffi::c_uchar;
|
use std::ffi::c_uchar;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use LexError;
|
use LexError;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn Literal__drop(literal: *mut Literal);
|
|
||||||
fn Literal__string(str: *const c_uchar, len: u64) -> Literal;
|
|
||||||
fn Literal__byte_string(bytes: *const u8, len: u64) -> Literal;
|
|
||||||
fn Literal__from_string(str: *const c_uchar, len: u64, lit: *mut Literal) -> bool;
|
fn Literal__from_string(str: *const c_uchar, len: u64, lit: *mut Literal) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Unsigned {
|
pub enum LitKind {
|
||||||
Unsigned8(u8),
|
Byte,
|
||||||
Unsigned16(u16),
|
Char,
|
||||||
Unsigned32(u32),
|
Integer,
|
||||||
Unsigned64(u64),
|
Float,
|
||||||
// u128 is not ffi safe, hence this representation
|
Str,
|
||||||
// https://github.com/rust-lang/rust/issues/54341
|
StrRaw(u8),
|
||||||
Unsigned128(u64, u64),
|
ByteStr,
|
||||||
|
ByteStrRaw(u8),
|
||||||
|
Err,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Signed {
|
pub struct Literal {
|
||||||
Signed8(i8),
|
kind: LitKind,
|
||||||
Signed16(i16),
|
text: FFIString,
|
||||||
Signed32(i32),
|
has_suffix: bool,
|
||||||
Signed64(i64),
|
suffix: FFIString,
|
||||||
// i128 is not ffi safe, hence this representation
|
// FIXME: Add span, cannot add whilst Span remain an empty type
|
||||||
// https://github.com/rust-lang/rust/issues/54341
|
|
||||||
Signed128(u64, u64),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
macro_rules! suffixed_int_literals {
|
||||||
#[derive(Debug)]
|
($($name: ident => $kind: ident,)*) => ($(
|
||||||
pub enum Literal {
|
pub fn $name(n : $kind) -> Literal {
|
||||||
/// String literal internal representation
|
Literal {
|
||||||
///
|
kind : LitKind::Integer,
|
||||||
/// # Note
|
text: FFIString::new(&n.to_string()),
|
||||||
/// This variant is constructed through FFI
|
has_suffix : true,
|
||||||
#[allow(dead_code)]
|
suffix: FFIString::new(stringify!($kind))
|
||||||
String {
|
}
|
||||||
data: *const c_uchar,
|
}
|
||||||
len: u64,
|
)*)
|
||||||
},
|
}
|
||||||
/// Bytestring literal internal representation
|
|
||||||
///
|
macro_rules! unsuffixed_int_literals {
|
||||||
/// # Note
|
($($name: ident => $kind: ident,)*) => ($(
|
||||||
/// This variant is constructed through FFI
|
pub fn $name(n : $kind) -> Literal {
|
||||||
#[allow(dead_code)]
|
Literal {
|
||||||
ByteString {
|
kind : LitKind::Integer,
|
||||||
data: *const u8,
|
text: FFIString::new(&n.to_string()),
|
||||||
size: u64,
|
has_suffix : false,
|
||||||
},
|
suffix: FFIString::new("")
|
||||||
Char(u32),
|
}
|
||||||
Unsigned(Unsigned, bool),
|
}
|
||||||
Signed(Signed, bool),
|
)*)
|
||||||
Usize(u64, bool),
|
|
||||||
ISize(i64, bool),
|
|
||||||
Float32(f32, bool),
|
|
||||||
Float64(f64, bool),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Literal {
|
impl Literal {
|
||||||
pub fn u8_suffixed(n: u8) -> Self {
|
suffixed_int_literals! {
|
||||||
Literal::Unsigned(Unsigned::Unsigned8(n), true)
|
u8_suffixed => u8,
|
||||||
|
u16_suffixed => u16,
|
||||||
|
u32_suffixed => u32,
|
||||||
|
u64_suffixed => u64,
|
||||||
|
u128_suffixed => u128,
|
||||||
|
usize_suffixed => usize,
|
||||||
|
i8_suffixed => i8,
|
||||||
|
i16_suffixed => i16,
|
||||||
|
i32_suffixed => i32,
|
||||||
|
i64_suffixed => i64,
|
||||||
|
i128_suffixed => i128,
|
||||||
|
isize_suffixed => isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn u16_suffixed(n: u16) -> Self {
|
unsuffixed_int_literals! {
|
||||||
Literal::Unsigned(Unsigned::Unsigned16(n), true)
|
u8_unsuffixed => u8,
|
||||||
}
|
u16_unsuffixed => u16,
|
||||||
|
u32_unsuffixed => u32,
|
||||||
pub fn u32_suffixed(n: u32) -> Self {
|
u64_unsuffixed => u64,
|
||||||
Literal::Unsigned(Unsigned::Unsigned32(n), true)
|
u128_unsuffixed => u128,
|
||||||
}
|
usize_unsuffixed => usize,
|
||||||
|
i8_unsuffixed => i8,
|
||||||
pub fn u64_suffixed(n: u64) -> Self {
|
i16_unsuffixed => i16,
|
||||||
Literal::Unsigned(Unsigned::Unsigned64(n), true)
|
i32_unsuffixed => i32,
|
||||||
}
|
i64_unsuffixed => i64,
|
||||||
|
i128_unsuffixed => i128,
|
||||||
pub fn u128_suffixed(n: u128) -> Self {
|
isize_unsuffixed => isize,
|
||||||
Literal::Unsigned(
|
|
||||||
Unsigned::Unsigned128(
|
|
||||||
(n >> 64).try_into().unwrap(),
|
|
||||||
(n & 0xFFFFFFFFFFFFFFFF).try_into().unwrap(),
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn usize_suffixed(n: usize) -> Self {
|
|
||||||
Literal::Usize(n.try_into().expect("Cannot convert usize to u64"), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i8_suffixed(n: i8) -> Self {
|
|
||||||
Literal::Signed(Signed::Signed8(n), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i16_suffixed(n: i16) -> Self {
|
|
||||||
Literal::Signed(Signed::Signed16(n), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i32_suffixed(n: i32) -> Self {
|
|
||||||
Literal::Signed(Signed::Signed32(n), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i64_suffixed(n: i64) -> Self {
|
|
||||||
Literal::Signed(Signed::Signed64(n), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i128_suffixed(n: i128) -> Self {
|
|
||||||
Literal::Signed(
|
|
||||||
Signed::Signed128(
|
|
||||||
(n >> 64).try_into().unwrap(),
|
|
||||||
(n & 0xFFFFFFFFFFFFFFFF).try_into().unwrap(),
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isize_suffixed(n: isize) -> Self {
|
|
||||||
Literal::ISize(n.try_into().expect("Cannot convert isize to i64"), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unsuffixed
|
|
||||||
|
|
||||||
pub fn u8_unsuffixed(n: u8) -> Self {
|
|
||||||
Literal::Unsigned(Unsigned::Unsigned8(n), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn u16_unsuffixed(n: u16) -> Self {
|
|
||||||
Literal::Unsigned(Unsigned::Unsigned16(n), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn u32_unsuffixed(n: u32) -> Self {
|
|
||||||
Literal::Unsigned(Unsigned::Unsigned32(n), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn u64_unsuffixed(n: u64) -> Self {
|
|
||||||
Literal::Unsigned(Unsigned::Unsigned64(n), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn u128_unsuffixed(n: u128) -> Self {
|
|
||||||
Literal::Unsigned(
|
|
||||||
Unsigned::Unsigned128(
|
|
||||||
(n >> 64).try_into().unwrap(),
|
|
||||||
(n & 0xFFFFFFFFFFFFFFFF).try_into().unwrap(),
|
|
||||||
),
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn usize_unsuffixed(n: usize) -> Self {
|
|
||||||
Literal::Usize(n.try_into().expect("Cannot convert usize to u64"), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i8_unsuffixed(n: i8) -> Self {
|
|
||||||
Literal::Signed(Signed::Signed8(n), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i16_unsuffixed(n: i16) -> Self {
|
|
||||||
Literal::Signed(Signed::Signed16(n), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i32_unsuffixed(n: i32) -> Self {
|
|
||||||
Literal::Signed(Signed::Signed32(n), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i64_unsuffixed(n: i64) -> Self {
|
|
||||||
Literal::Signed(Signed::Signed64(n), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i128_unsuffixed(n: i128) -> Self {
|
|
||||||
Literal::Signed(
|
|
||||||
Signed::Signed128(
|
|
||||||
(n >> 64).try_into().unwrap(),
|
|
||||||
(n & 0xFFFFFFFFFFFFFFFF).try_into().unwrap(),
|
|
||||||
),
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isize_unsuffixed(n: isize) -> Self {
|
|
||||||
Literal::ISize(n.try_into().expect("Cannot convert isize to i64"), false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32_unsuffixed(n: f32) -> Self {
|
pub fn f32_unsuffixed(n: f32) -> Self {
|
||||||
Literal::Float32(n, false)
|
let mut repr = n.to_string();
|
||||||
|
if !repr.contains('.') {
|
||||||
|
repr.push_str(".0");
|
||||||
|
}
|
||||||
|
|
||||||
|
Literal {
|
||||||
|
kind: LitKind::Float,
|
||||||
|
text: FFIString::new(&repr),
|
||||||
|
has_suffix: false,
|
||||||
|
suffix: FFIString::new(""),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32_suffixed(n: f32) -> Self {
|
pub fn f32_suffixed(n: f32) -> Self {
|
||||||
Literal::Float32(n, true)
|
Literal {
|
||||||
|
kind: LitKind::Float,
|
||||||
|
text: FFIString::new(&n.to_string()),
|
||||||
|
has_suffix: true,
|
||||||
|
suffix: FFIString::new("f32"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64_unsuffixed(n: f64) -> Self {
|
pub fn f64_unsuffixed(n: f64) -> Self {
|
||||||
Literal::Float64(n, false)
|
let mut repr = n.to_string();
|
||||||
|
if !repr.contains('.') {
|
||||||
|
repr.push_str(".0");
|
||||||
|
}
|
||||||
|
|
||||||
|
Literal {
|
||||||
|
kind: LitKind::Float,
|
||||||
|
text: FFIString::new(&repr),
|
||||||
|
has_suffix: false,
|
||||||
|
suffix: FFIString::new(""),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64_suffixed(n: f64) -> Self {
|
pub fn f64_suffixed(n: f64) -> Self {
|
||||||
Literal::Float64(n, true)
|
Literal {
|
||||||
|
kind: LitKind::Float,
|
||||||
|
text: FFIString::new(&n.to_string()),
|
||||||
|
has_suffix: true,
|
||||||
|
suffix: FFIString::new("f64"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn string(string: &str) -> Self {
|
pub fn string(string: &str) -> Self {
|
||||||
unsafe { Literal__string(string.as_ptr(), string.len().try_into().unwrap()) }
|
Literal {
|
||||||
|
kind: LitKind::Str,
|
||||||
|
text: FFIString::new(string),
|
||||||
|
has_suffix: false,
|
||||||
|
suffix: FFIString::new(""),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn character(c: char) -> Self {
|
pub fn character(c: char) -> Self {
|
||||||
Literal::Char(c.into())
|
Literal {
|
||||||
|
kind: LitKind::Char,
|
||||||
|
text: FFIString::new(&c.to_string()),
|
||||||
|
has_suffix: false,
|
||||||
|
suffix: FFIString::new(""),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn byte_string(bytes: &[u8]) -> Self {
|
pub fn byte_string(bytes: &[u8]) -> Self {
|
||||||
unsafe { Literal__byte_string(bytes.as_ptr(), bytes.len().try_into().unwrap()) }
|
Literal {
|
||||||
|
kind: LitKind::ByteStr,
|
||||||
|
text: FFIString::new(&bytes.escape_ascii().to_string()),
|
||||||
|
has_suffix: false,
|
||||||
|
suffix: FFIString::new(""),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
@ -226,138 +172,53 @@ impl Literal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Literal {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
match self {
|
|
||||||
Literal::String { .. } | Literal::ByteString { .. } => unsafe {
|
|
||||||
Literal__drop(self as *mut Literal)
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Literal {
|
impl fmt::Display for Literal {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
let text = &self.text.to_string();
|
||||||
Literal::String { data, len } => {
|
match self.kind {
|
||||||
let slice =
|
LitKind::Byte => {
|
||||||
unsafe { std::slice::from_raw_parts(*data, (*len).try_into().unwrap()) };
|
f.write_str("b'")?;
|
||||||
|
f.write_str(text)?;
|
||||||
|
f.write_str("'")?;
|
||||||
|
}
|
||||||
|
LitKind::Char => {
|
||||||
|
f.write_str("'")?;
|
||||||
|
f.write_str(text)?;
|
||||||
|
f.write_str("'")?;
|
||||||
|
}
|
||||||
|
LitKind::Str => {
|
||||||
f.write_str("\"")?;
|
f.write_str("\"")?;
|
||||||
f.write_str(std::str::from_utf8(slice).unwrap())?;
|
f.write_str(text)?;
|
||||||
f.write_str("\"")?;
|
f.write_str("\"")?;
|
||||||
}
|
}
|
||||||
Literal::ByteString { data, size } => {
|
LitKind::StrRaw(n) => {
|
||||||
|
f.write_str("r")?;
|
||||||
|
for _ in 0..n {
|
||||||
|
f.write_str("#")?;
|
||||||
|
}
|
||||||
|
f.write_str("\"")?;
|
||||||
|
f.write_str(text)?;
|
||||||
|
f.write_str("\"")?;
|
||||||
|
}
|
||||||
|
LitKind::ByteStr => {
|
||||||
f.write_str("b\"")?;
|
f.write_str("b\"")?;
|
||||||
let slice =
|
f.write_str(text)?;
|
||||||
unsafe { std::slice::from_raw_parts(*data, (*size).try_into().unwrap()) };
|
f.write_str("\"")?;
|
||||||
for &byte in slice {
|
|
||||||
if byte != b'"' && (b' '..=b'z').contains(&byte) {
|
|
||||||
char::try_from(byte).unwrap().fmt(f)?;
|
|
||||||
} else {
|
|
||||||
write!(f, "\\x{:02x}", byte)?;
|
|
||||||
}
|
}
|
||||||
|
LitKind::ByteStrRaw(n) => {
|
||||||
|
f.write_str("br")?;
|
||||||
|
for _ in 0..n {
|
||||||
|
f.write_str("#")?;
|
||||||
}
|
}
|
||||||
f.write_str("b\"")?;
|
f.write_str("\"")?;
|
||||||
}
|
f.write_str(text)?;
|
||||||
Literal::Char(val) => {
|
f.write_str("\"")?;
|
||||||
let ch: char = (*val).try_into().unwrap();
|
|
||||||
match ch {
|
|
||||||
'\'' => f.write_str("'\\''")?,
|
|
||||||
'\0' => f.write_str("'\\0'")?,
|
|
||||||
'\n' => f.write_str("'\\n'")?,
|
|
||||||
' '..='z' => write!(f, "'{}'", ch)?,
|
|
||||||
_ => write!(f, "'\\u{:x}'", val)?,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Literal::Unsigned(val, suffixed) => match val {
|
|
||||||
Unsigned::Unsigned8(val) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("u8")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Unsigned::Unsigned16(val) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("u16")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Unsigned::Unsigned32(val) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("u32")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Unsigned::Unsigned64(val) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("u64")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Unsigned::Unsigned128(h, l) => {
|
|
||||||
((u128::from(*h) << 64) & u128::from(*l)).fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("u128")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Literal::Signed(val, suffixed) => match val {
|
|
||||||
Signed::Signed8(val) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("i8")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Signed::Signed16(val) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("i16")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Signed::Signed32(val) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("i32")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Signed::Signed64(val) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("i64")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Signed::Signed128(h, l) => {
|
|
||||||
((i128::from(*h) << 64) & i128::from(*l)).fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("i128")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Literal::Usize(val, suffixed) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("usize")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Literal::ISize(val, suffixed) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("isize")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Literal::Float32(val, suffixed) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("f32")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Literal::Float64(val, suffixed) => {
|
|
||||||
val.fmt(f)?;
|
|
||||||
if *suffixed {
|
|
||||||
f.write_str("f64")?;
|
|
||||||
}
|
}
|
||||||
|
_ => f.write_str(text)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.has_suffix {
|
||||||
|
f.write_str(&self.suffix.to_string())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -367,7 +228,13 @@ impl FromStr for Literal {
|
|||||||
type Err = LexError;
|
type Err = LexError;
|
||||||
|
|
||||||
fn from_str(string: &str) -> Result<Self, LexError> {
|
fn from_str(string: &str) -> Result<Self, LexError> {
|
||||||
let mut lit = Literal::Char(0);
|
// Structure that will be filled in by the cpp
|
||||||
|
let mut lit = Literal {
|
||||||
|
kind: LitKind::Err,
|
||||||
|
text: FFIString::new(""),
|
||||||
|
has_suffix: false,
|
||||||
|
suffix: FFIString::new(""),
|
||||||
|
};
|
||||||
// TODO: We might want to pass a LexError by reference to retrieve
|
// TODO: We might want to pass a LexError by reference to retrieve
|
||||||
// error information
|
// error information
|
||||||
if unsafe {
|
if unsafe {
|
||||||
@ -383,19 +250,3 @@ impl FromStr for Literal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Literal {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
match self {
|
|
||||||
Literal::String { data, len } => unsafe { Literal__string(*data, *len) },
|
|
||||||
Literal::ByteString { data, size } => unsafe { Literal__byte_string(*data, *size) },
|
|
||||||
Literal::Char(val) => Literal::Char(*val),
|
|
||||||
Literal::Unsigned(val, suffixed) => Literal::Unsigned(*val, *suffixed),
|
|
||||||
Literal::Signed(val, suffixed) => Literal::Signed(*val, *suffixed),
|
|
||||||
Literal::Usize(val, suffixed) => Literal::Usize(*val, *suffixed),
|
|
||||||
Literal::ISize(val, suffixed) => Literal::ISize(*val, *suffixed),
|
|
||||||
Literal::Float32(val, suffixed) => Literal::Float32(*val, *suffixed),
|
|
||||||
Literal::Float64(val, suffixed) => Literal::Float64(*val, *suffixed),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user