diff options
author | jjasmine <tanghocle456@gmail.com> | 2024-05-08 11:06:00 -0700 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-17 16:35:35 +0100 |
commit | ab988c156f9a1a7eed1684b8bb40d05aa757c0f8 (patch) | |
tree | 778fab1b1ab1a4ad74b9648a0a1eccd8517b4872 /gcc | |
parent | 9e9be0f396e304e27598405ff26f02f0f0a47c96 (diff) | |
download | gcc-ab988c156f9a1a7eed1684b8bb40d05aa757c0f8.zip gcc-ab988c156f9a1a7eed1684b8bb40d05aa757c0f8.tar.gz gcc-ab988c156f9a1a7eed1684b8bb40d05aa757c0f8.tar.bz2 |
gccrs: Almost done with top level parsing
gcc/rust/ChangeLog:
* expand/rust-macro-builtins-asm.cc (struct AsmParseError): title.
(enum InlineAsmDirSpec): title.
(enum InlineAsmOptions): title.
(struct AsmArg): title.
(parseAsmArg): title.
(parse_global_asm): title.
(parse_nonglobal_asm): title.
(parse_asm): title.
(parseDirSpec): title.
(parse_format_string): title.
(MacroBuiltin::global_asm_handler): title.
(MacroBuiltin::nonglobal_asm_handler): title.
* expand/rust-macro-builtins.cc: title.
* expand/rust-macro-builtins.h: title.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins-asm.cc | 178 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins.cc | 6 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins.h | 6 |
3 files changed, 186 insertions, 4 deletions
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc index e50694d..7958d91 100644 --- a/gcc/rust/expand/rust-macro-builtins-asm.cc +++ b/gcc/rust/expand/rust-macro-builtins-asm.cc @@ -18,3 +18,181 @@ #include "rust-macro-builtins.h" #include "rust-macro-builtins-helpers.h" +#include "rust-macro-invoc-lexer.h" + +namespace Rust { + +struct AsmParseError +{ +}; + +// This is just an enum to hold some operands right now. +enum InlineAsmDirSpec +{ + In, + Out, + InOut, + SplitInOut, + Const, + Sym, + Label, +}; + +enum InlineAsmOptions +{ + +}; + +typedef std::string symbol_name; +typedef std::vector<AST::Expr> Templates; +typedef std::vector<InlineAsmDirSpec> Operands; +typedef std::map<std::string, int> RegisterArgs; +typedef std::map<symbol_name, int> ClobberAbis; +typedef std::map<symbol_name, int> NamedValues; + +struct AsmArg +{ + Templates templates; + Operands operands; + std::map<symbol_name, int> named_values; + RegisterArgs register_arguments; + ClobberAbis clobber_abis; + InlineAsmOptions options; + std::vector<InlineAsmOptions> + options_span; // TODO: @badumbatish @jjasmine I have no idea what span do, i + // copied it out of rustc_builtin_macros/src/asm.rs +}; + +tl::optional<AsmArg> +parseAsmArg (Parser<MacroInvocLexer> &p, bool is_global_asm); +static tl::optional<AST::Fragment> +parse_global_asm (location_t invoc_locus, AST::MacroInvocData &invoc); +static tl::optional<AST::Fragment> +parse_nonglobal_asm (location_t invoc_locus, AST::MacroInvocData &invoc); +static tl::optional<AST::Fragment> +parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, + bool is_global_asm); + +tl::optional<InlineAsmDirSpec> +parseDirSpec (Parser<MacroInvocLexer> &p, TokenId last_token_id) +{ + return tl::nullopt; +} +tl::optional<AsmArg> +parseAsmArg (Parser<MacroInvocLexer> &p, bool is_global_asm) +{ + return tl::nullopt; +} + +tl::optional<std::string> +parse_format_string (Parser<MacroInvocLexer> &parser, TokenId last_token_id) +{ + auto token = parser.peek_current_token (); + + if (token->get_id () != last_token_id && token->get_id () == STRING_LITERAL) + { + // very nice, we got a supposedly formatted string. + std::cout << token->get_token_description () << std::endl; + parser.skip_token (); + return "formatted string"; + } + else + { + parser.skip_token (); + std::cout << token->get_token_description () << std::endl; + + rust_error_at (token->get_locus (), + "asm template must be a string literal"); + return tl::nullopt; + } +} + +tl::optional<AST::Fragment> +MacroBuiltin::global_asm_handler (location_t invoc_locus, + AST::MacroInvocData &invoc) +{ + // Just to clarify the code + bool is_global_asm = true; + return parse_asm (invoc_locus, invoc, is_global_asm); +} + +tl::optional<AST::Fragment> +MacroBuiltin::nonglobal_asm_handler (location_t invoc_locus, + AST::MacroInvocData &invoc) +{ + // Just to clarify the code + bool is_global_asm = false; + return parse_asm (invoc_locus, invoc, is_global_asm); +} + +static tl::optional<AST::Fragment> +parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, + bool is_global_asm) +{ + // From the rule of asm. + // We first peek and see if it is a format string or not. + // If yes, we process the first ever format string, and move on to the + // recurrent of format string Else we exit out + + // After that, we peek and see if it is a reoccuring stream of format string + // or not. If it is, keep on going to do this format string. Else, move on + + // After that, we peek and see if it is a reoccuring stream of operands or not + // If it is, keep on going to do this operand thingy. + // Else, move on + + // We check if there is an optional "," at the end, per ABNF spec. + // If it is, consume it. + + // Done + MacroInvocLexer lex (invoc.get_delim_tok_tree ().to_token_stream ()); + Parser<MacroInvocLexer> parser (lex); + auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser); + + // Parse the first ever formatted string, success or not, will skip 1 token + auto fm_string = parse_format_string (parser, last_token_id); + if (fm_string == tl::nullopt) + return tl::nullopt; + + // formatted string stream + auto token = parser.peek_current_token (); + while (token->get_id () != last_token_id) + { + std::cout << token->get_token_description () << std::endl; + token = parser.peek_current_token (); + if (token->get_id () != COMMA) + { + break; + } + parser.skip_token (); + // Ok after the comma is good, we better be parsing correctly everything + // in here, which is formatted string in ABNF + + fm_string = parse_format_string (parser, last_token_id); + } + + // operands stream + token = parser.peek_current_token (); + while (token->get_id () != last_token_id) + { + std::cout << token->get_token_description () << std::endl; + + token = parser.peek_current_token (); + if (token->get_id () != COMMA) + { + break; + } + parser.skip_token (); + // Ok after the left paren is good, we better be parsing correctly + // everything in here, which is operand in ABNF + + // TODO: Work on parsing operands + fm_string = parse_format_string (parser, last_token_id); + } + + // TODO: Handle the optional "," + + return tl::nullopt; +} + +} // namespace Rust diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index 61b677a..e4144d1 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -62,7 +62,6 @@ const BiMap<std::string, BuiltinMacro> MacroBuiltin::builtins = {{ {"concat_idents", BuiltinMacro::ConcatIdents}, {"module_path", BuiltinMacro::ModulePath}, {"asm", BuiltinMacro::Asm}, - {"llvm_asm", BuiltinMacro::LlvmAsm}, {"global_asm", BuiltinMacro::GlobalAsm}, {"log_syntax", BuiltinMacro::LogSyntax}, {"trace_macros", BuiltinMacro::TraceMacros}, @@ -109,13 +108,12 @@ std::unordered_map<std::string, AST::MacroTranscriberFunc> {"include", MacroBuiltin::include_handler}, {"format_args", format_args_maker (AST::FormatArgs::Newline::No)}, {"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)}, + {"asm", MacroBuiltin::nonglobal_asm_handler}, + {"global_asm", MacroBuiltin::global_asm_handler}, /* Unimplemented macro builtins */ {"option_env", MacroBuiltin::sorry}, {"concat_idents", MacroBuiltin::sorry}, {"module_path", MacroBuiltin::sorry}, - {"asm", MacroBuiltin::sorry}, - {"llvm_asm", MacroBuiltin::sorry}, - {"global_asm", MacroBuiltin::sorry}, {"log_syntax", MacroBuiltin::sorry}, {"trace_macros", MacroBuiltin::sorry}, {"test", MacroBuiltin::sorry}, diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h index 6ba43ff..10377e9 100644 --- a/gcc/rust/expand/rust-macro-builtins.h +++ b/gcc/rust/expand/rust-macro-builtins.h @@ -160,6 +160,12 @@ public: AST::MacroInvocData &invoc); static tl::optional<AST::Fragment> + nonglobal_asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc); + + static tl::optional<AST::Fragment> + global_asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc); + + static tl::optional<AST::Fragment> format_args_handler (location_t invoc_locus, AST::MacroInvocData &invoc, AST::FormatArgs::Newline nl); |