]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: libproc_macro: Change cpp literal representation
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Wed, 10 May 2023 13:17:46 +0000 (15:17 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:37:19 +0000 (18:37 +0100)
Change the literal representation on cpp side to match the new one in
rust. This means FFIString had to be implemented on cpp side. A few
helper functions has also been introduced.

libgrust/ChangeLog:

* libproc_macro/Makefile.am: Add ffistring unit to
compiled objects list.
* libproc_macro/Makefile.in: Regenerate.
* libproc_macro/literal.cc (Literal::drop): Change with
a call to ffistring drop function.
(Literal::make_literal): Add new helper constructor
(Literal__drop): Remove this function.
(Literal__string): Likewise.
(Literal__byte_string): Likewise.
(Literal__from_string): Moved this function.
(Literal::make_unsigned): Changed the constructor to match the
new layout.
(Literal::make_signed): Likewise.
(Literal::clone): Reimplement th eclone function.
(Literal::make_u8): Changed the constructor, make suffixed by
default.
(Literal::make_u16): Likewise.
(Literal::make_u32): Likewise.
(Literal::make_u64): Likewise.
(Literal::make_i8): Likewise.
(Literal::make_i16): Likewise.
(Literal::make_i32): Likewise.
(Literal::make_i64): Likewise.
(Literal::make_string): Likewise.
(Literal::make_byte_string): Likewise.
(Literal::make_f32): Likewise.
(Literal::make_f64): Likewise.
(Literal::make_char): Likewise.
(Literal::make_usize): Likewise.
(Literal::make_isize): Likewise.
(LitKind::make_byte): Add new helper constructor to avoid having
to set the payload value.
(LitKind::make_char): Likewise.
(LitKind::make_integer): Likewise.
(LitKind::make_float): Likewise.
(LitKind::make_str): Likewise.
(LitKind::make_str_raw): Add a new helper constructor which
takes the payload value as an argument.
(LitKind::make_byte_str): Add new helper constructor to avoid
mistakes with payload value.
(LitKind::make_byte_str_raw): Add a new helper constructor which
takes the payload value as an argument.
* libproc_macro/literal.h: Add new functions prototype.
(enum UnsignedTag): Removed because it is now unused.
(struct Payload128): Likewise.
(union UnsignedPayload): Likewise.
(struct Unsigned): Likewise.
(enum SignedTag): Likewise.
(union SignedPayload): Likewise.
(struct Signed): Likewise.
(enum LiteralTag): Likewise.
(enum LitKindTag): Likewise.
(struct StringPayload): Likewise.
(struct ByteStringPayload): Likewise.
(union LitKindPayload): Likewise.
(struct UnsignedSuffixPayload): Likewise.
(struct LitKind): Add new literal kind struct representation to
match the enum on rust side.
(struct SignedSuffixPayload): Removed because now unused.
(struct UsizePayload): Likewise.
(struct IsizePayload): Likewise.
(struct Float32Payload): Likewise.
(struct Float64Payload): Likewise.
(union LiteralPayload): Likewise.
(struct Literal): Changed the internals of the structure.
(Literal__drop): Removed the drop function fom the c interface.
(Literal__string): Removed unused function.
(Literal__byte_string): Removed unused function.
* libproc_macro/ffistring.cc: New file.
* libproc_macro/ffistring.h: New file.

gcc/rust/ChangeLog:

* lex/rust-token.h: Implement hash for token id enumeration.
* util/rust-token-converter.cc (dispatch_float_literals): Update
to new internals.
(dispatch_integer_literals): Likewise.
(convert): Likewise.
(string_literal): Remove function.
(byte_string_literal): Likewise.
(unsigned_literal): Likewise.
(signed_literal): Likewise.
(from_literal): Update with new internals.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/lex/rust-token.h
gcc/rust/util/rust-token-converter.cc
libgrust/libproc_macro/Makefile.am
libgrust/libproc_macro/Makefile.in
libgrust/libproc_macro/ffistring.cc [new file with mode: 0644]
libgrust/libproc_macro/ffistring.h [new file with mode: 0644]
libgrust/libproc_macro/literal.cc
libgrust/libproc_macro/literal.h

index c7ec753a123eea41dc760c169b19de8f2c3585da..716b3ce3686ba0cc7ab16e8ca564335ccb0159d0 100644 (file)
@@ -456,4 +456,16 @@ return *str;
 };
 } // namespace Rust
 
+namespace std {
+template <> struct hash<Rust::PrimitiveCoreType>
+{
+  size_t operator() (const Rust::PrimitiveCoreType &coretype) const noexcept
+  {
+    return hash<std::underlying_type<Rust::PrimitiveCoreType>::type> () (
+      static_cast<std::underlying_type<Rust::PrimitiveCoreType>::type> (
+       coretype));
+  }
+};
+} // namespace std
+
 #endif
index 2047ea729678c50a67a3b92c5db8972e38ec4754..d56493f5411c2ef21589ede1b5d59f288932f40b 100644 (file)
 #include "rust-lex.h"
 #include "rust-token-converter.h"
 #include "libproc_macro/proc_macro.h"
+#include "bi-map.h"
+
+#include <string>
 
 namespace Rust {
 
+static const BiMap<PrimitiveCoreType, std::string> suffixes
+  = {{{CORETYPE_F32, "f32"},
+      {CORETYPE_F64, "f64"},
+      {CORETYPE_U8, "u8"},
+      {CORETYPE_U16, "u16"},
+      {CORETYPE_U32, "u32"},
+      {CORETYPE_U64, "u64"},
+      {CORETYPE_U128, "u128"},
+      {CORETYPE_I8, "i8"},
+      {CORETYPE_I16, "i16"},
+      {CORETYPE_I32, "i32"},
+      {CORETYPE_I64, "i64"},
+      {CORETYPE_I128, "i128"},
+      {CORETYPE_ISIZE, "isize"},
+      {CORETYPE_USIZE, "usize"}}};
+
 static void
 pop_group (std::vector<ProcMacro::TokenStream> &streams,
           ProcMacro::Delimiter delim)
@@ -35,93 +54,24 @@ static void
 dispatch_float_literals (ProcMacro::TokenStream &ts,
                         const const_TokenPtr &token)
 {
-  std::string::size_type sz;
   auto str = token->as_string ();
-  switch (token->get_type_hint ())
-    {
-      case CORETYPE_F32: {
-       auto value = std::stof (str, &sz);
-       ts.push (ProcMacro::TokenTree::make_tokentree (
-         ProcMacro::Literal::make_f32 (value, sz != str.length ())));
-      }
-      break;
-      case CORETYPE_F64: {
-       auto value = std::stod (str, &sz);
-       ts.push (ProcMacro::TokenTree::make_tokentree (
-         ProcMacro::Literal::make_f64 (value, sz != str.length ())));
-      }
-      break;
-    default:
-      gcc_unreachable ();
-    }
+  auto kind = ProcMacro::LitKind::make_float ();
+  auto lookup = suffixes.lookup (token->get_type_hint ());
+  auto suffix = suffixes.is_iter_ok (lookup) ? lookup->second : "";
+  ts.push (ProcMacro::TokenTree::make_tokentree (
+    ProcMacro::Literal::make_literal (kind, str, suffix)));
 }
 
 static void
 dispatch_integer_literals (ProcMacro::TokenStream &ts,
                           const const_TokenPtr &token)
 {
-  std::string::size_type sz;
   auto str = token->as_string ();
-  unsigned long long uvalue;
-  long long svalue;
-
-  switch (token->get_type_hint ())
-    {
-    case CORETYPE_U8:
-      uvalue = std::stoull (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_u8 (uvalue, sz != str.length ())));
-      break;
-    case CORETYPE_U16:
-      uvalue = std::stoull (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_u16 (uvalue, sz != str.length ())));
-      break;
-    case CORETYPE_U32:
-      uvalue = std::stoull (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_u32 (uvalue, sz != str.length ())));
-      break;
-    case CORETYPE_U64:
-      uvalue = std::stoull (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_u32 (uvalue, sz != str.length ())));
-      break;
-    case CORETYPE_I8:
-      svalue = std::stoll (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_i8 (svalue, sz != str.length ())));
-      break;
-    case CORETYPE_I16:
-      svalue = std::stoll (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_i16 (svalue, sz != str.length ())));
-      break;
-    case CORETYPE_I32:
-      svalue = std::stoll (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_i32 (svalue, sz != str.length ())));
-      break;
-    case CORETYPE_I64:
-      svalue = std::stoll (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_i32 (svalue, sz != str.length ())));
-      break;
-    case CORETYPE_INT:
-      svalue = std::stoll (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_isize (svalue, sz != str.length ())));
-      break;
-    case CORETYPE_UINT:
-      uvalue = std::stoull (str, &sz);
-      ts.push (ProcMacro::TokenTree::make_tokentree (
-       ProcMacro::Literal::make_usize (uvalue, sz != str.length ())));
-      break;
-    case CORETYPE_UNKNOWN:
-    default:
-      gcc_unreachable ();
-      break;
-    }
+  auto kind = ProcMacro::LitKind::make_integer ();
+  auto lookup = suffixes.lookup (token->get_type_hint ());
+  auto suffix = suffixes.is_iter_ok (lookup) ? lookup->second : "";
+  ts.push (ProcMacro::TokenTree::make_tokentree (
+    ProcMacro::Literal::make_literal (kind, str, suffix)));
 }
 
 ProcMacro::TokenStream
@@ -140,21 +90,25 @@ convert (const std::vector<const_TokenPtr> &tokens)
        case INT_LITERAL:
          dispatch_integer_literals (trees.back (), token);
          break;
-       // FIXME: Why does BYTE_CHAR_LITERAL is not handled by rustc ?
-       case CHAR_LITERAL: // TODO: UTF-8 handling
+       case CHAR_LITERAL:
          trees.back ().push (ProcMacro::TokenTree::make_tokentree (
-           ProcMacro::Literal::make_char (token->as_string ()[0])));
+           ProcMacro::Literal::make_literal (ProcMacro::LitKind::make_char (),
+                                             token->as_string ())));
          break;
        case STRING_LITERAL:
          trees.back ().push (ProcMacro::TokenTree::make_tokentree (
-           ProcMacro::Literal::make_string (token->as_string ())));
+           ProcMacro::Literal::make_literal (ProcMacro::LitKind::make_str (),
+                                             token->as_string ())));
          break;
-         case BYTE_STRING_LITERAL: {
-           auto str = token->as_string ();
-           std::vector<uint8_t> data (str.begin (), str.end ());
-           trees.back ().push (ProcMacro::TokenTree::make_tokentree (
-             ProcMacro::Literal::make_byte_string (data)));
-         }
+       case BYTE_CHAR_LITERAL:
+         trees.back ().push (ProcMacro::TokenTree::make_tokentree (
+           ProcMacro::Literal::make_literal (ProcMacro::LitKind::make_byte (),
+                                             token->as_string ())));
+         break;
+       case BYTE_STRING_LITERAL:
+         trees.back ().push (ProcMacro::TokenTree::make_tokentree (
+           ProcMacro::Literal::make_literal (
+             ProcMacro::LitKind::make_byte_str (), token->as_string ())));
          break;
        // Ident
        case IDENTIFIER:
@@ -321,91 +275,6 @@ from_ident (const ProcMacro::Ident &ident, std::vector<const_TokenPtr> &result)
   result.push_back (lexer.peek_token ());
 }
 
-static void
-string_literal (const ProcMacro::StringPayload &payload,
-               std::vector<const_TokenPtr> &result)
-{
-  // TODO: UTF-8 string
-  result.push_back (Token::make_string (
-    Location (),
-    std::string (reinterpret_cast<const char *> (payload.data), payload.len)));
-}
-
-static void
-byte_string_literal (const ProcMacro::ByteStringPayload &payload,
-                    std::vector<const_TokenPtr> &result)
-{
-  result.push_back (Token::make_byte_string (
-    Location (),
-    std::string (reinterpret_cast<const char *> (payload.data), payload.size)));
-}
-
-static void
-unsigned_literal (const ProcMacro::Unsigned &lit,
-                 std::vector<const_TokenPtr> &result)
-{
-  switch (lit.tag)
-    {
-    case ProcMacro::UNSIGNED_8:
-      result.push_back (Token::make_int (Location (),
-                                        std::to_string (lit.payload.unsigned8),
-                                        CORETYPE_U8));
-      break;
-    case ProcMacro::UNSIGNED_16:
-      result.push_back (
-       Token::make_int (Location (), std::to_string (lit.payload.unsigned16),
-                        CORETYPE_U16));
-      break;
-    case ProcMacro::UNSIGNED_32:
-      result.push_back (
-       Token::make_int (Location (), std::to_string (lit.payload.unsigned32),
-                        CORETYPE_U32));
-      break;
-    case ProcMacro::UNSIGNED_64:
-      result.push_back (
-       Token::make_int (Location (), std::to_string (lit.payload.unsigned64),
-                        CORETYPE_U64));
-      break;
-    case ProcMacro::UNSIGNED_128:
-      // TODO: Handle 128 bits
-    default:
-      gcc_unreachable ();
-    }
-}
-
-static void
-signed_literal (const ProcMacro::Signed &lit,
-               std::vector<const_TokenPtr> &result)
-{
-  switch (lit.tag)
-    {
-    case ProcMacro::SIGNED_8:
-      result.push_back (Token::make_int (Location (),
-                                        std::to_string (lit.payload.signed8),
-                                        CORETYPE_I8));
-      break;
-    case ProcMacro::SIGNED_16:
-      result.push_back (Token::make_int (Location (),
-                                        std::to_string (lit.payload.signed16),
-                                        CORETYPE_I16));
-      break;
-    case ProcMacro::SIGNED_32:
-      result.push_back (Token::make_int (Location (),
-                                        std::to_string (lit.payload.signed32),
-                                        CORETYPE_I32));
-      break;
-    case ProcMacro::SIGNED_64:
-      result.push_back (Token::make_int (Location (),
-                                        std::to_string (lit.payload.signed64),
-                                        CORETYPE_I64));
-      break;
-    case ProcMacro::SIGNED_128:
-      // TODO: Handle 128 bits
-    default:
-      gcc_unreachable ();
-    }
-}
-
 /**
  * Append the token corresponding to a given Literal to a vector.
  *
@@ -416,46 +285,39 @@ static void
 from_literal (const ProcMacro::Literal &literal,
              std::vector<const_TokenPtr> &result)
 {
-  switch (literal.tag)
+  auto lookup = suffixes.lookup (literal.suffix.to_string ());
+  auto suffix
+    = suffixes.is_iter_ok (lookup) ? lookup->second : CORETYPE_UNKNOWN;
+  // FIXME: Add spans instead of empty locations
+  switch (literal.kind.tag)
     {
-    case ProcMacro::STRING:
-      string_literal (literal.payload.string_payload, result);
-      break;
-    case ProcMacro::BYTE_STRING:
-      byte_string_literal (literal.payload.byte_string_payload, result);
+    case ProcMacro::BYTE:
+      result.push_back (
+       Token::make_byte_char (Location (), literal.text.to_string ()[0]));
       break;
     case ProcMacro::CHAR:
       result.push_back (
-       Token::make_char (Location (), literal.payload.char_payload));
+       Token::make_char (Location (), literal.text.to_string ()[0]));
       break;
-    case ProcMacro::UNSIGNED:
-      unsigned_literal (literal.payload.unsigned_payload.value, result);
-      break;
-    case ProcMacro::SIGNED:
-      signed_literal (literal.payload.signed_payload.value, result);
-      break;
-    case ProcMacro::USIZE:
+    case ProcMacro::INTEGER:
       result.push_back (
-       Token::make_int (Location (),
-                        std::to_string (literal.payload.usize_payload.value),
-                        CORETYPE_USIZE));
+       Token::make_int (Location (), literal.text.to_string (), suffix));
       break;
-    case ProcMacro::ISIZE:
+    case ProcMacro::FLOAT:
       result.push_back (
-       Token::make_int (Location (),
-                        std::to_string (literal.payload.isize_payload.value),
-                        CORETYPE_ISIZE));
+       Token::make_float (Location (), literal.text.to_string (), suffix));
       break;
-    case ProcMacro::FLOAT32:
-      result.push_back (Token::make_float (
-       Location (), std::to_string (literal.payload.float32_payload.value),
-       CORETYPE_F32));
+    case ProcMacro::STR:
+      result.push_back (
+       Token::make_string (Location (), literal.text.to_string ()));
       break;
-    case ProcMacro::FLOAT64:
-      result.push_back (Token::make_float (
-       Location (), std::to_string (literal.payload.float64_payload.value),
-       CORETYPE_F64));
+    case ProcMacro::BYTE_STR:
+      result.push_back (
+       Token::make_byte_string (Location (), literal.text.to_string ()));
       break;
+    // FIXME: Handle raw string
+    case ProcMacro::STR_RAW:
+    case ProcMacro::BYTE_STR_RAW:
     default:
       gcc_unreachable ();
     }
index 0fe221142486db0ab53ccac0bd2da4f31efae166..493508cd9ee64f363563179f7433e4a847976f38 100644 (file)
@@ -52,7 +52,14 @@ LIBOBJS = @LIBOBJS@
 objext = @OBJEXT@
 
 REQUIRED_OFILES =                                                      \
-       ./proc_macro.$(objext) ./literal.$(objext) ./group.$(objext) ./ident.$(objext) ./punct.$(objext) ./tokenstream.$(objext) ./tokentree.$(objext)
+       ./proc_macro.$(objext) \
+       ./literal.$(objext) \
+       ./group.$(objext) \
+       ./ident.$(objext) \
+       ./punct.$(objext) \
+       ./tokenstream.$(objext) \
+       ./tokentree.$(objext) \
+       ./ffistring.$(objext)
 
 all: $(TARGETLIB)
 
index 6eb5365d1ac9aa37dcbe96dc74caf4cd51570c28..36031effcab302e0693bc3b5471751e93d9e8008 100644 (file)
@@ -311,7 +311,14 @@ AM_MAKEFLAGS = \
 TARGETLIB = ./libproc_macro.a
 objext = @OBJEXT@
 REQUIRED_OFILES = \
-       ./proc_macro.$(objext) ./literal.$(objext) ./group.$(objext) ./ident.$(objext) ./punct.$(objext) ./tokenstream.$(objext) ./tokentree.$(objext)
+       ./proc_macro.$(objext) \
+       ./literal.$(objext) \
+       ./group.$(objext) \
+       ./ident.$(objext) \
+       ./punct.$(objext) \
+       ./tokenstream.$(objext) \
+       ./tokentree.$(objext) \
+       ./ffistring.$(objext)
 
 all: all-am
 
diff --git a/libgrust/libproc_macro/ffistring.cc b/libgrust/libproc_macro/ffistring.cc
new file mode 100644 (file)
index 0000000..1623bc9
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2023 Free Software Foundation, Inc.
+//
+// This file is part of the GNU Proc Macro Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+#include <cstring>
+#include "ffistring.h"
+
+namespace ProcMacro {
+void
+FFIString::drop (FFIString *str)
+{
+  delete[] str->data;
+  str->len = 0;
+}
+
+FFIString
+FFIString::make_ffistring (const std::string &str)
+{
+  return make_ffistring (reinterpret_cast<const unsigned char *> (str.c_str ()),
+                        str.length ());
+}
+
+FFIString
+FFIString::make_ffistring (const unsigned char *data, std::uint64_t len)
+{
+  const unsigned char *inner = new unsigned char[len];
+  return {inner, len};
+}
+
+FFIString
+FFIString::clone () const
+{
+  unsigned char *inner = new unsigned char[this->len];
+  std::memcpy (inner, this->data, this->len);
+  return {inner, this->len};
+}
+
+std::string
+FFIString::to_string () const
+{
+  return std::string (reinterpret_cast<const char *> (this->data), this->len);
+}
+
+} // namespace ProcMacro
diff --git a/libgrust/libproc_macro/ffistring.h b/libgrust/libproc_macro/ffistring.h
new file mode 100644 (file)
index 0000000..c151645
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (C) 2023 Free Software Foundation, Inc.
+//
+// This file is part of the GNU Proc Macro Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef FFISTRING_H
+#define FFISTRING_H
+
+#include <cstdint>
+#include <string>
+
+namespace ProcMacro {
+
+struct FFIString
+{
+  const unsigned char *data;
+  std::uint64_t len;
+
+public:
+  FFIString clone () const;
+  std::string to_string () const;
+  static FFIString make_ffistring (const std::string &str);
+  static FFIString make_ffistring (const unsigned char *data,
+                                  std::uint64_t len);
+  static void drop (FFIString *str);
+};
+
+extern "C" {
+FFIString
+FFIString__new (const unsigned char *data, std::uint64_t len);
+
+void
+FFIString__drop (FFIString *str);
+}
+
+} // namespace ProcMacro
+
+#endif /* ! FFISTRING_H */
index 39474ce3120afac93b06a9da56dabbd4330726e3..e3d171f72681582a557783f10bde1fda37929496 100644 (file)
 
 namespace ProcMacro {
 
-void
-Literal::drop (Literal *lit)
-{
-  switch (lit->tag)
-    {
-    case STRING:
-      delete[] lit->payload.string_payload.data;
-      lit->payload.string_payload.len = 0;
-      break;
-    case BYTE_STRING:
-      delete[] lit->payload.byte_string_payload.data;
-      lit->payload.byte_string_payload.size = 0;
-      break;
-    case CHAR:
-    case UNSIGNED:
-    case SIGNED:
-    case USIZE:
-    case ISIZE:
-    case FLOAT32:
-    case FLOAT64:
-      break;
-    }
-}
-
 extern "C" {
-
-void
-Literal__drop (Literal *lit)
-{
-  Literal::drop (lit);
-}
-
-Literal
-Literal__string (const unsigned char *str, std::uint64_t len)
-{
-  return Literal::make_string (str, len);
-}
-
-Literal
-Literal__byte_string (const std::uint8_t *bytes, std::uint64_t len)
-{
-  return Literal::make_byte_string (bytes, len);
-}
-
 bool
 Literal__from_string (const unsigned char *str, std::uint64_t len, Literal *lit)
 {
-  // FIXME: implement this function with parser
+  // FIXME: implement this function with lexer
   std::abort ();
   return false;
 }
 }
 
-Literal
-Literal::make_unsigned (UnsignedSuffixPayload p)
+void
+Literal::drop (Literal *lit)
 {
-  LiteralPayload payload;
-  payload.unsigned_payload = p;
-  return {UNSIGNED, payload};
+  FFIString::drop (&lit->text);
+  FFIString::drop (&lit->suffix);
 }
 
 Literal
-Literal::make_signed (SignedSuffixPayload p)
+Literal::clone () const
 {
-  LiteralPayload payload;
-  payload.signed_payload = p;
-  return {SIGNED, payload};
+  return {this->kind, this->text.clone (), this->has_suffix,
+         this->suffix.clone ()};
 }
 
 Literal
-Literal::clone () const
+Literal::make_literal (LitKind kind, const std::string &text,
+                      const std::string &suffix)
 {
-  Literal lit = *this;
-  switch (this->tag)
-    {
-    case STRING:
-      lit.payload.string_payload.data
-       = new unsigned char[lit.payload.string_payload.len];
-      std::memcpy (lit.payload.string_payload.data,
-                  this->payload.string_payload.data,
-                  lit.payload.string_payload.len);
-      break;
-    case BYTE_STRING:
-      lit.payload.byte_string_payload.data
-       = new uint8_t[lit.payload.byte_string_payload.size];
-      std::memcpy (lit.payload.byte_string_payload.data,
-                  this->payload.byte_string_payload.data,
-                  lit.payload.byte_string_payload.size);
-      break;
-    default:
-      break;
-    }
-  return lit;
+  auto ffi_text = FFIString::make_ffistring (text);
+  auto ffi_suffix = FFIString::make_ffistring (suffix);
+  return {kind, ffi_text, suffix != "", ffi_suffix};
 }
 
 Literal
 Literal::make_u8 (std::uint8_t value, bool suffixed)
 {
-  UnsignedPayload unsigned_payload;
-  unsigned_payload.unsigned8 = value;
-  Unsigned val{UNSIGNED_8, unsigned_payload};
-  UnsignedSuffixPayload payload{val, suffixed};
-
-  return make_unsigned (payload);
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "u8" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
 }
 
 Literal
 Literal::make_u16 (std::uint16_t value, bool suffixed)
 {
-  UnsignedPayload unsigned_payload;
-  unsigned_payload.unsigned16 = value;
-  Unsigned val{UNSIGNED_16, unsigned_payload};
-  UnsignedSuffixPayload payload{val, suffixed};
-
-  return make_unsigned (payload);
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "u16" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
 }
 
 Literal
 Literal::make_u32 (std::uint32_t value, bool suffixed)
 {
-  UnsignedPayload unsigned_payload;
-  unsigned_payload.unsigned32 = value;
-  Unsigned val{UNSIGNED_32, unsigned_payload};
-  UnsignedSuffixPayload payload{val, suffixed};
-
-  return make_unsigned (payload);
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "u32" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
 }
 
 Literal
 Literal::make_u64 (std::uint64_t value, bool suffixed)
 {
-  UnsignedPayload unsigned_payload;
-  unsigned_payload.unsigned64 = value;
-  Unsigned val{UNSIGNED_64, unsigned_payload};
-  UnsignedSuffixPayload payload{val, suffixed};
-
-  return make_unsigned (payload);
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "u64" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
 }
 
 Literal
 Literal::make_i8 (std::int8_t value, bool suffixed)
 {
-  SignedPayload signed_payload;
-  signed_payload.signed8 = value;
-  Signed val{SIGNED_8, signed_payload};
-  SignedSuffixPayload payload{val, suffixed};
-
-  return make_signed (payload);
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "i8" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
 }
 
 Literal
 Literal::make_i16 (std::int16_t value, bool suffixed)
 {
-  SignedPayload signed_payload;
-  signed_payload.signed16 = value;
-  Signed val{SIGNED_16, signed_payload};
-  SignedSuffixPayload payload{val, suffixed};
-
-  return make_signed (payload);
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "i16" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
 }
 
 Literal
 Literal::make_i32 (std::int32_t value, bool suffixed)
 {
-  SignedPayload signed_payload;
-  signed_payload.signed32 = value;
-  Signed val{SIGNED_32, signed_payload};
-  SignedSuffixPayload payload = {val, suffixed};
-
-  return make_signed (payload);
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "i32" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
 }
 
 Literal
 Literal::make_i64 (std::int64_t value, bool suffixed)
 {
-  SignedPayload signed_payload;
-  signed_payload.signed64 = value;
-  Signed val{SIGNED_64, signed_payload};
-  SignedSuffixPayload payload{val, suffixed};
-
-  return make_signed (payload);
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "i64" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
 }
 
 Literal
 Literal::make_string (const std::string &str)
 {
-  return make_string (reinterpret_cast<const unsigned char *> (str.c_str ()),
-                     str.length ());
+  auto text = FFIString::make_ffistring (str);
+  auto suffix = FFIString::make_ffistring ("");
+  return {LitKind::make_str (), text, false, suffix};
 }
 
 Literal
-Literal::make_string (const unsigned char *str, std::uint64_t len)
+Literal::make_byte_string (const std::vector<std::uint8_t> &vec)
 {
-  unsigned char *data = new unsigned char[len];
-  StringPayload str_payload = {data, len};
-  std::memcpy (data, str, len);
-  LiteralPayload payload;
-  payload.string_payload = str_payload;
-  return {STRING, payload};
+  auto text
+    = FFIString::make_ffistring (std::string (vec.cbegin (), vec.cend ()));
+  auto suffix = FFIString::make_ffistring ("");
+  return {LitKind::make_byte_str (), text, false, suffix};
 }
 
 Literal
-Literal::make_byte_string (const std::vector<std::uint8_t> &vec)
+Literal::make_f32 (float value, bool suffixed)
 {
-  return make_byte_string (vec.data (), vec.size ());
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "f32" : "");
+  return {LitKind::make_float (), text, suffixed, suffix};
 }
 
 Literal
-Literal::make_byte_string (const std::uint8_t *bytes, std::uint64_t len)
+Literal::make_f64 (double value, bool suffixed)
 {
-  std::uint8_t *data = new std::uint8_t[len];
-  ByteStringPayload bstr_payload = {data, len};
-  std::memcpy (data, bytes, len);
-  LiteralPayload payload;
-  payload.byte_string_payload = bstr_payload;
-  return {BYTE_STRING, payload};
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "f64" : "");
+  return {LitKind::make_float (), text, suffixed, suffix};
 }
 
 Literal
-Literal::make_f32 (float value, bool suffixed)
+Literal::make_char (std::uint32_t ch)
 {
-  Float32Payload f{value, suffixed};
-  LiteralPayload payload;
-  payload.float32_payload = f;
-  return {FLOAT32, payload};
+  auto text = FFIString::make_ffistring (std::to_string ((char) ch));
+  auto suffix = FFIString::make_ffistring ("");
+  return {LitKind::make_char (), text, false, suffix};
 }
 
 Literal
-Literal::make_f64 (double value, bool suffixed)
+Literal::make_usize (std::uint64_t value, bool suffixed)
 {
-  Float64Payload f{value, suffixed};
-  LiteralPayload payload;
-  payload.float64_payload = f;
-  return {FLOAT64, payload};
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "usize" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
 }
 
 Literal
-Literal::make_char (std::uint32_t ch)
+Literal::make_isize (std::int64_t value, bool suffixed)
+{
+  auto text = FFIString::make_ffistring (std::to_string (value));
+  auto suffix = FFIString::make_ffistring (suffixed ? "isize" : "");
+  return {LitKind::make_integer (), text, suffixed, suffix};
+}
+
+LitKind
+LitKind::make_byte ()
 {
-  LiteralPayload payload;
-  payload.char_payload = ch;
+  LitKindPayload payload;
+  return {BYTE, payload};
+}
+
+LitKind
+LitKind::make_char ()
+{
+  LitKindPayload payload;
   return {CHAR, payload};
 }
 
-Literal
-Literal::make_usize (std::uint64_t value, bool suffixed)
+LitKind
+LitKind::make_integer ()
 {
-  UsizePayload p{value, suffixed};
-  LiteralPayload payload;
-  payload.usize_payload = p;
-  return {USIZE, payload};
+  LitKindPayload payload;
+  return {INTEGER, payload};
 }
 
-Literal
-Literal::make_isize (std::int64_t value, bool suffixed)
+LitKind
+LitKind::make_float ()
+{
+  LitKindPayload payload;
+  return {FLOAT, payload};
+}
+
+LitKind
+LitKind::make_str ()
+{
+  LitKindPayload payload;
+  return {STR, payload};
+}
+
+LitKind
+LitKind::make_str_raw (std::uint8_t val)
+{
+  LitKindPayload payload;
+  payload.str_raw = val;
+  return {STR_RAW, payload};
+}
+
+LitKind
+LitKind::make_byte_str ()
+{
+  LitKindPayload payload;
+  return {BYTE_STR, payload};
+}
+
+LitKind
+LitKind::make_byte_str_raw (std::uint8_t val)
 {
-  IsizePayload p{value, suffixed};
-  LiteralPayload payload;
-  payload.isize_payload = p;
-  return {ISIZE, payload};
+  LitKindPayload payload;
+  payload.byte_str_raw = val;
+  return {BYTE_STR_RAW, payload};
 }
 
 } // namespace ProcMacro
index f48b534e3f0383083567a966f1e016ba681565d9..fa2df3f62ea060ec47d0c767992105e47b98d070 100644 (file)
 #include <cstdint>
 #include <string>
 #include <vector>
+#include "ffistring.h"
 
 namespace ProcMacro {
-enum UnsignedTag
-{
-  UNSIGNED_8,
-  UNSIGNED_16,
-  UNSIGNED_32,
-  UNSIGNED_64,
-  UNSIGNED_128
-};
-
-struct Payload128
-{
-  std::uint64_t low;
-  std::uint64_t high;
-};
-
-union UnsignedPayload
-{
-  std::uint8_t unsigned8;
-  std::uint16_t unsigned16;
-  std::uint32_t unsigned32;
-  std::uint64_t unsigned64;
-  Payload128 unsigned128;
-};
-
-struct Unsigned
-{
-  UnsignedTag tag;
-  UnsignedPayload payload;
-};
-
-enum SignedTag
-{
-  SIGNED_8,
-  SIGNED_16,
-  SIGNED_32,
-  SIGNED_64,
-  SIGNED_128
-};
-
-union SignedPayload
-{
-  std::int8_t signed8;
-  std::int16_t signed16;
-  std::int32_t signed32;
-  std::int64_t signed64;
-};
-
-struct Signed
-{
-  SignedTag tag;
-  SignedPayload payload;
-};
 
-enum LiteralTag
+enum LitKindTag
 {
-  STRING,
-  BYTE_STRING,
+  BYTE,
   CHAR,
-  UNSIGNED,
-  SIGNED,
-  USIZE,
-  ISIZE,
-  FLOAT32,
-  FLOAT64
-};
-
-struct StringPayload
-{
-  unsigned char *data;
-  std::uint64_t len;
+  INTEGER,
+  FLOAT,
+  STR,
+  STR_RAW,
+  BYTE_STR,
+  BYTE_STR_RAW,
 };
 
-struct ByteStringPayload
+union LitKindPayload
 {
-  std::uint8_t *data;
-  std::uint64_t size;
+  std::uint8_t str_raw;
+  std::uint8_t byte_str_raw;
 };
 
-struct UnsignedSuffixPayload
+struct LitKind
 {
-  Unsigned value;
-  bool suffix;
-};
+  LitKindTag tag;
+  LitKindPayload payload;
 
-struct SignedSuffixPayload
-{
-  Signed value;
-  bool suffix;
-};
-
-struct UsizePayload
-{
-  std::uint64_t value;
-  bool suffix;
-};
-
-struct IsizePayload
-{
-  std::int64_t value;
-  bool suffix;
-};
-
-struct Float32Payload
-{
-  float value;
-  bool suffix;
-};
-
-struct Float64Payload
-{
-  double value;
-  bool suffix;
-};
-
-union LiteralPayload
-{
-  StringPayload string_payload;
-  ByteStringPayload byte_string_payload;
-  std::uint32_t char_payload;
-  UnsignedSuffixPayload unsigned_payload;
-  SignedSuffixPayload signed_payload;
-  UsizePayload usize_payload;
-  IsizePayload isize_payload;
-  Float32Payload float32_payload;
-  Float64Payload float64_payload;
+private:
+public:
+  static LitKind make_byte ();
+  static LitKind make_char ();
+  static LitKind make_integer ();
+  static LitKind make_float ();
+  static LitKind make_str ();
+  static LitKind make_str_raw (std::uint8_t val);
+  static LitKind make_byte_str ();
+  static LitKind make_byte_str_raw (std::uint8_t val);
 };
 
 struct Literal
 {
-  LiteralTag tag;
-  LiteralPayload payload;
+  LitKind kind;
+  FFIString text;
+  bool has_suffix;
+  FFIString suffix;
+  // TODO: Add span once done in rust interface
 
 public:
   Literal clone () const;
 
-  static Literal make_u8 (std::uint8_t value, bool suffixed = false);
-  static Literal make_u16 (std::uint16_t value, bool suffixed = false);
-  static Literal make_u32 (std::uint32_t value, bool suffixed = false);
-  static Literal make_u64 (std::uint64_t value, bool suffixed = false);
+  static Literal make_literal (const LitKind kind, const std::string &text,
+                              const std::string &suffix = "");
+  static Literal make_u8 (std::uint8_t value, bool suffixed = true);
+  static Literal make_u16 (std::uint16_t value, bool suffixed = true);
+  static Literal make_u32 (std::uint32_t value, bool suffixed = true);
+  static Literal make_u64 (std::uint64_t value, bool suffixed = true);
 
-  static Literal make_i8 (std::int8_t value, bool suffixed = false);
-  static Literal make_i16 (std::int16_t value, bool suffixed = false);
-  static Literal make_i32 (std::int32_t value, bool suffixed = false);
-  static Literal make_i64 (std::int64_t value, bool suffixed = false);
+  static Literal make_i8 (std::int8_t value, bool suffixed = true);
+  static Literal make_i16 (std::int16_t value, bool suffixed = true);
+  static Literal make_i32 (std::int32_t value, bool suffixed = true);
+  static Literal make_i64 (std::int64_t value, bool suffixed = true);
 
   static Literal make_string (const std::string &str);
-  static Literal make_string (const unsigned char *str, std::uint64_t len);
   static Literal make_byte_string (const std::vector<std::uint8_t> &vec);
-  static Literal make_byte_string (const std::uint8_t *bytes,
-                                  std::uint64_t len);
 
   static Literal make_f32 (float value, bool suffixed = false);
   static Literal make_f64 (double value, bool suffixed = false);
 
   static Literal make_char (std::uint32_t ch);
-  static Literal make_usize (std::uint64_t value, bool suffixed = false);
-  static Literal make_isize (std::int64_t value, bool suffixed = false);
+  static Literal make_usize (std::uint64_t value, bool suffixed = true);
+  static Literal make_isize (std::int64_t value, bool suffixed = true);
 
   static void drop (Literal *lit);
-
-private:
-  static Literal make_unsigned (UnsignedSuffixPayload p);
-  static Literal make_signed (SignedSuffixPayload p);
 };
 
 extern "C" {
-void
-Literal__drop (Literal *lit);
-
-Literal
-Literal__string (const unsigned char *str, std::uint64_t len);
-
-Literal
-Literal__byte_string (const std::uint8_t *bytes, std::uint64_t len);
-
 bool
 Literal__from_string (const unsigned char *str, std::uint64_t len,
                      Literal *lit);