Skip to content

Commit 2c03f34

Browse files
committed
Add initial support for macro expansion
This is the first pass at implementing macros more testcases are needed. This does not support repetition matchers but it supports simple declarative macros and transcribes them. The approach taken here is that we reuse our existing parser to call the apropriate functions as specified as part of the MacroFragmentType enum if the parser does not have errors parsing that item then it must be a match. Then once we match a rule we have a map of the token begin/end offsets for each fragment match, this is then used to adjust and create a new token stream for the macro rule definition so that when we feed it to the parser the tokens are already substituted. The resulting expression or item is then attached to the respective macro invocation and this is then name resolved and used for hir lowering. Fixes #17 #22 Addresses #573
1 parent ef62630 commit 2c03f34

File tree

15 files changed

+1017
-255
lines changed

15 files changed

+1017
-255
lines changed

gcc/rust/ast/rust-ast-full-test.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4390,7 +4390,8 @@ DelimTokenTree::to_token_stream () const
43904390

43914391
// simulate presence of delimiters
43924392
const_TokenPtr left_paren
4393-
= Rust::Token::make (LEFT_PAREN, Linemap::unknown_location ());
4393+
= Rust::Token::make (left_delim_type_tok_token_id (delim_type),
4394+
Linemap::unknown_location ());
43944395
tokens.push_back (
43954396
std::unique_ptr<Token> (new Token (std::move (left_paren))));
43964397

@@ -4403,7 +4404,8 @@ DelimTokenTree::to_token_stream () const
44034404
}
44044405

44054406
const_TokenPtr right_paren
4406-
= Rust::Token::make (RIGHT_PAREN, Linemap::unknown_location ());
4407+
= Rust::Token::make (right_delim_type_tok_token_id (delim_type),
4408+
Linemap::unknown_location ());
44074409
tokens.push_back (
44084410
std::unique_ptr<Token> (new Token (std::move (right_paren))));
44094411

gcc/rust/ast/rust-ast.h

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,13 @@
2222

2323
#include "rust-system.h"
2424
#include "rust-hir-map.h"
25-
26-
// gccrs imports
27-
// required for AST::Token
2825
#include "rust-token.h"
2926
#include "rust-location.h"
3027

3128
namespace Rust {
3229
// TODO: remove typedefs and make actual types for these
3330
typedef std::string Identifier;
3431
typedef int TupleIndex;
35-
3632
struct Session;
3733

3834
namespace AST {
@@ -48,34 +44,6 @@ enum DelimType
4844
CURLY
4945
};
5046

51-
// Base AST node object - TODO is this really required or useful? Where to draw
52-
// line?
53-
/*class Node {
54-
public:
55-
// Gets node's Location.
56-
Location get_locus() const {
57-
return loc;
58-
}
59-
60-
// Sets node's Location.
61-
void set_locus(Location loc_) {
62-
loc = loc_;
63-
}
64-
65-
// Get node output as a string. Pure virtual.
66-
virtual std::string as_string() const = 0;
67-
68-
virtual ~Node() {}
69-
70-
// TODO: constructor including Location? Make all derived classes have
71-
Location?
72-
73-
private:
74-
// The node's location.
75-
Location loc;
76-
};*/
77-
// decided to not have node as a "node" would never need to be stored
78-
7947
// forward decl for use in token tree method
8048
class Token;
8149

@@ -108,6 +76,14 @@ class TokenTree
10876
class MacroMatch
10977
{
11078
public:
79+
enum MacroMatchType
80+
{
81+
Fragment,
82+
Repetition,
83+
Matcher,
84+
Tok
85+
};
86+
11187
virtual ~MacroMatch () {}
11288

11389
virtual std::string as_string () const = 0;
@@ -121,6 +97,8 @@ class MacroMatch
12197

12298
virtual void accept_vis (ASTVisitor &vis) = 0;
12399

100+
virtual MacroMatchType get_macro_match_type () const = 0;
101+
124102
protected:
125103
// pure virtual clone implementation
126104
virtual MacroMatch *clone_macro_match_impl () const = 0;
@@ -234,6 +212,11 @@ class Token : public TokenTree, public MacroMatch
234212
// Get a new token pointer copy.
235213
const_TokenPtr get_tok_ptr () const { return tok_ref; }
236214

215+
MacroMatchType get_macro_match_type () const override
216+
{
217+
return MacroMatchType::Tok;
218+
}
219+
237220
protected:
238221
// No virtual for now as not polymorphic but can be in future
239222
/*virtual*/ Token *clone_token_impl () const { return new Token (*this); }
@@ -788,6 +771,43 @@ class DelimTokenTree : public TokenTree, public AttrInput
788771
{
789772
return AttrInput::AttrInputType::TOKEN_TREE;
790773
}
774+
775+
std::vector<std::unique_ptr<TokenTree> > &get_token_trees ()
776+
{
777+
return token_trees;
778+
}
779+
780+
DelimType get_delim_type () const { return delim_type; }
781+
782+
static TokenId left_delim_type_tok_token_id (DelimType delim_type)
783+
{
784+
switch (delim_type)
785+
{
786+
case PARENS:
787+
return LEFT_PAREN;
788+
case SQUARE:
789+
return LEFT_SQUARE;
790+
case CURLY:
791+
return LEFT_CURLY;
792+
default:
793+
gcc_unreachable ();
794+
}
795+
}
796+
797+
static TokenId right_delim_type_tok_token_id (DelimType delim_type)
798+
{
799+
switch (delim_type)
800+
{
801+
case PARENS:
802+
return RIGHT_PAREN;
803+
case SQUARE:
804+
return RIGHT_SQUARE;
805+
case CURLY:
806+
return RIGHT_CURLY;
807+
default:
808+
gcc_unreachable ();
809+
}
810+
}
791811
};
792812

793813
/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to

0 commit comments

Comments
 (0)