Skip to content

Commit 1f0621d

Browse files
committed
Begin teaching rustc to parse literals, atoms, stmts, blocks, items, modules, crates.
1 parent 8beb118 commit 1f0621d

File tree

6 files changed

+182
-38
lines changed

6 files changed

+182
-38
lines changed

src/comp/driver/rustc.rs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,12 @@ fn main(vec[str] args) {
2727
auto i = 0;
2828
auto sess = session.session();
2929
for (str filename in args) {
30-
if (i > 0) {
31-
auto p = parser.new_parser(sess, filename);
32-
log "opened file: " + filename;
33-
auto tok = p.peek();
34-
while (true) {
35-
alt (tok) {
36-
case (token.EOF()) { ret; }
37-
case (_) {
38-
log token.to_str(tok);
39-
p.bump();
40-
tok = p.peek();
41-
}
42-
}
43-
}
44-
}
45-
i += 1;
30+
if (i > 0) {
31+
auto p = parser.new_parser(sess, filename);
32+
log "opened file: " + filename;
33+
auto crate = parser.parse_crate(p);
34+
}
35+
i += 1;
4636
}
4737

4838
// Test LLVM module-writing. Nothing interesting yet.

src/comp/fe/ast.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import util.common.span;
55

66
type ident = str;
77

8-
type crate = rec( str filename,
9-
_mod module);
8+
type crate = rec(_mod module);
109

1110
type block = vec[@stmt];
1211

1312
tag stmt {
1413
stmt_block(block);
1514
stmt_decl(@decl);
1615
stmt_ret(option[@lval]);
16+
stmt_log(@atom);
1717
}
1818

1919

@@ -36,6 +36,7 @@ tag atom {
3636
tag lit {
3737
lit_char(char);
3838
lit_int(int);
39+
lit_uint(uint);
3940
lit_nil;
4041
lit_bool(bool);
4142
}
@@ -44,7 +45,11 @@ tag ty {
4445
ty_nil;
4546
ty_bool;
4647
ty_int;
48+
ty_uint;
49+
ty_machine(util.common.ty_mach);
4750
ty_char;
51+
ty_str;
52+
ty_box(@ty);
4853
}
4954

5055
tag mode {

src/comp/fe/lexer.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@ import std._str;
33
import std.map;
44
import std.map.hashmap;
55
import util.common;
6-
7-
fn new_str_hash[V]() -> map.hashmap[str,V] {
8-
let map.hashfn[str] hasher = _str.hash;
9-
let map.eqfn[str] eqer = _str.eq;
10-
ret map.mk_hashmap[str,V](hasher, eqer);
11-
}
6+
import util.common.new_str_hash;
127

138
state type reader = state obj {
149
fn is_eof() -> bool;

src/comp/fe/parser.rs

Lines changed: 161 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import std._io;
22
import driver.session;
33
import util.common;
4+
import util.common.new_str_hash;
5+
6+
// FIXME: import std.util.option and use it here.
7+
// import std.util.option;
8+
9+
tag option[T] {
10+
none;
11+
some(T);
12+
}
13+
414

515
state type parser =
616
state obj {
@@ -19,6 +29,7 @@ state fn new_parser(session.session sess, str path) -> parser {
1929
lexer.reader rdr)
2030
{
2131
state fn peek() -> token.token {
32+
log token.to_str(tok);
2233
ret tok;
2334
}
2435

@@ -56,40 +67,176 @@ state fn expect(parser p, token.token t) {
5667
let str s = "expecting ";
5768
s += token.to_str(t);
5869
s += ", found ";
59-
s += token.to_str(t);
70+
s += token.to_str(p.peek());
6071
p.err(s);
6172
}
6273
}
6374

6475
state fn parse_ident(parser p) -> ast.ident {
6576
alt (p.peek()) {
66-
case (token.IDENT(?i)) { ret i; }
77+
case (token.IDENT(?i)) { p.bump(); ret i; }
6778
case (_) {
6879
p.err("expecting ident");
6980
fail;
7081
}
7182
}
7283
}
7384

74-
state fn parse_item(parser p) -> tup(ast.ident, ast.item) {
85+
state fn parse_ty(parser p) -> ast.ty {
86+
alt (p.peek()) {
87+
case (token.INT) { p.bump(); ret ast.ty_int; }
88+
case (token.UINT) { p.bump(); ret ast.ty_int; }
89+
case (token.STR) { p.bump(); ret ast.ty_str; }
90+
case (token.CHAR) { p.bump(); ret ast.ty_char; }
91+
case (token.MACH(?tm)) { p.bump(); ret ast.ty_machine(tm); }
92+
}
93+
p.err("expecting type");
94+
fail;
95+
}
96+
97+
state fn parse_slot(parser p) -> ast.slot {
98+
let ast.mode m = ast.val;
99+
if (p.peek() == token.BINOP(token.AND)) {
100+
m = ast.alias;
101+
p.bump();
102+
}
103+
let ast.ty t = parse_ty(p);
104+
ret rec(ty=t, mode=m);
105+
}
106+
107+
state fn parse_seq[T](token.token bra,
108+
token.token ket,
109+
option[token.token] sep,
110+
(state fn(parser) -> T) f,
111+
parser p) -> vec[T] {
112+
let bool first = true;
113+
expect(p, bra);
114+
let vec[T] v = vec();
115+
while (p.peek() != ket) {
116+
alt(sep) {
117+
case (some[token.token](?t)) {
118+
if (first) {
119+
first = false;
120+
} else {
121+
expect(p, t);
122+
}
123+
}
124+
case (_) {
125+
}
126+
}
127+
// FIXME: v += f(p) doesn't work at the moment.
128+
let T t = f(p);
129+
v += vec(t);
130+
}
131+
expect(p, ket);
132+
ret v;
133+
}
134+
135+
state fn parse_lit(parser p) -> ast.lit {
75136
alt (p.peek()) {
76-
case (token.FN()) {
137+
case (token.LIT_INT(?i)) {
138+
p.bump();
139+
ret ast.lit_int(i);
140+
}
141+
case (token.LIT_UINT(?u)) {
77142
p.bump();
78-
auto id = parse_ident(p);
79-
expect(p, token.LPAREN);
80-
let vec[rec(ast.slot slot, ast.ident ident)] inputs = vec();
81-
let vec[@ast.stmt] body = vec();
82-
auto output = rec(ty = ast.ty_nil, mode = ast.val );
83-
let ast._fn f = rec(inputs = inputs,
84-
output = output,
85-
body = body);
86-
ret tup(id, ast.item_fn(@f));
143+
ret ast.lit_uint(u);
144+
}
145+
case (token.LIT_CHAR(?c)) {
146+
p.bump();
147+
ret ast.lit_char(c);
148+
}
149+
case (token.LIT_BOOL(?b)) {
150+
p.bump();
151+
ret ast.lit_bool(b);
87152
}
88153
}
89-
p.err("expecting item");
154+
p.err("expected literal");
90155
fail;
91156
}
92157

158+
state fn parse_atom(parser p) -> ast.atom {
159+
ret ast.atom_lit(@parse_lit(p));
160+
}
161+
162+
state fn parse_stmt(parser p) -> @ast.stmt {
163+
alt (p.peek()) {
164+
case (token.LOG) {
165+
p.bump();
166+
auto a = @parse_atom(p);
167+
expect(p, token.SEMI);
168+
ret @ast.stmt_log(a);
169+
}
170+
}
171+
p.err("expected statement");
172+
fail;
173+
}
174+
175+
state fn parse_block(parser p) -> ast.block {
176+
auto f = parse_stmt;
177+
// FIXME: passing parse_stmt as an lval doesn't work at the moment.
178+
ret parse_seq[@ast.stmt](token.LBRACE,
179+
token.RBRACE,
180+
none[token.token],
181+
f, p);
182+
}
183+
184+
state fn parse_slot_ident_pair(parser p) ->
185+
rec(ast.slot slot, ast.ident ident) {
186+
auto s = parse_slot(p);
187+
auto i = parse_ident(p);
188+
ret rec(slot=s, ident=i);
189+
}
190+
191+
state fn parse_fn(parser p) -> tup(ast.ident, ast.item) {
192+
expect(p, token.FN);
193+
auto id = parse_ident(p);
194+
auto pf = parse_slot_ident_pair;
195+
auto inputs =
196+
// FIXME: passing parse_slot_ident_pair as an lval doesn't work at the
197+
// moment.
198+
parse_seq[rec(ast.slot slot, ast.ident ident)]
199+
(token.LPAREN,
200+
token.RPAREN,
201+
some(token.COMMA),
202+
pf, p);
203+
204+
auto output;
205+
if (p.peek() == token.RARROW) {
206+
p.bump();
207+
output = rec(ty=parse_ty(p), mode=ast.val);
208+
} else {
209+
output = rec(ty=ast.ty_nil, mode=ast.val);
210+
}
211+
212+
auto body = parse_block(p);
213+
214+
let ast._fn f = rec(inputs = inputs,
215+
output = output,
216+
body = body);
217+
218+
ret tup(id, ast.item_fn(@f));
219+
}
220+
221+
state fn parse_item(parser p) -> tup(ast.ident, ast.item) {
222+
alt (p.peek()) {
223+
case (token.FN) {
224+
ret parse_fn(p);
225+
}
226+
}
227+
p.err("expectied item");
228+
fail;
229+
}
230+
231+
state fn parse_crate(parser p) -> ast.crate {
232+
let ast._mod m = new_str_hash[ast.item]();
233+
while (p.peek() != token.EOF) {
234+
auto i = parse_item(p);
235+
m.insert(i._0, i._1);
236+
}
237+
ret rec(module=m);
238+
}
239+
93240
//
94241
// Local Variables:
95242
// mode: rust

src/comp/fe/token.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import util.common.ty_mach;
22
import util.common.ty_mach_to_str;
3+
import util.common.new_str_hash;
34
import std._int;
45
import std._uint;
56

src/comp/util/common.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ fn ty_mach_to_str(ty_mach tm) -> str {
3535
}
3636
}
3737

38+
fn new_str_hash[V]() -> std.map.hashmap[str,V] {
39+
let std.map.hashfn[str] hasher = std._str.hash;
40+
let std.map.eqfn[str] eqer = std._str.eq;
41+
ret std.map.mk_hashmap[str,V](hasher, eqer);
42+
}
43+
3844
//
3945
// Local Variables:
4046
// mode: rust

0 commit comments

Comments
 (0)