{
using RegType = AST::InlineAsmRegOrRegClass::Type;
auto &parser = inline_asm_ctx.parser;
- auto last_token_id = inline_asm_ctx.last_token_id;
if (!parser.skip_token (LEFT_PAREN))
{
// None
// };
auto &parser = inline_asm_ctx.parser;
- auto last_token_id = inline_asm_ctx.last_token_id;
AST::InlineAsmOperand reg_operand;
rust_debug ("Enter parse_reg_operand");
auto token = parser.peek_current_token ();
return parse_asm (invoc_locus, invoc, is_global_asm);
}
-int
-parse_asm_arg (InlineAsmContext &inline_asm_ctx)
+tl::expected<InlineAsmContext, std::string>
+parse_asm_arg (InlineAsmContext inline_asm_ctx)
{
auto &parser = inline_asm_ctx.parser;
auto last_token_id = inline_asm_ctx.last_token_id;
// std::cout << "reg_operand" << std::endl;
auto operand = parse_reg_operand (inline_asm_ctx);
}
- return 0;
+ return tl::expected<InlineAsmContext, std::string> (inline_asm_ctx);
}
tl::optional<AST::Fragment>
AST::InlineAsm inline_asm (invoc_locus, is_global_asm);
auto inline_asm_ctx = InlineAsmContext (inline_asm, parser, last_token_id);
+ // operands stream, also handles the optional ","
+ tl::expected<InlineAsmContext, std::string> resulting_context
+ = tl::expected<InlineAsmContext, std::string> (inline_asm_ctx);
+ resulting_context.and_then (parse_format_strings)
+ .and_then (parse_asm_arg)
+ .and_then (validate);
+
+ // TODO: I'm putting the validation here because the rust reference put it
+ // here Per Arthur's advice we would actually do the validation in a different
+ // stage. and visit on the InlineAsm AST instead of it's context.
+ auto is_valid = (bool) resulting_context;
+
+ if (is_valid)
+ {
+ AST::SingleASTNode single = AST::SingleASTNode (
+ inline_asm_ctx.inline_asm.clone_expr_without_block ());
+ std::vector<AST::SingleASTNode> single_vec = {single};
+
+ AST::Fragment fragment_ast
+ = AST::Fragment (single_vec,
+ std::vector<std::unique_ptr<AST::Token>> ());
+ return fragment_ast;
+ }
+ else
+ {
+ return tl::nullopt;
+ }
+}
+
+tl::expected<InlineAsmContext, std::string>
+parse_format_strings (InlineAsmContext inline_asm_ctx)
+{
// Parse the first ever formatted string, success or not, will skip 1 token
+ auto parser = inline_asm_ctx.parser;
+ auto last_token_id = inline_asm_ctx.last_token_id;
auto fm_string = parse_format_string (inline_asm_ctx);
if (fm_string == tl::nullopt)
{
rust_error_at (parser.peek_current_token ()->get_locus (),
"%s template must be a string literal", "asm");
- return tl::nullopt;
+ return tl::unexpected<std::string> ("ERROR");
}
// formatted string stream
}
}
- // operands stream, also handles the optional ","
- parse_asm_arg (inline_asm_ctx);
-
- // TODO: I'm putting the validation here because the rust reference put it
- // here Per Arthur's advice we would actually do the validation in a different
- // stage. and visit on the InlineAsm AST instead of it's context.
- auto is_valid = validate (inline_asm_ctx);
-
- if (is_valid)
- {
- AST::SingleASTNode single = AST::SingleASTNode (
- inline_asm_ctx.inline_asm.clone_expr_without_block ());
- std::vector<AST::SingleASTNode> single_vec = {single};
-
- AST::Fragment fragment_ast
- = AST::Fragment (single_vec,
- std::vector<std::unique_ptr<AST::Token>> ());
- return fragment_ast;
- }
- else
- {
- return tl::nullopt;
- }
+ return tl::expected<InlineAsmContext, std::string> (inline_asm_ctx);
}
// bool
// return true;
// }
-bool
-validate (InlineAsmContext &inline_asm_ctx)
+tl::expected<InlineAsmContext, std::string>
+validate (InlineAsmContext inline_asm_ctx)
{
- return true;
+ return tl::expected<InlineAsmContext, std::string> (inline_asm_ctx);
}
} // namespace Rust
#include "rust-macro-builtins.h"
#include "rust-macro-builtins-helpers.h"
+#include "expected.h"
#include "rust-macro-invoc-lexer.h"
#include "rust/ast/rust-expr.h"
namespace Rust {
parser (parser), last_token_id (last_token_id)
{}
+ // InlineAsmContext (InlineAsmContext && inline_asm_ctx)
+ // : allow_templates(inline_asm_ctx.allow_templates),
+ // is_explicit(inline_asm_ctx.is_explicit),
+ // consumed_comma_without_formatted_string(inline_asm_ctx.consumed_comma_without_formatted_string),
+ // inline_asm(inline_asm_ctx.inline_asm),
+ // parser(inline_asm_ctx.parser),
+ // last_token_id(inline_asm_ctx.last_token_id) {}
+
bool is_global_asm () { return inline_asm.is_global_asm; }
bool allows_templates () { return allow_templates; }
}
};
-int
-parse_asm_arg (InlineAsmContext &inline_asm_ctx);
+// Expected calls
+tl::expected<InlineAsmContext, std::string>
+validate (InlineAsmContext inline_asm_ctx);
+
+tl::expected<InlineAsmContext, std::string>
+parse_asm_arg (InlineAsmContext inline_asm_ctx);
+
+tl::expected<InlineAsmContext, std::string>
+parse_format_strings (InlineAsmContext inline_asm_ctx);
tl::optional<AST::Fragment>
parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
tl::optional<std::string>
parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
InlineAsmContext &inline_asm_ctx);
-bool
-validate (InlineAsmContext &inline_asm_ctx);
+
std::set<std::string> potentially_nonpromoted_keywords
= {"in", "out", "lateout", "inout", "inlateout", "const", "sym", "label"};