aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2023-11-30 14:11:41 +0100
committerCohenArthur <arthur.cohen@embecosm.com>2024-02-26 17:32:38 +0000
commit7b25f53a416868059299661ddf769ec4c9c2516d (patch)
tree78fb5b2af443b15fcd5dbc97a5bb73d6faae7288 /gcc/rust
parent486b2043a08ff49605ea7d52fc2c3f5403d72079 (diff)
downloadgcc-7b25f53a416868059299661ddf769ec4c9c2516d.zip
gcc-7b25f53a416868059299661ddf769ec4c9c2516d.tar.gz
gcc-7b25f53a416868059299661ddf769ec4c9c2516d.tar.bz2
libgrust: Add format_parser library
Compile libformat_parser and link to it. gcc/rust/ChangeLog: * Make-lang.in: Compile libformat_parser. * ast/rust-fmt.cc: New FFI definitions. * ast/rust-fmt.h: Likewise. * expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler): Call into libformat_parser. * expand/rust-macro-builtins.h: Define format_args!() handler proper. libgrust/ChangeLog: * libformat_parser/Cargo.lock: New file. * libformat_parser/Cargo.toml: New file. * libformat_parser/generic_format_parser/Cargo.toml: New file. * libformat_parser/generic_format_parser/src/lib.rs: New file. * libformat_parser/src/bin.rs: New file. * libformat_parser/src/lib.rs: New file.
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/Make-lang.in15
-rw-r--r--gcc/rust/ast/rust-fmt.cc77
-rw-r--r--gcc/rust/ast/rust-fmt.h189
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc12
-rw-r--r--gcc/rust/expand/rust-macro-builtins.h3
5 files changed, 141 insertions, 155 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 6696b47..7c8ab6e 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -54,6 +54,8 @@ GCCRS_D_OBJS = \
rust/rustspec.o \
$(END)
+LIBS += -ldl -lpthread
+
gccrs$(exeext): $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \
@@ -209,14 +211,14 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
-RUST_LDFLAGS = $(LDFLAGS) -L./../libgrust/libproc_macro_internal
-RUST_LIBDEPS = $(LIBDEPS) ../libgrust/libproc_macro_internal/libproc_macro_internal.a
+RUST_LDFLAGS = $(LDFLAGS) -L./../libgrust/libproc_macro_internal -L./../libgrust/librustc_format_parser/
+RUST_LIBDEPS = $(LIBDEPS) ../libgrust/libproc_macro_internal/libproc_macro_internal.a rust/libformat_parser.a
# The compiler itself is called crab1
crab1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(RUST_LIBDEPS) $(rust.prev)
@$(call LINK_PROGRESS,$(INDEX.rust),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(RUST_LDFLAGS) -o $@ \
- $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) ../libgrust/libproc_macro_internal/libproc_macro_internal.a $(BACKENDLIBS)
+ $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) ../libgrust/libproc_macro_internal/libproc_macro_internal.a rust/libformat_parser.a $(BACKENDLIBS)
@$(call LINK_PROGRESS,$(INDEX.rust),end)
# Build hooks.
@@ -402,6 +404,13 @@ rust/%.o: rust/lex/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
+%.toml:
+ echo $@
+
+rust/libformat_parser.a: $(srcdir)/../libgrust/libformat_parser/Cargo.toml $(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
+ cargo build --manifest-path $(srcdir)/../libgrust/libformat_parser/Cargo.toml --release # FIXME: Not always release, right?
+ cp $(srcdir)/../libgrust/libformat_parser/target/release/liblibformat_parser.a $@
+
# build all rust/parse files in rust folder, add cross-folder includes
rust/%.o: rust/parse/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index 9f9ba48..559b1c8 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -19,78 +19,23 @@
#include "rust-fmt.h"
namespace Rust {
-tl::expected<Fmt, Fmt::Error>
-Fmt::parse_fmt_string (Fmt::Input input)
-{
- return Fmt ();
-}
+namespace Fmt {
-tl::expected<Fmt::Result<tl::optional<Fmt::Format>>, Fmt::Error>
-Fmt::maybe_format (Fmt::Input input)
+Pieces
+Pieces::collect (const std::string &to_parse)
{
- tl::optional<Fmt::Format> none = tl::nullopt;
+ auto piece_slice = collect_pieces (to_parse.c_str ());
- return Fmt::Result (input, none);
-}
+ rust_debug ("[ARTHUR] %p, %lu", (void *) piece_slice.ptr, piece_slice.len);
-tl::expected<Fmt::Result<Fmt::Format>, Fmt::Error>
-Fmt::format (Input input)
-{
- return Fmt::Result (input, Format ());
-}
+ // this performs multiple copies, can we avoid them maybe?
+ auto pieces
+ = std::vector (piece_slice.ptr, piece_slice.ptr + piece_slice.len);
-tl::expected<Fmt::Result<Fmt::Argument>, Fmt::Error>
-Fmt::argument (Input input)
-{
- return Fmt::Result (input, Argument ());
-}
+ rust_debug ("[ARTHUR] %p, %lu", (void *) pieces.data (), pieces.size ());
-tl::expected<Fmt::Result<Fmt::FormatSpec>, Fmt::Error>
-Fmt::format_spec (Input input)
-{
- return Fmt::Result (input, FormatSpec ());
-}
-
-tl::expected<Fmt::Result<Fmt::Fill>, Fmt::Error>
-Fmt::fill (Input input)
-{
- return Fmt::Result (input, Fill ());
-}
-
-tl::expected<Fmt::Result<Fmt::Align>, Fmt::Error>
-Fmt::align (Input input)
-{
- switch (input[0])
- {
- case '<':
- return Fmt::Result (input.substr (1), Align::Left);
- case '^':
- return Fmt::Result (input.substr (1), Align::Top);
- case '>':
- return Fmt::Result (input.substr (1), Align::Right);
- default:
- // TODO: Store the character here
- // TODO: Can we have proper error locations?
- // TODO: Maybe we should use a Rust::Literal string instead of a string
- return tl::make_unexpected (Error::Align);
- }
-}
-
-tl::expected<Fmt::Result<Fmt::Sign>, Fmt::Error>
-Fmt::sign (Input input)
-{
- switch (input[0])
- {
- case '+':
- return Fmt::Result (input.substr (1), Sign::Plus);
- case '-':
- return Fmt::Result (input.substr (1), Sign::Minus);
- default:
- // TODO: Store the character here
- // TODO: Can we have proper error locations?
- // TODO: Maybe we should use a Rust::Literal string instead of a string
- return tl::make_unexpected (Error::Sign);
- }
+ return Pieces{};
}
+} // namespace Fmt
} // namespace Rust
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index f3dd53d..0050977 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -19,115 +19,134 @@
#ifndef RUST_FMT_H
#define RUST_FMT_H
-#include "expected.h"
-#include "optional.h"
-#include "rust-ast.h"
+#include "rust-diagnostics.h"
#include "rust-system.h"
namespace Rust {
+namespace Fmt {
-/**
- * This class implements the parsing of Rust format strings according to the
- * grammar here: https://doc.rust-lang.org/std/fmt/index.html#syntax
- */
-// TODO: Are there features that are only present in specific Rust editions?
-class Fmt
+struct RustHamster
{
-public:
- // TODO: Keep location information
- // TODO: Switch to a Rust::AST::Literal here
- using Input = std::string;
+ // hehe
+};
- enum class Error
- {
- Align,
- Sign,
- };
+struct InnerSpan
+{
+};
- template <typename T> class Result
+struct Count
+{
+ enum class Kind
+ {
+ Is,
+ IsName,
+ IsParam,
+ IsStar,
+ Implied
+ } kind;
+
+ union
{
- public:
- explicit Result (Input remaining_input, T result)
- : remaining_input (remaining_input), result (result)
- {}
+ size_t is;
+ std::pair<RustHamster, InnerSpan> is_name;
+ size_t is_param;
+ size_t is_star;
+ } data;
+};
- private:
- Input remaining_input;
- T result;
- };
+struct DebugHex
+{
+};
- // FIXME: Do not use an owned string here
- static tl::expected<Fmt, Fmt::Error> parse_fmt_string (Input input);
+struct Sign
+{
+};
-private:
- // the parse functions should return the remaining input as well as the
- // expected node let's look at nom
- // TODO: no string view :( use an owned string for now?
+struct Alignment
+{
+};
- template <typename T> struct ParseResult
- {
- tl::expected<Result<T>, Error> inner;
+struct RustString
+{
+ // hehe
+};
- ParseResult (tl::expected<Result<T>, Error> inner) : inner (inner) {}
- ParseResult operator= (tl::expected<Result<T>, Error> inner)
- {
- return ParseResult (inner);
- }
+struct Position
+{
+};
- Input remaining_input () { return inner->remaining_input; }
- T value () { return inner->value; }
- };
+struct FormatSpec
+{
+ /// Optionally specified character to fill alignment with.
+ tl::optional<char /* FIXME: This is a Rust char, not a C++ char - use an uint32_t instead? */> fill;
+ /// Span of the optionally specified fill character.
+ tl::optional<InnerSpan> fill_span;
+ /// Optionally specified alignment.
+ Alignment align;
+ /// The `+` or `-` flag.
+ tl::optional<Sign> sign;
+ /// The `#` flag.
+ bool alternate;
+ /// The `0` flag.
+ bool zero_pad;
+ /// The `x` or `X` flag. (Only for `Debug`.)
+ tl::optional<DebugHex> debug_hex;
+ /// The integer precision to use.
+ // Count <'a> precision;
+ /// The span of the precision formatting flag (for diagnostics).
+ tl::optional<InnerSpan> precision_span;
+ /// The string width requested for the resulting format.
+ // Count <'a> width;
+ /// The span of the width formatting flag (for diagnostics).
+ tl::optional<InnerSpan> width_span;
+ /// The descriptor string representing the name of the format desired for
+ /// this argument, this can be empty or any number of characters, although
+ /// it is required to be one word.
+ RustHamster ty;
+ // &'a str ty;
+ /// The span of the descriptor string (for diagnostics).
+ tl::optional<InnerSpan> ty_span;
+};
- struct Format
- {
- };
+struct Argument
+{
+ Position position;
+ InnerSpan inner_span;
+ FormatSpec format;
+};
- struct Argument
+struct Piece
+{
+ enum class Kind
{
- enum struct Kind
- {
- Integer,
- Identifier,
- } kind;
+ String,
+ NextArgument
+ } kind;
- int integer;
- Identifier identifier;
- };
-
- struct FormatSpec
+ union
{
- };
+ RustString string;
+ Argument *next_argument;
+ } data;
+};
- struct Fill
- {
- char to_fill;
- };
+struct PieceSlice
+{
+ Piece *ptr;
+ size_t len;
+};
- enum class Align
- {
- Left,
- Top,
- Right
- };
+extern "C" {
+PieceSlice
+collect_pieces (const char *);
+}
- enum class Sign
- {
- Plus,
- Minus
- };
-
- // let's do one function per rule in the BNF
- static tl::expected<Result<std::string>, Error> text (Input input);
- static tl::expected<Result<tl::optional<Format>>, Error>
- maybe_format (Input input);
- static tl::expected<Result<Format>, Error> format (Input input);
- static tl::expected<Result<Argument>, Error> argument (Input input);
- static tl::expected<Result<FormatSpec>, Error> format_spec (Input input);
- static tl::expected<Result<Fill>, Error> fill (Input input);
- static tl::expected<Result<Align>, Error> align (Input input);
- static tl::expected<Result<Sign>, Error> sign (Input input);
+struct Pieces
+{
+ static Pieces collect (const std::string &to_parse);
};
+} // namespace Fmt
} // namespace Rust
#endif // ! RUST_FMT_H
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 71da575..0e57406 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -30,6 +30,7 @@
#include "rust-parse.h"
#include "rust-session-manager.h"
#include "rust-attribute-values.h"
+#include "rust-fmt.h"
namespace Rust {
@@ -89,8 +90,8 @@ std::unordered_map<std::string, AST::MacroTranscriberFunc>
{"env", MacroBuiltin::env_handler},
{"cfg", MacroBuiltin::cfg_handler},
{"include", MacroBuiltin::include_handler},
+ {"format_args", MacroBuiltin::format_args_handler},
/* Unimplemented macro builtins */
- {"format_args", MacroBuiltin::sorry},
{"option_env", MacroBuiltin::sorry},
{"format_args_nl", MacroBuiltin::sorry},
{"concat_idents", MacroBuiltin::sorry},
@@ -943,6 +944,15 @@ MacroBuiltin::stringify_handler (location_t invoc_locus,
}
tl::optional<AST::Fragment>
+MacroBuiltin::format_args_handler (location_t invoc_locus,
+ AST::MacroInvocData &invoc)
+{
+ Fmt::Pieces::collect ("heyo this {is} what I {} want to {3}, {parse}");
+
+ return AST::Fragment::create_empty ();
+}
+
+tl::optional<AST::Fragment>
MacroBuiltin::sorry (location_t invoc_locus, AST::MacroInvocData &invoc)
{
rust_sorry_at (invoc_locus, "unimplemented builtin macro: %qs",
diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h
index 6a84a8b..f9ab3fc 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -157,6 +157,9 @@ public:
static tl::optional<AST::Fragment> line_handler (location_t invoc_locus,
AST::MacroInvocData &invoc);
+ static tl::optional<AST::Fragment>
+ format_args_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
+
static tl::optional<AST::Fragment> sorry (location_t invoc_locus,
AST::MacroInvocData &invoc);