aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-09-01 13:24:14 -0700
committerGraydon Hoare <[email protected]>2010-09-01 13:24:14 -0700
commiteb90be779877caa2e2d51095301f83695d77dd44 (patch)
tree76756b9fa7e4cfc6284632b7cde93302d87348c4 /src/comp
parentWhitespace churn. (diff)
downloadrust-eb90be779877caa2e2d51095301f83695d77dd44.tar.xz
rust-eb90be779877caa2e2d51095301f83695d77dd44.zip
Add session, span tracking, error reporting, beginning of a function to parse an item to rustc.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/driver/rustc.rs3
-rw-r--r--src/comp/driver/session.rs37
-rw-r--r--src/comp/fe/ast.rs7
-rw-r--r--src/comp/fe/lexer.rs73
-rw-r--r--src/comp/fe/parser.rs75
-rw-r--r--src/comp/rustc.rc1
-rw-r--r--src/comp/util/common.rs4
7 files changed, 165 insertions, 35 deletions
diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs
index 42bd91c5..a5463940 100644
--- a/src/comp/driver/rustc.rs
+++ b/src/comp/driver/rustc.rs
@@ -25,9 +25,10 @@ fn main(vec[str] args) {
log "You want rustboot, the compiler next door.";
auto i = 0;
+ auto sess = session.session();
for (str filename in args) {
if (i > 0) {
- auto p = parser.new_parser(filename);
+ auto p = parser.new_parser(sess, filename);
log "opened file: " + filename;
auto tok = p.peek();
while (true) {
diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs
new file mode 100644
index 00000000..3b92e073
--- /dev/null
+++ b/src/comp/driver/session.rs
@@ -0,0 +1,37 @@
+import util.common.span;
+import std._uint;
+
+io obj session() {
+ io fn span_err(span sp, str msg) {
+ let str s = sp.filename;
+ s += ':' as u8;
+ // We really need #fmt soon!
+ s += _uint.to_str(sp.lo.line, 10u);
+ s += ':' as u8;
+ s += _uint.to_str(sp.lo.col, 10u);
+ s += ':' as u8;
+ s += _uint.to_str(sp.hi.line, 10u);
+ s += ':' as u8;
+ s += _uint.to_str(sp.hi.col, 10u);
+ s += ": error: ";
+ s += msg;
+ log s;
+ fail;
+ }
+
+ io fn err(str msg) {
+ let str s = "error: ";
+ s += msg;
+ log s;
+ fail;
+ }
+}
+
+
+// Local Variables:
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
+// End:
diff --git a/src/comp/fe/ast.rs b/src/comp/fe/ast.rs
index 3a329ded..ba084979 100644
--- a/src/comp/fe/ast.rs
+++ b/src/comp/fe/ast.rs
@@ -1,13 +1,14 @@
import std.util.option;
import std.map.hashmap;
+import util.common.span;
type ident = str;
type crate = rec( str filename,
_mod module);
-type block = vec[stmt];
+type block = vec[@stmt];
type stmt = tag( stmt_block(block),
stmt_decl(@decl),
@@ -20,7 +21,7 @@ type lval = tag( lval_ident(ident),
lval_ext(@lval, ident),
lval_idx(@lval, @atom) );
-type atom = tag( atom_lit(lit));
+type atom = tag( atom_lit(@lit), atom_lval(@lval) );
type lit = tag( lit_char(char),
lit_int(int),
@@ -32,7 +33,7 @@ type ty = tag( ty_nil(),
ty_int(),
ty_char() );
-type mode = tag( local(), alias() );
+type mode = tag( val(), alias() );
type slot = rec(ty ty, mode mode);
diff --git a/src/comp/fe/lexer.rs b/src/comp/fe/lexer.rs
index 95aac8c5..e2c83dcc 100644
--- a/src/comp/fe/lexer.rs
+++ b/src/comp/fe/lexer.rs
@@ -10,33 +10,46 @@ fn new_str_hash[V]() -> map.hashmap[str,V] {
ret map.mk_hashmap[str,V](hasher, eqer);
}
-type reader = obj {
- fn is_eof() -> bool;
- fn curr() -> char;
- fn next() -> char;
- fn bump();
- fn get_curr_pos() -> tup(str,uint,uint);
- fn get_keywords() -> hashmap[str,token.token];
- fn get_reserved() -> hashmap[str,()];
+state type reader = state obj {
+ fn is_eof() -> bool;
+ fn curr() -> char;
+ fn next() -> char;
+ state fn bump();
+ state fn mark();
+ fn get_filename() -> str;
+ fn get_mark_pos() -> common.pos;
+ fn get_curr_pos() -> common.pos;
+ fn get_keywords() -> hashmap[str,token.token];
+ fn get_reserved() -> hashmap[str,()];
};
fn new_reader(stdio_reader rdr, str filename) -> reader
{
- obj reader(stdio_reader rdr,
- str filename,
- mutable char c,
- mutable char n,
- mutable uint line,
- mutable uint col,
- hashmap[str,token.token] keywords,
- hashmap[str,()] reserved)
- {
+ state obj reader(stdio_reader rdr,
+ str filename,
+ mutable char c,
+ mutable char n,
+ mutable uint mark_line,
+ mutable uint mark_col,
+ mutable uint line,
+ mutable uint col,
+ hashmap[str,token.token] keywords,
+ hashmap[str,()] reserved) {
+
fn is_eof() -> bool {
ret c == (-1) as char;
}
- fn get_curr_pos() -> tup(str,uint,uint) {
- ret tup(filename, line, col);
+ fn get_curr_pos() -> common.pos {
+ ret rec(line=line, col=col);
+ }
+
+ fn get_mark_pos() -> common.pos {
+ ret rec(line=mark_line, col=mark_col);
+ }
+
+ fn get_filename() -> str {
+ ret filename;
}
fn curr() -> char {
@@ -47,7 +60,7 @@ fn new_reader(stdio_reader rdr, str filename) -> reader
ret n;
}
- fn bump() {
+ state fn bump() {
c = n;
if (c == (-1) as char) {
@@ -56,7 +69,7 @@ fn new_reader(stdio_reader rdr, str filename) -> reader
if (c == '\n') {
line += 1u;
- col = 0u;
+ col = 1u;
} else {
col += 1u;
}
@@ -64,6 +77,11 @@ fn new_reader(stdio_reader rdr, str filename) -> reader
n = rdr.getc() as char;
}
+ state fn mark() {
+ mark_line = line;
+ mark_col = col;
+ }
+
fn get_keywords() -> hashmap[str,token.token] {
ret keywords;
}
@@ -171,7 +189,7 @@ fn new_reader(stdio_reader rdr, str filename) -> reader
keywords.insert("f64", token.MACH(common.ty_f64()));
ret reader(rdr, filename, rdr.getc() as char, rdr.getc() as char,
- 1u, 1u, keywords, reserved);
+ 1u, 1u, 1u, 1u, keywords, reserved);
}
@@ -229,14 +247,14 @@ fn is_whitespace(char c) -> bool {
ret c == ' ' || c == '\t' || c == '\r' || c == '\n';
}
-fn consume_any_whitespace(reader rdr) {
+state fn consume_any_whitespace(reader rdr) {
while (is_whitespace(rdr.curr())) {
rdr.bump();
}
be consume_any_line_comment(rdr);
}
-fn consume_any_line_comment(reader rdr) {
+state fn consume_any_line_comment(reader rdr) {
if (rdr.curr() == '/') {
alt (rdr.next()) {
case ('/') {
@@ -259,7 +277,7 @@ fn consume_any_line_comment(reader rdr) {
}
-fn consume_block_comment(reader rdr) {
+state fn consume_block_comment(reader rdr) {
let int level = 1;
while (level > 0) {
if (rdr.curr() == '/' && rdr.next() == '*') {
@@ -280,7 +298,7 @@ fn consume_block_comment(reader rdr) {
be consume_any_whitespace(rdr);
}
-fn next_token(reader rdr) -> token.token {
+state fn next_token(reader rdr) -> token.token {
auto accum_str = "";
auto accum_int = 0;
@@ -341,8 +359,7 @@ fn next_token(reader rdr) -> token.token {
ret token.LIT_INT(accum_int);
}
-
- fn binop(reader rdr, token.binop op) -> token.token {
+ state fn binop(reader rdr, token.binop op) -> token.token {
rdr.bump();
if (rdr.next() == '=') {
rdr.bump();
diff --git a/src/comp/fe/parser.rs b/src/comp/fe/parser.rs
index d2da7910..6ffd911e 100644
--- a/src/comp/fe/parser.rs
+++ b/src/comp/fe/parser.rs
@@ -1,25 +1,94 @@
import std._io;
+import driver.session;
+import util.common;
state type parser =
state obj {
state fn peek() -> token.token;
state fn bump();
+ io fn err(str s);
+ fn get_session() -> session.session;
+ fn get_span() -> common.span;
};
-fn new_parser(str path) -> parser {
- state obj stdio_parser(mutable token.token tok,
+state fn new_parser(session.session sess, str path) -> parser {
+ state obj stdio_parser(session.session sess,
+ mutable token.token tok,
+ mutable common.pos lo,
+ mutable common.pos hi,
lexer.reader rdr)
{
state fn peek() -> token.token {
ret tok;
}
+
state fn bump() {
tok = lexer.next_token(rdr);
+ lo = rdr.get_mark_pos();
+ hi = rdr.get_curr_pos();
+ }
+
+ io fn err(str m) {
+ auto span = rec(filename = rdr.get_filename(),
+ lo = lo, hi = hi);
+ sess.span_err(span, m);
+ }
+
+ fn get_session() -> session.session {
+ ret sess;
+ }
+
+ fn get_span() -> common.span {
+ ret rec(filename = rdr.get_filename(),
+ lo = lo, hi = hi);
}
}
auto srdr = _io.new_stdio_reader(path);
auto rdr = lexer.new_reader(srdr, path);
- ret stdio_parser(lexer.next_token(rdr), rdr);
+ auto npos = rdr.get_curr_pos();
+ ret stdio_parser(sess, lexer.next_token(rdr), npos, npos, rdr);
+}
+
+state fn expect(parser p, token.token t) {
+ // FIXME: comparing tags would be good. One of these days.
+ if (true /* p.peek() == t */) {
+ p.bump();
+ } else {
+ let str s = "expecting ";
+ s += token.to_str(t);
+ s += ", found ";
+ s += token.to_str(t);
+ p.err(s);
+ }
+}
+
+state fn parse_ident(parser p) -> ast.ident {
+ alt (p.peek()) {
+ case (token.IDENT(i)) { ret i; }
+ case (_) {
+ p.err("expecting ident");
+ fail;
+ }
+ }
+}
+
+state fn parse_item(parser p) -> tup(ast.ident, ast.item) {
+ alt (p.peek()) {
+ case (token.FN()) {
+ p.bump();
+ auto id = parse_ident(p);
+ expect(p, token.LPAREN());
+ let vec[rec(ast.slot slot, ast.ident ident)] inputs = vec();
+ let vec[@ast.stmt] body = vec();
+ auto output = rec(ty = ast.ty_nil(), mode = ast.val() );
+ let ast._fn f = rec(inputs = inputs,
+ output = output,
+ body = body);
+ ret tup(id, ast.item_fn(@f));
+ }
+ }
+ p.err("expecting item");
+ fail;
}
//
diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc
index 4e186b17..5f5bc893 100644
--- a/src/comp/rustc.rc
+++ b/src/comp/rustc.rc
@@ -12,6 +12,7 @@ mod fe {
mod driver {
mod rustc;
+ mod session;
}
mod util {
diff --git a/src/comp/util/common.rs b/src/comp/util/common.rs
index 51d843b4..9bcb67b2 100644
--- a/src/comp/util/common.rs
+++ b/src/comp/util/common.rs
@@ -1,3 +1,7 @@
+import std._uint;
+
+type pos = rec(uint line, uint col);
+type span = rec(str filename, pos lo, pos hi);
type ty_mach = tag( ty_i8(), ty_i16(), ty_i32(), ty_i64(),
ty_u8(), ty_u16(), ty_u32(), ty_u64(),