@@ -27,32 +27,41 @@ tag file_type {
27
27
28
28
type ty_or_bang = util:: common:: ty_or_bang[ @ast:: ty ] ;
29
29
30
+ // Temporary: to introduce a tag in order to make a recursive type work
31
+ tag xmacro {
32
+ x( macro) ;
33
+ }
34
+
30
35
state type parser =
31
36
state obj {
32
- fn peek( ) -> token:: token;
33
- fn bump ( ) ;
34
- fn err ( str s) -> !;
35
- fn restrict ( restriction r) ;
36
- fn get_restriction ( ) -> restriction ;
37
- fn get_file_type ( ) -> file_type ;
38
- fn get_env ( ) -> eval:: env ;
39
- fn get_session ( ) -> session:: session ;
40
- fn get_span ( ) -> common:: span ;
41
- fn get_lo_pos ( ) -> uint ;
42
- fn get_hi_pos ( ) -> uint ;
43
- fn get_last_lo_pos ( ) -> uint ;
44
- fn next_def_id ( ) -> ast:: def_id ;
45
- fn set_def ( ast:: def_num ) ;
46
- fn get_prec_table ( ) -> vec[ op_spec ] ;
47
- fn get_str ( token:: str_num ) -> str ;
48
- fn get_reader ( ) -> lexer:: reader ;
49
- fn get_filemap ( ) -> codemap:: filemap ;
50
- fn get_bad_expr_words ( ) -> std:: map:: hashmap [ str, ( ) ] ;
51
- fn get_chpos ( ) -> uint ;
52
- fn get_ann ( ) -> ast:: ann ;
53
- fn next_ann_num ( ) -> uint ;
37
+ fn peek( ) -> token:: token;
38
+ fn bump ( ) ;
39
+ fn err ( str s) -> !;
40
+ fn restrict ( restriction r) ;
41
+ fn get_restriction ( ) -> restriction ;
42
+ fn get_file_type ( ) -> file_type ;
43
+ fn get_env ( ) -> eval:: env ;
44
+ fn get_session ( ) -> session:: session ;
45
+ fn get_span ( ) -> common:: span ;
46
+ fn get_lo_pos ( ) -> uint ;
47
+ fn get_hi_pos ( ) -> uint ;
48
+ fn get_last_lo_pos ( ) -> uint ;
49
+ fn next_def_id ( ) -> ast:: def_id ;
50
+ fn set_def ( ast:: def_num ) ;
51
+ fn get_prec_table ( ) -> vec[ op_spec ] ;
52
+ fn get_str ( token:: str_num ) -> str ;
53
+ fn get_reader ( ) -> lexer:: reader ;
54
+ fn get_filemap ( ) -> codemap:: filemap ;
55
+ fn get_bad_expr_words ( ) -> std:: map:: hashmap [ str, ( ) ] ;
56
+ fn get_macros ( ) -> std:: map:: hashmap [ str, xmacro] ;
57
+ fn get_chpos ( ) -> uint ;
58
+ fn get_ann ( ) -> ast:: ann ;
59
+ fn next_ann_num ( ) -> uint ;
54
60
} ;
55
61
62
+ type macro = fn ( & parser , common:: span , & vec[ @ast:: expr] , option:: t[ str ] )
63
+ -> @ast:: expr ;
64
+
56
65
fn new_parser ( session:: session sess,
57
66
eval:: env env,
58
67
ast:: def_id initial_def ,
@@ -70,7 +79,8 @@ fn new_parser(session::session sess,
70
79
lexer:: reader rdr,
71
80
vec[ op_spec] precs,
72
81
mutable uint next_ann_var,
73
- std:: map:: hashmap[ str, ( ) ] bad_words)
82
+ std:: map:: hashmap[ str, ( ) ] bad_words,
83
+ std:: map:: hashmap[ str, xmacro] macros)
74
84
{
75
85
fn peek ( ) -> token:: token {
76
86
ret tok;
@@ -143,6 +153,10 @@ fn new_parser(session::session sess,
143
153
ret bad_words;
144
154
}
145
155
156
+ fn get_macros ( ) -> std:: map:: hashmap [ str, xmacro] {
157
+ ret macros;
158
+ }
159
+
146
160
fn get_chpos ( ) -> uint { ret rdr. get_chpos ( ) ; }
147
161
148
162
fn get_ann ( ) -> ast:: ann {
@@ -169,7 +183,7 @@ fn new_parser(session::session sess,
169
183
ret stdio_parser ( sess, env, ftype, lexer:: next_token ( rdr) ,
170
184
npos, npos, npos, initial_def. _1 , UNRESTRICTED ,
171
185
initial_def. _0 , rdr, prec_table ( ) , next_ann,
172
- bad_expr_word_table ( ) ) ;
186
+ bad_expr_word_table ( ) , macro_table ( ) ) ;
173
187
}
174
188
175
189
// These are the words that shouldn't be allowed as value identifiers,
@@ -213,6 +227,13 @@ fn bad_expr_word_table() -> std::map::hashmap[str, ()] {
213
227
ret words;
214
228
}
215
229
230
+ fn macro_table ( ) -> std:: map:: hashmap [ str, xmacro] {
231
+ auto macros = new_str_hash[ xmacro] ( ) ;
232
+ macros. insert ( "fmt" , x ( extfmt:: expand_syntax_ext) ) ;
233
+ macros. insert ( "env" , x ( extenv:: expand_syntax_ext) ) ;
234
+ ret macros;
235
+ }
236
+
216
237
fn unexpected ( & parser p, token:: token t) -> ! {
217
238
let str s = "unexpected token: " ;
218
239
s += token:: to_str ( p. get_reader ( ) , t) ;
@@ -1037,23 +1058,15 @@ fn expand_syntax_ext(&parser p, common::span sp,
1037
1058
1038
1059
assert ( vec:: len[ ast:: ident] ( path. node . idents ) > 0 u) ;
1039
1060
auto extname = path. node . idents . ( 0 ) ;
1040
- if ( str:: eq ( extname, "fmt" ) ) {
1041
- auto expanded = extfmt:: expand_syntax_ext ( p, args, body) ;
1042
- auto newexpr = ast:: expr_ext ( path, args, body,
1043
- expanded,
1044
- p. get_ann ( ) ) ;
1045
-
1046
- ret newexpr;
1047
- } else if ( str:: eq ( extname, "env" ) ) {
1048
- auto expanded = extenv:: expand_syntax_ext ( p, sp, args, body) ;
1049
- auto newexpr = ast:: expr_ext ( path, args, body,
1050
- expanded,
1051
- p. get_ann ( ) ) ;
1052
-
1053
- ret newexpr;
1054
- } else {
1055
- p. err ( "unknown syntax extension" ) ;
1056
- fail;
1061
+
1062
+ alt ( p. get_macros ( ) . find ( extname) ) {
1063
+ case ( none[ xmacro] ) {
1064
+ p. err ( "unknown macro: '" + extname + "'" ) ;
1065
+ }
1066
+ case ( some[ xmacro] ( x ( ?ext) ) ) {
1067
+ ret ast:: expr_ext ( path, args, body, ext ( p, sp, args, body) ,
1068
+ p. get_ann ( ) ) ;
1069
+ }
1057
1070
}
1058
1071
}
1059
1072
0 commit comments