diff options
Diffstat (limited to 'src/comp/front/parser.rs')
| -rw-r--r-- | src/comp/front/parser.rs | 170 |
1 files changed, 138 insertions, 32 deletions
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index f71fae61..1b29c285 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -1,5 +1,6 @@ import std._io; import std._vec; +import std._str; import std.option; import std.option.some; import std.option.none; @@ -114,6 +115,18 @@ impure fn parse_ident(parser p) -> ast.ident { } } + +impure fn parse_str_lit(parser p) -> ast.ident { + alt (p.peek()) { + case (token.LIT_STR(?s)) { p.bump(); ret s; } + case (_) { + p.err("expecting string literal"); + fail; + } + } +} + + impure fn parse_ty_fn(parser p, ast.span lo) -> ast.ty_ { impure fn parse_fn_input_ty(parser p) -> rec(ast.mode mode, @ast.ty ty) { auto mode; @@ -1405,6 +1418,34 @@ impure fn parse_item_obj(parser p, ast.layer lyr) -> @ast.item { ret @spanned(lo, meths.span, item); } +fn index_mod_item(@ast.item item, ast.mod_index index, uint u) { + alt (item.node) { + case (ast.item_const(?id, _, _, _, _)) { + index.insert(id, ast.mie_item(u)); + } + case (ast.item_fn(?id, _, _, _, _)) { + index.insert(id, ast.mie_item(u)); + } + case (ast.item_mod(?id, _, _)) { + index.insert(id, ast.mie_item(u)); + } + case (ast.item_ty(?id, _, _, _, _)) { + index.insert(id, ast.mie_item(u)); + } + case (ast.item_tag(?id, ?variants, _, _)) { + index.insert(id, ast.mie_item(u)); + let uint variant_idx = 0u; + for (ast.variant v in variants) { + index.insert(v.name, ast.mie_tag_variant(u, variant_idx)); + variant_idx += 1u; + } + } + case (ast.item_obj(?id, _, _, _, _)) { + index.insert(id, ast.mie_item(u)); + } + } +} + impure fn parse_mod_items(parser p, token.token term) -> ast._mod { auto index = new_str_hash[ast.mod_index_entry](); auto view_items = parse_view(p, index); @@ -1413,38 +1454,11 @@ impure fn parse_mod_items(parser p, token.token term) -> ast._mod { while (p.peek() != term) { auto item = parse_item(p); items += vec(item); - - // Index the item. - alt (item.node) { - case (ast.item_const(?id, _, _, _, _)) { - index.insert(id, ast.mie_item(u)); - } - case (ast.item_fn(?id, _, _, _, _)) { - index.insert(id, ast.mie_item(u)); - } - case (ast.item_mod(?id, _, _)) { - index.insert(id, ast.mie_item(u)); - } - case (ast.item_ty(?id, _, _, _, _)) { - index.insert(id, ast.mie_item(u)); - } - case (ast.item_tag(?id, ?variants, _, _)) { - index.insert(id, ast.mie_item(u)); - let uint variant_idx = 0u; - for (ast.variant v in variants) { - index.insert(v.name, ast.mie_tag_variant(u, variant_idx)); - variant_idx += 1u; - } - } - case (ast.item_obj(?id, _, _, _, _)) { - index.insert(id, ast.mie_item(u)); - } - } - + index_mod_item(item, index, u); u += 1u; } ret rec(view_items=view_items, items=items, index=index); - } +} impure fn parse_item_const(parser p) -> @ast.item { auto lo = p.get_span(); @@ -1765,20 +1779,112 @@ impure fn parse_view(parser p, ast.mod_index index) -> vec[@ast.view_item] { ret items; } -impure fn parse_crate_from_crate_file(parser p) -> @ast.crate { +impure fn parse_crate_from_source_file(parser p) -> @ast.crate { auto lo = p.get_span(); auto hi = lo; auto m = parse_mod_items(p, token.EOF); ret @spanned(lo, hi, rec(module=m)); } -impure fn parse_crate_from_source_file(parser p) -> @ast.crate { +// Logic for parsing crate files (.rc) +// +// Each crate file is a sequence of directives. +// +// Each directive imperatively extends its environment with 0 or more items. + +impure fn parse_crate_directive(str prefix, parser p, + &mutable vec[@ast.item] items, + hashmap[ast.ident,ast.mod_index_entry] index) +{ auto lo = p.get_span(); auto hi = lo; - auto m = parse_mod_items(p, token.EOF); + alt (p.peek()) { + case (token.CONST) { + auto c = parse_item_const(p); + index_mod_item(c, index, _vec.len[@ast.item](items)); + append[@ast.item](items, c); + } + case (token.MOD) { + p.bump(); + auto id = parse_ident(p); + auto file_path = id; + alt (p.peek()) { + case (token.EQ) { + p.bump(); + // FIXME: turn this into parse+eval expr + file_path = parse_str_lit(p); + } + case (_) {} + } + + // dir-qualify file path. + auto full_path = prefix + std.os.path_sep() + file_path; + + alt (p.peek()) { + + // mod x = "foo.rs"; + + case (token.SEMI) { + hi = p.get_span(); + p.bump(); + if (!_str.ends_with(full_path, ".rs")) { + full_path += ".rs"; + } + auto p0 = new_parser(p.get_session(), 0, full_path); + auto m0 = parse_mod_items(p0, token.EOF); + auto im = ast.item_mod(id, m0, p.next_def_id()); + auto i = @spanned(lo, hi, im); + index_mod_item(i, index, _vec.len[@ast.item](items)); + append[@ast.item](items, i); + } + + // mod x = "foo_dir" { ...directives... } + + case (token.LBRACE) { + p.bump(); + auto m0 = parse_crate_directives(full_path, p, + token.RBRACE); + hi = p.get_span(); + expect(p, token.RBRACE); + auto im = ast.item_mod(id, m0, p.next_def_id()); + auto i = @spanned(lo, hi, im); + index_mod_item(i, index, _vec.len[@ast.item](items)); + append[@ast.item](items, i); + } + + case (?t) { + unexpected(p, t); + } + } + } + } +} + +impure fn parse_crate_directives(str prefix, parser p, + token.token term) -> ast._mod { + auto index = new_str_hash[ast.mod_index_entry](); + auto view_items = parse_view(p, index); + + let vec[@ast.item] items = vec(); + + while (p.peek() != term) { + parse_crate_directive(prefix, p, items, index); + } + + ret rec(view_items=view_items, items=items, index=index); +} + +impure fn parse_crate_from_crate_file(parser p) -> @ast.crate { + auto lo = p.get_span(); + auto hi = lo; + auto prefix = std.path.dirname(lo.filename); + auto m = parse_crate_directives(prefix, p, token.EOF); + hi = p.get_span(); + expect(p, token.EOF); ret @spanned(lo, hi, rec(module=m)); } + // // Local Variables: // mode: rust |