@@ -5,6 +5,9 @@ import std::str;
5
5
import std:: option;
6
6
import std:: option:: some;
7
7
import std:: option:: none;
8
+ import std:: either;
9
+ import std:: either:: left;
10
+ import std:: either:: right;
8
11
import std:: map:: hashmap;
9
12
import driver:: session;
10
13
import util:: common;
@@ -816,14 +819,9 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
816
819
hi = es. span . hi ;
817
820
ex = ast:: expr_bind ( e, es. node , p. get_ann ( ) ) ;
818
821
} else if ( p. peek ( ) == token:: POUND ) {
819
- p. bump ( ) ;
820
- auto pth = parse_path ( p) ;
821
- auto es =
822
- parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) ,
823
- parse_expr, p) ;
824
- hi = es. span . hi ;
825
- auto ext_span = rec ( lo=lo, hi=hi) ;
826
- ex = expand_syntax_ext ( p, ext_span, pth, es. node , none) ;
822
+ auto ex_ext = parse_syntax_ext ( p) ;
823
+ lo = ex_ext. span . lo ;
824
+ ex = ex_ext. node ;
827
825
} else if ( eat_word ( p, "fail" ) ) {
828
826
auto msg;
829
827
alt ( p. peek ( ) ) {
@@ -917,6 +915,21 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
917
915
ret @spanned ( lo, hi, ex) ;
918
916
}
919
917
918
+ fn parse_syntax_ext ( & parser p) -> @ast:: expr {
919
+ auto lo = p. get_lo_pos ( ) ;
920
+ expect ( p, token:: POUND ) ;
921
+ ret parse_syntax_ext_inner ( p, lo) ;
922
+ }
923
+
924
+ fn parse_syntax_ext_inner ( & parser p, uint lo) -> @ast:: expr {
925
+ auto pth = parse_path ( p) ;
926
+ auto es = parse_seq ( token:: LPAREN , token:: RPAREN ,
927
+ some ( token:: COMMA ) , parse_expr, p) ;
928
+ auto hi = es. span . hi ;
929
+ auto ext_span = rec ( lo=lo, hi=hi) ;
930
+ auto ex = expand_syntax_ext ( p, ext_span, pth, es. node , none) ;
931
+ ret @spanned ( lo, hi, ex) ;
932
+ }
920
933
921
934
/*
922
935
* FIXME: This is a crude approximation of the syntax-extension system,
@@ -1423,7 +1436,22 @@ fn parse_source_stmt(&parser p) -> @ast::stmt {
1423
1436
auto hi = p. get_span ( ) ;
1424
1437
ret @spanned ( lo, decl. span . hi , ast:: stmt_decl ( decl, p. get_ann ( ) ) ) ;
1425
1438
} else {
1426
- alt ( parse_item ( p, [ ] ) ) {
1439
+
1440
+ auto item_attrs;
1441
+ alt ( parse_attrs_or_ext ( p) ) {
1442
+ case ( none) {
1443
+ item_attrs = [ ] ;
1444
+ }
1445
+ case ( some ( left ( ?attrs) ) ) {
1446
+ item_attrs = attrs;
1447
+ }
1448
+ case ( some ( right ( ?ext) ) ) {
1449
+ ret @spanned ( lo, ext. span . hi ,
1450
+ ast:: stmt_expr ( ext, p. get_ann ( ) ) ) ;
1451
+ }
1452
+ }
1453
+
1454
+ alt ( parse_item ( p, item_attrs) ) {
1427
1455
case ( got_item ( ?i) ) {
1428
1456
auto hi = i. span . hi ;
1429
1457
auto decl = @spanned ( lo, hi, ast:: decl_item ( i) ) ;
@@ -1936,6 +1964,26 @@ fn parse_item(&parser p, vec[ast::attribute] attrs) -> parsed_item {
1936
1964
} else { ret no_item; }
1937
1965
}
1938
1966
1967
+ // A type to distingush between the parsing of item attributes or syntax
1968
+ // extensions, which both begin with token.POUND
1969
+ type attr_or_ext = option:: t [ either:: t[ vec[ ast:: attribute] ,
1970
+ @ast:: expr] ] ;
1971
+
1972
+ fn parse_attrs_or_ext ( & parser p) -> attr_or_ext {
1973
+ if ( p. peek ( ) == token:: POUND ) {
1974
+ auto lo = p. get_lo_pos ( ) ;
1975
+ p. bump ( ) ;
1976
+ if ( p. peek ( ) == token:: LBRACKET ) {
1977
+ auto first_attr = parse_attribute_inner ( p, lo) ;
1978
+ ret some ( left ( [ first_attr] + parse_attributes ( p) ) ) ;
1979
+ } else {
1980
+ ret some ( right ( parse_syntax_ext_inner ( p, lo) ) ) ;
1981
+ }
1982
+ } else {
1983
+ ret none;
1984
+ }
1985
+ }
1986
+
1939
1987
fn parse_attributes ( & parser p) -> vec[ ast:: attribute ] {
1940
1988
let vec[ ast:: attribute] attrs = [ ] ;
1941
1989
while ( p. peek ( ) == token:: POUND ) { attrs += [ parse_attribute ( p) ] ; }
@@ -1945,6 +1993,10 @@ fn parse_attributes(&parser p) -> vec[ast::attribute] {
1945
1993
fn parse_attribute ( & parser p) -> ast:: attribute {
1946
1994
auto lo = p. get_lo_pos ( ) ;
1947
1995
expect ( p, token:: POUND ) ;
1996
+ ret parse_attribute_inner ( p, lo) ;
1997
+ }
1998
+
1999
+ fn parse_attribute_inner ( & parser p, uint lo) -> ast:: attribute {
1948
2000
expect ( p, token:: LBRACKET ) ;
1949
2001
auto meta_item = parse_meta_item ( p) ;
1950
2002
expect ( p, token:: RBRACKET ) ;
0 commit comments