Skip to content

Commit 9b6a581

Browse files
paulstansifergraydon
authored andcommitted
---
yaml --- r: 2933 b: refs/heads/master c: 79fcd51 h: refs/heads/master i: 2931: 2ac3391 v: v3
1 parent 5c01897 commit 9b6a581

File tree

5 files changed

+65
-76
lines changed

5 files changed

+65
-76
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: cfc75695a57de94de618b1f5f7c163d213fbc36b
2+
refs/heads/master: 79fcd51b4659aabb8cf92bcc69a20207dbd53492

trunk/src/comp/front/extenv.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ import std::generic_os;
1414
export expand_syntax_ext;
1515

1616
// FIXME: Need to thread parser through here to handle errors correctly
17-
fn expand_syntax_ext(parser::parser p,
17+
fn expand_syntax_ext(&parser::parser p,
1818
common::span sp,
19-
vec[@ast::expr] args,
19+
&vec[@ast::expr] args,
2020
option::t[str] body) -> @ast::expr {
2121

2222
if (vec::len[@ast::expr](args) != 1u) {

trunk/src/comp/front/extfmt.rs

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,12 @@ import std::option;
1313
import std::option::none;
1414
import std::option::some;
1515

16-
import std::extfmt::ct::signedness;
17-
import std::extfmt::ct::signed;
18-
import std::extfmt::ct::unsigned;
19-
import std::extfmt::ct::caseness;
20-
import std::extfmt::ct::case_upper;
21-
import std::extfmt::ct::case_lower;
22-
import std::extfmt::ct::ty;
23-
import std::extfmt::ct::ty_bool;
24-
import std::extfmt::ct::ty_str;
25-
import std::extfmt::ct::ty_char;
26-
import std::extfmt::ct::ty_int;
27-
import std::extfmt::ct::ty_bits;
28-
import std::extfmt::ct::ty_hex;
29-
import std::extfmt::ct::ty_octal;
30-
import std::extfmt::ct::flag;
31-
import std::extfmt::ct::flag_left_justify;
32-
import std::extfmt::ct::flag_left_zero_pad;
33-
import std::extfmt::ct::flag_space_for_sign;
34-
import std::extfmt::ct::flag_sign_always;
35-
import std::extfmt::ct::flag_alternate;
36-
import std::extfmt::ct::count;
37-
import std::extfmt::ct::count_is;
38-
import std::extfmt::ct::count_is_param;
39-
import std::extfmt::ct::count_is_next_param;
40-
import std::extfmt::ct::count_implied;
41-
import std::extfmt::ct::conv;
42-
import std::extfmt::ct::piece;
43-
import std::extfmt::ct::piece_string;
44-
import std::extfmt::ct::piece_conv;
45-
import std::extfmt::ct::parse_fmt_string;
16+
import std::extfmt::ct::*;
4617

4718
export expand_syntax_ext;
4819

49-
fn expand_syntax_ext(parser p,
50-
vec[@ast::expr] args,
20+
fn expand_syntax_ext(&parser p, common::span sp,
21+
&vec[@ast::expr] args,
5122
option::t[str] body) -> @ast::expr {
5223

5324
if (vec::len[@ast::expr](args) == 0u) {

trunk/src/comp/front/parser.rs

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,41 @@ tag file_type {
2727

2828
type ty_or_bang = util::common::ty_or_bang[@ast::ty];
2929

30+
// Temporary: to introduce a tag in order to make a recursive type work
31+
tag xmacro {
32+
x(macro);
33+
}
34+
3035
state type parser =
3136
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;
5460
};
5561

62+
type macro = fn(&parser, common::span, &vec[@ast::expr], option::t[str])
63+
-> @ast::expr;
64+
5665
fn new_parser(session::session sess,
5766
eval::env env,
5867
ast::def_id initial_def,
@@ -70,7 +79,8 @@ fn new_parser(session::session sess,
7079
lexer::reader rdr,
7180
vec[op_spec] precs,
7281
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)
7484
{
7585
fn peek() -> token::token {
7686
ret tok;
@@ -143,6 +153,10 @@ fn new_parser(session::session sess,
143153
ret bad_words;
144154
}
145155

156+
fn get_macros() -> std::map::hashmap[str, xmacro] {
157+
ret macros;
158+
}
159+
146160
fn get_chpos() -> uint {ret rdr.get_chpos();}
147161

148162
fn get_ann() -> ast::ann {
@@ -169,7 +183,7 @@ fn new_parser(session::session sess,
169183
ret stdio_parser(sess, env, ftype, lexer::next_token(rdr),
170184
npos, npos, npos, initial_def._1, UNRESTRICTED,
171185
initial_def._0, rdr, prec_table(), next_ann,
172-
bad_expr_word_table());
186+
bad_expr_word_table(), macro_table());
173187
}
174188

175189
// 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, ()] {
213227
ret words;
214228
}
215229

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+
216237
fn unexpected(&parser p, token::token t) -> ! {
217238
let str s = "unexpected token: ";
218239
s += token::to_str(p.get_reader(), t);
@@ -1037,23 +1058,15 @@ fn expand_syntax_ext(&parser p, common::span sp,
10371058

10381059
assert (vec::len[ast::ident](path.node.idents) > 0u);
10391060
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+
}
10571070
}
10581071
}
10591072

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
// error-pattern:unknown macro
3+
fn main() {
4+
#iamnotanextensionthatexists("");
5+
}

0 commit comments

Comments
 (0)