about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-09-01 13:24:14 -0700
committerGraydon Hoare <graydon@mozilla.com>2010-09-01 13:24:14 -0700
commiteb90be779877caa2e2d51095301f83695d77dd44 (patch)
tree76756b9fa7e4cfc6284632b7cde93302d87348c4 /src/comp
parentb90e6b93c1d48d4a4816467dd489794bc2c89c9c (diff)
downloadrust-eb90be779877caa2e2d51095301f83695d77dd44.tar.gz
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 42bd91c59bf..a54639409ea 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 00000000000..3b92e073e68
--- /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 3a329dede1c..ba084979389 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 95aac8c519e..e2c83dccc88 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 d2da791017e..6ffd911e830 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 4e186b171ef..5f5bc893ae2 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 51d843b45e7..9bcb67b2dc8 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(),